blob: d4657a76e5633e5e6b323b227ba28ff97ceb277d [file] [log] [blame]
epoger@google.comec3ed6a2011-07-28 14:26:00 +00001
bsalomon@google.com27847de2011-02-22 20:59:41 +00002/*
epoger@google.comec3ed6a2011-07-28 14:26:00 +00003 * Copyright 2010 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.
bsalomon@google.com27847de2011-02-22 20:59:41 +00007 */
8
epoger@google.comec3ed6a2011-07-28 14:26:00 +00009
bsalomon@google.com27847de2011-02-22 20:59:41 +000010#ifndef GrContext_DEFINED
11#define GrContext_DEFINED
12
bsalomon@google.com27847de2011-02-22 20:59:41 +000013#include "GrPaint.h"
robertphillips@google.comf6747b02012-06-12 00:32:28 +000014#include "GrAARectRenderer.h"
robertphillips@google.coma2d71482012-08-01 20:08:47 +000015#include "GrClipData.h"
bsalomon@google.comc287a892011-08-19 14:49:36 +000016// not strictly needed but requires WK change in LayerTextureUpdaterCanvas to
17// remove.
rmistry@google.comfbfcd562012-08-23 18:09:54 +000018#include "GrRenderTarget.h"
robertphillips@google.coma2d71482012-08-01 20:08:47 +000019#include "SkClipStack.h"
bsalomon@google.com27847de2011-02-22 20:59:41 +000020
senorblanco@chromium.org3b4dd902012-03-05 20:41:22 +000021class GrAutoScratchTexture;
robertphillips@google.coma9b06232012-08-30 11:06:31 +000022class GrCacheKey;
bsalomon@google.com10e04bf2012-03-30 14:35:04 +000023class GrDrawState;
bsalomon@google.com583a1e32011-08-17 13:42:46 +000024class GrDrawTarget;
bsalomon@google.com27847de2011-02-22 20:59:41 +000025class GrFontCache;
bsalomon@google.com05ef5102011-05-02 21:14:59 +000026class GrGpu;
bsalomon@google.com583a1e32011-08-17 13:42:46 +000027class GrIndexBuffer;
bsalomon@google.com27847de2011-02-22 20:59:41 +000028class GrIndexBufferAllocPool;
29class GrInOrderDrawBuffer;
bsalomon@google.com583a1e32011-08-17 13:42:46 +000030class GrPathRenderer;
bsalomon@google.com30085192011-08-19 15:42:31 +000031class GrPathRendererChain;
bsalomon@google.com50398bf2011-07-26 20:45:30 +000032class GrResourceEntry;
33class GrResourceCache;
bsalomon@google.com558a75b2011-08-08 17:01:14 +000034class GrStencilBuffer;
bsalomon@google.com583a1e32011-08-17 13:42:46 +000035class GrVertexBuffer;
bsalomon@google.com50398bf2011-07-26 20:45:30 +000036class GrVertexBufferAllocPool;
robertphillips@google.com72176b22012-05-23 13:19:12 +000037class GrSoftwarePathRenderer;
bsalomon@google.com50398bf2011-07-26 20:45:30 +000038
bsalomon@google.com91826102011-03-21 19:51:57 +000039class GR_API GrContext : public GrRefCnt {
bsalomon@google.com27847de2011-02-22 20:59:41 +000040public:
reed@google.comfa35e3d2012-06-26 20:16:17 +000041 SK_DECLARE_INST_COUNT(GrContext)
42
bsalomon@google.com27847de2011-02-22 20:59:41 +000043 /**
44 * Creates a GrContext from within a 3D context.
45 */
bsalomon@google.com05ef5102011-05-02 21:14:59 +000046 static GrContext* Create(GrEngine engine,
47 GrPlatform3DContext context3D);
bsalomon@google.com27847de2011-02-22 20:59:41 +000048
bsalomon@google.comc0af3172012-06-15 14:10:09 +000049 /**
50 * Returns the number of GrContext instances for the current thread.
51 */
52 static int GetThreadInstanceCount();
53
bsalomon@google.com27847de2011-02-22 20:59:41 +000054 virtual ~GrContext();
55
56 /**
57 * The GrContext normally assumes that no outsider is setting state
58 * within the underlying 3D API's context/device/whatever. This call informs
59 * the context that the state was modified and it should resend. Shouldn't
60 * be called frequently for good performance.
61 */
62 void resetContext();
63
bsalomon@google.com8fe72472011-03-30 21:26:44 +000064 /**
65 * Abandons all gpu resources, assumes 3D API state is unknown. Call this
66 * if you have lost the associated GPU context, and thus internal texture,
67 * buffer, etc. references/IDs are now invalid. Should be called even when
68 * GrContext is no longer going to be used for two reasons:
69 * 1) ~GrContext will not try to free the objects in the 3D API.
70 * 2) If you've created GrResources that outlive the GrContext they will
71 * be marked as invalid (GrResource::isValid()) and won't attempt to
72 * free their underlying resource in the 3D API.
73 * Content drawn since the last GrContext::flush() may be lost.
74 */
75 void contextLost();
bsalomon@google.com27847de2011-02-22 20:59:41 +000076
77 /**
junov@google.com53a55842011-06-08 22:55:10 +000078 * Similar to contextLost, but makes no attempt to reset state.
79 * Use this method when GrContext destruction is pending, but
80 * the graphics context is destroyed first.
81 */
82 void contextDestroyed();
83
84 /**
bsalomon@google.com8fe72472011-03-30 21:26:44 +000085 * Frees gpu created by the context. Can be called to reduce GPU memory
86 * pressure.
bsalomon@google.com27847de2011-02-22 20:59:41 +000087 */
bsalomon@google.com8fe72472011-03-30 21:26:44 +000088 void freeGpuResources();
89
bsalomon@google.com07fc0d12012-06-22 15:15:59 +000090 /**
91 * Returns the number of bytes of GPU memory hosted by the texture cache.
92 */
93 size_t getGpuTextureCacheBytes() const;
94
bsalomon@google.com8fe72472011-03-30 21:26:44 +000095 ///////////////////////////////////////////////////////////////////////////
96 // Textures
bsalomon@google.com27847de2011-02-22 20:59:41 +000097
98 /**
bsalomon@google.com1fadb202011-12-12 16:10:08 +000099 * Create a new entry, based on the specified key and texture, and return
robertphillips@google.com1f47f4f2012-08-16 14:49:16 +0000100 * a "locked" texture. Must call be balanced with an unlockTexture() call.
bsalomon@google.com1fadb202011-12-12 16:10:08 +0000101 *
bsalomon@google.comb8670992012-07-25 21:27:09 +0000102 * @param params The tex params used to draw a texture may help determine
103 * the cache entry used. (e.g. different versions may exist
104 * for different wrap modes on GPUs with limited NPOT
105 * texture support). NULL implies clamp wrap modes.
bsalomon@google.com1fadb202011-12-12 16:10:08 +0000106 * @param desc Description of the texture properties.
robertphillips@google.com9c2ea842012-08-13 17:47:59 +0000107 * @param cacheData Cache-specific properties (e.g., texture gen ID)
bsalomon@google.com1fadb202011-12-12 16:10:08 +0000108 * @param srcData Pointer to the pixel values.
109 * @param rowBytes The number of bytes between rows of the texture. Zero
110 * implies tightly packed rows.
111 */
robertphillips@google.com1f47f4f2012-08-16 14:49:16 +0000112 GrTexture* createAndLockTexture(const GrTextureParams* params,
113 const GrTextureDesc& desc,
114 const GrCacheData& cacheData,
115 void* srcData, size_t rowBytes);
bsalomon@google.com1fadb202011-12-12 16:10:08 +0000116
117 /**
robertphillips@google.coma9b06232012-08-30 11:06:31 +0000118 * Look for a texture that matches 'key' in the cache. If not found,
119 * return NULL.
120 */
121 GrTexture* findTexture(const GrCacheKey& key);
122
123 /**
bsalomon@google.com50398bf2011-07-26 20:45:30 +0000124 * Search for an entry based on key and dimensions. If found, "lock" it and
robertphillips@google.com1f47f4f2012-08-16 14:49:16 +0000125 * return it. The return value will be NULL if not found.
bsalomon@google.com1fadb202011-12-12 16:10:08 +0000126 * Must be balanced with an unlockTexture() call.
127 *
bsalomon@google.comb8670992012-07-25 21:27:09 +0000128 * @param desc Description of the texture properties.
robertphillips@google.com9c2ea842012-08-13 17:47:59 +0000129 * @param cacheData Cache-specific properties (e.g., texture gen ID)
bsalomon@google.comb8670992012-07-25 21:27:09 +0000130 * @param params The tex params used to draw a texture may help determine
131 * the cache entry used. (e.g. different versions may exist
132 * for different wrap modes on GPUs with limited NPOT
133 * texture support). NULL implies clamp wrap modes.
bsalomon@google.com50398bf2011-07-26 20:45:30 +0000134 */
robertphillips@google.com1f47f4f2012-08-16 14:49:16 +0000135 GrTexture* findAndLockTexture(const GrTextureDesc& desc,
136 const GrCacheData& cacheData,
137 const GrTextureParams* params);
bsalomon@google.comfb309512011-11-30 14:13:48 +0000138 /**
139 * Determines whether a texture is in the cache. If the texture is found it
140 * will not be locked or returned. This call does not affect the priority of
141 * the texture for deletion.
142 */
robertphillips@google.com75b3c962012-06-07 12:08:45 +0000143 bool isTextureInCache(const GrTextureDesc& desc,
robertphillips@google.com9c2ea842012-08-13 17:47:59 +0000144 const GrCacheData& cacheData,
bsalomon@google.comb8670992012-07-25 21:27:09 +0000145 const GrTextureParams* params) const;
bsalomon@google.com50398bf2011-07-26 20:45:30 +0000146
147 /**
148 * Enum that determines how closely a returned scratch texture must match
149 * a provided GrTextureDesc.
150 */
151 enum ScratchTexMatch {
152 /**
153 * Finds a texture that exactly matches the descriptor.
154 */
155 kExact_ScratchTexMatch,
156 /**
157 * Finds a texture that approximately matches the descriptor. Will be
158 * at least as large in width and height as desc specifies. If desc
159 * specifies that texture is a render target then result will be a
160 * render target. If desc specifies a render target and doesn't set the
161 * no stencil flag then result will have a stencil. Format and aa level
162 * will always match.
163 */
164 kApprox_ScratchTexMatch
165 };
bsalomon@google.com27847de2011-02-22 20:59:41 +0000166
167 /**
bsalomon@google.comfea37b52011-04-25 15:51:06 +0000168 * Returns a texture matching the desc. It's contents are unknown. Subsequent
169 * requests with the same descriptor are not guaranteed to return the same
170 * texture. The same texture is guaranteed not be returned again until it is
robertphillips@google.com15c0fea2012-06-22 12:41:43 +0000171 * unlocked. Call must be balanced with an unlockTexture() call.
bsalomon@google.coma39f4042011-04-26 13:18:16 +0000172 *
173 * Textures created by createAndLockTexture() hide the complications of
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000174 * tiling non-power-of-two textures on APIs that don't support this (e.g.
bsalomon@google.com50398bf2011-07-26 20:45:30 +0000175 * unextended GLES2). Tiling a npot texture created by lockScratchTexture on
bsalomon@google.coma39f4042011-04-26 13:18:16 +0000176 * such an API will create gaps in the tiling pattern. This includes clamp
177 * mode. (This may be addressed in a future update.)
bsalomon@google.comfea37b52011-04-25 15:51:06 +0000178 */
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000179 GrTexture* lockScratchTexture(const GrTextureDesc& desc,
robertphillips@google.com1f47f4f2012-08-16 14:49:16 +0000180 ScratchTexMatch match);
bsalomon@google.comb5b31682011-06-16 18:05:35 +0000181
182 /**
robertphillips@google.coma9b06232012-08-30 11:06:31 +0000183 * Make a texture un-purgeable in the cache
184 */
185 void lockTexture(GrTexture* texture);
186
187 /**
bsalomon@google.com27847de2011-02-22 20:59:41 +0000188 * When done with an entry, call unlockTexture(entry) on it, which returns
189 * it to the cache, where it may be purged.
190 */
robertphillips@google.com1f47f4f2012-08-16 14:49:16 +0000191 void unlockTexture(GrTexture* texture);
bsalomon@google.com27847de2011-02-22 20:59:41 +0000192
193 /**
bsalomon@google.com27847de2011-02-22 20:59:41 +0000194 * Creates a texture that is outside the cache. Does not count against
195 * cache's budget.
196 */
robertphillips@google.com75b3c962012-06-07 12:08:45 +0000197 GrTexture* createUncachedTexture(const GrTextureDesc& desc,
bsalomon@google.com27847de2011-02-22 20:59:41 +0000198 void* srcData,
199 size_t rowBytes);
200
201 /**
bsalomon@google.comb8670992012-07-25 21:27:09 +0000202 * Returns true if the specified use of an indexed texture is supported.
203 * Support may depend upon whether the texture params indicate that the
204 * texture will be tiled. Passing NULL for the texture params indicates
205 * clamp mode.
bsalomon@google.com27847de2011-02-22 20:59:41 +0000206 */
bsalomon@google.comb8670992012-07-25 21:27:09 +0000207 bool supportsIndex8PixelConfig(const GrTextureParams*,
bsalomon@google.com1f221a72011-08-23 20:54:07 +0000208 int width,
209 int height) const;
bsalomon@google.com27847de2011-02-22 20:59:41 +0000210
211 /**
bsalomon@google.com07fc0d12012-06-22 15:15:59 +0000212 * Return the current texture cache limits.
213 *
214 * @param maxTextures If non-null, returns maximum number of textures that
215 * can be held in the cache.
216 * @param maxTextureBytes If non-null, returns maximum number of bytes of
217 * texture memory that can be held in the cache.
bsalomon@google.com27847de2011-02-22 20:59:41 +0000218 */
bsalomon@google.com07fc0d12012-06-22 15:15:59 +0000219 void getTextureCacheLimits(int* maxTextures, size_t* maxTextureBytes) const;
bsalomon@google.com27847de2011-02-22 20:59:41 +0000220
221 /**
bsalomon@google.com07fc0d12012-06-22 15:15:59 +0000222 * Specify the texture cache limits. If the current cache exceeds either
223 * of these, it will be purged (LRU) to keep the cache within these limits.
bsalomon@google.com27847de2011-02-22 20:59:41 +0000224 *
bsalomon@google.com07fc0d12012-06-22 15:15:59 +0000225 * @param maxTextures The maximum number of textures that can be held in
226 * the cache.
bsalomon@google.com27847de2011-02-22 20:59:41 +0000227 * @param maxTextureBytes The maximum number of bytes of texture memory
228 * that can be held in the cache.
229 */
bsalomon@google.com07fc0d12012-06-22 15:15:59 +0000230 void setTextureCacheLimits(int maxTextures, size_t maxTextureBytes);
bsalomon@google.com27847de2011-02-22 20:59:41 +0000231
232 /**
233 * Return the max width or height of a texture supported by the current gpu
234 */
bsalomon@google.com91958362011-06-13 17:58:13 +0000235 int getMaxTextureSize() const;
236
237 /**
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000238 * Return the max width or height of a render target supported by the
bsalomon@google.com91958362011-06-13 17:58:13 +0000239 * current gpu
240 */
241 int getMaxRenderTargetSize() const;
bsalomon@google.com27847de2011-02-22 20:59:41 +0000242
243 ///////////////////////////////////////////////////////////////////////////
244 // Render targets
245
246 /**
bsalomon@google.com5877ffd2011-04-11 17:58:48 +0000247 * Sets the render target.
248 * @param target the render target to set. (should not be NULL.)
249 */
250 void setRenderTarget(GrRenderTarget* target);
251
252 /**
253 * Gets the current render target.
254 * @return the currently bound render target. Should never be NULL.
255 */
256 const GrRenderTarget* getRenderTarget() const;
257 GrRenderTarget* getRenderTarget();
258
robertphillips@google.comf69a11b2012-06-15 13:58:07 +0000259 GrAARectRenderer* getAARectRenderer() { return fAARectRenderer; }
260
robertphillips@google.com99a5ac02012-04-10 19:26:38 +0000261 /**
262 * Can the provided configuration act as a color render target?
263 */
264 bool isConfigRenderable(GrPixelConfig config) const;
265
bsalomon@google.com5877ffd2011-04-11 17:58:48 +0000266 ///////////////////////////////////////////////////////////////////////////
267 // Platform Surfaces
268
bsalomon@google.com5877ffd2011-04-11 17:58:48 +0000269 /**
bsalomon@google.come269f212011-11-07 13:29:52 +0000270 * Wraps an existing texture with a GrTexture object.
271 *
272 * OpenGL: if the object is a texture Gr may change its GL texture params
273 * when it is drawn.
274 *
275 * @param desc description of the object to create.
276 *
277 * @return GrTexture object or NULL on failure.
278 */
279 GrTexture* createPlatformTexture(const GrPlatformTextureDesc& desc);
280
281 /**
282 * Wraps an existing render target with a GrRenderTarget object. It is
283 * similar to createPlatformTexture but can be used to draw into surfaces
284 * that are not also textures (e.g. FBO 0 in OpenGL, or an MSAA buffer that
285 * the client will resolve to a texture).
286 *
287 * @param desc description of the object to create.
288 *
289 * @return GrTexture object or NULL on failure.
290 */
291 GrRenderTarget* createPlatformRenderTarget(
292 const GrPlatformRenderTargetDesc& desc);
293
bsalomon@google.com27847de2011-02-22 20:59:41 +0000294 ///////////////////////////////////////////////////////////////////////////
295 // Matrix state
296
297 /**
298 * Gets the current transformation matrix.
299 * @return the current matrix.
300 */
301 const GrMatrix& getMatrix() const;
302
303 /**
304 * Sets the transformation matrix.
305 * @param m the matrix to set.
306 */
307 void setMatrix(const GrMatrix& m);
308
309 /**
310 * Concats the current matrix. The passed matrix is applied before the
311 * current matrix.
312 * @param m the matrix to concat.
313 */
314 void concatMatrix(const GrMatrix& m) const;
315
316
317 ///////////////////////////////////////////////////////////////////////////
318 // Clip state
319 /**
320 * Gets the current clip.
321 * @return the current clip.
322 */
robertphillips@google.combeb1af72012-07-26 18:52:16 +0000323 const GrClipData* getClip() const;
bsalomon@google.com27847de2011-02-22 20:59:41 +0000324
325 /**
326 * Sets the clip.
robertphillips@google.combeb1af72012-07-26 18:52:16 +0000327 * @param clipData the clip to set.
bsalomon@google.com27847de2011-02-22 20:59:41 +0000328 */
robertphillips@google.combeb1af72012-07-26 18:52:16 +0000329 void setClip(const GrClipData* clipData);
bsalomon@google.com27847de2011-02-22 20:59:41 +0000330
bsalomon@google.com27847de2011-02-22 20:59:41 +0000331 ///////////////////////////////////////////////////////////////////////////
332 // Draws
333
334 /**
bsalomon@google.com6aa25c32011-04-27 19:55:29 +0000335 * Clear the entire or rect of the render target, ignoring any clips.
336 * @param rect the rect to clear or the whole thing if rect is NULL.
337 * @param color the color to clear to.
robertphillips@google.comc82a8b72012-06-21 20:15:48 +0000338 * @param target if non-NULL, the render target to clear otherwise clear
339 * the current render target
bsalomon@google.com27847de2011-02-22 20:59:41 +0000340 */
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000341 void clear(const GrIRect* rect, GrColor color,
robertphillips@google.comc82a8b72012-06-21 20:15:48 +0000342 GrRenderTarget* target = NULL);
bsalomon@google.com27847de2011-02-22 20:59:41 +0000343
344 /**
345 * Draw everywhere (respecting the clip) with the paint.
346 */
347 void drawPaint(const GrPaint& paint);
348
349 /**
350 * Draw the rect using a paint.
351 * @param paint describes how to color pixels.
352 * @param strokeWidth If strokeWidth < 0, then the rect is filled, else
353 * the rect is mitered stroked based on strokeWidth. If
354 * strokeWidth == 0, then the stroke is always a single
355 * pixel thick.
356 * @param matrix Optional matrix applied to the rect. Applied before
357 * context's matrix or the paint's matrix.
358 * The rects coords are used to access the paint (through texture matrix)
359 */
360 void drawRect(const GrPaint& paint,
361 const GrRect&,
362 GrScalar strokeWidth = -1,
363 const GrMatrix* matrix = NULL);
364
365 /**
366 * Maps a rect of paint coordinates onto the a rect of destination
367 * coordinates. Each rect can optionally be transformed. The srcRect
368 * is stretched over the dstRect. The dstRect is transformed by the
369 * context's matrix and the srcRect is transformed by the paint's matrix.
370 * Additional optional matrices can be provided by parameters.
371 *
372 * @param paint describes how to color pixels.
373 * @param dstRect the destination rect to draw.
374 * @param srcRect rect of paint coordinates to be mapped onto dstRect
375 * @param dstMatrix Optional matrix to transform dstRect. Applied before
376 * context's matrix.
377 * @param srcMatrix Optional matrix to transform srcRect Applied before
378 * paint's matrix.
379 */
380 void drawRectToRect(const GrPaint& paint,
381 const GrRect& dstRect,
382 const GrRect& srcRect,
383 const GrMatrix* dstMatrix = NULL,
384 const GrMatrix* srcMatrix = NULL);
385
386 /**
bsalomon@google.comd302f142011-03-03 13:54:13 +0000387 * Draws a path.
bsalomon@google.com27847de2011-02-22 20:59:41 +0000388 *
389 * @param paint describes how to color pixels.
reed@google.com07f3ee12011-05-16 17:21:57 +0000390 * @param path the path to draw
bsalomon@google.com27847de2011-02-22 20:59:41 +0000391 * @param fill the path filling rule to use.
392 * @param translate optional additional translation applied to the
393 * path.
394 */
bsalomon@google.com8d033a12012-04-27 15:52:53 +0000395 void drawPath(const GrPaint& paint, const SkPath& path, GrPathFill fill,
bsalomon@google.comd302f142011-03-03 13:54:13 +0000396 const GrPoint* translate = NULL);
reed@google.com07f3ee12011-05-16 17:21:57 +0000397
bsalomon@google.com27847de2011-02-22 20:59:41 +0000398 /**
399 * Draws vertices with a paint.
400 *
401 * @param paint describes how to color pixels.
402 * @param primitiveType primitives type to draw.
403 * @param vertexCount number of vertices.
404 * @param positions array of vertex positions, required.
405 * @param texCoords optional array of texture coordinates used
406 * to access the paint.
407 * @param colors optional array of per-vertex colors, supercedes
408 * the paint's color field.
409 * @param indices optional array of indices. If NULL vertices
410 * are drawn non-indexed.
411 * @param indexCount if indices is non-null then this is the
412 * number of indices.
413 */
414 void drawVertices(const GrPaint& paint,
415 GrPrimitiveType primitiveType,
416 int vertexCount,
417 const GrPoint positions[],
418 const GrPoint texs[],
419 const GrColor colors[],
420 const uint16_t indices[],
421 int indexCount);
422
bsalomon@google.com93c96602012-04-27 13:05:21 +0000423 /**
424 * Draws an oval.
425 *
426 * @param paint describes how to color pixels.
427 * @param rect the bounding rect of the oval.
428 * @param strokeWidth if strokeWidth < 0, then the oval is filled, else
429 * the rect is stroked based on strokeWidth. If
430 * strokeWidth == 0, then the stroke is always a single
431 * pixel thick.
432 */
433 void drawOval(const GrPaint& paint,
434 const GrRect& rect,
435 SkScalar strokeWidth);
436
bsalomon@google.com27847de2011-02-22 20:59:41 +0000437 ///////////////////////////////////////////////////////////////////////////
438 // Misc.
439
440 /**
bsalomon@google.coma7f84e12011-03-10 14:13:19 +0000441 * Flags that affect flush() behavior.
442 */
443 enum FlushBits {
444 /**
445 * A client may want Gr to bind a GrRenderTarget in the 3D API so that
446 * it can be rendered to directly. However, Gr lazily sets state. Simply
447 * calling setRenderTarget() followed by flush() without flags may not
448 * bind the render target. This flag forces the context to bind the last
449 * set render target in the 3D API.
450 */
451 kForceCurrentRenderTarget_FlushBit = 0x1,
452 /**
453 * A client may reach a point where it has partially rendered a frame
454 * through a GrContext that it knows the user will never see. This flag
455 * causes the flush to skip submission of deferred content to the 3D API
456 * during the flush.
457 */
458 kDiscard_FlushBit = 0x2,
459 };
460
461 /**
bsalomon@google.com27847de2011-02-22 20:59:41 +0000462 * Call to ensure all drawing to the context has been issued to the
463 * underlying 3D API.
bsalomon@google.coma7f84e12011-03-10 14:13:19 +0000464 * @param flagsBitfield flags that control the flushing behavior. See
465 * FlushBits.
bsalomon@google.com27847de2011-02-22 20:59:41 +0000466 */
bsalomon@google.com8fe72472011-03-30 21:26:44 +0000467 void flush(int flagsBitfield = 0);
bsalomon@google.com6f379512011-11-16 20:36:03 +0000468
bsalomon@google.com0342a852012-08-20 19:22:38 +0000469 /**
470 * These flags can be used with the read/write pixels functions below.
471 */
472 enum PixelOpsFlags {
473 /** The GrContext will not be flushed. This means that the read or write may occur before
474 previous draws have executed. */
475 kDontFlush_PixelOpsFlag = 0x1,
476 /** The src for write or dst read is unpremultiplied. This is only respected if both the
477 config src and dst configs are an RGBA/BGRA 8888 format. */
478 kUnpremul_PixelOpsFlag = 0x2,
479 };
480
bsalomon@google.com27847de2011-02-22 20:59:41 +0000481 /**
bsalomon@google.com669fdc42011-04-05 17:08:27 +0000482 * Reads a rectangle of pixels from a render target.
bsalomon@google.com0342a852012-08-20 19:22:38 +0000483 * @param target the render target to read from. NULL means the current render target.
bsalomon@google.com669fdc42011-04-05 17:08:27 +0000484 * @param left left edge of the rectangle to read (inclusive)
485 * @param top top edge of the rectangle to read (inclusive)
486 * @param width width of rectangle to read in pixels.
487 * @param height height of rectangle to read in pixels.
488 * @param config the pixel config of the destination buffer
489 * @param buffer memory to read the rectangle into.
bsalomon@google.com0342a852012-08-20 19:22:38 +0000490 * @param rowBytes number of bytes bewtween consecutive rows. Zero means rows are tightly
491 * packed.
492 * @param pixelOpsFlags see PixelOpsFlags enum above.
bsalomon@google.com669fdc42011-04-05 17:08:27 +0000493 *
bsalomon@google.com0342a852012-08-20 19:22:38 +0000494 * @return true if the read succeeded, false if not. The read can fail because of an unsupported
495 * pixel config or because no render target is currently set and NULL was passed for
496 * target.
bsalomon@google.com27847de2011-02-22 20:59:41 +0000497 */
bsalomon@google.com669fdc42011-04-05 17:08:27 +0000498 bool readRenderTargetPixels(GrRenderTarget* target,
499 int left, int top, int width, int height,
bsalomon@google.com0342a852012-08-20 19:22:38 +0000500 GrPixelConfig config, void* buffer,
501 size_t rowBytes = 0,
502 uint32_t pixelOpsFlags = 0);
bsalomon@google.com6f379512011-11-16 20:36:03 +0000503
504 /**
bsalomon@google.com0342a852012-08-20 19:22:38 +0000505 * Copy the src pixels [buffer, rowbytes, pixelconfig] into a render target at the specified
506 * rectangle.
507 * @param target the render target to write into. NULL means the current render target.
bsalomon@google.com6f379512011-11-16 20:36:03 +0000508 * @param left left edge of the rectangle to write (inclusive)
509 * @param top top edge of the rectangle to write (inclusive)
510 * @param width width of rectangle to write in pixels.
511 * @param height height of rectangle to write in pixels.
512 * @param config the pixel config of the source buffer
513 * @param buffer memory to read the rectangle from.
bsalomon@google.com0342a852012-08-20 19:22:38 +0000514 * @param rowBytes number of bytes bewtween consecutive rows. Zero means rows are tightly
515 * packed.
516 * @param pixelOpsFlags see PixelOpsFlags enum above.
bsalomon@google.com6f379512011-11-16 20:36:03 +0000517 */
518 void writeRenderTargetPixels(GrRenderTarget* target,
519 int left, int top, int width, int height,
520 GrPixelConfig config, const void* buffer,
bsalomon@google.com0342a852012-08-20 19:22:38 +0000521 size_t rowBytes = 0,
522 uint32_t pixelOpsFlags = 0);
bsalomon@google.com669fdc42011-04-05 17:08:27 +0000523
524 /**
525 * Reads a rectangle of pixels from a texture.
bsalomon@google.com6f379512011-11-16 20:36:03 +0000526 * @param texture the texture to read from.
bsalomon@google.com669fdc42011-04-05 17:08:27 +0000527 * @param left left edge of the rectangle to read (inclusive)
528 * @param top top edge of the rectangle to read (inclusive)
529 * @param width width of rectangle to read in pixels.
530 * @param height height of rectangle to read in pixels.
531 * @param config the pixel config of the destination buffer
532 * @param buffer memory to read the rectangle into.
bsalomon@google.com0342a852012-08-20 19:22:38 +0000533 * @param rowBytes number of bytes bewtween consecutive rows. Zero means rows are tightly
534 * packed.
535 * @param pixelOpsFlags see PixelOpsFlags enum above.
bsalomon@google.com669fdc42011-04-05 17:08:27 +0000536 *
bsalomon@google.com0342a852012-08-20 19:22:38 +0000537 * @return true if the read succeeded, false if not. The read can fail because of an unsupported
538 * pixel config.
bsalomon@google.com669fdc42011-04-05 17:08:27 +0000539 */
bsalomon@google.com6f379512011-11-16 20:36:03 +0000540 bool readTexturePixels(GrTexture* texture,
bsalomon@google.com669fdc42011-04-05 17:08:27 +0000541 int left, int top, int width, int height,
bsalomon@google.com6f379512011-11-16 20:36:03 +0000542 GrPixelConfig config, void* buffer,
bsalomon@google.com0342a852012-08-20 19:22:38 +0000543 size_t rowBytes = 0,
544 uint32_t pixelOpsFlags = 0);
bsalomon@google.com27847de2011-02-22 20:59:41 +0000545
546 /**
bsalomon@google.com6f379512011-11-16 20:36:03 +0000547 * Writes a rectangle of pixels to a texture.
548 * @param texture the render target to read from.
549 * @param left left edge of the rectangle to write (inclusive)
550 * @param top top edge of the rectangle to write (inclusive)
551 * @param width width of rectangle to write in pixels.
552 * @param height height of rectangle to write in pixels.
553 * @param config the pixel config of the source buffer
554 * @param buffer memory to read pixels from
555 * @param rowBytes number of bytes bewtween consecutive rows. Zero
556 * means rows are tightly packed.
bsalomon@google.com0342a852012-08-20 19:22:38 +0000557 * @param pixelOpsFlags see PixelOpsFlags enum above.
bsalomon@google.com27847de2011-02-22 20:59:41 +0000558 */
bsalomon@google.com6f379512011-11-16 20:36:03 +0000559 void writeTexturePixels(GrTexture* texture,
560 int left, int top, int width, int height,
561 GrPixelConfig config, const void* buffer,
bsalomon@google.com0342a852012-08-20 19:22:38 +0000562 size_t rowBytes,
563 uint32_t pixelOpsFlags = 0);
564
565
senorblanco@chromium.org027de5f2011-07-08 18:03:33 +0000566 /**
senorblanco@chromium.orgef843cd2011-12-02 19:11:17 +0000567 * Copies all texels from one texture to another.
568 * @param src the texture to copy from.
569 * @param dst the render target to copy to.
570 */
571 void copyTexture(GrTexture* src, GrRenderTarget* dst);
bsalomon@google.com75f9f252012-01-31 13:35:56 +0000572
573 /**
574 * Resolves a render target that has MSAA. The intermediate MSAA buffer is
575 * downsampled to the associated GrTexture (accessible via
576 * GrRenderTarget::asTexture()). Any pending draws to the render target will
577 * be executed before the resolve.
578 *
579 * This is only necessary when a client wants to access the object directly
580 * using the underlying graphics API. GrContext will detect when it must
581 * perform a resolve to a GrTexture used as the source of a draw or before
582 * reading pixels back from a GrTexture or GrRenderTarget.
583 */
584 void resolveRenderTarget(GrRenderTarget* target);
585
senorblanco@chromium.orgef843cd2011-12-02 19:11:17 +0000586 /**
senorblanco@chromium.org3b4dd902012-03-05 20:41:22 +0000587 * Applies a 2D Gaussian blur to a given texture.
588 * @param srcTexture The source texture to be blurred.
senorblanco@chromium.org1e95d712012-07-18 19:52:53 +0000589 * @param canClobberSrc If true, srcTexture may be overwritten, and
590 * may be returned as the result.
senorblanco@chromium.org3b4dd902012-03-05 20:41:22 +0000591 * @param rect The destination rectangle.
592 * @param sigmaX The blur's standard deviation in X.
593 * @param sigmaY The blur's standard deviation in Y.
senorblanco@chromium.org1e95d712012-07-18 19:52:53 +0000594 * @return the blurred texture, which may be srcTexture ref'ed, or a
595 * new texture. It is the caller's responsibility to unref this texture.
senorblanco@chromium.org027de5f2011-07-08 18:03:33 +0000596 */
senorblanco@chromium.org3b4dd902012-03-05 20:41:22 +0000597 GrTexture* gaussianBlur(GrTexture* srcTexture,
senorblanco@chromium.org1e95d712012-07-18 19:52:53 +0000598 bool canClobberSrc,
senorblanco@chromium.org3b4dd902012-03-05 20:41:22 +0000599 const SkRect& rect,
600 float sigmaX, float sigmaY);
601
senorblanco@chromium.orgaadd9f82011-07-12 19:44:51 +0000602 /**
bsalomon@google.com82aa7482012-08-13 14:22:17 +0000603 * Zooms a subset of the texture to a larger size with a nice edge.
604 * The inner rectangle is a simple scaling of the texture by a factor of
605 * |zoom|. The outer |inset| pixels transition from the background texture
606 * to the zoomed coordinate system at a rate of
607 * (distance_to_edge / inset) ^2, producing a rounded lens effect.
608 * @param srcTexture The source texture to be zoomed.
609 * @param dstRect The destination rectangle.
610 * @param srcRect The source rectangle. Must be smaller than
611 * dstRect
612 * @param inset Number of pixels to blend along the edges.
613 * @return the zoomed texture, which is dstTexture.
614 */
615 GrTexture* zoom(GrTexture* srcTexture,
616 const SkRect& dstRect, const SkRect& srcRect, float inset);
617
bsalomon@google.com27847de2011-02-22 20:59:41 +0000618 ///////////////////////////////////////////////////////////////////////////
619 // Helpers
620
621 class AutoRenderTarget : ::GrNoncopyable {
622 public:
623 AutoRenderTarget(GrContext* context, GrRenderTarget* target) {
bsalomon@google.com27847de2011-02-22 20:59:41 +0000624 fPrevTarget = context->getRenderTarget();
bsalomon@google.coma04e8e82012-08-27 12:53:13 +0000625 context->setRenderTarget(target);
626 fContext = context;
627 }
628 AutoRenderTarget(GrContext* context) {
629 fPrevTarget = context->getRenderTarget();
630 fContext = context;
bsalomon@google.com27847de2011-02-22 20:59:41 +0000631 }
632 ~AutoRenderTarget() {
633 if (fContext) {
634 fContext->setRenderTarget(fPrevTarget);
635 }
636 }
637 private:
638 GrContext* fContext;
639 GrRenderTarget* fPrevTarget;
640 };
641
robertphillips@google.comfea85ac2012-07-11 18:53:23 +0000642 /**
643 * Save/restore the view-matrix in the context.
644 */
645 class AutoMatrix : GrNoncopyable {
646 public:
bsalomon@google.coma04e8e82012-08-27 12:53:13 +0000647 enum InitialMatrix {
648 kPreserve_InitialMatrix,
649 kIdentity_InitialMatrix,
650 };
651
robertphillips@google.comfea85ac2012-07-11 18:53:23 +0000652 AutoMatrix() : fContext(NULL) {}
bsalomon@google.coma04e8e82012-08-27 12:53:13 +0000653
654 AutoMatrix(GrContext* ctx, InitialMatrix initialState) : fContext(ctx) {
robertphillips@google.comfea85ac2012-07-11 18:53:23 +0000655 fMatrix = ctx->getMatrix();
bsalomon@google.coma04e8e82012-08-27 12:53:13 +0000656 switch (initialState) {
657 case kPreserve_InitialMatrix:
658 break;
659 case kIdentity_InitialMatrix:
660 ctx->setMatrix(GrMatrix::I());
661 break;
662 default:
663 GrCrash("Unexpected initial matrix state");
664 }
robertphillips@google.comfea85ac2012-07-11 18:53:23 +0000665 }
bsalomon@google.coma04e8e82012-08-27 12:53:13 +0000666
robertphillips@google.comfea85ac2012-07-11 18:53:23 +0000667 AutoMatrix(GrContext* ctx, const GrMatrix& matrix) : fContext(ctx) {
668 fMatrix = ctx->getMatrix();
669 ctx->setMatrix(matrix);
670 }
bsalomon@google.coma04e8e82012-08-27 12:53:13 +0000671
robertphillips@google.comfea85ac2012-07-11 18:53:23 +0000672 void set(GrContext* ctx) {
673 if (NULL != fContext) {
674 fContext->setMatrix(fMatrix);
675 }
676 fMatrix = ctx->getMatrix();
677 fContext = ctx;
678 }
bsalomon@google.coma04e8e82012-08-27 12:53:13 +0000679
robertphillips@google.comfea85ac2012-07-11 18:53:23 +0000680 void set(GrContext* ctx, const GrMatrix& matrix) {
681 if (NULL != fContext) {
682 fContext->setMatrix(fMatrix);
683 }
684 fMatrix = ctx->getMatrix();
685 ctx->setMatrix(matrix);
686 fContext = ctx;
687 }
bsalomon@google.coma04e8e82012-08-27 12:53:13 +0000688
robertphillips@google.comfea85ac2012-07-11 18:53:23 +0000689 ~AutoMatrix() {
690 if (NULL != fContext) {
691 fContext->setMatrix(fMatrix);
692 }
693 }
694
695 private:
696 GrContext* fContext;
697 GrMatrix fMatrix;
698 };
bsalomon@google.com27847de2011-02-22 20:59:41 +0000699
robertphillips@google.com56c79b12012-07-11 20:57:46 +0000700 class AutoClip : GrNoncopyable {
701 public:
bsalomon@google.coma04e8e82012-08-27 12:53:13 +0000702 // This enum exists to require a caller of the constructor to acknowledge that the clip will
703 // initially be wide open. It also could be extended if there are other desirable initial
704 // clip states.
705 enum InitialClip {
706 kWideOpen_InitialClip,
707 };
708
709 AutoClip(GrContext* context, InitialClip initialState) {
710 GrAssert(kWideOpen_InitialClip == initialState);
711 fOldClip = context->getClip();
712 fNewClipData.fClipStack = &fNewClipStack;
713 context->setClip(&fNewClipData);
714 fContext = context;
715 }
716
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000717 AutoClip(GrContext* context, const GrRect& newClipRect)
robertphillips@google.com56c79b12012-07-11 20:57:46 +0000718 : fContext(context)
robertphillips@google.combeb1af72012-07-26 18:52:16 +0000719 , fNewClipStack(newClipRect) {
720 fNewClipData.fClipStack = &fNewClipStack;
721
robertphillips@google.com56c79b12012-07-11 20:57:46 +0000722 fOldClip = fContext->getClip();
robertphillips@google.combeb1af72012-07-26 18:52:16 +0000723 fContext->setClip(&fNewClipData);
robertphillips@google.com56c79b12012-07-11 20:57:46 +0000724 }
725
726 ~AutoClip() {
727 if (NULL != fContext) {
728 fContext->setClip(fOldClip);
729 }
730 }
731 private:
robertphillips@google.combeb1af72012-07-26 18:52:16 +0000732 GrContext* fContext;
733 const GrClipData* fOldClip;
734
robertphillips@google.com641f8b12012-07-31 19:15:58 +0000735 SkClipStack fNewClipStack;
robertphillips@google.combeb1af72012-07-26 18:52:16 +0000736 GrClipData fNewClipData;
robertphillips@google.com56c79b12012-07-11 20:57:46 +0000737 };
738
bsalomon@google.coma04e8e82012-08-27 12:53:13 +0000739 class AutoWideOpenIdentityDraw {
740 public:
741 AutoWideOpenIdentityDraw(GrContext* ctx, GrRenderTarget* rt)
742 : fAutoClip(ctx, AutoClip::kWideOpen_InitialClip)
743 , fAutoRT(ctx, rt)
744 , fAutoMatrix(ctx, AutoMatrix::kIdentity_InitialMatrix) {
745 }
746 private:
747 AutoClip fAutoClip;
748 AutoRenderTarget fAutoRT;
749 AutoMatrix fAutoMatrix;
750 };
751
bsalomon@google.com27847de2011-02-22 20:59:41 +0000752 ///////////////////////////////////////////////////////////////////////////
753 // Functions intended for internal use only.
754 GrGpu* getGpu() { return fGpu; }
bsalomon@google.com1f221a72011-08-23 20:54:07 +0000755 const GrGpu* getGpu() const { return fGpu; }
bsalomon@google.com27847de2011-02-22 20:59:41 +0000756 GrFontCache* getFontCache() { return fFontCache; }
757 GrDrawTarget* getTextTarget(const GrPaint& paint);
bsalomon@google.com27847de2011-02-22 20:59:41 +0000758 const GrIndexBuffer* getQuadIndexBuffer() const;
bsalomon@google.com9923c2b2012-06-06 18:21:18 +0000759
bsalomon@google.com558a75b2011-08-08 17:01:14 +0000760 /**
761 * Stencil buffers add themselves to the cache using
762 * addAndLockStencilBuffer. When a SB's RT-attachment count
763 * reaches zero the SB unlocks itself using unlockStencilBuffer and is
764 * eligible for purging. findStencilBuffer is called to check the cache for
765 * a SB that matching an RT's criteria. If a match is found that has been
766 * unlocked (its attachment count has reached 0) then it will be relocked.
767 */
robertphillips@google.com1f47f4f2012-08-16 14:49:16 +0000768 void addAndLockStencilBuffer(GrStencilBuffer* sb);
769 void unlockStencilBuffer(GrStencilBuffer* sb);
bsalomon@google.com558a75b2011-08-08 17:01:14 +0000770 GrStencilBuffer* findStencilBuffer(int width, int height, int sampleCnt);
bsalomon@google.com27847de2011-02-22 20:59:41 +0000771
robertphillips@google.com2c756812012-05-22 20:28:23 +0000772 GrPathRenderer* getPathRenderer(const SkPath& path,
773 GrPathFill fill,
774 const GrDrawTarget* target,
robertphillips@google.com72176b22012-05-23 13:19:12 +0000775 bool antiAlias,
776 bool allowSW);
robertphillips@google.com2c756812012-05-22 20:28:23 +0000777
robertphillips@google.com5f9f2f52012-08-22 10:57:05 +0000778#ifdef GR_DEBUG
779 void printCacheStats() const;
780#endif
781
bsalomon@google.com27847de2011-02-22 20:59:41 +0000782private:
bsalomon@google.com1d4edd32012-08-16 18:36:06 +0000783 // Used to indicate whether a draw should be performed immediately or queued in fDrawBuffer.
784 enum BufferedDraw {
785 kYes_BufferedDraw,
786 kNo_BufferedDraw,
bsalomon@google.com27847de2011-02-22 20:59:41 +0000787 };
bsalomon@google.com1d4edd32012-08-16 18:36:06 +0000788 BufferedDraw fLastDrawWasBuffered;
bsalomon@google.com27847de2011-02-22 20:59:41 +0000789
bsalomon@google.com50398bf2011-07-26 20:45:30 +0000790 GrGpu* fGpu;
bsalomon@google.com10e04bf2012-03-30 14:35:04 +0000791 GrDrawState* fDrawState;
792
bsalomon@google.com50398bf2011-07-26 20:45:30 +0000793 GrResourceCache* fTextureCache;
794 GrFontCache* fFontCache;
bsalomon@google.comdfe75bc2011-03-25 12:31:16 +0000795
bsalomon@google.com30085192011-08-19 15:42:31 +0000796 GrPathRendererChain* fPathRendererChain;
robertphillips@google.com72176b22012-05-23 13:19:12 +0000797 GrSoftwarePathRenderer* fSoftwarePathRenderer;
bsalomon@google.com27847de2011-02-22 20:59:41 +0000798
799 GrVertexBufferAllocPool* fDrawBufferVBAllocPool;
800 GrIndexBufferAllocPool* fDrawBufferIBAllocPool;
801 GrInOrderDrawBuffer* fDrawBuffer;
802
robertphillips@google.comf69a11b2012-06-15 13:58:07 +0000803 GrAARectRenderer* fAARectRenderer;
bsalomon@google.comdfe75bc2011-03-25 12:31:16 +0000804
bsalomon@google.coma04e8e82012-08-27 12:53:13 +0000805 bool fDidTestPMConversions;
806 int fPMToUPMConversion;
807 int fUPMToPMConversion;
808
robertphillips@google.comf69a11b2012-06-15 13:58:07 +0000809 GrContext(GrGpu* gpu);
bsalomon@google.com205d4602011-04-25 12:43:45 +0000810
bsalomon@google.com8fe72472011-03-30 21:26:44 +0000811 void setupDrawBuffer();
812
bsalomon@google.com27847de2011-02-22 20:59:41 +0000813 void flushDrawBuffer();
814
bsalomon@google.com10e04bf2012-03-30 14:35:04 +0000815 void setPaint(const GrPaint& paint);
bsalomon@google.com27847de2011-02-22 20:59:41 +0000816
bsalomon@google.com07ea2db2012-08-17 14:06:49 +0000817 /// Sets the paint and returns the target to draw into. The paint can be NULL in which case the
818 /// draw state is left unmodified.
819 GrDrawTarget* prepareToDraw(const GrPaint*, BufferedDraw);
bsalomon@google.com27847de2011-02-22 20:59:41 +0000820
bsalomon@google.com8d033a12012-04-27 15:52:53 +0000821 void internalDrawPath(const GrPaint& paint, const SkPath& path,
bsalomon@google.com93c96602012-04-27 13:05:21 +0000822 GrPathFill fill, const GrPoint* translate);
823
robertphillips@google.com3319f332012-08-13 18:00:36 +0000824 GrTexture* createResizedTexture(const GrTextureDesc& desc,
825 const GrCacheData& cacheData,
826 void* srcData,
827 size_t rowBytes,
828 bool needsFiltering);
829
robertphillips@google.com15c0fea2012-06-22 12:41:43 +0000830 // Needed so GrTexture's returnToCache helper function can call
831 // addExistingTextureToCache
832 friend class GrTexture;
833
834 // Add an existing texture to the texture cache. This is intended solely
835 // for use with textures released from an GrAutoScratchTexture.
836 void addExistingTextureToCache(GrTexture* texture);
reed@google.comfa35e3d2012-06-26 20:16:17 +0000837
bsalomon@google.coma04e8e82012-08-27 12:53:13 +0000838 GrCustomStage* createPMToUPMEffect(GrTexture* texture, bool swapRAndB);
839 GrCustomStage* createUPMToPMEffect(GrTexture* texture, bool swapRAndB);
840
reed@google.comfa35e3d2012-06-26 20:16:17 +0000841 typedef GrRefCnt INHERITED;
bsalomon@google.com27847de2011-02-22 20:59:41 +0000842};
843
844/**
bsalomon@google.com50398bf2011-07-26 20:45:30 +0000845 * Gets and locks a scratch texture from a descriptor using
846 * either exact or approximate criteria. Unlocks texture in
847 * the destructor.
senorblanco@chromium.orgaadd9f82011-07-12 19:44:51 +0000848 */
bsalomon@google.com50398bf2011-07-26 20:45:30 +0000849class GrAutoScratchTexture : ::GrNoncopyable {
senorblanco@chromium.orgaadd9f82011-07-12 19:44:51 +0000850public:
bsalomon@google.com50398bf2011-07-26 20:45:30 +0000851 GrAutoScratchTexture()
robertphillips@google.com1f47f4f2012-08-16 14:49:16 +0000852 : fContext(NULL)
853 , fTexture(NULL) {
senorblanco@chromium.orgaadd9f82011-07-12 19:44:51 +0000854 }
bsalomon@google.com50398bf2011-07-26 20:45:30 +0000855
856 GrAutoScratchTexture(GrContext* context,
857 const GrTextureDesc& desc,
858 GrContext::ScratchTexMatch match =
859 GrContext::kApprox_ScratchTexMatch)
robertphillips@google.com1f47f4f2012-08-16 14:49:16 +0000860 : fContext(NULL)
861 , fTexture(NULL) {
bsalomon@google.com50398bf2011-07-26 20:45:30 +0000862 this->set(context, desc, match);
863 }
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000864
bsalomon@google.com50398bf2011-07-26 20:45:30 +0000865 ~GrAutoScratchTexture() {
robertphillips@google.com9ec07532012-06-22 12:01:30 +0000866 this->reset();
867 }
868
869 void reset() {
robertphillips@google.com1f47f4f2012-08-16 14:49:16 +0000870 if (NULL != fContext && NULL != fTexture) {
871 fContext->unlockTexture(fTexture);
872 fTexture = NULL;
senorblanco@chromium.orgaadd9f82011-07-12 19:44:51 +0000873 }
874 }
bsalomon@google.com84223112011-07-14 14:45:44 +0000875
robertphillips@google.com15c0fea2012-06-22 12:41:43 +0000876 /*
877 * When detaching a texture we do not unlock it in the texture cache but
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000878 * we do set the returnToCache flag. In this way the texture remains
879 * "locked" in the texture cache until it is freed and recycled in
880 * GrTexture::internal_dispose. In reality, the texture has been removed
881 * from the cache (because this is in AutoScratchTexture) and by not
882 * calling unlockTexture we simply don't re-add it. It will be reattached
robertphillips@google.com15c0fea2012-06-22 12:41:43 +0000883 * in GrTexture::internal_dispose.
884 *
885 * Note that the caller is assumed to accept and manage the ref to the
886 * returned texture.
887 */
888 GrTexture* detach() {
robertphillips@google.com1f47f4f2012-08-16 14:49:16 +0000889 GrTexture* temp = fTexture;
robertphillips@google.com15c0fea2012-06-22 12:41:43 +0000890
robertphillips@google.com521eaf82012-08-22 11:03:19 +0000891 // Conceptually the texture's cache entry loses its ref to the
892 // texture while the caller of this method gets a ref.
893 GrAssert(NULL != temp->getCacheEntry());
894
robertphillips@google.com1f47f4f2012-08-16 14:49:16 +0000895 fTexture = NULL;
robertphillips@google.com15c0fea2012-06-22 12:41:43 +0000896
897 temp->setFlag((GrTextureFlags) GrTexture::kReturnToCache_FlagBit);
robertphillips@google.com15c0fea2012-06-22 12:41:43 +0000898 return temp;
899 }
900
bsalomon@google.com50398bf2011-07-26 20:45:30 +0000901 GrTexture* set(GrContext* context,
902 const GrTextureDesc& desc,
903 GrContext::ScratchTexMatch match =
904 GrContext::kApprox_ScratchTexMatch) {
robertphillips@google.com9ec07532012-06-22 12:01:30 +0000905 this->reset();
906
bsalomon@google.com50398bf2011-07-26 20:45:30 +0000907 fContext = context;
908 if (NULL != fContext) {
robertphillips@google.com1f47f4f2012-08-16 14:49:16 +0000909 fTexture = fContext->lockScratchTexture(desc, match);
910 if (NULL == fTexture) {
bsalomon@google.com50398bf2011-07-26 20:45:30 +0000911 fContext = NULL;
912 }
robertphillips@google.com1f47f4f2012-08-16 14:49:16 +0000913 return fTexture;
bsalomon@google.com50398bf2011-07-26 20:45:30 +0000914 } else {
915 return NULL;
916 }
917 }
918
robertphillips@google.com1f47f4f2012-08-16 14:49:16 +0000919 GrTexture* texture() { return fTexture; }
920
senorblanco@chromium.orgaadd9f82011-07-12 19:44:51 +0000921private:
bsalomon@google.com50398bf2011-07-26 20:45:30 +0000922 GrContext* fContext;
robertphillips@google.com1f47f4f2012-08-16 14:49:16 +0000923 GrTexture* fTexture;
senorblanco@chromium.orgaadd9f82011-07-12 19:44:51 +0000924};
925
bsalomon@google.com27847de2011-02-22 20:59:41 +0000926#endif