1 /* 2 Copyright 2011 Google Inc. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 18 #ifndef GrTexture_DEFINED 19 #define GrTexture_DEFINED 20 21 #include "GrRefCnt.h" 22 #include "GrClip.h" 23 #include "GrResource.h" 24 25 class GrTexture; 26 27 /** 28 * GrRenderTarget represents a 2D buffer of pixels that can be rendered to. 29 * A context's render target is set by setRenderTarget(). Render targets are 30 * created by a createTexture with the kRenderTarget_TextureFlag flag. 31 * Additionally, GrContext provides methods for creating GrRenderTargets 32 * that wrap externally created render targets. 33 */ 34 class GrRenderTarget : public GrResource { 35 36 public: 37 /** 38 * @return the width of the rendertarget 39 */ 40 int width() const { return fWidth; } 41 /** 42 * @return the height of the rendertarget 43 */ 44 int height() const { return fHeight; } 45 46 /** 47 * @return the number of stencil bits in the rendertarget 48 */ 49 int stencilBits() const { return fStencilBits; } 50 51 /** 52 * @return the texture associated with the rendertarget, may be NULL. 53 */ 54 GrTexture* asTexture() {return fTexture;} 55 56 /** 57 * @return true if the render target is multisampled, false otherwise 58 */ 59 bool isMultisampled() { return fIsMultisampled; } 60 61 /** 62 * Call to indicate the multisample contents were modified such that the 63 * render target needs to be resolved before it can be used as texture. Gr 64 * tracks this for its own drawing and thus this only needs to be called 65 * when the render target has been modified outside of Gr. Only meaningful 66 * for Gr-created RT/Textures and Platform RT/Textures created with the 67 * kGrCanResolve flag. 68 * @param rect a rect bounding the area needing resolve. NULL indicates 69 * the whole RT needs resolving. 70 */ 71 void flagAsNeedingResolve(const GrIRect* rect = NULL); 72 73 /** 74 * Call to override the region that needs to be resolved. 75 */ 76 void overrideResolveRect(const GrIRect rect); 77 78 /** 79 * Call to indicate that GrRenderTarget was externally resolved. This may 80 * allow Gr to skip a redundant resolve step. 81 */ 82 void flagAsResolved() { fResolveRect.setLargestInverted(); } 83 84 /** 85 * @return true if the GrRenderTarget requires MSAA resolving 86 */ 87 bool needsResolve() const { return !fResolveRect.isEmpty(); } 88 89 /** 90 * Returns a rect bounding the region needing resolving. 91 */ 92 const GrIRect& getResolveRect() const { return fResolveRect; } 93 94 /** 95 * Reads a rectangle of pixels from the render target. 96 * @param left left edge of the rectangle to read (inclusive) 97 * @param top top edge of the rectangle to read (inclusive) 98 * @param width width of rectangle to read in pixels. 99 * @param height height of rectangle to read in pixels. 100 * @param config the pixel config of the destination buffer 101 * @param buffer memory to read the rectangle into. 102 * 103 * @return true if the read succeeded, false if not. The read can fail 104 * because of a unsupported pixel config. 105 */ 106 bool readPixels(int left, int top, int width, int height, 107 GrPixelConfig config, void* buffer); 108 109 // a MSAA RT may require explicit resolving , it may auto-resolve (e.g. FBO 110 // 0 in GL), or be unresolvable because the client didn't give us the 111 // resolve destination. 112 enum ResolveType { 113 kCanResolve_ResolveType, 114 kAutoResolves_ResolveType, 115 kCantResolve_ResolveType, 116 }; 117 virtual ResolveType getResolveType() const = 0; 118 119 protected: 120 GrRenderTarget(GrGpu* gpu, 121 GrTexture* texture, 122 int width, 123 int height, 124 int stencilBits, 125 bool isMultisampled) 126 : INHERITED(gpu) 127 , fTexture(texture) 128 , fWidth(width) 129 , fHeight(height) 130 , fStencilBits(stencilBits) 131 , fIsMultisampled(isMultisampled) 132 { 133 fResolveRect.setLargestInverted(); 134 } 135 136 friend class GrTexture; 137 // When a texture unrefs an owned rendertarget this func 138 // removes the back pointer. This could be done called from 139 // texture's destructor but would have to be done in derived 140 // class. By the time of texture base destructor it has already 141 // lost its pointer to the rt. 142 void onTextureReleaseRenderTarget() { 143 GrAssert(NULL != fTexture); 144 fTexture = NULL; 145 } 146 147 private: 148 GrTexture* fTexture; // not ref'ed 149 int fWidth; 150 int fHeight; 151 int fStencilBits; 152 bool fIsMultisampled; 153 GrIRect fResolveRect; 154 155 // GrGpu keeps a cached clip in the render target to avoid redundantly 156 // rendering the clip into the same stencil buffer. 157 friend class GrGpu; 158 GrClip fLastStencilClip; 159 160 typedef GrResource INHERITED; 161 }; 162 163 class GrTexture : public GrResource { 164 165 public: 166 /** 167 * Retrieves the width of the texture. 168 * 169 * @return the width in texels 170 */ 171 int width() const { return fWidth; } 172 173 /** 174 * Retrieves the height of the texture. 175 * 176 * @return the height in texels 177 */ 178 int height() const { return fHeight; } 179 180 /** 181 * Convert from texels to normalized texture coords for POT textures 182 * only. 183 */ 184 GrFixed normalizeFixedX(GrFixed x) const { GrAssert(GrIsPow2(fWidth)); 185 return x >> fShiftFixedX; } 186 GrFixed normalizeFixedY(GrFixed y) const { GrAssert(GrIsPow2(fHeight)); 187 return y >> fShiftFixedY; } 188 189 /** 190 * Retrieves the pixel config specified when the texture was created. 191 */ 192 GrPixelConfig config() const { return fConfig; } 193 194 /** 195 * Approximate number of bytes used by the texture 196 */ 197 size_t sizeInBytes() const { 198 return fWidth * fHeight * GrBytesPerPixel(fConfig); 199 } 200 201 /** 202 * Updates a subrectangle of texels in the texture. 203 * 204 * @param x left edge of rectangle to update 205 * @param y top edge of rectangle to update 206 * @param width width of rectangle to update 207 * @param height height of rectangle to update 208 * @param srcData width*height texels of data in same format that was used 209 * at texture creation. 210 */ 211 virtual void uploadTextureData(uint32_t x, 212 uint32_t y, 213 uint32_t width, 214 uint32_t height, 215 const void* srcData) = 0; 216 217 /** 218 * Reads a rectangle of pixels from the texture. 219 * @param left left edge of the rectangle to read (inclusive) 220 * @param top top edge of the rectangle to read (inclusive) 221 * @param width width of rectangle to read in pixels. 222 * @param height height of rectangle to read in pixels. 223 * @param config the pixel config of the destination buffer 224 * @param buffer memory to read the rectangle into. 225 * 226 * @return true if the read succeeded, false if not. The read can fail 227 * because of a unsupported pixel config. 228 */ 229 bool readPixels(int left, int top, int width, int height, 230 GrPixelConfig config, void* buffer); 231 232 /** 233 * Retrieves the render target underlying this texture that can be passed to 234 * GrGpu::setRenderTarget(). 235 * 236 * @return handle to render target or NULL if the texture is not a 237 * render target 238 */ 239 GrRenderTarget* asRenderTarget() { return fRenderTarget; } 240 241 /** 242 * Removes the reference on the associated GrRenderTarget held by this 243 * texture. Afterwards asRenderTarget() will return NULL. The 244 * GrRenderTarget survives the release if another ref is held on it. 245 */ 246 void releaseRenderTarget() { 247 if (NULL != fRenderTarget) { 248 GrAssert(fRenderTarget->asTexture() == this); 249 fRenderTarget->onTextureReleaseRenderTarget(); 250 fRenderTarget->unref(); 251 fRenderTarget = NULL; 252 } 253 } 254 255 /** 256 * Return the native ID or handle to the texture, depending on the 257 * platform. e.g. on opengl, return the texture ID. 258 */ 259 virtual intptr_t getTextureHandle() = 0; 260 261 #if GR_DEBUG 262 void validate() const { 263 this->INHERITED::validate(); 264 } 265 #else 266 void validate() const {} 267 #endif 268 269 protected: 270 GrRenderTarget* fRenderTarget; // texture refs its rt representation 271 // base class cons sets to NULL 272 // subclass cons can create and set 273 274 GrTexture(GrGpu* gpu, 275 int width, 276 int height, 277 GrPixelConfig config) 278 : INHERITED(gpu) 279 , fRenderTarget(NULL) 280 , fWidth(width) 281 , fHeight(height) 282 , fConfig(config) { 283 // only make sense if alloc size is pow2 284 fShiftFixedX = 31 - Gr_clz(fWidth); 285 fShiftFixedY = 31 - Gr_clz(fHeight); 286 } 287 288 // GrResource overrides 289 virtual void onRelease() { 290 releaseRenderTarget(); 291 } 292 293 virtual void onAbandon() { 294 if (NULL != fRenderTarget) { 295 fRenderTarget->abandon(); 296 } 297 } 298 299 private: 300 int fWidth; 301 int fHeight; 302 // these two shift a fixed-point value into normalized coordinates 303 // for this texture if the texture is power of two sized. 304 int fShiftFixedX; 305 int fShiftFixedY; 306 307 GrPixelConfig fConfig; 308 309 typedef GrResource INHERITED; 310 }; 311 312 #endif 313 314