blob: cadf0f274778deed60e25e1c021c2431ad7e609e [file] [log] [blame]
reed@google.comac10a2d2010-12-22 21:39:39 +00001/*
bsalomon@google.com1da07462011-03-10 14:51:57 +00002 Copyright 2011 Google Inc.
reed@google.comac10a2d2010-12-22 21:39:39 +00003
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"
bsalomon@google.comd302f142011-03-03 13:54:13 +000022#include "GrClip.h"
bsalomon@google.com8fe72472011-03-30 21:26:44 +000023#include "GrResource.h"
reed@google.comac10a2d2010-12-22 21:39:39 +000024
25class 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
bsalomon@google.com1c13c962011-02-14 16:51:21 +000030 * created by a createTexture with the kRenderTarget_TextureFlag flag.
31 * Additionally, GrContext provides methods for creating GrRenderTargets
32 * that wrap externally created render targets.
reed@google.comac10a2d2010-12-22 21:39:39 +000033 */
bsalomon@google.com8fe72472011-03-30 21:26:44 +000034class GrRenderTarget : public GrResource {
bsalomon@google.com6dcf4992011-04-05 21:16:14 +000035
reed@google.comac10a2d2010-12-22 21:39:39 +000036public:
37 /**
38 * @return the width of the rendertarget
39 */
bsalomon@google.comd302f142011-03-03 13:54:13 +000040 int width() const { return fWidth; }
reed@google.comac10a2d2010-12-22 21:39:39 +000041 /**
42 * @return the height of the rendertarget
43 */
bsalomon@google.comd302f142011-03-03 13:54:13 +000044 int height() const { return fHeight; }
45
46 /**
bsalomon@google.comcee661a2011-07-26 12:32:36 +000047 * @return the pixel config. Can be kUnknown_GrPixelConfig
48 * if client asked us to render to a target that has a pixel
49 * config that isn't equivalent with one of our configs.
50 */
51 int config() const { return fConfig; }
52
53 /**
bsalomon@google.comd302f142011-03-03 13:54:13 +000054 * @return the number of stencil bits in the rendertarget
55 */
56 int stencilBits() const { return fStencilBits; }
bsalomon@google.com1c13c962011-02-14 16:51:21 +000057
reed@google.comac10a2d2010-12-22 21:39:39 +000058 /**
59 * @return the texture associated with the rendertarget, may be NULL.
60 */
61 GrTexture* asTexture() {return fTexture;}
62
bsalomon@google.com669fdc42011-04-05 17:08:27 +000063 /**
bsalomon@google.com0b96a842011-07-13 21:53:49 +000064 * If this RT is multisampled, this is the multisample buffer
65 * @return the 3D API's handle to this object (e.g. FBO ID in OpenGL)
66 */
67 virtual intptr_t getRenderTargetHandle() const = 0;
68
69 /**
70 * If this RT is multisampled, this is the buffer it is resolved to.
71 * Otherwise, same as getRenderTargetHandle().
72 * (In GL a separate FBO ID is used for the msaa and resolved buffers)
73 * @return the 3D API's handle to this object (e.g. FBO ID in OpenGL)
74 */
75 virtual intptr_t getRenderTargetResolvedHandle() const = 0;
76
77 /**
bsalomon@google.comf954d8d2011-04-06 17:50:02 +000078 * @return true if the render target is multisampled, false otherwise
79 */
80 bool isMultisampled() { return fIsMultisampled; }
81
82 /**
bsalomon@google.com5877ffd2011-04-11 17:58:48 +000083 * Call to indicate the multisample contents were modified such that the
84 * render target needs to be resolved before it can be used as texture. Gr
85 * tracks this for its own drawing and thus this only needs to be called
86 * when the render target has been modified outside of Gr. Only meaningful
87 * for Gr-created RT/Textures and Platform RT/Textures created with the
88 * kGrCanResolve flag.
bsalomon@google.com8295dc12011-05-02 12:53:34 +000089 * @param rect a rect bounding the area needing resolve. NULL indicates
90 * the whole RT needs resolving.
bsalomon@google.com5877ffd2011-04-11 17:58:48 +000091 */
bsalomon@google.com8295dc12011-05-02 12:53:34 +000092 void flagAsNeedingResolve(const GrIRect* rect = NULL);
93
94 /**
95 * Call to override the region that needs to be resolved.
96 */
97 void overrideResolveRect(const GrIRect rect);
bsalomon@google.com5877ffd2011-04-11 17:58:48 +000098
99 /**
100 * Call to indicate that GrRenderTarget was externally resolved. This may
101 * allow Gr to skip a redundant resolve step.
102 */
bsalomon@google.com8295dc12011-05-02 12:53:34 +0000103 void flagAsResolved() { fResolveRect.setLargestInverted(); }
bsalomon@google.com5877ffd2011-04-11 17:58:48 +0000104
105 /**
106 * @return true if the GrRenderTarget requires MSAA resolving
107 */
bsalomon@google.com8295dc12011-05-02 12:53:34 +0000108 bool needsResolve() const { return !fResolveRect.isEmpty(); }
109
110 /**
111 * Returns a rect bounding the region needing resolving.
112 */
113 const GrIRect& getResolveRect() const { return fResolveRect; }
bsalomon@google.com5877ffd2011-04-11 17:58:48 +0000114
bsalomon@google.comcee661a2011-07-26 12:32:36 +0000115 // GrResource overrides
116 virtual size_t sizeInBytes() const;
117
bsalomon@google.com5877ffd2011-04-11 17:58:48 +0000118 /**
bsalomon@google.com669fdc42011-04-05 17:08:27 +0000119 * Reads a rectangle of pixels from the render target.
120 * @param left left edge of the rectangle to read (inclusive)
121 * @param top top edge of the rectangle to read (inclusive)
122 * @param width width of rectangle to read in pixels.
123 * @param height height of rectangle to read in pixels.
124 * @param config the pixel config of the destination buffer
125 * @param buffer memory to read the rectangle into.
126 *
127 * @return true if the read succeeded, false if not. The read can fail
128 * because of a unsupported pixel config.
129 */
130 bool readPixels(int left, int top, int width, int height,
131 GrPixelConfig config, void* buffer);
132
bsalomon@google.com5877ffd2011-04-11 17:58:48 +0000133 // a MSAA RT may require explicit resolving , it may auto-resolve (e.g. FBO
134 // 0 in GL), or be unresolvable because the client didn't give us the
135 // resolve destination.
136 enum ResolveType {
137 kCanResolve_ResolveType,
138 kAutoResolves_ResolveType,
139 kCantResolve_ResolveType,
140 };
141 virtual ResolveType getResolveType() const = 0;
142
reed@google.comac10a2d2010-12-22 21:39:39 +0000143protected:
bsalomon@google.com8fe72472011-03-30 21:26:44 +0000144 GrRenderTarget(GrGpu* gpu,
145 GrTexture* texture,
bsalomon@google.comd302f142011-03-03 13:54:13 +0000146 int width,
147 int height,
bsalomon@google.comcee661a2011-07-26 12:32:36 +0000148 GrPixelConfig config,
bsalomon@google.comf954d8d2011-04-06 17:50:02 +0000149 int stencilBits,
150 bool isMultisampled)
bsalomon@google.com8fe72472011-03-30 21:26:44 +0000151 : INHERITED(gpu)
152 , fTexture(texture)
153 , fWidth(width)
154 , fHeight(height)
bsalomon@google.comcee661a2011-07-26 12:32:36 +0000155 , fConfig(config)
bsalomon@google.com8fe72472011-03-30 21:26:44 +0000156 , fStencilBits(stencilBits)
bsalomon@google.comf954d8d2011-04-06 17:50:02 +0000157 , fIsMultisampled(isMultisampled)
bsalomon@google.com8295dc12011-05-02 12:53:34 +0000158 {
159 fResolveRect.setLargestInverted();
160 }
bsalomon@google.comd302f142011-03-03 13:54:13 +0000161
bsalomon@google.com6dcf4992011-04-05 21:16:14 +0000162 friend class GrTexture;
163 // When a texture unrefs an owned rendertarget this func
164 // removes the back pointer. This could be done called from
165 // texture's destructor but would have to be done in derived
166 // class. By the time of texture base destructor it has already
167 // lost its pointer to the rt.
168 void onTextureReleaseRenderTarget() {
169 GrAssert(NULL != fTexture);
170 fTexture = NULL;
171 }
bsalomon@google.comd302f142011-03-03 13:54:13 +0000172
bsalomon@google.com8295dc12011-05-02 12:53:34 +0000173private:
bsalomon@google.com6dcf4992011-04-05 21:16:14 +0000174 GrTexture* fTexture; // not ref'ed
bsalomon@google.comcee661a2011-07-26 12:32:36 +0000175 int fWidth;
176 int fHeight;
177 GrPixelConfig fConfig;
178 int fStencilBits;
179 bool fIsMultisampled;
180 GrIRect fResolveRect;
bsalomon@google.comd302f142011-03-03 13:54:13 +0000181
bsalomon@google.comd302f142011-03-03 13:54:13 +0000182 // GrGpu keeps a cached clip in the render target to avoid redundantly
183 // rendering the clip into the same stencil buffer.
184 friend class GrGpu;
185 GrClip fLastStencilClip;
186
bsalomon@google.com8fe72472011-03-30 21:26:44 +0000187 typedef GrResource INHERITED;
reed@google.comac10a2d2010-12-22 21:39:39 +0000188};
189
bsalomon@google.com8fe72472011-03-30 21:26:44 +0000190class GrTexture : public GrResource {
bsalomon@google.com8fe72472011-03-30 21:26:44 +0000191
reed@google.comac10a2d2010-12-22 21:39:39 +0000192public:
reed@google.comac10a2d2010-12-22 21:39:39 +0000193 /**
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000194 * Retrieves the width of the texture.
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000195 *
reed@google.comac10a2d2010-12-22 21:39:39 +0000196 * @return the width in texels
197 */
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000198 int width() const { return fWidth; }
bsalomon@google.com8fe72472011-03-30 21:26:44 +0000199
reed@google.comac10a2d2010-12-22 21:39:39 +0000200 /**
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000201 * Retrieves the height of the texture.
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000202 *
reed@google.comac10a2d2010-12-22 21:39:39 +0000203 * @return the height in texels
204 */
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000205 int height() const { return fHeight; }
reed@google.comac10a2d2010-12-22 21:39:39 +0000206
207 /**
208 * Convert from texels to normalized texture coords for POT textures
209 * only.
210 */
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000211 GrFixed normalizeFixedX(GrFixed x) const { GrAssert(GrIsPow2(fWidth));
reed@google.comac10a2d2010-12-22 21:39:39 +0000212 return x >> fShiftFixedX; }
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000213 GrFixed normalizeFixedY(GrFixed y) const { GrAssert(GrIsPow2(fHeight));
reed@google.comac10a2d2010-12-22 21:39:39 +0000214 return y >> fShiftFixedY; }
215
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000216 /**
reed@google.comac10a2d2010-12-22 21:39:39 +0000217 * Retrieves the pixel config specified when the texture was created.
218 */
bsalomon@google.com669fdc42011-04-05 17:08:27 +0000219 GrPixelConfig config() const { return fConfig; }
reed@google.comac10a2d2010-12-22 21:39:39 +0000220
221 /**
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000222 * Approximate number of bytes used by the texture
reed@google.comac10a2d2010-12-22 21:39:39 +0000223 */
bsalomon@google.comcee661a2011-07-26 12:32:36 +0000224 virtual size_t sizeInBytes() const {
bsalomon@google.com669fdc42011-04-05 17:08:27 +0000225 return fWidth * fHeight * GrBytesPerPixel(fConfig);
reed@google.comac10a2d2010-12-22 21:39:39 +0000226 }
227
228 /**
229 * Updates a subrectangle of texels in the texture.
230 *
junov@google.com4ee7ae52011-06-30 17:30:49 +0000231 * @param x left edge of rectangle to update
232 * @param y top edge of rectangle to update
233 * @param width width of rectangle to update
234 * @param height height of rectangle to update
235 * @param srcData width*height texels of data in same format that was
236 * used at texture creation.
237 * @param rowBytes number of bytes per row in srcData, 0 means rows are
238 * packed
reed@google.comac10a2d2010-12-22 21:39:39 +0000239 */
bsalomon@google.com79d2dbe2011-06-13 19:28:02 +0000240 virtual void uploadTextureData(int x,
241 int y,
242 int width,
243 int height,
junov@google.com4ee7ae52011-06-30 17:30:49 +0000244 const void* srcData,
245 size_t rowBytes) = 0;
reed@google.comac10a2d2010-12-22 21:39:39 +0000246
247 /**
bsalomon@google.com669fdc42011-04-05 17:08:27 +0000248 * Reads a rectangle of pixels from the texture.
249 * @param left left edge of the rectangle to read (inclusive)
250 * @param top top edge of the rectangle to read (inclusive)
251 * @param width width of rectangle to read in pixels.
252 * @param height height of rectangle to read in pixels.
253 * @param config the pixel config of the destination buffer
254 * @param buffer memory to read the rectangle into.
255 *
256 * @return true if the read succeeded, false if not. The read can fail
257 * because of a unsupported pixel config.
258 */
259 bool readPixels(int left, int top, int width, int height,
260 GrPixelConfig config, void* buffer);
261
262 /**
reed@google.comac10a2d2010-12-22 21:39:39 +0000263 * Retrieves the render target underlying this texture that can be passed to
264 * GrGpu::setRenderTarget().
265 *
bsalomon@google.com6dcf4992011-04-05 21:16:14 +0000266 * @return handle to render target or NULL if the texture is not a
reed@google.comac10a2d2010-12-22 21:39:39 +0000267 * render target
268 */
bsalomon@google.com6dcf4992011-04-05 21:16:14 +0000269 GrRenderTarget* asRenderTarget() { return fRenderTarget; }
reed@google.comac10a2d2010-12-22 21:39:39 +0000270
271 /**
bsalomon@google.com1da07462011-03-10 14:51:57 +0000272 * Removes the reference on the associated GrRenderTarget held by this
bsalomon@google.com8fe72472011-03-30 21:26:44 +0000273 * texture. Afterwards asRenderTarget() will return NULL. The
bsalomon@google.com1da07462011-03-10 14:51:57 +0000274 * GrRenderTarget survives the release if another ref is held on it.
reed@google.comac10a2d2010-12-22 21:39:39 +0000275 */
bsalomon@google.com6dcf4992011-04-05 21:16:14 +0000276 void releaseRenderTarget() {
277 if (NULL != fRenderTarget) {
278 GrAssert(fRenderTarget->asTexture() == this);
279 fRenderTarget->onTextureReleaseRenderTarget();
280 fRenderTarget->unref();
281 fRenderTarget = NULL;
282 }
283 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000284
285 /**
286 * Return the native ID or handle to the texture, depending on the
287 * platform. e.g. on opengl, return the texture ID.
288 */
bsalomon@google.comcee661a2011-07-26 12:32:36 +0000289 virtual intptr_t getTextureHandle() const = 0;
reed@google.comac10a2d2010-12-22 21:39:39 +0000290
291#if GR_DEBUG
292 void validate() const {
293 this->INHERITED::validate();
294 }
295#else
296 void validate() const {}
297#endif
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000298
bsalomon@google.com6dcf4992011-04-05 21:16:14 +0000299protected:
300 GrRenderTarget* fRenderTarget; // texture refs its rt representation
301 // base class cons sets to NULL
302 // subclass cons can create and set
303
304 GrTexture(GrGpu* gpu,
305 int width,
306 int height,
307 GrPixelConfig config)
308 : INHERITED(gpu)
309 , fRenderTarget(NULL)
310 , fWidth(width)
311 , fHeight(height)
312 , fConfig(config) {
313 // only make sense if alloc size is pow2
314 fShiftFixedX = 31 - Gr_clz(fWidth);
315 fShiftFixedY = 31 - Gr_clz(fHeight);
316 }
bsalomon@google.comcee661a2011-07-26 12:32:36 +0000317
bsalomon@google.com6dcf4992011-04-05 21:16:14 +0000318 // GrResource overrides
319 virtual void onRelease() {
320 releaseRenderTarget();
321 }
322
323 virtual void onAbandon() {
324 if (NULL != fRenderTarget) {
325 fRenderTarget->abandon();
326 }
327 }
328
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000329private:
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000330 int fWidth;
331 int fHeight;
reed@google.comac10a2d2010-12-22 21:39:39 +0000332 // these two shift a fixed-point value into normalized coordinates
333 // for this texture if the texture is power of two sized.
334 int fShiftFixedX;
335 int fShiftFixedY;
bsalomon@google.com669fdc42011-04-05 17:08:27 +0000336
337 GrPixelConfig fConfig;
reed@google.comac10a2d2010-12-22 21:39:39 +0000338
bsalomon@google.com8fe72472011-03-30 21:26:44 +0000339 typedef GrResource INHERITED;
reed@google.comac10a2d2010-12-22 21:39:39 +0000340};
341
342#endif
343