• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
asRenderTarget()28     GrRenderTarget* asRenderTarget() override { return this; }
asRenderTarget()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      */
isUnifiedMultisampled()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      */
isStencilBufferMultisampled()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      */
numColorSamples()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      */
numStencilSamples()80     int numStencilSamples() const {
81         return fDesc.fSampleCnt;
82     }
83 
84     /**
85      * @return true if the surface is mixed sampled, false otherwise.
86      */
hasMixedSamples()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      */
flagAsResolved()114     void flagAsResolved() { fResolveRect.setLargestInverted(); }
115 
116     /**
117      * @return true if the GrRenderTarget requires MSAA resolving
118      */
needsResolve()119     bool needsResolve() const { return !fResolveRect.isEmpty(); }
120 
121     /**
122      * Returns a rect bounding the region needing resolving.
123      */
getResolveRect()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);
getLastDrawTarget()156     GrDrawTarget* getLastDrawTarget() { return fLastDrawTarget; }
157 
158 protected:
159     GrRenderTarget(GrGpu* gpu, LifeCycle lifeCycle, const GrSurfaceDesc& desc,
160                    SampleConfig sampleConfig, GrStencilAttachment* stencil = nullptr)
INHERITED(gpu,lifeCycle,desc)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