michael@0: /* michael@0: * Copyright 2011 Google Inc. michael@0: * michael@0: * Use of this source code is governed by a BSD-style license that can be michael@0: * found in the LICENSE file. michael@0: */ michael@0: michael@0: #ifndef GrRenderTarget_DEFINED michael@0: #define GrRenderTarget_DEFINED michael@0: michael@0: #include "GrSurface.h" michael@0: #include "SkRect.h" michael@0: michael@0: class GrStencilBuffer; michael@0: class GrTexture; michael@0: michael@0: /** michael@0: * GrRenderTarget represents a 2D buffer of pixels that can be rendered to. michael@0: * A context's render target is set by setRenderTarget(). Render targets are michael@0: * created by a createTexture with the kRenderTarget_TextureFlag flag. michael@0: * Additionally, GrContext provides methods for creating GrRenderTargets michael@0: * that wrap externally created render targets. michael@0: */ michael@0: class GrRenderTarget : public GrSurface { michael@0: public: michael@0: SK_DECLARE_INST_COUNT(GrRenderTarget) michael@0: michael@0: // GrResource overrides michael@0: virtual size_t sizeInBytes() const SK_OVERRIDE; michael@0: michael@0: // GrSurface overrides michael@0: /** michael@0: * @return the texture associated with the render target, may be NULL. michael@0: */ michael@0: virtual GrTexture* asTexture() SK_OVERRIDE { return fTexture; } michael@0: virtual const GrTexture* asTexture() const SK_OVERRIDE { return fTexture; } michael@0: michael@0: /** michael@0: * @return this render target. michael@0: */ michael@0: virtual GrRenderTarget* asRenderTarget() SK_OVERRIDE { return this; } michael@0: virtual const GrRenderTarget* asRenderTarget() const SK_OVERRIDE { michael@0: return this; michael@0: } michael@0: michael@0: virtual bool readPixels(int left, int top, int width, int height, michael@0: GrPixelConfig config, michael@0: void* buffer, michael@0: size_t rowBytes = 0, michael@0: uint32_t pixelOpsFlags = 0) SK_OVERRIDE; michael@0: michael@0: virtual void writePixels(int left, int top, int width, int height, michael@0: GrPixelConfig config, michael@0: const void* buffer, michael@0: size_t rowBytes = 0, michael@0: uint32_t pixelOpsFlags = 0) SK_OVERRIDE; michael@0: michael@0: // GrRenderTarget michael@0: /** michael@0: * If this RT is multisampled, this is the multisample buffer michael@0: * @return the 3D API's handle to this object (e.g. FBO ID in OpenGL) michael@0: */ michael@0: virtual GrBackendObject getRenderTargetHandle() const = 0; michael@0: michael@0: /** michael@0: * If this RT is multisampled, this is the buffer it is resolved to. michael@0: * Otherwise, same as getRenderTargetHandle(). michael@0: * (In GL a separate FBO ID is used for the MSAA and resolved buffers) michael@0: * @return the 3D API's handle to this object (e.g. FBO ID in OpenGL) michael@0: */ michael@0: virtual GrBackendObject getRenderTargetResolvedHandle() const = 0; michael@0: michael@0: /** michael@0: * @return true if the surface is multisampled, false otherwise michael@0: */ michael@0: bool isMultisampled() const { return 0 != fDesc.fSampleCnt; } michael@0: michael@0: /** michael@0: * @return the number of samples-per-pixel or zero if non-MSAA. michael@0: */ michael@0: int numSamples() const { return fDesc.fSampleCnt; } michael@0: michael@0: /** michael@0: * Call to indicate the multisample contents were modified such that the michael@0: * render target needs to be resolved before it can be used as texture. Gr michael@0: * tracks this for its own drawing and thus this only needs to be called michael@0: * when the render target has been modified outside of Gr. This has no michael@0: * effect on wrapped backend render targets. michael@0: * michael@0: * @param rect a rect bounding the area needing resolve. NULL indicates michael@0: * the whole RT needs resolving. michael@0: */ michael@0: void flagAsNeedingResolve(const SkIRect* rect = NULL); michael@0: michael@0: /** michael@0: * Call to override the region that needs to be resolved. michael@0: */ michael@0: void overrideResolveRect(const SkIRect rect); michael@0: michael@0: /** michael@0: * Call to indicate that GrRenderTarget was externally resolved. This may michael@0: * allow Gr to skip a redundant resolve step. michael@0: */ michael@0: void flagAsResolved() { fResolveRect.setLargestInverted(); } michael@0: michael@0: /** michael@0: * @return true if the GrRenderTarget requires MSAA resolving michael@0: */ michael@0: bool needsResolve() const { return !fResolveRect.isEmpty(); } michael@0: michael@0: /** michael@0: * Returns a rect bounding the region needing resolving. michael@0: */ michael@0: const SkIRect& getResolveRect() const { return fResolveRect; } michael@0: michael@0: /** michael@0: * If the render target is multisampled this will perform a multisample michael@0: * resolve. Any pending draws to the target are first flushed. This only michael@0: * applies to render targets that are associated with GrTextures. After the michael@0: * function returns the GrTexture will contain the resolved pixels. michael@0: */ michael@0: void resolve(); michael@0: michael@0: // a MSAA RT may require explicit resolving , it may auto-resolve (e.g. FBO michael@0: // 0 in GL), or be unresolvable because the client didn't give us the michael@0: // resolve destination. michael@0: enum ResolveType { michael@0: kCanResolve_ResolveType, michael@0: kAutoResolves_ResolveType, michael@0: kCantResolve_ResolveType, michael@0: }; michael@0: virtual ResolveType getResolveType() const = 0; michael@0: michael@0: /** michael@0: * GrStencilBuffer is not part of the public API. michael@0: */ michael@0: GrStencilBuffer* getStencilBuffer() const { return fStencilBuffer; } michael@0: void setStencilBuffer(GrStencilBuffer* stencilBuffer); michael@0: michael@0: protected: michael@0: GrRenderTarget(GrGpu* gpu, michael@0: bool isWrapped, michael@0: GrTexture* texture, michael@0: const GrTextureDesc& desc) michael@0: : INHERITED(gpu, isWrapped, desc) michael@0: , fStencilBuffer(NULL) michael@0: , fTexture(texture) { michael@0: fResolveRect.setLargestInverted(); michael@0: } michael@0: michael@0: // override of GrResource michael@0: virtual void onAbandon() SK_OVERRIDE; michael@0: virtual void onRelease() SK_OVERRIDE; michael@0: michael@0: private: michael@0: friend class GrTexture; michael@0: // called by ~GrTexture to remove the non-ref'ed back ptr. michael@0: void owningTextureDestroyed() { michael@0: SkASSERT(NULL != fTexture); michael@0: fTexture = NULL; michael@0: } michael@0: michael@0: GrStencilBuffer* fStencilBuffer; michael@0: GrTexture* fTexture; // not ref'ed michael@0: michael@0: SkIRect fResolveRect; michael@0: michael@0: typedef GrSurface INHERITED; michael@0: }; michael@0: michael@0: #endif