blob: d811b35caa01b67e06f47db92a05844d48c3df68 [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.
bsalomon@google.com8295dc12011-05-02 12:53:34 +000068 * @param rect a rect bounding the area needing resolve. NULL indicates
69 * the whole RT needs resolving.
bsalomon@google.com5877ffd2011-04-11 17:58:48 +000070 */
bsalomon@google.com8295dc12011-05-02 12:53:34 +000071 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);
bsalomon@google.com5877ffd2011-04-11 17:58:48 +000077
78 /**
79 * Call to indicate that GrRenderTarget was externally resolved. This may
80 * allow Gr to skip a redundant resolve step.
81 */
bsalomon@google.com8295dc12011-05-02 12:53:34 +000082 void flagAsResolved() { fResolveRect.setLargestInverted(); }
bsalomon@google.com5877ffd2011-04-11 17:58:48 +000083
84 /**
85 * @return true if the GrRenderTarget requires MSAA resolving
86 */
bsalomon@google.com8295dc12011-05-02 12:53:34 +000087 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; }
bsalomon@google.com5877ffd2011-04-11 17:58:48 +000093
94 /**
bsalomon@google.com669fdc42011-04-05 17:08:27 +000095 * 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
bsalomon@google.com5877ffd2011-04-11 17:58:48 +0000109 // 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
reed@google.comac10a2d2010-12-22 21:39:39 +0000119protected:
bsalomon@google.com8fe72472011-03-30 21:26:44 +0000120 GrRenderTarget(GrGpu* gpu,
121 GrTexture* texture,
bsalomon@google.comd302f142011-03-03 13:54:13 +0000122 int width,
123 int height,
bsalomon@google.comf954d8d2011-04-06 17:50:02 +0000124 int stencilBits,
125 bool isMultisampled)
bsalomon@google.com8fe72472011-03-30 21:26:44 +0000126 : INHERITED(gpu)
127 , fTexture(texture)
128 , fWidth(width)
129 , fHeight(height)
130 , fStencilBits(stencilBits)
bsalomon@google.comf954d8d2011-04-06 17:50:02 +0000131 , fIsMultisampled(isMultisampled)
bsalomon@google.com8295dc12011-05-02 12:53:34 +0000132 {
133 fResolveRect.setLargestInverted();
134 }
bsalomon@google.comd302f142011-03-03 13:54:13 +0000135
bsalomon@google.com6dcf4992011-04-05 21:16:14 +0000136 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 }
bsalomon@google.comd302f142011-03-03 13:54:13 +0000146
bsalomon@google.com8295dc12011-05-02 12:53:34 +0000147private:
bsalomon@google.com6dcf4992011-04-05 21:16:14 +0000148 GrTexture* fTexture; // not ref'ed
bsalomon@google.comd302f142011-03-03 13:54:13 +0000149 int fWidth;
150 int fHeight;
151 int fStencilBits;
bsalomon@google.comf954d8d2011-04-06 17:50:02 +0000152 bool fIsMultisampled;
bsalomon@google.com8295dc12011-05-02 12:53:34 +0000153 GrIRect fResolveRect;
bsalomon@google.comd302f142011-03-03 13:54:13 +0000154
bsalomon@google.comd302f142011-03-03 13:54:13 +0000155 // 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
bsalomon@google.com8fe72472011-03-30 21:26:44 +0000160 typedef GrResource INHERITED;
reed@google.comac10a2d2010-12-22 21:39:39 +0000161};
162
bsalomon@google.com8fe72472011-03-30 21:26:44 +0000163class GrTexture : public GrResource {
bsalomon@google.com8fe72472011-03-30 21:26:44 +0000164
reed@google.comac10a2d2010-12-22 21:39:39 +0000165public:
reed@google.comac10a2d2010-12-22 21:39:39 +0000166 /**
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000167 * Retrieves the width of the texture.
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000168 *
reed@google.comac10a2d2010-12-22 21:39:39 +0000169 * @return the width in texels
170 */
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000171 int width() const { return fWidth; }
bsalomon@google.com8fe72472011-03-30 21:26:44 +0000172
reed@google.comac10a2d2010-12-22 21:39:39 +0000173 /**
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000174 * Retrieves the height of the texture.
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000175 *
reed@google.comac10a2d2010-12-22 21:39:39 +0000176 * @return the height in texels
177 */
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000178 int height() const { return fHeight; }
reed@google.comac10a2d2010-12-22 21:39:39 +0000179
180 /**
181 * Convert from texels to normalized texture coords for POT textures
182 * only.
183 */
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000184 GrFixed normalizeFixedX(GrFixed x) const { GrAssert(GrIsPow2(fWidth));
reed@google.comac10a2d2010-12-22 21:39:39 +0000185 return x >> fShiftFixedX; }
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000186 GrFixed normalizeFixedY(GrFixed y) const { GrAssert(GrIsPow2(fHeight));
reed@google.comac10a2d2010-12-22 21:39:39 +0000187 return y >> fShiftFixedY; }
188
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000189 /**
reed@google.comac10a2d2010-12-22 21:39:39 +0000190 * Retrieves the pixel config specified when the texture was created.
191 */
bsalomon@google.com669fdc42011-04-05 17:08:27 +0000192 GrPixelConfig config() const { return fConfig; }
reed@google.comac10a2d2010-12-22 21:39:39 +0000193
194 /**
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000195 * Approximate number of bytes used by the texture
reed@google.comac10a2d2010-12-22 21:39:39 +0000196 */
197 size_t sizeInBytes() const {
bsalomon@google.com669fdc42011-04-05 17:08:27 +0000198 return fWidth * fHeight * GrBytesPerPixel(fConfig);
reed@google.comac10a2d2010-12-22 21:39:39 +0000199 }
200
201 /**
202 * Updates a subrectangle of texels in the texture.
203 *
junov@google.com4ee7ae52011-06-30 17:30:49 +0000204 * @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
209 * used at texture creation.
210 * @param rowBytes number of bytes per row in srcData, 0 means rows are
211 * packed
reed@google.comac10a2d2010-12-22 21:39:39 +0000212 */
bsalomon@google.com79d2dbe2011-06-13 19:28:02 +0000213 virtual void uploadTextureData(int x,
214 int y,
215 int width,
216 int height,
junov@google.com4ee7ae52011-06-30 17:30:49 +0000217 const void* srcData,
218 size_t rowBytes) = 0;
reed@google.comac10a2d2010-12-22 21:39:39 +0000219
220 /**
bsalomon@google.com669fdc42011-04-05 17:08:27 +0000221 * Reads a rectangle of pixels from the texture.
222 * @param left left edge of the rectangle to read (inclusive)
223 * @param top top edge of the rectangle to read (inclusive)
224 * @param width width of rectangle to read in pixels.
225 * @param height height of rectangle to read in pixels.
226 * @param config the pixel config of the destination buffer
227 * @param buffer memory to read the rectangle into.
228 *
229 * @return true if the read succeeded, false if not. The read can fail
230 * because of a unsupported pixel config.
231 */
232 bool readPixels(int left, int top, int width, int height,
233 GrPixelConfig config, void* buffer);
234
235 /**
reed@google.comac10a2d2010-12-22 21:39:39 +0000236 * Retrieves the render target underlying this texture that can be passed to
237 * GrGpu::setRenderTarget().
238 *
bsalomon@google.com6dcf4992011-04-05 21:16:14 +0000239 * @return handle to render target or NULL if the texture is not a
reed@google.comac10a2d2010-12-22 21:39:39 +0000240 * render target
241 */
bsalomon@google.com6dcf4992011-04-05 21:16:14 +0000242 GrRenderTarget* asRenderTarget() { return fRenderTarget; }
reed@google.comac10a2d2010-12-22 21:39:39 +0000243
244 /**
bsalomon@google.com1da07462011-03-10 14:51:57 +0000245 * Removes the reference on the associated GrRenderTarget held by this
bsalomon@google.com8fe72472011-03-30 21:26:44 +0000246 * texture. Afterwards asRenderTarget() will return NULL. The
bsalomon@google.com1da07462011-03-10 14:51:57 +0000247 * GrRenderTarget survives the release if another ref is held on it.
reed@google.comac10a2d2010-12-22 21:39:39 +0000248 */
bsalomon@google.com6dcf4992011-04-05 21:16:14 +0000249 void releaseRenderTarget() {
250 if (NULL != fRenderTarget) {
251 GrAssert(fRenderTarget->asTexture() == this);
252 fRenderTarget->onTextureReleaseRenderTarget();
253 fRenderTarget->unref();
254 fRenderTarget = NULL;
255 }
256 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000257
258 /**
259 * Return the native ID or handle to the texture, depending on the
260 * platform. e.g. on opengl, return the texture ID.
261 */
262 virtual intptr_t getTextureHandle() = 0;
263
264#if GR_DEBUG
265 void validate() const {
266 this->INHERITED::validate();
267 }
268#else
269 void validate() const {}
270#endif
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000271
bsalomon@google.com6dcf4992011-04-05 21:16:14 +0000272protected:
273 GrRenderTarget* fRenderTarget; // texture refs its rt representation
274 // base class cons sets to NULL
275 // subclass cons can create and set
276
277 GrTexture(GrGpu* gpu,
278 int width,
279 int height,
280 GrPixelConfig config)
281 : INHERITED(gpu)
282 , fRenderTarget(NULL)
283 , fWidth(width)
284 , fHeight(height)
285 , fConfig(config) {
286 // only make sense if alloc size is pow2
287 fShiftFixedX = 31 - Gr_clz(fWidth);
288 fShiftFixedY = 31 - Gr_clz(fHeight);
289 }
290
291 // GrResource overrides
292 virtual void onRelease() {
293 releaseRenderTarget();
294 }
295
296 virtual void onAbandon() {
297 if (NULL != fRenderTarget) {
298 fRenderTarget->abandon();
299 }
300 }
301
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000302private:
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000303 int fWidth;
304 int fHeight;
reed@google.comac10a2d2010-12-22 21:39:39 +0000305 // these two shift a fixed-point value into normalized coordinates
306 // for this texture if the texture is power of two sized.
307 int fShiftFixedX;
308 int fShiftFixedY;
bsalomon@google.com669fdc42011-04-05 17:08:27 +0000309
310 GrPixelConfig fConfig;
reed@google.comac10a2d2010-12-22 21:39:39 +0000311
bsalomon@google.com8fe72472011-03-30 21:26:44 +0000312 typedef GrResource INHERITED;
reed@google.comac10a2d2010-12-22 21:39:39 +0000313};
314
315#endif
316