blob: 0d46b89e77a32d8c3308998a6e9a00a8c7b6df7c [file] [log] [blame]
epoger@google.comec3ed6a2011-07-28 14:26:00 +00001
reed@google.comac10a2d2010-12-22 21:39:39 +00002/*
epoger@google.comec3ed6a2011-07-28 14:26:00 +00003 * Copyright 2011 Google Inc.
4 *
5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
reed@google.comac10a2d2010-12-22 21:39:39 +00007 */
8
9
epoger@google.comec3ed6a2011-07-28 14:26:00 +000010
reed@google.comac10a2d2010-12-22 21:39:39 +000011#ifndef GrTexture_DEFINED
12#define GrTexture_DEFINED
13
14#include "GrRefCnt.h"
bsalomon@google.comd302f142011-03-03 13:54:13 +000015#include "GrClip.h"
bsalomon@google.com8fe72472011-03-30 21:26:44 +000016#include "GrResource.h"
reed@google.comac10a2d2010-12-22 21:39:39 +000017
18class GrTexture;
19
20/**
21 * GrRenderTarget represents a 2D buffer of pixels that can be rendered to.
22 * A context's render target is set by setRenderTarget(). Render targets are
bsalomon@google.com1c13c962011-02-14 16:51:21 +000023 * created by a createTexture with the kRenderTarget_TextureFlag flag.
24 * Additionally, GrContext provides methods for creating GrRenderTargets
25 * that wrap externally created render targets.
reed@google.comac10a2d2010-12-22 21:39:39 +000026 */
bsalomon@google.com8fe72472011-03-30 21:26:44 +000027class GrRenderTarget : public GrResource {
bsalomon@google.com6dcf4992011-04-05 21:16:14 +000028
reed@google.comac10a2d2010-12-22 21:39:39 +000029public:
30 /**
31 * @return the width of the rendertarget
32 */
bsalomon@google.comd302f142011-03-03 13:54:13 +000033 int width() const { return fWidth; }
reed@google.comac10a2d2010-12-22 21:39:39 +000034 /**
35 * @return the height of the rendertarget
36 */
bsalomon@google.comd302f142011-03-03 13:54:13 +000037 int height() const { return fHeight; }
38
39 /**
bsalomon@google.comcee661a2011-07-26 12:32:36 +000040 * @return the pixel config. Can be kUnknown_GrPixelConfig
41 * if client asked us to render to a target that has a pixel
42 * config that isn't equivalent with one of our configs.
43 */
44 int config() const { return fConfig; }
45
46 /**
bsalomon@google.comd302f142011-03-03 13:54:13 +000047 * @return the number of stencil bits in the rendertarget
48 */
49 int stencilBits() const { return fStencilBits; }
bsalomon@google.com1c13c962011-02-14 16:51:21 +000050
reed@google.comac10a2d2010-12-22 21:39:39 +000051 /**
52 * @return the texture associated with the rendertarget, may be NULL.
53 */
54 GrTexture* asTexture() {return fTexture;}
55
bsalomon@google.com669fdc42011-04-05 17:08:27 +000056 /**
bsalomon@google.com0b96a842011-07-13 21:53:49 +000057 * If this RT is multisampled, this is the multisample buffer
58 * @return the 3D API's handle to this object (e.g. FBO ID in OpenGL)
59 */
60 virtual intptr_t getRenderTargetHandle() const = 0;
61
62 /**
63 * If this RT is multisampled, this is the buffer it is resolved to.
64 * Otherwise, same as getRenderTargetHandle().
65 * (In GL a separate FBO ID is used for the msaa and resolved buffers)
66 * @return the 3D API's handle to this object (e.g. FBO ID in OpenGL)
67 */
68 virtual intptr_t getRenderTargetResolvedHandle() const = 0;
69
70 /**
bsalomon@google.comf954d8d2011-04-06 17:50:02 +000071 * @return true if the render target is multisampled, false otherwise
72 */
73 bool isMultisampled() { return fIsMultisampled; }
74
75 /**
bsalomon@google.com5877ffd2011-04-11 17:58:48 +000076 * Call to indicate the multisample contents were modified such that the
77 * render target needs to be resolved before it can be used as texture. Gr
78 * tracks this for its own drawing and thus this only needs to be called
79 * when the render target has been modified outside of Gr. Only meaningful
80 * for Gr-created RT/Textures and Platform RT/Textures created with the
81 * kGrCanResolve flag.
bsalomon@google.com8295dc12011-05-02 12:53:34 +000082 * @param rect a rect bounding the area needing resolve. NULL indicates
83 * the whole RT needs resolving.
bsalomon@google.com5877ffd2011-04-11 17:58:48 +000084 */
bsalomon@google.com8295dc12011-05-02 12:53:34 +000085 void flagAsNeedingResolve(const GrIRect* rect = NULL);
86
87 /**
88 * Call to override the region that needs to be resolved.
89 */
90 void overrideResolveRect(const GrIRect rect);
bsalomon@google.com5877ffd2011-04-11 17:58:48 +000091
92 /**
93 * Call to indicate that GrRenderTarget was externally resolved. This may
94 * allow Gr to skip a redundant resolve step.
95 */
bsalomon@google.com8295dc12011-05-02 12:53:34 +000096 void flagAsResolved() { fResolveRect.setLargestInverted(); }
bsalomon@google.com5877ffd2011-04-11 17:58:48 +000097
98 /**
99 * @return true if the GrRenderTarget requires MSAA resolving
100 */
bsalomon@google.com8295dc12011-05-02 12:53:34 +0000101 bool needsResolve() const { return !fResolveRect.isEmpty(); }
102
103 /**
104 * Returns a rect bounding the region needing resolving.
105 */
106 const GrIRect& getResolveRect() const { return fResolveRect; }
bsalomon@google.com5877ffd2011-04-11 17:58:48 +0000107
bsalomon@google.comcee661a2011-07-26 12:32:36 +0000108 // GrResource overrides
109 virtual size_t sizeInBytes() const;
110
bsalomon@google.com5877ffd2011-04-11 17:58:48 +0000111 /**
bsalomon@google.com669fdc42011-04-05 17:08:27 +0000112 * Reads a rectangle of pixels from the render target.
113 * @param left left edge of the rectangle to read (inclusive)
114 * @param top top edge of the rectangle to read (inclusive)
115 * @param width width of rectangle to read in pixels.
116 * @param height height of rectangle to read in pixels.
117 * @param config the pixel config of the destination buffer
118 * @param buffer memory to read the rectangle into.
119 *
120 * @return true if the read succeeded, false if not. The read can fail
121 * because of a unsupported pixel config.
122 */
123 bool readPixels(int left, int top, int width, int height,
124 GrPixelConfig config, void* buffer);
125
bsalomon@google.com5877ffd2011-04-11 17:58:48 +0000126 // a MSAA RT may require explicit resolving , it may auto-resolve (e.g. FBO
127 // 0 in GL), or be unresolvable because the client didn't give us the
128 // resolve destination.
129 enum ResolveType {
130 kCanResolve_ResolveType,
131 kAutoResolves_ResolveType,
132 kCantResolve_ResolveType,
133 };
134 virtual ResolveType getResolveType() const = 0;
135
reed@google.comac10a2d2010-12-22 21:39:39 +0000136protected:
bsalomon@google.com8fe72472011-03-30 21:26:44 +0000137 GrRenderTarget(GrGpu* gpu,
138 GrTexture* texture,
bsalomon@google.comd302f142011-03-03 13:54:13 +0000139 int width,
140 int height,
bsalomon@google.comcee661a2011-07-26 12:32:36 +0000141 GrPixelConfig config,
bsalomon@google.comf954d8d2011-04-06 17:50:02 +0000142 int stencilBits,
143 bool isMultisampled)
bsalomon@google.com8fe72472011-03-30 21:26:44 +0000144 : INHERITED(gpu)
145 , fTexture(texture)
146 , fWidth(width)
147 , fHeight(height)
bsalomon@google.comcee661a2011-07-26 12:32:36 +0000148 , fConfig(config)
bsalomon@google.com8fe72472011-03-30 21:26:44 +0000149 , fStencilBits(stencilBits)
bsalomon@google.comf954d8d2011-04-06 17:50:02 +0000150 , fIsMultisampled(isMultisampled)
bsalomon@google.com8295dc12011-05-02 12:53:34 +0000151 {
152 fResolveRect.setLargestInverted();
153 }
bsalomon@google.comd302f142011-03-03 13:54:13 +0000154
bsalomon@google.com6dcf4992011-04-05 21:16:14 +0000155 friend class GrTexture;
156 // When a texture unrefs an owned rendertarget this func
157 // removes the back pointer. This could be done called from
158 // texture's destructor but would have to be done in derived
159 // class. By the time of texture base destructor it has already
160 // lost its pointer to the rt.
161 void onTextureReleaseRenderTarget() {
162 GrAssert(NULL != fTexture);
163 fTexture = NULL;
164 }
bsalomon@google.comd302f142011-03-03 13:54:13 +0000165
bsalomon@google.com8295dc12011-05-02 12:53:34 +0000166private:
bsalomon@google.com6dcf4992011-04-05 21:16:14 +0000167 GrTexture* fTexture; // not ref'ed
bsalomon@google.comcee661a2011-07-26 12:32:36 +0000168 int fWidth;
169 int fHeight;
170 GrPixelConfig fConfig;
171 int fStencilBits;
172 bool fIsMultisampled;
173 GrIRect fResolveRect;
bsalomon@google.comd302f142011-03-03 13:54:13 +0000174
bsalomon@google.comd302f142011-03-03 13:54:13 +0000175 // GrGpu keeps a cached clip in the render target to avoid redundantly
176 // rendering the clip into the same stencil buffer.
177 friend class GrGpu;
178 GrClip fLastStencilClip;
179
bsalomon@google.com8fe72472011-03-30 21:26:44 +0000180 typedef GrResource INHERITED;
reed@google.comac10a2d2010-12-22 21:39:39 +0000181};
182
bsalomon@google.com8fe72472011-03-30 21:26:44 +0000183class GrTexture : public GrResource {
bsalomon@google.com8fe72472011-03-30 21:26:44 +0000184
reed@google.comac10a2d2010-12-22 21:39:39 +0000185public:
reed@google.comac10a2d2010-12-22 21:39:39 +0000186 /**
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000187 * Retrieves the width of the texture.
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000188 *
reed@google.comac10a2d2010-12-22 21:39:39 +0000189 * @return the width in texels
190 */
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000191 int width() const { return fWidth; }
bsalomon@google.com8fe72472011-03-30 21:26:44 +0000192
reed@google.comac10a2d2010-12-22 21:39:39 +0000193 /**
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000194 * Retrieves the height of the texture.
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000195 *
reed@google.comac10a2d2010-12-22 21:39:39 +0000196 * @return the height in texels
197 */
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000198 int height() const { return fHeight; }
reed@google.comac10a2d2010-12-22 21:39:39 +0000199
200 /**
201 * Convert from texels to normalized texture coords for POT textures
202 * only.
203 */
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000204 GrFixed normalizeFixedX(GrFixed x) const { GrAssert(GrIsPow2(fWidth));
reed@google.comac10a2d2010-12-22 21:39:39 +0000205 return x >> fShiftFixedX; }
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000206 GrFixed normalizeFixedY(GrFixed y) const { GrAssert(GrIsPow2(fHeight));
reed@google.comac10a2d2010-12-22 21:39:39 +0000207 return y >> fShiftFixedY; }
208
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000209 /**
reed@google.comac10a2d2010-12-22 21:39:39 +0000210 * Retrieves the pixel config specified when the texture was created.
211 */
bsalomon@google.com669fdc42011-04-05 17:08:27 +0000212 GrPixelConfig config() const { return fConfig; }
reed@google.comac10a2d2010-12-22 21:39:39 +0000213
214 /**
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000215 * Approximate number of bytes used by the texture
reed@google.comac10a2d2010-12-22 21:39:39 +0000216 */
bsalomon@google.comcee661a2011-07-26 12:32:36 +0000217 virtual size_t sizeInBytes() const {
bsalomon@google.com669fdc42011-04-05 17:08:27 +0000218 return fWidth * fHeight * GrBytesPerPixel(fConfig);
reed@google.comac10a2d2010-12-22 21:39:39 +0000219 }
220
221 /**
222 * Updates a subrectangle of texels in the texture.
223 *
junov@google.com4ee7ae52011-06-30 17:30:49 +0000224 * @param x left edge of rectangle to update
225 * @param y top edge of rectangle to update
226 * @param width width of rectangle to update
227 * @param height height of rectangle to update
228 * @param srcData width*height texels of data in same format that was
229 * used at texture creation.
230 * @param rowBytes number of bytes per row in srcData, 0 means rows are
231 * packed
reed@google.comac10a2d2010-12-22 21:39:39 +0000232 */
bsalomon@google.com79d2dbe2011-06-13 19:28:02 +0000233 virtual void uploadTextureData(int x,
234 int y,
235 int width,
236 int height,
junov@google.com4ee7ae52011-06-30 17:30:49 +0000237 const void* srcData,
238 size_t rowBytes) = 0;
reed@google.comac10a2d2010-12-22 21:39:39 +0000239
240 /**
bsalomon@google.com669fdc42011-04-05 17:08:27 +0000241 * Reads a rectangle of pixels from the texture.
242 * @param left left edge of the rectangle to read (inclusive)
243 * @param top top edge of the rectangle to read (inclusive)
244 * @param width width of rectangle to read in pixels.
245 * @param height height of rectangle to read in pixels.
246 * @param config the pixel config of the destination buffer
247 * @param buffer memory to read the rectangle into.
248 *
249 * @return true if the read succeeded, false if not. The read can fail
250 * because of a unsupported pixel config.
251 */
252 bool readPixels(int left, int top, int width, int height,
253 GrPixelConfig config, void* buffer);
254
255 /**
reed@google.comac10a2d2010-12-22 21:39:39 +0000256 * Retrieves the render target underlying this texture that can be passed to
257 * GrGpu::setRenderTarget().
258 *
bsalomon@google.com6dcf4992011-04-05 21:16:14 +0000259 * @return handle to render target or NULL if the texture is not a
reed@google.comac10a2d2010-12-22 21:39:39 +0000260 * render target
261 */
bsalomon@google.com6dcf4992011-04-05 21:16:14 +0000262 GrRenderTarget* asRenderTarget() { return fRenderTarget; }
reed@google.comac10a2d2010-12-22 21:39:39 +0000263
264 /**
bsalomon@google.com1da07462011-03-10 14:51:57 +0000265 * Removes the reference on the associated GrRenderTarget held by this
bsalomon@google.com8fe72472011-03-30 21:26:44 +0000266 * texture. Afterwards asRenderTarget() will return NULL. The
bsalomon@google.com1da07462011-03-10 14:51:57 +0000267 * GrRenderTarget survives the release if another ref is held on it.
reed@google.comac10a2d2010-12-22 21:39:39 +0000268 */
bsalomon@google.com6dcf4992011-04-05 21:16:14 +0000269 void releaseRenderTarget() {
270 if (NULL != fRenderTarget) {
271 GrAssert(fRenderTarget->asTexture() == this);
272 fRenderTarget->onTextureReleaseRenderTarget();
273 fRenderTarget->unref();
274 fRenderTarget = NULL;
275 }
276 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000277
278 /**
279 * Return the native ID or handle to the texture, depending on the
280 * platform. e.g. on opengl, return the texture ID.
281 */
bsalomon@google.comcee661a2011-07-26 12:32:36 +0000282 virtual intptr_t getTextureHandle() const = 0;
reed@google.comac10a2d2010-12-22 21:39:39 +0000283
284#if GR_DEBUG
285 void validate() const {
286 this->INHERITED::validate();
287 }
288#else
289 void validate() const {}
290#endif
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000291
bsalomon@google.com6dcf4992011-04-05 21:16:14 +0000292protected:
293 GrRenderTarget* fRenderTarget; // texture refs its rt representation
294 // base class cons sets to NULL
295 // subclass cons can create and set
296
297 GrTexture(GrGpu* gpu,
298 int width,
299 int height,
300 GrPixelConfig config)
301 : INHERITED(gpu)
302 , fRenderTarget(NULL)
303 , fWidth(width)
304 , fHeight(height)
305 , fConfig(config) {
306 // only make sense if alloc size is pow2
307 fShiftFixedX = 31 - Gr_clz(fWidth);
308 fShiftFixedY = 31 - Gr_clz(fHeight);
309 }
bsalomon@google.comcee661a2011-07-26 12:32:36 +0000310
bsalomon@google.com6dcf4992011-04-05 21:16:14 +0000311 // GrResource overrides
312 virtual void onRelease() {
313 releaseRenderTarget();
314 }
315
316 virtual void onAbandon() {
317 if (NULL != fRenderTarget) {
318 fRenderTarget->abandon();
319 }
320 }
321
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000322private:
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000323 int fWidth;
324 int fHeight;
reed@google.comac10a2d2010-12-22 21:39:39 +0000325 // these two shift a fixed-point value into normalized coordinates
326 // for this texture if the texture is power of two sized.
327 int fShiftFixedX;
328 int fShiftFixedY;
bsalomon@google.com669fdc42011-04-05 17:08:27 +0000329
330 GrPixelConfig fConfig;
reed@google.comac10a2d2010-12-22 21:39:39 +0000331
bsalomon@google.com8fe72472011-03-30 21:26:44 +0000332 typedef GrResource INHERITED;
reed@google.comac10a2d2010-12-22 21:39:39 +0000333};
334
335#endif
336