blob: 50ed35db8f52fe9f976a6aada61a42c5226a2756 [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 /**
47 * @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
108 /**
bsalomon@google.com669fdc42011-04-05 17:08:27 +0000109 * Reads a rectangle of pixels from the render target.
110 * @param left left edge of the rectangle to read (inclusive)
111 * @param top top edge of the rectangle to read (inclusive)
112 * @param width width of rectangle to read in pixels.
113 * @param height height of rectangle to read in pixels.
114 * @param config the pixel config of the destination buffer
115 * @param buffer memory to read the rectangle into.
116 *
117 * @return true if the read succeeded, false if not. The read can fail
118 * because of a unsupported pixel config.
119 */
120 bool readPixels(int left, int top, int width, int height,
121 GrPixelConfig config, void* buffer);
122
bsalomon@google.com5877ffd2011-04-11 17:58:48 +0000123 // a MSAA RT may require explicit resolving , it may auto-resolve (e.g. FBO
124 // 0 in GL), or be unresolvable because the client didn't give us the
125 // resolve destination.
126 enum ResolveType {
127 kCanResolve_ResolveType,
128 kAutoResolves_ResolveType,
129 kCantResolve_ResolveType,
130 };
131 virtual ResolveType getResolveType() const = 0;
132
reed@google.comac10a2d2010-12-22 21:39:39 +0000133protected:
bsalomon@google.com8fe72472011-03-30 21:26:44 +0000134 GrRenderTarget(GrGpu* gpu,
135 GrTexture* texture,
bsalomon@google.comd302f142011-03-03 13:54:13 +0000136 int width,
137 int height,
bsalomon@google.comf954d8d2011-04-06 17:50:02 +0000138 int stencilBits,
139 bool isMultisampled)
bsalomon@google.com8fe72472011-03-30 21:26:44 +0000140 : INHERITED(gpu)
141 , fTexture(texture)
142 , fWidth(width)
143 , fHeight(height)
144 , fStencilBits(stencilBits)
bsalomon@google.comf954d8d2011-04-06 17:50:02 +0000145 , fIsMultisampled(isMultisampled)
bsalomon@google.com8295dc12011-05-02 12:53:34 +0000146 {
147 fResolveRect.setLargestInverted();
148 }
bsalomon@google.comd302f142011-03-03 13:54:13 +0000149
bsalomon@google.com6dcf4992011-04-05 21:16:14 +0000150 friend class GrTexture;
151 // When a texture unrefs an owned rendertarget this func
152 // removes the back pointer. This could be done called from
153 // texture's destructor but would have to be done in derived
154 // class. By the time of texture base destructor it has already
155 // lost its pointer to the rt.
156 void onTextureReleaseRenderTarget() {
157 GrAssert(NULL != fTexture);
158 fTexture = NULL;
159 }
bsalomon@google.comd302f142011-03-03 13:54:13 +0000160
bsalomon@google.com8295dc12011-05-02 12:53:34 +0000161private:
bsalomon@google.com6dcf4992011-04-05 21:16:14 +0000162 GrTexture* fTexture; // not ref'ed
vandebo@chromium.orgec364712011-07-26 03:44:05 +0000163 int fWidth;
164 int fHeight;
165 int fStencilBits;
166 bool fIsMultisampled;
167 GrIRect fResolveRect;
bsalomon@google.comd302f142011-03-03 13:54:13 +0000168
bsalomon@google.comd302f142011-03-03 13:54:13 +0000169 // GrGpu keeps a cached clip in the render target to avoid redundantly
170 // rendering the clip into the same stencil buffer.
171 friend class GrGpu;
172 GrClip fLastStencilClip;
173
bsalomon@google.com8fe72472011-03-30 21:26:44 +0000174 typedef GrResource INHERITED;
reed@google.comac10a2d2010-12-22 21:39:39 +0000175};
176
bsalomon@google.com8fe72472011-03-30 21:26:44 +0000177class GrTexture : public GrResource {
bsalomon@google.com8fe72472011-03-30 21:26:44 +0000178
reed@google.comac10a2d2010-12-22 21:39:39 +0000179public:
reed@google.comac10a2d2010-12-22 21:39:39 +0000180 /**
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000181 * Retrieves the width of the texture.
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000182 *
reed@google.comac10a2d2010-12-22 21:39:39 +0000183 * @return the width in texels
184 */
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000185 int width() const { return fWidth; }
bsalomon@google.com8fe72472011-03-30 21:26:44 +0000186
reed@google.comac10a2d2010-12-22 21:39:39 +0000187 /**
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000188 * Retrieves the height of the texture.
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000189 *
reed@google.comac10a2d2010-12-22 21:39:39 +0000190 * @return the height in texels
191 */
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000192 int height() const { return fHeight; }
reed@google.comac10a2d2010-12-22 21:39:39 +0000193
194 /**
195 * Convert from texels to normalized texture coords for POT textures
196 * only.
197 */
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000198 GrFixed normalizeFixedX(GrFixed x) const { GrAssert(GrIsPow2(fWidth));
reed@google.comac10a2d2010-12-22 21:39:39 +0000199 return x >> fShiftFixedX; }
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000200 GrFixed normalizeFixedY(GrFixed y) const { GrAssert(GrIsPow2(fHeight));
reed@google.comac10a2d2010-12-22 21:39:39 +0000201 return y >> fShiftFixedY; }
202
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000203 /**
reed@google.comac10a2d2010-12-22 21:39:39 +0000204 * Retrieves the pixel config specified when the texture was created.
205 */
bsalomon@google.com669fdc42011-04-05 17:08:27 +0000206 GrPixelConfig config() const { return fConfig; }
reed@google.comac10a2d2010-12-22 21:39:39 +0000207
208 /**
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000209 * Approximate number of bytes used by the texture
reed@google.comac10a2d2010-12-22 21:39:39 +0000210 */
vandebo@chromium.orgec364712011-07-26 03:44:05 +0000211 size_t sizeInBytes() const {
bsalomon@google.com669fdc42011-04-05 17:08:27 +0000212 return fWidth * fHeight * GrBytesPerPixel(fConfig);
reed@google.comac10a2d2010-12-22 21:39:39 +0000213 }
214
215 /**
216 * Updates a subrectangle of texels in the texture.
217 *
junov@google.com4ee7ae52011-06-30 17:30:49 +0000218 * @param x left edge of rectangle to update
219 * @param y top edge of rectangle to update
220 * @param width width of rectangle to update
221 * @param height height of rectangle to update
222 * @param srcData width*height texels of data in same format that was
223 * used at texture creation.
224 * @param rowBytes number of bytes per row in srcData, 0 means rows are
225 * packed
reed@google.comac10a2d2010-12-22 21:39:39 +0000226 */
bsalomon@google.com79d2dbe2011-06-13 19:28:02 +0000227 virtual void uploadTextureData(int x,
228 int y,
229 int width,
230 int height,
junov@google.com4ee7ae52011-06-30 17:30:49 +0000231 const void* srcData,
232 size_t rowBytes) = 0;
reed@google.comac10a2d2010-12-22 21:39:39 +0000233
234 /**
bsalomon@google.com669fdc42011-04-05 17:08:27 +0000235 * Reads a rectangle of pixels from the texture.
236 * @param left left edge of the rectangle to read (inclusive)
237 * @param top top edge of the rectangle to read (inclusive)
238 * @param width width of rectangle to read in pixels.
239 * @param height height of rectangle to read in pixels.
240 * @param config the pixel config of the destination buffer
241 * @param buffer memory to read the rectangle into.
242 *
243 * @return true if the read succeeded, false if not. The read can fail
244 * because of a unsupported pixel config.
245 */
246 bool readPixels(int left, int top, int width, int height,
247 GrPixelConfig config, void* buffer);
248
249 /**
reed@google.comac10a2d2010-12-22 21:39:39 +0000250 * Retrieves the render target underlying this texture that can be passed to
251 * GrGpu::setRenderTarget().
252 *
bsalomon@google.com6dcf4992011-04-05 21:16:14 +0000253 * @return handle to render target or NULL if the texture is not a
reed@google.comac10a2d2010-12-22 21:39:39 +0000254 * render target
255 */
bsalomon@google.com6dcf4992011-04-05 21:16:14 +0000256 GrRenderTarget* asRenderTarget() { return fRenderTarget; }
reed@google.comac10a2d2010-12-22 21:39:39 +0000257
258 /**
bsalomon@google.com1da07462011-03-10 14:51:57 +0000259 * Removes the reference on the associated GrRenderTarget held by this
bsalomon@google.com8fe72472011-03-30 21:26:44 +0000260 * texture. Afterwards asRenderTarget() will return NULL. The
bsalomon@google.com1da07462011-03-10 14:51:57 +0000261 * GrRenderTarget survives the release if another ref is held on it.
reed@google.comac10a2d2010-12-22 21:39:39 +0000262 */
bsalomon@google.com6dcf4992011-04-05 21:16:14 +0000263 void releaseRenderTarget() {
264 if (NULL != fRenderTarget) {
265 GrAssert(fRenderTarget->asTexture() == this);
266 fRenderTarget->onTextureReleaseRenderTarget();
267 fRenderTarget->unref();
268 fRenderTarget = NULL;
269 }
270 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000271
272 /**
273 * Return the native ID or handle to the texture, depending on the
274 * platform. e.g. on opengl, return the texture ID.
275 */
vandebo@chromium.orgec364712011-07-26 03:44:05 +0000276 virtual intptr_t getTextureHandle() = 0;
reed@google.comac10a2d2010-12-22 21:39:39 +0000277
278#if GR_DEBUG
279 void validate() const {
280 this->INHERITED::validate();
281 }
282#else
283 void validate() const {}
284#endif
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000285
bsalomon@google.com6dcf4992011-04-05 21:16:14 +0000286protected:
287 GrRenderTarget* fRenderTarget; // texture refs its rt representation
288 // base class cons sets to NULL
289 // subclass cons can create and set
290
291 GrTexture(GrGpu* gpu,
292 int width,
293 int height,
294 GrPixelConfig config)
295 : INHERITED(gpu)
296 , fRenderTarget(NULL)
297 , fWidth(width)
298 , fHeight(height)
299 , fConfig(config) {
300 // only make sense if alloc size is pow2
301 fShiftFixedX = 31 - Gr_clz(fWidth);
302 fShiftFixedY = 31 - Gr_clz(fHeight);
303 }
vandebo@chromium.orgec364712011-07-26 03:44:05 +0000304
bsalomon@google.com6dcf4992011-04-05 21:16:14 +0000305 // GrResource overrides
306 virtual void onRelease() {
307 releaseRenderTarget();
308 }
309
310 virtual void onAbandon() {
311 if (NULL != fRenderTarget) {
312 fRenderTarget->abandon();
313 }
314 }
315
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000316private:
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000317 int fWidth;
318 int fHeight;
reed@google.comac10a2d2010-12-22 21:39:39 +0000319 // these two shift a fixed-point value into normalized coordinates
320 // for this texture if the texture is power of two sized.
321 int fShiftFixedX;
322 int fShiftFixedY;
bsalomon@google.com669fdc42011-04-05 17:08:27 +0000323
324 GrPixelConfig fConfig;
reed@google.comac10a2d2010-12-22 21:39:39 +0000325
bsalomon@google.com8fe72472011-03-30 21:26:44 +0000326 typedef GrResource INHERITED;
reed@google.comac10a2d2010-12-22 21:39:39 +0000327};
328
329#endif
330