blob: 493bb8d672b595a3d69ed281eb7bbd0083e02df0 [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.com669fdc42011-04-05 17:08:27 +000062 * Reads a rectangle of pixels from the render target.
63 * @param left left edge of the rectangle to read (inclusive)
64 * @param top top edge of the rectangle to read (inclusive)
65 * @param width width of rectangle to read in pixels.
66 * @param height height of rectangle to read in pixels.
67 * @param config the pixel config of the destination buffer
68 * @param buffer memory to read the rectangle into.
69 *
70 * @return true if the read succeeded, false if not. The read can fail
71 * because of a unsupported pixel config.
72 */
73 bool readPixels(int left, int top, int width, int height,
74 GrPixelConfig config, void* buffer);
75
reed@google.comac10a2d2010-12-22 21:39:39 +000076protected:
bsalomon@google.com8fe72472011-03-30 21:26:44 +000077 GrRenderTarget(GrGpu* gpu,
78 GrTexture* texture,
bsalomon@google.comd302f142011-03-03 13:54:13 +000079 int width,
80 int height,
bsalomon@google.comf954d8d2011-04-06 17:50:02 +000081 int stencilBits,
82 bool isMultisampled)
bsalomon@google.com8fe72472011-03-30 21:26:44 +000083 : INHERITED(gpu)
84 , fTexture(texture)
85 , fWidth(width)
86 , fHeight(height)
87 , fStencilBits(stencilBits)
bsalomon@google.comf954d8d2011-04-06 17:50:02 +000088 , fIsMultisampled(isMultisampled)
bsalomon@google.com8fe72472011-03-30 21:26:44 +000089 {}
bsalomon@google.comd302f142011-03-03 13:54:13 +000090
bsalomon@google.com6dcf4992011-04-05 21:16:14 +000091 friend class GrTexture;
92 // When a texture unrefs an owned rendertarget this func
93 // removes the back pointer. This could be done called from
94 // texture's destructor but would have to be done in derived
95 // class. By the time of texture base destructor it has already
96 // lost its pointer to the rt.
97 void onTextureReleaseRenderTarget() {
98 GrAssert(NULL != fTexture);
99 fTexture = NULL;
100 }
bsalomon@google.comd302f142011-03-03 13:54:13 +0000101
bsalomon@google.com6dcf4992011-04-05 21:16:14 +0000102 GrTexture* fTexture; // not ref'ed
bsalomon@google.comd302f142011-03-03 13:54:13 +0000103 int fWidth;
104 int fHeight;
105 int fStencilBits;
bsalomon@google.comf954d8d2011-04-06 17:50:02 +0000106 bool fIsMultisampled;
bsalomon@google.comd302f142011-03-03 13:54:13 +0000107
108private:
109 // GrGpu keeps a cached clip in the render target to avoid redundantly
110 // rendering the clip into the same stencil buffer.
111 friend class GrGpu;
112 GrClip fLastStencilClip;
113
bsalomon@google.com8fe72472011-03-30 21:26:44 +0000114 typedef GrResource INHERITED;
reed@google.comac10a2d2010-12-22 21:39:39 +0000115};
116
bsalomon@google.com8fe72472011-03-30 21:26:44 +0000117class GrTexture : public GrResource {
bsalomon@google.com8fe72472011-03-30 21:26:44 +0000118
reed@google.comac10a2d2010-12-22 21:39:39 +0000119public:
reed@google.comac10a2d2010-12-22 21:39:39 +0000120 /**
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000121 * Retrieves the width of the texture.
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000122 *
reed@google.comac10a2d2010-12-22 21:39:39 +0000123 * @return the width in texels
124 */
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000125 int width() const { return fWidth; }
bsalomon@google.com8fe72472011-03-30 21:26:44 +0000126
reed@google.comac10a2d2010-12-22 21:39:39 +0000127 /**
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000128 * Retrieves the height of the texture.
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000129 *
reed@google.comac10a2d2010-12-22 21:39:39 +0000130 * @return the height in texels
131 */
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000132 int height() const { return fHeight; }
reed@google.comac10a2d2010-12-22 21:39:39 +0000133
134 /**
135 * Convert from texels to normalized texture coords for POT textures
136 * only.
137 */
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000138 GrFixed normalizeFixedX(GrFixed x) const { GrAssert(GrIsPow2(fWidth));
reed@google.comac10a2d2010-12-22 21:39:39 +0000139 return x >> fShiftFixedX; }
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000140 GrFixed normalizeFixedY(GrFixed y) const { GrAssert(GrIsPow2(fHeight));
reed@google.comac10a2d2010-12-22 21:39:39 +0000141 return y >> fShiftFixedY; }
142
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000143 /**
reed@google.comac10a2d2010-12-22 21:39:39 +0000144 * Retrieves the pixel config specified when the texture was created.
145 */
bsalomon@google.com669fdc42011-04-05 17:08:27 +0000146 GrPixelConfig config() const { return fConfig; }
reed@google.comac10a2d2010-12-22 21:39:39 +0000147
148 /**
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000149 * Approximate number of bytes used by the texture
reed@google.comac10a2d2010-12-22 21:39:39 +0000150 */
151 size_t sizeInBytes() const {
bsalomon@google.com669fdc42011-04-05 17:08:27 +0000152 return fWidth * fHeight * GrBytesPerPixel(fConfig);
reed@google.comac10a2d2010-12-22 21:39:39 +0000153 }
154
155 /**
156 * Updates a subrectangle of texels in the texture.
157 *
158 * @param x left edge of rectangle to update
159 * @param y top edge of rectangle to update
160 * @param width width of rectangle to update
161 * @param height height of rectangle to update
162 * @param srcData width*height texels of data in same format that was used
163 * at texture creation.
164 */
165 virtual void uploadTextureData(uint32_t x,
166 uint32_t y,
167 uint32_t width,
168 uint32_t height,
169 const void* srcData) = 0;
reed@google.comac10a2d2010-12-22 21:39:39 +0000170
171 /**
bsalomon@google.com669fdc42011-04-05 17:08:27 +0000172 * Reads a rectangle of pixels from the texture.
173 * @param left left edge of the rectangle to read (inclusive)
174 * @param top top edge of the rectangle to read (inclusive)
175 * @param width width of rectangle to read in pixels.
176 * @param height height of rectangle to read in pixels.
177 * @param config the pixel config of the destination buffer
178 * @param buffer memory to read the rectangle into.
179 *
180 * @return true if the read succeeded, false if not. The read can fail
181 * because of a unsupported pixel config.
182 */
183 bool readPixels(int left, int top, int width, int height,
184 GrPixelConfig config, void* buffer);
185
186 /**
reed@google.comac10a2d2010-12-22 21:39:39 +0000187 * Retrieves the render target underlying this texture that can be passed to
188 * GrGpu::setRenderTarget().
189 *
bsalomon@google.com6dcf4992011-04-05 21:16:14 +0000190 * @return handle to render target or NULL if the texture is not a
reed@google.comac10a2d2010-12-22 21:39:39 +0000191 * render target
192 */
bsalomon@google.com6dcf4992011-04-05 21:16:14 +0000193 GrRenderTarget* asRenderTarget() { return fRenderTarget; }
reed@google.comac10a2d2010-12-22 21:39:39 +0000194
195 /**
bsalomon@google.com1da07462011-03-10 14:51:57 +0000196 * Removes the reference on the associated GrRenderTarget held by this
bsalomon@google.com8fe72472011-03-30 21:26:44 +0000197 * texture. Afterwards asRenderTarget() will return NULL. The
bsalomon@google.com1da07462011-03-10 14:51:57 +0000198 * GrRenderTarget survives the release if another ref is held on it.
reed@google.comac10a2d2010-12-22 21:39:39 +0000199 */
bsalomon@google.com6dcf4992011-04-05 21:16:14 +0000200 void releaseRenderTarget() {
201 if (NULL != fRenderTarget) {
202 GrAssert(fRenderTarget->asTexture() == this);
203 fRenderTarget->onTextureReleaseRenderTarget();
204 fRenderTarget->unref();
205 fRenderTarget = NULL;
206 }
207 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000208
209 /**
210 * Return the native ID or handle to the texture, depending on the
211 * platform. e.g. on opengl, return the texture ID.
212 */
213 virtual intptr_t getTextureHandle() = 0;
214
215#if GR_DEBUG
216 void validate() const {
217 this->INHERITED::validate();
218 }
219#else
220 void validate() const {}
221#endif
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000222
bsalomon@google.com6dcf4992011-04-05 21:16:14 +0000223protected:
224 GrRenderTarget* fRenderTarget; // texture refs its rt representation
225 // base class cons sets to NULL
226 // subclass cons can create and set
227
228 GrTexture(GrGpu* gpu,
229 int width,
230 int height,
231 GrPixelConfig config)
232 : INHERITED(gpu)
233 , fRenderTarget(NULL)
234 , fWidth(width)
235 , fHeight(height)
236 , fConfig(config) {
237 // only make sense if alloc size is pow2
238 fShiftFixedX = 31 - Gr_clz(fWidth);
239 fShiftFixedY = 31 - Gr_clz(fHeight);
240 }
241
242 // GrResource overrides
243 virtual void onRelease() {
244 releaseRenderTarget();
245 }
246
247 virtual void onAbandon() {
248 if (NULL != fRenderTarget) {
249 fRenderTarget->abandon();
250 }
251 }
252
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000253private:
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000254 int fWidth;
255 int fHeight;
reed@google.comac10a2d2010-12-22 21:39:39 +0000256 // these two shift a fixed-point value into normalized coordinates
257 // for this texture if the texture is power of two sized.
258 int fShiftFixedX;
259 int fShiftFixedY;
bsalomon@google.com669fdc42011-04-05 17:08:27 +0000260
261 GrPixelConfig fConfig;
reed@google.comac10a2d2010-12-22 21:39:39 +0000262
bsalomon@google.com8fe72472011-03-30 21:26:44 +0000263 typedef GrResource INHERITED;
reed@google.comac10a2d2010-12-22 21:39:39 +0000264};
265
266#endif
267