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 GrDrawTarget;
     15 class GrStencilAttachment;
     16 class GrRenderTargetPriv;
     17 
     18 /**
     19  * GrRenderTarget represents a 2D buffer of pixels that can be rendered to.
     20  * A context's render target is set by setRenderTarget(). Render targets are
     21  * created by a createTexture with the kRenderTarget_SurfaceFlag flag.
     22  * Additionally, GrContext provides methods for creating GrRenderTargets
     23  * that wrap externally created render targets.
     24  */
     25 class GrRenderTarget : virtual public GrSurface {
     26 public:
     27     // GrSurface overrides
     28     GrRenderTarget* asRenderTarget() override { return this; }
     29     const GrRenderTarget* asRenderTarget() const  override { return this; }
     30 
     31     // GrRenderTarget
     32     /**
     33      * On some hardware it is possible for a render target to have multisampling
     34      * only in certain buffers.
     35      * Enforce only two legal sample configs.
     36      * kUnified_SampleConfig signifies multisampling in both color and stencil
     37      * buffers and is available across all hardware.
     38      * kStencil_SampleConfig means multisampling is present in stencil buffer
     39      * only; this config requires hardware support of
     40      * NV_framebuffer_mixed_samples.
     41     */
     42     enum SampleConfig {
     43         kUnified_SampleConfig = 0,
     44         kStencil_SampleConfig = 1
     45     };
     46 
     47     /**
     48      * @return true if the surface is multisampled in all buffers,
     49      *         false otherwise
     50      */
     51     bool isUnifiedMultisampled() const {
     52         if (fSampleConfig != kUnified_SampleConfig) {
     53             return false;
     54         }
     55         return 0 != fDesc.fSampleCnt;
     56     }
     57 
     58     /**
     59      * @return true if the surface is multisampled in the stencil buffer,
     60      *         false otherwise
     61      */
     62     bool isStencilBufferMultisampled() const {
     63         return 0 != fDesc.fSampleCnt;
     64     }
     65 
     66     /**
     67      * @return the number of color samples-per-pixel, or zero if non-MSAA or
     68      *         multisampled in the stencil buffer only.
     69      */
     70     int numColorSamples() const {
     71         if (fSampleConfig == kUnified_SampleConfig) {
     72             return fDesc.fSampleCnt;
     73         }
     74         return 0;
     75     }
     76 
     77     /**
     78      * @return the number of stencil samples-per-pixel, or zero if non-MSAA.
     79      */
     80     int numStencilSamples() const {
     81         return fDesc.fSampleCnt;
     82     }
     83 
     84     /**
     85      * @return true if the surface is mixed sampled, false otherwise.
     86      */
     87     bool hasMixedSamples() const {
     88         SkASSERT(kStencil_SampleConfig != fSampleConfig ||
     89                  this->isStencilBufferMultisampled());
     90         return kStencil_SampleConfig == fSampleConfig;
     91     }
     92 
     93     /**
     94      * Call to indicate the multisample contents were modified such that the
     95      * render target needs to be resolved before it can be used as texture. Gr
     96      * tracks this for its own drawing and thus this only needs to be called
     97      * when the render target has been modified outside of Gr. This has no
     98      * effect on wrapped backend render targets.
     99      *
    100      * @param rect  a rect bounding the area needing resolve. NULL indicates
    101      *              the whole RT needs resolving.
    102      */
    103     void flagAsNeedingResolve(const SkIRect* rect = NULL);
    104 
    105     /**
    106      * Call to override the region that needs to be resolved.
    107      */
    108     void overrideResolveRect(const SkIRect rect);
    109 
    110     /**
    111      * Call to indicate that GrRenderTarget was externally resolved. This may
    112      * allow Gr to skip a redundant resolve step.
    113      */
    114     void flagAsResolved() { fResolveRect.setLargestInverted(); }
    115 
    116     /**
    117      * @return true if the GrRenderTarget requires MSAA resolving
    118      */
    119     bool needsResolve() const { return !fResolveRect.isEmpty(); }
    120 
    121     /**
    122      * Returns a rect bounding the region needing resolving.
    123      */
    124     const SkIRect& getResolveRect() const { return fResolveRect; }
    125 
    126     /**
    127      * Provide a performance hint that the render target's contents are allowed
    128      * to become undefined.
    129      */
    130     void discard();
    131 
    132     // a MSAA RT may require explicit resolving , it may auto-resolve (e.g. FBO
    133     // 0 in GL), or be unresolvable because the client didn't give us the
    134     // resolve destination.
    135     enum ResolveType {
    136         kCanResolve_ResolveType,
    137         kAutoResolves_ResolveType,
    138         kCantResolve_ResolveType,
    139     };
    140     virtual ResolveType getResolveType() const = 0;
    141 
    142     /**
    143      *  Return the native ID or handle to the rendertarget, depending on the
    144      *  platform. e.g. on OpenGL, return the FBO ID.
    145      */
    146     virtual GrBackendObject getRenderTargetHandle() const = 0;
    147 
    148     // Checked when this object is asked to attach a stencil buffer.
    149     virtual bool canAttemptStencilAttachment() const = 0;
    150 
    151     // Provides access to functions that aren't part of the public API.
    152     GrRenderTargetPriv renderTargetPriv();
    153     const GrRenderTargetPriv renderTargetPriv() const;
    154 
    155     void setLastDrawTarget(GrDrawTarget* dt);
    156     GrDrawTarget* getLastDrawTarget() { return fLastDrawTarget; }
    157 
    158 protected:
    159     GrRenderTarget(GrGpu* gpu, LifeCycle lifeCycle, const GrSurfaceDesc& desc,
    160                    SampleConfig sampleConfig, GrStencilAttachment* stencil = nullptr)
    161         : INHERITED(gpu, lifeCycle, desc)
    162         , fStencilAttachment(stencil)
    163         , fSampleConfig(sampleConfig)
    164         , fLastDrawTarget(nullptr) {
    165         fResolveRect.setLargestInverted();
    166     }
    167 
    168     ~GrRenderTarget() override;
    169 
    170     // override of GrResource
    171     void onAbandon() override;
    172     void onRelease() override;
    173 
    174 private:
    175     // Allows the backends to perform any additional work that is required for attaching a
    176     // GrStencilAttachment. When this is called, the GrStencilAttachment has already been put onto
    177     // the GrRenderTarget. This function must return false if any failures occur when completing the
    178     // stencil attachment.
    179     virtual bool completeStencilAttachment() = 0;
    180 
    181     friend class GrRenderTargetPriv;
    182 
    183     GrStencilAttachment*  fStencilAttachment;
    184     SampleConfig          fSampleConfig;
    185 
    186     SkIRect               fResolveRect;
    187 
    188     // The last drawTarget that wrote to or is currently going to write to this renderTarget
    189     // The drawTarget can be closed (e.g., no draw context is currently bound
    190     // to this renderTarget).
    191     // This back-pointer is required so that we can add a dependancy between
    192     // the drawTarget used to create the current contents of this renderTarget
    193     // and the drawTarget of a destination renderTarget to which this one is being drawn.
    194     GrDrawTarget* fLastDrawTarget;
    195 
    196     typedef GrSurface INHERITED;
    197 };
    198 
    199 
    200 #endif
    201