Home | History | Annotate | Download | only in gpu
      1 /*
      2  * Copyright 2011 Google Inc.
      3  *
      4  * Use of this source code is governed by a BSD-style license that can be
      5  * found in the LICENSE file.
      6  */
      7 
      8 #ifndef GrRenderTarget_DEFINED
      9 #define GrRenderTarget_DEFINED
     10 
     11 #include "GrSurface.h"
     12 #include "SkRect.h"
     13 
     14 class GrStencilBuffer;
     15 class GrTexture;
     16 
     17 /**
     18  * GrRenderTarget represents a 2D buffer of pixels that can be rendered to.
     19  * A context's render target is set by setRenderTarget(). Render targets are
     20  * created by a createTexture with the kRenderTarget_TextureFlag flag.
     21  * Additionally, GrContext provides methods for creating GrRenderTargets
     22  * that wrap externally created render targets.
     23  */
     24 class GrRenderTarget : public GrSurface {
     25 public:
     26     SK_DECLARE_INST_COUNT(GrRenderTarget)
     27 
     28     // GrResource overrides
     29     virtual size_t gpuMemorySize() const SK_OVERRIDE;
     30 
     31     // GrSurface overrides
     32     /**
     33      * @return the texture associated with the render target, may be NULL.
     34      */
     35     virtual GrTexture* asTexture() SK_OVERRIDE { return fTexture; }
     36     virtual const GrTexture* asTexture() const SK_OVERRIDE { return fTexture; }
     37 
     38     /**
     39      * @return this render target.
     40      */
     41     virtual GrRenderTarget* asRenderTarget() SK_OVERRIDE { return this; }
     42     virtual const GrRenderTarget* asRenderTarget() const  SK_OVERRIDE {
     43         return this;
     44     }
     45 
     46     virtual bool readPixels(int left, int top, int width, int height,
     47                             GrPixelConfig config,
     48                             void* buffer,
     49                             size_t rowBytes = 0,
     50                             uint32_t pixelOpsFlags = 0) SK_OVERRIDE;
     51 
     52     virtual void writePixels(int left, int top, int width, int height,
     53                              GrPixelConfig config,
     54                              const void* buffer,
     55                              size_t rowBytes = 0,
     56                              uint32_t pixelOpsFlags = 0) SK_OVERRIDE;
     57 
     58     // GrRenderTarget
     59     /**
     60      * If this RT is multisampled, this is the multisample buffer
     61      * @return the 3D API's handle to this object (e.g. FBO ID in OpenGL)
     62      */
     63     virtual GrBackendObject getRenderTargetHandle() const = 0;
     64 
     65     /**
     66      * If this RT is multisampled, this is the buffer it is resolved to.
     67      * Otherwise, same as getRenderTargetHandle().
     68      * (In GL a separate FBO ID is used for the MSAA and resolved buffers)
     69      * @return the 3D API's handle to this object (e.g. FBO ID in OpenGL)
     70      */
     71     virtual GrBackendObject getRenderTargetResolvedHandle() const = 0;
     72 
     73     /**
     74      * @return true if the surface is multisampled, false otherwise
     75      */
     76     bool isMultisampled() const { return 0 != fDesc.fSampleCnt; }
     77 
     78     /**
     79      * @return the number of samples-per-pixel or zero if non-MSAA.
     80      */
     81     int numSamples() const { return fDesc.fSampleCnt; }
     82 
     83     /**
     84      * Call to indicate the multisample contents were modified such that the
     85      * render target needs to be resolved before it can be used as texture. Gr
     86      * tracks this for its own drawing and thus this only needs to be called
     87      * when the render target has been modified outside of Gr. This has no
     88      * effect on wrapped backend render targets.
     89      *
     90      * @param rect  a rect bounding the area needing resolve. NULL indicates
     91      *              the whole RT needs resolving.
     92      */
     93     void flagAsNeedingResolve(const SkIRect* rect = NULL);
     94 
     95     /**
     96      * Call to override the region that needs to be resolved.
     97      */
     98     void overrideResolveRect(const SkIRect rect);
     99 
    100     /**
    101      * Call to indicate that GrRenderTarget was externally resolved. This may
    102      * allow Gr to skip a redundant resolve step.
    103      */
    104     void flagAsResolved() { fResolveRect.setLargestInverted(); }
    105 
    106     /**
    107      * @return true if the GrRenderTarget requires MSAA resolving
    108      */
    109     bool needsResolve() const { return !fResolveRect.isEmpty(); }
    110 
    111     /**
    112      * Returns a rect bounding the region needing resolving.
    113      */
    114     const SkIRect& getResolveRect() const { return fResolveRect; }
    115 
    116     /**
    117      * If the render target is multisampled this will perform a multisample
    118      * resolve. Any pending draws to the target are first flushed. This only
    119      * applies to render targets that are associated with GrTextures. After the
    120      * function returns the GrTexture will contain the resolved pixels.
    121      */
    122     void resolve();
    123 
    124     /**
    125      * Provide a performance hint that the render target's contents are allowed
    126      * to become undefined.
    127      */
    128     void discard();
    129 
    130     // a MSAA RT may require explicit resolving , it may auto-resolve (e.g. FBO
    131     // 0 in GL), or be unresolvable because the client didn't give us the
    132     // resolve destination.
    133     enum ResolveType {
    134         kCanResolve_ResolveType,
    135         kAutoResolves_ResolveType,
    136         kCantResolve_ResolveType,
    137     };
    138     virtual ResolveType getResolveType() const = 0;
    139 
    140     /**
    141      * GrStencilBuffer is not part of the public API.
    142      */
    143     GrStencilBuffer* getStencilBuffer() const { return fStencilBuffer; }
    144     void setStencilBuffer(GrStencilBuffer* stencilBuffer);
    145 
    146 protected:
    147     GrRenderTarget(GrGpu* gpu,
    148                    bool isWrapped,
    149                    GrTexture* texture,
    150                    const GrTextureDesc& desc)
    151         : INHERITED(gpu, isWrapped, desc)
    152         , fStencilBuffer(NULL)
    153         , fTexture(texture) {
    154         fResolveRect.setLargestInverted();
    155     }
    156 
    157     // override of GrResource
    158     virtual void onAbandon() SK_OVERRIDE;
    159     virtual void onRelease() SK_OVERRIDE;
    160 
    161 private:
    162     friend class GrTexture;
    163     // called by ~GrTexture to remove the non-ref'ed back ptr.
    164     void owningTextureDestroyed() {
    165         SkASSERT(NULL != fTexture);
    166         fTexture = NULL;
    167     }
    168 
    169     GrStencilBuffer*  fStencilBuffer;
    170     GrTexture*        fTexture; // not ref'ed
    171 
    172     SkIRect           fResolveRect;
    173 
    174     typedef GrSurface INHERITED;
    175 };
    176 
    177 #endif
    178