blob: 6d4f4d76a91919551261a1572cb940d4e10bfcd9 [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.comf954d8d2011-04-06 17:50:02 +000057 * @return true if the render target is multisampled, false otherwise
58 */
59 bool isMultisampled() { return fIsMultisampled; }
60
61 /**
bsalomon@google.com5877ffd2011-04-11 17:58:48 +000062 * 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 */
69 void flagAsNeedingResolve() {
70 fNeedsResolve = kCanResolve_ResolveType == getResolveType();
71 }
72
73 /**
74 * Call to indicate that GrRenderTarget was externally resolved. This may
75 * allow Gr to skip a redundant resolve step.
76 */
77 void flagAsResolved() { fNeedsResolve = false; }
78
79 /**
80 * @return true if the GrRenderTarget requires MSAA resolving
81 */
82 bool needsResolve() { return fNeedsResolve; }
83
84 /**
bsalomon@google.com669fdc42011-04-05 17:08:27 +000085 * Reads a rectangle of pixels from the render target.
86 * @param left left edge of the rectangle to read (inclusive)
87 * @param top top edge of the rectangle to read (inclusive)
88 * @param width width of rectangle to read in pixels.
89 * @param height height of rectangle to read in pixels.
90 * @param config the pixel config of the destination buffer
91 * @param buffer memory to read the rectangle into.
92 *
93 * @return true if the read succeeded, false if not. The read can fail
94 * because of a unsupported pixel config.
95 */
96 bool readPixels(int left, int top, int width, int height,
97 GrPixelConfig config, void* buffer);
98
bsalomon@google.com5877ffd2011-04-11 17:58:48 +000099 // a MSAA RT may require explicit resolving , it may auto-resolve (e.g. FBO
100 // 0 in GL), or be unresolvable because the client didn't give us the
101 // resolve destination.
102 enum ResolveType {
103 kCanResolve_ResolveType,
104 kAutoResolves_ResolveType,
105 kCantResolve_ResolveType,
106 };
107 virtual ResolveType getResolveType() const = 0;
108
reed@google.comac10a2d2010-12-22 21:39:39 +0000109protected:
bsalomon@google.com8fe72472011-03-30 21:26:44 +0000110 GrRenderTarget(GrGpu* gpu,
111 GrTexture* texture,
bsalomon@google.comd302f142011-03-03 13:54:13 +0000112 int width,
113 int height,
bsalomon@google.comf954d8d2011-04-06 17:50:02 +0000114 int stencilBits,
115 bool isMultisampled)
bsalomon@google.com8fe72472011-03-30 21:26:44 +0000116 : INHERITED(gpu)
117 , fTexture(texture)
118 , fWidth(width)
119 , fHeight(height)
120 , fStencilBits(stencilBits)
bsalomon@google.comf954d8d2011-04-06 17:50:02 +0000121 , fIsMultisampled(isMultisampled)
bsalomon@google.com5877ffd2011-04-11 17:58:48 +0000122 , fNeedsResolve(false)
bsalomon@google.com8fe72472011-03-30 21:26:44 +0000123 {}
bsalomon@google.comd302f142011-03-03 13:54:13 +0000124
bsalomon@google.com6dcf4992011-04-05 21:16:14 +0000125 friend class GrTexture;
126 // When a texture unrefs an owned rendertarget this func
127 // removes the back pointer. This could be done called from
128 // texture's destructor but would have to be done in derived
129 // class. By the time of texture base destructor it has already
130 // lost its pointer to the rt.
131 void onTextureReleaseRenderTarget() {
132 GrAssert(NULL != fTexture);
133 fTexture = NULL;
134 }
bsalomon@google.comd302f142011-03-03 13:54:13 +0000135
bsalomon@google.com6dcf4992011-04-05 21:16:14 +0000136 GrTexture* fTexture; // not ref'ed
bsalomon@google.comd302f142011-03-03 13:54:13 +0000137 int fWidth;
138 int fHeight;
139 int fStencilBits;
bsalomon@google.comf954d8d2011-04-06 17:50:02 +0000140 bool fIsMultisampled;
bsalomon@google.com5877ffd2011-04-11 17:58:48 +0000141 bool fNeedsResolve;
bsalomon@google.comd302f142011-03-03 13:54:13 +0000142
143private:
144 // GrGpu keeps a cached clip in the render target to avoid redundantly
145 // rendering the clip into the same stencil buffer.
146 friend class GrGpu;
147 GrClip fLastStencilClip;
148
bsalomon@google.com8fe72472011-03-30 21:26:44 +0000149 typedef GrResource INHERITED;
reed@google.comac10a2d2010-12-22 21:39:39 +0000150};
151
bsalomon@google.com8fe72472011-03-30 21:26:44 +0000152class GrTexture : public GrResource {
bsalomon@google.com8fe72472011-03-30 21:26:44 +0000153
reed@google.comac10a2d2010-12-22 21:39:39 +0000154public:
reed@google.comac10a2d2010-12-22 21:39:39 +0000155 /**
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000156 * Retrieves the width of the texture.
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000157 *
reed@google.comac10a2d2010-12-22 21:39:39 +0000158 * @return the width in texels
159 */
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000160 int width() const { return fWidth; }
bsalomon@google.com8fe72472011-03-30 21:26:44 +0000161
reed@google.comac10a2d2010-12-22 21:39:39 +0000162 /**
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000163 * Retrieves the height of the texture.
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000164 *
reed@google.comac10a2d2010-12-22 21:39:39 +0000165 * @return the height in texels
166 */
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000167 int height() const { return fHeight; }
reed@google.comac10a2d2010-12-22 21:39:39 +0000168
169 /**
170 * Convert from texels to normalized texture coords for POT textures
171 * only.
172 */
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000173 GrFixed normalizeFixedX(GrFixed x) const { GrAssert(GrIsPow2(fWidth));
reed@google.comac10a2d2010-12-22 21:39:39 +0000174 return x >> fShiftFixedX; }
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000175 GrFixed normalizeFixedY(GrFixed y) const { GrAssert(GrIsPow2(fHeight));
reed@google.comac10a2d2010-12-22 21:39:39 +0000176 return y >> fShiftFixedY; }
177
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000178 /**
reed@google.comac10a2d2010-12-22 21:39:39 +0000179 * Retrieves the pixel config specified when the texture was created.
180 */
bsalomon@google.com669fdc42011-04-05 17:08:27 +0000181 GrPixelConfig config() const { return fConfig; }
reed@google.comac10a2d2010-12-22 21:39:39 +0000182
183 /**
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000184 * Approximate number of bytes used by the texture
reed@google.comac10a2d2010-12-22 21:39:39 +0000185 */
186 size_t sizeInBytes() const {
bsalomon@google.com669fdc42011-04-05 17:08:27 +0000187 return fWidth * fHeight * GrBytesPerPixel(fConfig);
reed@google.comac10a2d2010-12-22 21:39:39 +0000188 }
189
190 /**
191 * Updates a subrectangle of texels in the texture.
192 *
193 * @param x left edge of rectangle to update
194 * @param y top edge of rectangle to update
195 * @param width width of rectangle to update
196 * @param height height of rectangle to update
197 * @param srcData width*height texels of data in same format that was used
198 * at texture creation.
199 */
200 virtual void uploadTextureData(uint32_t x,
201 uint32_t y,
202 uint32_t width,
203 uint32_t height,
204 const void* srcData) = 0;
reed@google.comac10a2d2010-12-22 21:39:39 +0000205
206 /**
bsalomon@google.com669fdc42011-04-05 17:08:27 +0000207 * Reads a rectangle of pixels from the texture.
208 * @param left left edge of the rectangle to read (inclusive)
209 * @param top top edge of the rectangle to read (inclusive)
210 * @param width width of rectangle to read in pixels.
211 * @param height height of rectangle to read in pixels.
212 * @param config the pixel config of the destination buffer
213 * @param buffer memory to read the rectangle into.
214 *
215 * @return true if the read succeeded, false if not. The read can fail
216 * because of a unsupported pixel config.
217 */
218 bool readPixels(int left, int top, int width, int height,
219 GrPixelConfig config, void* buffer);
220
221 /**
reed@google.comac10a2d2010-12-22 21:39:39 +0000222 * Retrieves the render target underlying this texture that can be passed to
223 * GrGpu::setRenderTarget().
224 *
bsalomon@google.com6dcf4992011-04-05 21:16:14 +0000225 * @return handle to render target or NULL if the texture is not a
reed@google.comac10a2d2010-12-22 21:39:39 +0000226 * render target
227 */
bsalomon@google.com6dcf4992011-04-05 21:16:14 +0000228 GrRenderTarget* asRenderTarget() { return fRenderTarget; }
reed@google.comac10a2d2010-12-22 21:39:39 +0000229
230 /**
bsalomon@google.com1da07462011-03-10 14:51:57 +0000231 * Removes the reference on the associated GrRenderTarget held by this
bsalomon@google.com8fe72472011-03-30 21:26:44 +0000232 * texture. Afterwards asRenderTarget() will return NULL. The
bsalomon@google.com1da07462011-03-10 14:51:57 +0000233 * GrRenderTarget survives the release if another ref is held on it.
reed@google.comac10a2d2010-12-22 21:39:39 +0000234 */
bsalomon@google.com6dcf4992011-04-05 21:16:14 +0000235 void releaseRenderTarget() {
236 if (NULL != fRenderTarget) {
237 GrAssert(fRenderTarget->asTexture() == this);
238 fRenderTarget->onTextureReleaseRenderTarget();
239 fRenderTarget->unref();
240 fRenderTarget = NULL;
241 }
242 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000243
244 /**
245 * Return the native ID or handle to the texture, depending on the
246 * platform. e.g. on opengl, return the texture ID.
247 */
248 virtual intptr_t getTextureHandle() = 0;
249
250#if GR_DEBUG
251 void validate() const {
252 this->INHERITED::validate();
253 }
254#else
255 void validate() const {}
256#endif
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000257
bsalomon@google.com6dcf4992011-04-05 21:16:14 +0000258protected:
259 GrRenderTarget* fRenderTarget; // texture refs its rt representation
260 // base class cons sets to NULL
261 // subclass cons can create and set
262
263 GrTexture(GrGpu* gpu,
264 int width,
265 int height,
266 GrPixelConfig config)
267 : INHERITED(gpu)
268 , fRenderTarget(NULL)
269 , fWidth(width)
270 , fHeight(height)
271 , fConfig(config) {
272 // only make sense if alloc size is pow2
273 fShiftFixedX = 31 - Gr_clz(fWidth);
274 fShiftFixedY = 31 - Gr_clz(fHeight);
275 }
276
277 // GrResource overrides
278 virtual void onRelease() {
279 releaseRenderTarget();
280 }
281
282 virtual void onAbandon() {
283 if (NULL != fRenderTarget) {
284 fRenderTarget->abandon();
285 }
286 }
287
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000288private:
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000289 int fWidth;
290 int fHeight;
reed@google.comac10a2d2010-12-22 21:39:39 +0000291 // these two shift a fixed-point value into normalized coordinates
292 // for this texture if the texture is power of two sized.
293 int fShiftFixedX;
294 int fShiftFixedY;
bsalomon@google.com669fdc42011-04-05 17:08:27 +0000295
296 GrPixelConfig fConfig;
reed@google.comac10a2d2010-12-22 21:39:39 +0000297
bsalomon@google.com8fe72472011-03-30 21:26:44 +0000298 typedef GrResource INHERITED;
reed@google.comac10a2d2010-12-22 21:39:39 +0000299};
300
301#endif
302