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