blob: 76cba9aff0ad79dc51d388106d0515f9a75412ff [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
robertphillips@google.com59552022012-08-31 13:07:37 +000013#include "GrConfig.h"
bsalomon@google.com27847de2011-02-22 20:59:41 +000014#include "GrPaint.h"
robertphillips@google.comf6747b02012-06-12 00:32:28 +000015#include "GrAARectRenderer.h"
robertphillips@google.coma2d71482012-08-01 20:08:47 +000016#include "GrClipData.h"
bsalomon@google.comc287a892011-08-19 14:49:36 +000017// not strictly needed but requires WK change in LayerTextureUpdaterCanvas to
18// remove.
rmistry@google.comfbfcd562012-08-23 18:09:54 +000019#include "GrRenderTarget.h"
robertphillips@google.coma2d71482012-08-01 20:08:47 +000020#include "SkClipStack.h"
bsalomon@google.com27847de2011-02-22 20:59:41 +000021
senorblanco@chromium.org3b4dd902012-03-05 20:41:22 +000022class GrAutoScratchTexture;
robertphillips@google.coma9b06232012-08-30 11:06:31 +000023class GrCacheKey;
bsalomon@google.com10e04bf2012-03-30 14:35:04 +000024class GrDrawState;
bsalomon@google.com583a1e32011-08-17 13:42:46 +000025class GrDrawTarget;
bsalomon@google.com27847de2011-02-22 20:59:41 +000026class GrFontCache;
bsalomon@google.com05ef5102011-05-02 21:14:59 +000027class GrGpu;
bsalomon@google.com583a1e32011-08-17 13:42:46 +000028class GrIndexBuffer;
bsalomon@google.com27847de2011-02-22 20:59:41 +000029class GrIndexBufferAllocPool;
30class GrInOrderDrawBuffer;
bsalomon@google.com583a1e32011-08-17 13:42:46 +000031class GrPathRenderer;
bsalomon@google.com30085192011-08-19 15:42:31 +000032class GrPathRendererChain;
bsalomon@google.com50398bf2011-07-26 20:45:30 +000033class GrResourceEntry;
34class GrResourceCache;
bsalomon@google.com558a75b2011-08-08 17:01:14 +000035class GrStencilBuffer;
bsalomon@google.com583a1e32011-08-17 13:42:46 +000036class GrVertexBuffer;
bsalomon@google.com50398bf2011-07-26 20:45:30 +000037class GrVertexBufferAllocPool;
robertphillips@google.com72176b22012-05-23 13:19:12 +000038class GrSoftwarePathRenderer;
bsalomon@google.com50398bf2011-07-26 20:45:30 +000039
bsalomon@google.com91826102011-03-21 19:51:57 +000040class GR_API GrContext : public GrRefCnt {
bsalomon@google.com27847de2011-02-22 20:59:41 +000041public:
reed@google.comfa35e3d2012-06-26 20:16:17 +000042 SK_DECLARE_INST_COUNT(GrContext)
43
bsalomon@google.com27847de2011-02-22 20:59:41 +000044 /**
45 * Creates a GrContext from within a 3D context.
46 */
bsalomon@google.com05ef5102011-05-02 21:14:59 +000047 static GrContext* Create(GrEngine engine,
48 GrPlatform3DContext context3D);
bsalomon@google.com27847de2011-02-22 20:59:41 +000049
bsalomon@google.comc0af3172012-06-15 14:10:09 +000050 /**
51 * Returns the number of GrContext instances for the current thread.
52 */
53 static int GetThreadInstanceCount();
54
bsalomon@google.com27847de2011-02-22 20:59:41 +000055 virtual ~GrContext();
56
57 /**
58 * The GrContext normally assumes that no outsider is setting state
59 * within the underlying 3D API's context/device/whatever. This call informs
60 * the context that the state was modified and it should resend. Shouldn't
61 * be called frequently for good performance.
62 */
63 void resetContext();
64
bsalomon@google.com8fe72472011-03-30 21:26:44 +000065 /**
66 * Abandons all gpu resources, assumes 3D API state is unknown. Call this
67 * if you have lost the associated GPU context, and thus internal texture,
68 * buffer, etc. references/IDs are now invalid. Should be called even when
69 * GrContext is no longer going to be used for two reasons:
70 * 1) ~GrContext will not try to free the objects in the 3D API.
71 * 2) If you've created GrResources that outlive the GrContext they will
72 * be marked as invalid (GrResource::isValid()) and won't attempt to
73 * free their underlying resource in the 3D API.
74 * Content drawn since the last GrContext::flush() may be lost.
75 */
76 void contextLost();
bsalomon@google.com27847de2011-02-22 20:59:41 +000077
78 /**
junov@google.com53a55842011-06-08 22:55:10 +000079 * Similar to contextLost, but makes no attempt to reset state.
80 * Use this method when GrContext destruction is pending, but
81 * the graphics context is destroyed first.
82 */
83 void contextDestroyed();
84
85 /**
bsalomon@google.com8fe72472011-03-30 21:26:44 +000086 * Frees gpu created by the context. Can be called to reduce GPU memory
87 * pressure.
bsalomon@google.com27847de2011-02-22 20:59:41 +000088 */
bsalomon@google.com8fe72472011-03-30 21:26:44 +000089 void freeGpuResources();
90
bsalomon@google.com07fc0d12012-06-22 15:15:59 +000091 /**
92 * Returns the number of bytes of GPU memory hosted by the texture cache.
93 */
94 size_t getGpuTextureCacheBytes() const;
95
bsalomon@google.com8fe72472011-03-30 21:26:44 +000096 ///////////////////////////////////////////////////////////////////////////
97 // Textures
bsalomon@google.com27847de2011-02-22 20:59:41 +000098
99 /**
bsalomon@google.com1fadb202011-12-12 16:10:08 +0000100 * Create a new entry, based on the specified key and texture, and return
robertphillips@google.com1f47f4f2012-08-16 14:49:16 +0000101 * a "locked" texture. Must call be balanced with an unlockTexture() call.
bsalomon@google.com1fadb202011-12-12 16:10:08 +0000102 *
bsalomon@google.comb8670992012-07-25 21:27:09 +0000103 * @param params The tex params used to draw a texture may help determine
104 * the cache entry used. (e.g. different versions may exist
105 * for different wrap modes on GPUs with limited NPOT
106 * texture support). NULL implies clamp wrap modes.
bsalomon@google.com1fadb202011-12-12 16:10:08 +0000107 * @param desc Description of the texture properties.
robertphillips@google.com9c2ea842012-08-13 17:47:59 +0000108 * @param cacheData Cache-specific properties (e.g., texture gen ID)
bsalomon@google.com1fadb202011-12-12 16:10:08 +0000109 * @param srcData Pointer to the pixel values.
110 * @param rowBytes The number of bytes between rows of the texture. Zero
111 * implies tightly packed rows.
112 */
robertphillips@google.com1f47f4f2012-08-16 14:49:16 +0000113 GrTexture* createAndLockTexture(const GrTextureParams* params,
114 const GrTextureDesc& desc,
115 const GrCacheData& cacheData,
116 void* srcData, size_t rowBytes);
bsalomon@google.com1fadb202011-12-12 16:10:08 +0000117
118 /**
robertphillips@google.coma9b06232012-08-30 11:06:31 +0000119 * Look for a texture that matches 'key' in the cache. If not found,
120 * return NULL.
121 */
122 GrTexture* findTexture(const GrCacheKey& key);
123
124 /**
bsalomon@google.com50398bf2011-07-26 20:45:30 +0000125 * Search for an entry based on key and dimensions. If found, "lock" it and
robertphillips@google.com1f47f4f2012-08-16 14:49:16 +0000126 * return it. The return value will be NULL if not found.
bsalomon@google.com1fadb202011-12-12 16:10:08 +0000127 * Must be balanced with an unlockTexture() call.
128 *
bsalomon@google.comb8670992012-07-25 21:27:09 +0000129 * @param desc Description of the texture properties.
robertphillips@google.com9c2ea842012-08-13 17:47:59 +0000130 * @param cacheData Cache-specific properties (e.g., texture gen ID)
bsalomon@google.comb8670992012-07-25 21:27:09 +0000131 * @param params The tex params used to draw a texture may help determine
132 * the cache entry used. (e.g. different versions may exist
133 * for different wrap modes on GPUs with limited NPOT
134 * texture support). NULL implies clamp wrap modes.
bsalomon@google.com50398bf2011-07-26 20:45:30 +0000135 */
robertphillips@google.com1f47f4f2012-08-16 14:49:16 +0000136 GrTexture* findAndLockTexture(const GrTextureDesc& desc,
137 const GrCacheData& cacheData,
138 const GrTextureParams* params);
bsalomon@google.comfb309512011-11-30 14:13:48 +0000139 /**
140 * Determines whether a texture is in the cache. If the texture is found it
141 * will not be locked or returned. This call does not affect the priority of
142 * the texture for deletion.
143 */
robertphillips@google.com75b3c962012-06-07 12:08:45 +0000144 bool isTextureInCache(const GrTextureDesc& desc,
robertphillips@google.com9c2ea842012-08-13 17:47:59 +0000145 const GrCacheData& cacheData,
bsalomon@google.comb8670992012-07-25 21:27:09 +0000146 const GrTextureParams* params) const;
bsalomon@google.com50398bf2011-07-26 20:45:30 +0000147
148 /**
149 * Enum that determines how closely a returned scratch texture must match
150 * a provided GrTextureDesc.
151 */
152 enum ScratchTexMatch {
153 /**
154 * Finds a texture that exactly matches the descriptor.
155 */
156 kExact_ScratchTexMatch,
157 /**
158 * Finds a texture that approximately matches the descriptor. Will be
159 * at least as large in width and height as desc specifies. If desc
160 * specifies that texture is a render target then result will be a
161 * render target. If desc specifies a render target and doesn't set the
162 * no stencil flag then result will have a stencil. Format and aa level
163 * will always match.
164 */
165 kApprox_ScratchTexMatch
166 };
bsalomon@google.com27847de2011-02-22 20:59:41 +0000167
168 /**
bsalomon@google.comfea37b52011-04-25 15:51:06 +0000169 * Returns a texture matching the desc. It's contents are unknown. Subsequent
170 * requests with the same descriptor are not guaranteed to return the same
171 * texture. The same texture is guaranteed not be returned again until it is
robertphillips@google.com15c0fea2012-06-22 12:41:43 +0000172 * unlocked. Call must be balanced with an unlockTexture() call.
bsalomon@google.coma39f4042011-04-26 13:18:16 +0000173 *
174 * Textures created by createAndLockTexture() hide the complications of
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000175 * tiling non-power-of-two textures on APIs that don't support this (e.g.
bsalomon@google.com50398bf2011-07-26 20:45:30 +0000176 * unextended GLES2). Tiling a npot texture created by lockScratchTexture on
bsalomon@google.coma39f4042011-04-26 13:18:16 +0000177 * such an API will create gaps in the tiling pattern. This includes clamp
178 * mode. (This may be addressed in a future update.)
bsalomon@google.comfea37b52011-04-25 15:51:06 +0000179 */
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000180 GrTexture* lockScratchTexture(const GrTextureDesc& desc,
robertphillips@google.com1f47f4f2012-08-16 14:49:16 +0000181 ScratchTexMatch match);
bsalomon@google.comb5b31682011-06-16 18:05:35 +0000182
183 /**
robertphillips@google.coma9b06232012-08-30 11:06:31 +0000184 * Make a texture un-purgeable in the cache
185 */
186 void lockTexture(GrTexture* texture);
187
188 /**
bsalomon@google.com27847de2011-02-22 20:59:41 +0000189 * When done with an entry, call unlockTexture(entry) on it, which returns
190 * it to the cache, where it may be purged.
191 */
robertphillips@google.com1f47f4f2012-08-16 14:49:16 +0000192 void unlockTexture(GrTexture* texture);
bsalomon@google.com27847de2011-02-22 20:59:41 +0000193
194 /**
robertphillips@google.com50a035d2012-09-07 19:44:33 +0000195 * This method should be called whenever a GrTexture is unreffed or
196 * switched from exclusive to non-exclusive. This
197 * gives the resource cache a chance to discard unneeded textures.
198 */
199 void purgeCache();
200
201 /**
bsalomon@google.com27847de2011-02-22 20:59:41 +0000202 * Creates a texture that is outside the cache. Does not count against
203 * cache's budget.
204 */
robertphillips@google.com75b3c962012-06-07 12:08:45 +0000205 GrTexture* createUncachedTexture(const GrTextureDesc& desc,
bsalomon@google.com27847de2011-02-22 20:59:41 +0000206 void* srcData,
207 size_t rowBytes);
208
209 /**
bsalomon@google.comb8670992012-07-25 21:27:09 +0000210 * Returns true if the specified use of an indexed texture is supported.
211 * Support may depend upon whether the texture params indicate that the
212 * texture will be tiled. Passing NULL for the texture params indicates
213 * clamp mode.
bsalomon@google.com27847de2011-02-22 20:59:41 +0000214 */
bsalomon@google.comb8670992012-07-25 21:27:09 +0000215 bool supportsIndex8PixelConfig(const GrTextureParams*,
bsalomon@google.com1f221a72011-08-23 20:54:07 +0000216 int width,
217 int height) const;
bsalomon@google.com27847de2011-02-22 20:59:41 +0000218
219 /**
bsalomon@google.com07fc0d12012-06-22 15:15:59 +0000220 * Return the current texture cache limits.
221 *
222 * @param maxTextures If non-null, returns maximum number of textures that
223 * can be held in the cache.
224 * @param maxTextureBytes If non-null, returns maximum number of bytes of
225 * texture memory that can be held in the cache.
bsalomon@google.com27847de2011-02-22 20:59:41 +0000226 */
bsalomon@google.com07fc0d12012-06-22 15:15:59 +0000227 void getTextureCacheLimits(int* maxTextures, size_t* maxTextureBytes) const;
bsalomon@google.com27847de2011-02-22 20:59:41 +0000228
229 /**
bsalomon@google.com07fc0d12012-06-22 15:15:59 +0000230 * Specify the texture cache limits. If the current cache exceeds either
231 * of these, it will be purged (LRU) to keep the cache within these limits.
bsalomon@google.com27847de2011-02-22 20:59:41 +0000232 *
bsalomon@google.com07fc0d12012-06-22 15:15:59 +0000233 * @param maxTextures The maximum number of textures that can be held in
234 * the cache.
bsalomon@google.com27847de2011-02-22 20:59:41 +0000235 * @param maxTextureBytes The maximum number of bytes of texture memory
236 * that can be held in the cache.
237 */
bsalomon@google.com07fc0d12012-06-22 15:15:59 +0000238 void setTextureCacheLimits(int maxTextures, size_t maxTextureBytes);
bsalomon@google.com27847de2011-02-22 20:59:41 +0000239
240 /**
241 * Return the max width or height of a texture supported by the current gpu
242 */
bsalomon@google.com91958362011-06-13 17:58:13 +0000243 int getMaxTextureSize() const;
244
245 /**
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000246 * Return the max width or height of a render target supported by the
bsalomon@google.com91958362011-06-13 17:58:13 +0000247 * current gpu
248 */
249 int getMaxRenderTargetSize() const;
bsalomon@google.com27847de2011-02-22 20:59:41 +0000250
251 ///////////////////////////////////////////////////////////////////////////
252 // Render targets
253
254 /**
bsalomon@google.com5877ffd2011-04-11 17:58:48 +0000255 * Sets the render target.
256 * @param target the render target to set. (should not be NULL.)
257 */
258 void setRenderTarget(GrRenderTarget* target);
259
260 /**
261 * Gets the current render target.
262 * @return the currently bound render target. Should never be NULL.
263 */
264 const GrRenderTarget* getRenderTarget() const;
265 GrRenderTarget* getRenderTarget();
266
robertphillips@google.comf69a11b2012-06-15 13:58:07 +0000267 GrAARectRenderer* getAARectRenderer() { return fAARectRenderer; }
268
robertphillips@google.com99a5ac02012-04-10 19:26:38 +0000269 /**
270 * Can the provided configuration act as a color render target?
271 */
272 bool isConfigRenderable(GrPixelConfig config) const;
273
bsalomon@google.com5877ffd2011-04-11 17:58:48 +0000274 ///////////////////////////////////////////////////////////////////////////
275 // Platform Surfaces
276
bsalomon@google.com5877ffd2011-04-11 17:58:48 +0000277 /**
bsalomon@google.come269f212011-11-07 13:29:52 +0000278 * Wraps an existing texture with a GrTexture object.
279 *
280 * OpenGL: if the object is a texture Gr may change its GL texture params
281 * when it is drawn.
282 *
283 * @param desc description of the object to create.
284 *
285 * @return GrTexture object or NULL on failure.
286 */
287 GrTexture* createPlatformTexture(const GrPlatformTextureDesc& desc);
288
289 /**
290 * Wraps an existing render target with a GrRenderTarget object. It is
291 * similar to createPlatformTexture but can be used to draw into surfaces
292 * that are not also textures (e.g. FBO 0 in OpenGL, or an MSAA buffer that
293 * the client will resolve to a texture).
294 *
295 * @param desc description of the object to create.
296 *
297 * @return GrTexture object or NULL on failure.
298 */
299 GrRenderTarget* createPlatformRenderTarget(
300 const GrPlatformRenderTargetDesc& desc);
301
bsalomon@google.com27847de2011-02-22 20:59:41 +0000302 ///////////////////////////////////////////////////////////////////////////
303 // Matrix state
304
305 /**
306 * Gets the current transformation matrix.
307 * @return the current matrix.
308 */
309 const GrMatrix& getMatrix() const;
310
311 /**
312 * Sets the transformation matrix.
313 * @param m the matrix to set.
314 */
315 void setMatrix(const GrMatrix& m);
316
317 /**
318 * Concats the current matrix. The passed matrix is applied before the
319 * current matrix.
320 * @param m the matrix to concat.
321 */
322 void concatMatrix(const GrMatrix& m) const;
323
324
325 ///////////////////////////////////////////////////////////////////////////
326 // Clip state
327 /**
328 * Gets the current clip.
329 * @return the current clip.
330 */
robertphillips@google.combeb1af72012-07-26 18:52:16 +0000331 const GrClipData* getClip() const;
bsalomon@google.com27847de2011-02-22 20:59:41 +0000332
333 /**
334 * Sets the clip.
robertphillips@google.combeb1af72012-07-26 18:52:16 +0000335 * @param clipData the clip to set.
bsalomon@google.com27847de2011-02-22 20:59:41 +0000336 */
robertphillips@google.combeb1af72012-07-26 18:52:16 +0000337 void setClip(const GrClipData* clipData);
bsalomon@google.com27847de2011-02-22 20:59:41 +0000338
bsalomon@google.com27847de2011-02-22 20:59:41 +0000339 ///////////////////////////////////////////////////////////////////////////
340 // Draws
341
342 /**
bsalomon@google.com6aa25c32011-04-27 19:55:29 +0000343 * Clear the entire or rect of the render target, ignoring any clips.
344 * @param rect the rect to clear or the whole thing if rect is NULL.
345 * @param color the color to clear to.
robertphillips@google.comc82a8b72012-06-21 20:15:48 +0000346 * @param target if non-NULL, the render target to clear otherwise clear
347 * the current render target
bsalomon@google.com27847de2011-02-22 20:59:41 +0000348 */
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000349 void clear(const GrIRect* rect, GrColor color,
robertphillips@google.comc82a8b72012-06-21 20:15:48 +0000350 GrRenderTarget* target = NULL);
bsalomon@google.com27847de2011-02-22 20:59:41 +0000351
352 /**
353 * Draw everywhere (respecting the clip) with the paint.
354 */
355 void drawPaint(const GrPaint& paint);
356
357 /**
358 * Draw the rect using a paint.
359 * @param paint describes how to color pixels.
360 * @param strokeWidth If strokeWidth < 0, then the rect is filled, else
361 * the rect is mitered stroked based on strokeWidth. If
362 * strokeWidth == 0, then the stroke is always a single
363 * pixel thick.
364 * @param matrix Optional matrix applied to the rect. Applied before
365 * context's matrix or the paint's matrix.
366 * The rects coords are used to access the paint (through texture matrix)
367 */
368 void drawRect(const GrPaint& paint,
369 const GrRect&,
370 GrScalar strokeWidth = -1,
371 const GrMatrix* matrix = NULL);
372
373 /**
374 * Maps a rect of paint coordinates onto the a rect of destination
375 * coordinates. Each rect can optionally be transformed. The srcRect
376 * is stretched over the dstRect. The dstRect is transformed by the
377 * context's matrix and the srcRect is transformed by the paint's matrix.
378 * Additional optional matrices can be provided by parameters.
379 *
380 * @param paint describes how to color pixels.
381 * @param dstRect the destination rect to draw.
382 * @param srcRect rect of paint coordinates to be mapped onto dstRect
383 * @param dstMatrix Optional matrix to transform dstRect. Applied before
384 * context's matrix.
385 * @param srcMatrix Optional matrix to transform srcRect Applied before
386 * paint's matrix.
387 */
388 void drawRectToRect(const GrPaint& paint,
389 const GrRect& dstRect,
390 const GrRect& srcRect,
391 const GrMatrix* dstMatrix = NULL,
392 const GrMatrix* srcMatrix = NULL);
393
394 /**
bsalomon@google.comd302f142011-03-03 13:54:13 +0000395 * Draws a path.
bsalomon@google.com27847de2011-02-22 20:59:41 +0000396 *
397 * @param paint describes how to color pixels.
reed@google.com07f3ee12011-05-16 17:21:57 +0000398 * @param path the path to draw
bsalomon@google.com27847de2011-02-22 20:59:41 +0000399 * @param fill the path filling rule to use.
400 * @param translate optional additional translation applied to the
401 * path.
402 */
bsalomon@google.com8d033a12012-04-27 15:52:53 +0000403 void drawPath(const GrPaint& paint, const SkPath& path, GrPathFill fill,
bsalomon@google.comd302f142011-03-03 13:54:13 +0000404 const GrPoint* translate = NULL);
reed@google.com07f3ee12011-05-16 17:21:57 +0000405
bsalomon@google.com27847de2011-02-22 20:59:41 +0000406 /**
407 * Draws vertices with a paint.
408 *
409 * @param paint describes how to color pixels.
410 * @param primitiveType primitives type to draw.
411 * @param vertexCount number of vertices.
412 * @param positions array of vertex positions, required.
413 * @param texCoords optional array of texture coordinates used
414 * to access the paint.
415 * @param colors optional array of per-vertex colors, supercedes
416 * the paint's color field.
417 * @param indices optional array of indices. If NULL vertices
418 * are drawn non-indexed.
419 * @param indexCount if indices is non-null then this is the
420 * number of indices.
421 */
422 void drawVertices(const GrPaint& paint,
423 GrPrimitiveType primitiveType,
424 int vertexCount,
425 const GrPoint positions[],
426 const GrPoint texs[],
427 const GrColor colors[],
428 const uint16_t indices[],
429 int indexCount);
430
bsalomon@google.com93c96602012-04-27 13:05:21 +0000431 /**
432 * Draws an oval.
433 *
434 * @param paint describes how to color pixels.
435 * @param rect the bounding rect of the oval.
436 * @param strokeWidth if strokeWidth < 0, then the oval is filled, else
437 * the rect is stroked based on strokeWidth. If
438 * strokeWidth == 0, then the stroke is always a single
439 * pixel thick.
440 */
441 void drawOval(const GrPaint& paint,
442 const GrRect& rect,
443 SkScalar strokeWidth);
444
bsalomon@google.com27847de2011-02-22 20:59:41 +0000445 ///////////////////////////////////////////////////////////////////////////
446 // Misc.
447
448 /**
bsalomon@google.coma7f84e12011-03-10 14:13:19 +0000449 * Flags that affect flush() behavior.
450 */
451 enum FlushBits {
452 /**
453 * A client may want Gr to bind a GrRenderTarget in the 3D API so that
454 * it can be rendered to directly. However, Gr lazily sets state. Simply
455 * calling setRenderTarget() followed by flush() without flags may not
456 * bind the render target. This flag forces the context to bind the last
457 * set render target in the 3D API.
458 */
459 kForceCurrentRenderTarget_FlushBit = 0x1,
460 /**
461 * A client may reach a point where it has partially rendered a frame
462 * through a GrContext that it knows the user will never see. This flag
463 * causes the flush to skip submission of deferred content to the 3D API
464 * during the flush.
465 */
466 kDiscard_FlushBit = 0x2,
467 };
468
469 /**
bsalomon@google.com27847de2011-02-22 20:59:41 +0000470 * Call to ensure all drawing to the context has been issued to the
471 * underlying 3D API.
bsalomon@google.coma7f84e12011-03-10 14:13:19 +0000472 * @param flagsBitfield flags that control the flushing behavior. See
473 * FlushBits.
bsalomon@google.com27847de2011-02-22 20:59:41 +0000474 */
bsalomon@google.com8fe72472011-03-30 21:26:44 +0000475 void flush(int flagsBitfield = 0);
bsalomon@google.com6f379512011-11-16 20:36:03 +0000476
bsalomon@google.com0342a852012-08-20 19:22:38 +0000477 /**
478 * These flags can be used with the read/write pixels functions below.
479 */
480 enum PixelOpsFlags {
481 /** The GrContext will not be flushed. This means that the read or write may occur before
482 previous draws have executed. */
483 kDontFlush_PixelOpsFlag = 0x1,
484 /** The src for write or dst read is unpremultiplied. This is only respected if both the
485 config src and dst configs are an RGBA/BGRA 8888 format. */
486 kUnpremul_PixelOpsFlag = 0x2,
487 };
488
bsalomon@google.com27847de2011-02-22 20:59:41 +0000489 /**
bsalomon@google.com669fdc42011-04-05 17:08:27 +0000490 * Reads a rectangle of pixels from a render target.
bsalomon@google.com0342a852012-08-20 19:22:38 +0000491 * @param target the render target to read from. NULL means the current render target.
bsalomon@google.com669fdc42011-04-05 17:08:27 +0000492 * @param left left edge of the rectangle to read (inclusive)
493 * @param top top edge of the rectangle to read (inclusive)
494 * @param width width of rectangle to read in pixels.
495 * @param height height of rectangle to read in pixels.
496 * @param config the pixel config of the destination buffer
497 * @param buffer memory to read the rectangle into.
bsalomon@google.com0342a852012-08-20 19:22:38 +0000498 * @param rowBytes number of bytes bewtween consecutive rows. Zero means rows are tightly
499 * packed.
500 * @param pixelOpsFlags see PixelOpsFlags enum above.
bsalomon@google.com669fdc42011-04-05 17:08:27 +0000501 *
bsalomon@google.com0342a852012-08-20 19:22:38 +0000502 * @return true if the read succeeded, false if not. The read can fail because of an unsupported
503 * pixel config or because no render target is currently set and NULL was passed for
504 * target.
bsalomon@google.com27847de2011-02-22 20:59:41 +0000505 */
bsalomon@google.com669fdc42011-04-05 17:08:27 +0000506 bool readRenderTargetPixels(GrRenderTarget* target,
507 int left, int top, int width, int height,
bsalomon@google.com0342a852012-08-20 19:22:38 +0000508 GrPixelConfig config, void* buffer,
509 size_t rowBytes = 0,
510 uint32_t pixelOpsFlags = 0);
bsalomon@google.com6f379512011-11-16 20:36:03 +0000511
512 /**
bsalomon@google.com0342a852012-08-20 19:22:38 +0000513 * Copy the src pixels [buffer, rowbytes, pixelconfig] into a render target at the specified
514 * rectangle.
515 * @param target the render target to write into. NULL means the current render target.
bsalomon@google.com6f379512011-11-16 20:36:03 +0000516 * @param left left edge of the rectangle to write (inclusive)
517 * @param top top edge of the rectangle to write (inclusive)
518 * @param width width of rectangle to write in pixels.
519 * @param height height of rectangle to write in pixels.
520 * @param config the pixel config of the source buffer
521 * @param buffer memory to read the rectangle from.
bsalomon@google.com0342a852012-08-20 19:22:38 +0000522 * @param rowBytes number of bytes bewtween consecutive rows. Zero means rows are tightly
523 * packed.
524 * @param pixelOpsFlags see PixelOpsFlags enum above.
bsalomon@google.com6f379512011-11-16 20:36:03 +0000525 */
526 void writeRenderTargetPixels(GrRenderTarget* target,
527 int left, int top, int width, int height,
528 GrPixelConfig config, const void* buffer,
bsalomon@google.com0342a852012-08-20 19:22:38 +0000529 size_t rowBytes = 0,
530 uint32_t pixelOpsFlags = 0);
bsalomon@google.com669fdc42011-04-05 17:08:27 +0000531
532 /**
533 * Reads a rectangle of pixels from a texture.
bsalomon@google.com6f379512011-11-16 20:36:03 +0000534 * @param texture the texture to read from.
bsalomon@google.com669fdc42011-04-05 17:08:27 +0000535 * @param left left edge of the rectangle to read (inclusive)
536 * @param top top edge of the rectangle to read (inclusive)
537 * @param width width of rectangle to read in pixels.
538 * @param height height of rectangle to read in pixels.
539 * @param config the pixel config of the destination buffer
540 * @param buffer memory to read the rectangle into.
bsalomon@google.com0342a852012-08-20 19:22:38 +0000541 * @param rowBytes number of bytes bewtween consecutive rows. Zero means rows are tightly
542 * packed.
543 * @param pixelOpsFlags see PixelOpsFlags enum above.
bsalomon@google.com669fdc42011-04-05 17:08:27 +0000544 *
bsalomon@google.com0342a852012-08-20 19:22:38 +0000545 * @return true if the read succeeded, false if not. The read can fail because of an unsupported
546 * pixel config.
bsalomon@google.com669fdc42011-04-05 17:08:27 +0000547 */
bsalomon@google.com6f379512011-11-16 20:36:03 +0000548 bool readTexturePixels(GrTexture* texture,
bsalomon@google.com669fdc42011-04-05 17:08:27 +0000549 int left, int top, int width, int height,
bsalomon@google.com6f379512011-11-16 20:36:03 +0000550 GrPixelConfig config, void* buffer,
bsalomon@google.com0342a852012-08-20 19:22:38 +0000551 size_t rowBytes = 0,
552 uint32_t pixelOpsFlags = 0);
bsalomon@google.com27847de2011-02-22 20:59:41 +0000553
554 /**
bsalomon@google.com6f379512011-11-16 20:36:03 +0000555 * Writes a rectangle of pixels to a texture.
556 * @param texture the render target to read from.
557 * @param left left edge of the rectangle to write (inclusive)
558 * @param top top edge of the rectangle to write (inclusive)
559 * @param width width of rectangle to write in pixels.
560 * @param height height of rectangle to write in pixels.
561 * @param config the pixel config of the source buffer
562 * @param buffer memory to read pixels from
563 * @param rowBytes number of bytes bewtween consecutive rows. Zero
564 * means rows are tightly packed.
bsalomon@google.com0342a852012-08-20 19:22:38 +0000565 * @param pixelOpsFlags see PixelOpsFlags enum above.
bsalomon@google.com27847de2011-02-22 20:59:41 +0000566 */
bsalomon@google.com6f379512011-11-16 20:36:03 +0000567 void writeTexturePixels(GrTexture* texture,
568 int left, int top, int width, int height,
569 GrPixelConfig config, const void* buffer,
bsalomon@google.com0342a852012-08-20 19:22:38 +0000570 size_t rowBytes,
571 uint32_t pixelOpsFlags = 0);
572
573
senorblanco@chromium.org027de5f2011-07-08 18:03:33 +0000574 /**
senorblanco@chromium.orgef843cd2011-12-02 19:11:17 +0000575 * Copies all texels from one texture to another.
576 * @param src the texture to copy from.
577 * @param dst the render target to copy to.
578 */
579 void copyTexture(GrTexture* src, GrRenderTarget* dst);
bsalomon@google.com75f9f252012-01-31 13:35:56 +0000580
581 /**
582 * Resolves a render target that has MSAA. The intermediate MSAA buffer is
583 * downsampled to the associated GrTexture (accessible via
584 * GrRenderTarget::asTexture()). Any pending draws to the render target will
585 * be executed before the resolve.
586 *
587 * This is only necessary when a client wants to access the object directly
588 * using the underlying graphics API. GrContext will detect when it must
589 * perform a resolve to a GrTexture used as the source of a draw or before
590 * reading pixels back from a GrTexture or GrRenderTarget.
591 */
592 void resolveRenderTarget(GrRenderTarget* target);
593
senorblanco@chromium.orgef843cd2011-12-02 19:11:17 +0000594 /**
senorblanco@chromium.org3b4dd902012-03-05 20:41:22 +0000595 * Applies a 2D Gaussian blur to a given texture.
596 * @param srcTexture The source texture to be blurred.
senorblanco@chromium.org1e95d712012-07-18 19:52:53 +0000597 * @param canClobberSrc If true, srcTexture may be overwritten, and
598 * may be returned as the result.
senorblanco@chromium.org3b4dd902012-03-05 20:41:22 +0000599 * @param rect The destination rectangle.
600 * @param sigmaX The blur's standard deviation in X.
601 * @param sigmaY The blur's standard deviation in Y.
senorblanco@chromium.org1e95d712012-07-18 19:52:53 +0000602 * @return the blurred texture, which may be srcTexture ref'ed, or a
603 * new texture. It is the caller's responsibility to unref this texture.
senorblanco@chromium.org027de5f2011-07-08 18:03:33 +0000604 */
senorblanco@chromium.org3b4dd902012-03-05 20:41:22 +0000605 GrTexture* gaussianBlur(GrTexture* srcTexture,
senorblanco@chromium.org1e95d712012-07-18 19:52:53 +0000606 bool canClobberSrc,
senorblanco@chromium.org3b4dd902012-03-05 20:41:22 +0000607 const SkRect& rect,
608 float sigmaX, float sigmaY);
609
senorblanco@chromium.orgaadd9f82011-07-12 19:44:51 +0000610 /**
bsalomon@google.com82aa7482012-08-13 14:22:17 +0000611 * Zooms a subset of the texture to a larger size with a nice edge.
612 * The inner rectangle is a simple scaling of the texture by a factor of
613 * |zoom|. The outer |inset| pixels transition from the background texture
614 * to the zoomed coordinate system at a rate of
615 * (distance_to_edge / inset) ^2, producing a rounded lens effect.
616 * @param srcTexture The source texture to be zoomed.
617 * @param dstRect The destination rectangle.
618 * @param srcRect The source rectangle. Must be smaller than
619 * dstRect
620 * @param inset Number of pixels to blend along the edges.
621 * @return the zoomed texture, which is dstTexture.
622 */
623 GrTexture* zoom(GrTexture* srcTexture,
624 const SkRect& dstRect, const SkRect& srcRect, float inset);
625
bsalomon@google.com27847de2011-02-22 20:59:41 +0000626 ///////////////////////////////////////////////////////////////////////////
627 // Helpers
628
629 class AutoRenderTarget : ::GrNoncopyable {
630 public:
631 AutoRenderTarget(GrContext* context, GrRenderTarget* target) {
bsalomon@google.com27847de2011-02-22 20:59:41 +0000632 fPrevTarget = context->getRenderTarget();
bsalomon@google.coma04e8e82012-08-27 12:53:13 +0000633 context->setRenderTarget(target);
634 fContext = context;
635 }
636 AutoRenderTarget(GrContext* context) {
637 fPrevTarget = context->getRenderTarget();
638 fContext = context;
bsalomon@google.com27847de2011-02-22 20:59:41 +0000639 }
640 ~AutoRenderTarget() {
641 if (fContext) {
642 fContext->setRenderTarget(fPrevTarget);
643 }
644 }
645 private:
646 GrContext* fContext;
647 GrRenderTarget* fPrevTarget;
648 };
649
robertphillips@google.comfea85ac2012-07-11 18:53:23 +0000650 /**
651 * Save/restore the view-matrix in the context.
652 */
653 class AutoMatrix : GrNoncopyable {
654 public:
bsalomon@google.coma04e8e82012-08-27 12:53:13 +0000655 enum InitialMatrix {
656 kPreserve_InitialMatrix,
657 kIdentity_InitialMatrix,
658 };
659
robertphillips@google.comfea85ac2012-07-11 18:53:23 +0000660 AutoMatrix() : fContext(NULL) {}
bsalomon@google.coma04e8e82012-08-27 12:53:13 +0000661
662 AutoMatrix(GrContext* ctx, InitialMatrix initialState) : fContext(ctx) {
robertphillips@google.comfea85ac2012-07-11 18:53:23 +0000663 fMatrix = ctx->getMatrix();
bsalomon@google.coma04e8e82012-08-27 12:53:13 +0000664 switch (initialState) {
665 case kPreserve_InitialMatrix:
666 break;
667 case kIdentity_InitialMatrix:
668 ctx->setMatrix(GrMatrix::I());
669 break;
670 default:
671 GrCrash("Unexpected initial matrix state");
672 }
robertphillips@google.comfea85ac2012-07-11 18:53:23 +0000673 }
bsalomon@google.coma04e8e82012-08-27 12:53:13 +0000674
robertphillips@google.comfea85ac2012-07-11 18:53:23 +0000675 AutoMatrix(GrContext* ctx, const GrMatrix& matrix) : fContext(ctx) {
676 fMatrix = ctx->getMatrix();
677 ctx->setMatrix(matrix);
678 }
bsalomon@google.coma04e8e82012-08-27 12:53:13 +0000679
robertphillips@google.comfea85ac2012-07-11 18:53:23 +0000680 void set(GrContext* ctx) {
681 if (NULL != fContext) {
682 fContext->setMatrix(fMatrix);
683 }
684 fMatrix = ctx->getMatrix();
685 fContext = ctx;
686 }
bsalomon@google.coma04e8e82012-08-27 12:53:13 +0000687
robertphillips@google.comfea85ac2012-07-11 18:53:23 +0000688 void set(GrContext* ctx, const GrMatrix& matrix) {
689 if (NULL != fContext) {
690 fContext->setMatrix(fMatrix);
691 }
692 fMatrix = ctx->getMatrix();
693 ctx->setMatrix(matrix);
694 fContext = ctx;
695 }
bsalomon@google.coma04e8e82012-08-27 12:53:13 +0000696
robertphillips@google.comfea85ac2012-07-11 18:53:23 +0000697 ~AutoMatrix() {
698 if (NULL != fContext) {
699 fContext->setMatrix(fMatrix);
700 }
701 }
702
703 private:
704 GrContext* fContext;
705 GrMatrix fMatrix;
706 };
bsalomon@google.com27847de2011-02-22 20:59:41 +0000707
robertphillips@google.com56c79b12012-07-11 20:57:46 +0000708 class AutoClip : GrNoncopyable {
709 public:
bsalomon@google.coma04e8e82012-08-27 12:53:13 +0000710 // This enum exists to require a caller of the constructor to acknowledge that the clip will
711 // initially be wide open. It also could be extended if there are other desirable initial
712 // clip states.
713 enum InitialClip {
714 kWideOpen_InitialClip,
715 };
716
717 AutoClip(GrContext* context, InitialClip initialState) {
718 GrAssert(kWideOpen_InitialClip == initialState);
719 fOldClip = context->getClip();
720 fNewClipData.fClipStack = &fNewClipStack;
721 context->setClip(&fNewClipData);
722 fContext = context;
723 }
724
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000725 AutoClip(GrContext* context, const GrRect& newClipRect)
robertphillips@google.com56c79b12012-07-11 20:57:46 +0000726 : fContext(context)
robertphillips@google.combeb1af72012-07-26 18:52:16 +0000727 , fNewClipStack(newClipRect) {
728 fNewClipData.fClipStack = &fNewClipStack;
729
robertphillips@google.com56c79b12012-07-11 20:57:46 +0000730 fOldClip = fContext->getClip();
robertphillips@google.combeb1af72012-07-26 18:52:16 +0000731 fContext->setClip(&fNewClipData);
robertphillips@google.com56c79b12012-07-11 20:57:46 +0000732 }
733
734 ~AutoClip() {
735 if (NULL != fContext) {
736 fContext->setClip(fOldClip);
737 }
738 }
739 private:
robertphillips@google.combeb1af72012-07-26 18:52:16 +0000740 GrContext* fContext;
741 const GrClipData* fOldClip;
742
robertphillips@google.com641f8b12012-07-31 19:15:58 +0000743 SkClipStack fNewClipStack;
robertphillips@google.combeb1af72012-07-26 18:52:16 +0000744 GrClipData fNewClipData;
robertphillips@google.com56c79b12012-07-11 20:57:46 +0000745 };
746
bsalomon@google.coma04e8e82012-08-27 12:53:13 +0000747 class AutoWideOpenIdentityDraw {
748 public:
749 AutoWideOpenIdentityDraw(GrContext* ctx, GrRenderTarget* rt)
750 : fAutoClip(ctx, AutoClip::kWideOpen_InitialClip)
751 , fAutoRT(ctx, rt)
752 , fAutoMatrix(ctx, AutoMatrix::kIdentity_InitialMatrix) {
753 }
754 private:
755 AutoClip fAutoClip;
756 AutoRenderTarget fAutoRT;
757 AutoMatrix fAutoMatrix;
758 };
759
bsalomon@google.com27847de2011-02-22 20:59:41 +0000760 ///////////////////////////////////////////////////////////////////////////
761 // Functions intended for internal use only.
762 GrGpu* getGpu() { return fGpu; }
bsalomon@google.com1f221a72011-08-23 20:54:07 +0000763 const GrGpu* getGpu() const { return fGpu; }
bsalomon@google.com27847de2011-02-22 20:59:41 +0000764 GrFontCache* getFontCache() { return fFontCache; }
765 GrDrawTarget* getTextTarget(const GrPaint& paint);
bsalomon@google.com27847de2011-02-22 20:59:41 +0000766 const GrIndexBuffer* getQuadIndexBuffer() const;
bsalomon@google.com9923c2b2012-06-06 18:21:18 +0000767
bsalomon@google.com558a75b2011-08-08 17:01:14 +0000768 /**
769 * Stencil buffers add themselves to the cache using
770 * addAndLockStencilBuffer. When a SB's RT-attachment count
771 * reaches zero the SB unlocks itself using unlockStencilBuffer and is
robertphillips@google.comd6bbbf82012-09-05 15:46:34 +0000772 * eligible for purging. findAndLockStencilBuffer is called to check the
skia.committer@gmail.com6c778162012-09-06 02:01:13 +0000773 * cache for a SB that matches an RT's criteria.
bsalomon@google.com558a75b2011-08-08 17:01:14 +0000774 */
robertphillips@google.com1f47f4f2012-08-16 14:49:16 +0000775 void addAndLockStencilBuffer(GrStencilBuffer* sb);
776 void unlockStencilBuffer(GrStencilBuffer* sb);
robertphillips@google.comd6bbbf82012-09-05 15:46:34 +0000777 GrStencilBuffer* findAndLockStencilBuffer(int width, int height, int sampleCnt);
bsalomon@google.com27847de2011-02-22 20:59:41 +0000778
robertphillips@google.com2c756812012-05-22 20:28:23 +0000779 GrPathRenderer* getPathRenderer(const SkPath& path,
780 GrPathFill fill,
781 const GrDrawTarget* target,
robertphillips@google.com72176b22012-05-23 13:19:12 +0000782 bool antiAlias,
783 bool allowSW);
robertphillips@google.com2c756812012-05-22 20:28:23 +0000784
robertphillips@google.com59552022012-08-31 13:07:37 +0000785#if GR_CACHE_STATS
robertphillips@google.com5f9f2f52012-08-22 10:57:05 +0000786 void printCacheStats() const;
787#endif
788
bsalomon@google.com27847de2011-02-22 20:59:41 +0000789private:
bsalomon@google.com1d4edd32012-08-16 18:36:06 +0000790 // Used to indicate whether a draw should be performed immediately or queued in fDrawBuffer.
791 enum BufferedDraw {
792 kYes_BufferedDraw,
793 kNo_BufferedDraw,
bsalomon@google.com27847de2011-02-22 20:59:41 +0000794 };
bsalomon@google.com1d4edd32012-08-16 18:36:06 +0000795 BufferedDraw fLastDrawWasBuffered;
bsalomon@google.com27847de2011-02-22 20:59:41 +0000796
bsalomon@google.com50398bf2011-07-26 20:45:30 +0000797 GrGpu* fGpu;
bsalomon@google.com10e04bf2012-03-30 14:35:04 +0000798 GrDrawState* fDrawState;
799
bsalomon@google.com50398bf2011-07-26 20:45:30 +0000800 GrResourceCache* fTextureCache;
801 GrFontCache* fFontCache;
bsalomon@google.comdfe75bc2011-03-25 12:31:16 +0000802
bsalomon@google.com30085192011-08-19 15:42:31 +0000803 GrPathRendererChain* fPathRendererChain;
robertphillips@google.com72176b22012-05-23 13:19:12 +0000804 GrSoftwarePathRenderer* fSoftwarePathRenderer;
bsalomon@google.com27847de2011-02-22 20:59:41 +0000805
806 GrVertexBufferAllocPool* fDrawBufferVBAllocPool;
807 GrIndexBufferAllocPool* fDrawBufferIBAllocPool;
808 GrInOrderDrawBuffer* fDrawBuffer;
809
robertphillips@google.comf69a11b2012-06-15 13:58:07 +0000810 GrAARectRenderer* fAARectRenderer;
bsalomon@google.comdfe75bc2011-03-25 12:31:16 +0000811
bsalomon@google.coma04e8e82012-08-27 12:53:13 +0000812 bool fDidTestPMConversions;
813 int fPMToUPMConversion;
814 int fUPMToPMConversion;
815
robertphillips@google.comf69a11b2012-06-15 13:58:07 +0000816 GrContext(GrGpu* gpu);
bsalomon@google.com205d4602011-04-25 12:43:45 +0000817
bsalomon@google.com8fe72472011-03-30 21:26:44 +0000818 void setupDrawBuffer();
819
bsalomon@google.com27847de2011-02-22 20:59:41 +0000820 void flushDrawBuffer();
821
bsalomon@google.com10e04bf2012-03-30 14:35:04 +0000822 void setPaint(const GrPaint& paint);
bsalomon@google.com27847de2011-02-22 20:59:41 +0000823
bsalomon@google.com07ea2db2012-08-17 14:06:49 +0000824 /// Sets the paint and returns the target to draw into. The paint can be NULL in which case the
825 /// draw state is left unmodified.
826 GrDrawTarget* prepareToDraw(const GrPaint*, BufferedDraw);
bsalomon@google.com27847de2011-02-22 20:59:41 +0000827
bsalomon@google.com8d033a12012-04-27 15:52:53 +0000828 void internalDrawPath(const GrPaint& paint, const SkPath& path,
bsalomon@google.com93c96602012-04-27 13:05:21 +0000829 GrPathFill fill, const GrPoint* translate);
830
robertphillips@google.com3319f332012-08-13 18:00:36 +0000831 GrTexture* createResizedTexture(const GrTextureDesc& desc,
832 const GrCacheData& cacheData,
833 void* srcData,
834 size_t rowBytes,
835 bool needsFiltering);
836
robertphillips@google.com15c0fea2012-06-22 12:41:43 +0000837 // Needed so GrTexture's returnToCache helper function can call
838 // addExistingTextureToCache
839 friend class GrTexture;
840
841 // Add an existing texture to the texture cache. This is intended solely
842 // for use with textures released from an GrAutoScratchTexture.
843 void addExistingTextureToCache(GrTexture* texture);
reed@google.comfa35e3d2012-06-26 20:16:17 +0000844
bsalomon@google.coma04e8e82012-08-27 12:53:13 +0000845 GrCustomStage* createPMToUPMEffect(GrTexture* texture, bool swapRAndB);
846 GrCustomStage* createUPMToPMEffect(GrTexture* texture, bool swapRAndB);
847
reed@google.comfa35e3d2012-06-26 20:16:17 +0000848 typedef GrRefCnt INHERITED;
bsalomon@google.com27847de2011-02-22 20:59:41 +0000849};
850
851/**
bsalomon@google.com50398bf2011-07-26 20:45:30 +0000852 * Gets and locks a scratch texture from a descriptor using
853 * either exact or approximate criteria. Unlocks texture in
854 * the destructor.
senorblanco@chromium.orgaadd9f82011-07-12 19:44:51 +0000855 */
bsalomon@google.com50398bf2011-07-26 20:45:30 +0000856class GrAutoScratchTexture : ::GrNoncopyable {
senorblanco@chromium.orgaadd9f82011-07-12 19:44:51 +0000857public:
bsalomon@google.com50398bf2011-07-26 20:45:30 +0000858 GrAutoScratchTexture()
robertphillips@google.com1f47f4f2012-08-16 14:49:16 +0000859 : fContext(NULL)
860 , fTexture(NULL) {
senorblanco@chromium.orgaadd9f82011-07-12 19:44:51 +0000861 }
bsalomon@google.com50398bf2011-07-26 20:45:30 +0000862
863 GrAutoScratchTexture(GrContext* context,
864 const GrTextureDesc& desc,
865 GrContext::ScratchTexMatch match =
866 GrContext::kApprox_ScratchTexMatch)
robertphillips@google.com1f47f4f2012-08-16 14:49:16 +0000867 : fContext(NULL)
868 , fTexture(NULL) {
bsalomon@google.com50398bf2011-07-26 20:45:30 +0000869 this->set(context, desc, match);
870 }
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000871
bsalomon@google.com50398bf2011-07-26 20:45:30 +0000872 ~GrAutoScratchTexture() {
robertphillips@google.com9ec07532012-06-22 12:01:30 +0000873 this->reset();
874 }
875
876 void reset() {
robertphillips@google.com1f47f4f2012-08-16 14:49:16 +0000877 if (NULL != fContext && NULL != fTexture) {
878 fContext->unlockTexture(fTexture);
879 fTexture = NULL;
senorblanco@chromium.orgaadd9f82011-07-12 19:44:51 +0000880 }
881 }
bsalomon@google.com84223112011-07-14 14:45:44 +0000882
robertphillips@google.com15c0fea2012-06-22 12:41:43 +0000883 /*
884 * When detaching a texture we do not unlock it in the texture cache but
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000885 * we do set the returnToCache flag. In this way the texture remains
886 * "locked" in the texture cache until it is freed and recycled in
887 * GrTexture::internal_dispose. In reality, the texture has been removed
888 * from the cache (because this is in AutoScratchTexture) and by not
889 * calling unlockTexture we simply don't re-add it. It will be reattached
robertphillips@google.com15c0fea2012-06-22 12:41:43 +0000890 * in GrTexture::internal_dispose.
891 *
892 * Note that the caller is assumed to accept and manage the ref to the
893 * returned texture.
894 */
895 GrTexture* detach() {
robertphillips@google.com1f47f4f2012-08-16 14:49:16 +0000896 GrTexture* temp = fTexture;
robertphillips@google.com15c0fea2012-06-22 12:41:43 +0000897
robertphillips@google.com521eaf82012-08-22 11:03:19 +0000898 // Conceptually the texture's cache entry loses its ref to the
899 // texture while the caller of this method gets a ref.
900 GrAssert(NULL != temp->getCacheEntry());
901
robertphillips@google.com1f47f4f2012-08-16 14:49:16 +0000902 fTexture = NULL;
robertphillips@google.com15c0fea2012-06-22 12:41:43 +0000903
904 temp->setFlag((GrTextureFlags) GrTexture::kReturnToCache_FlagBit);
robertphillips@google.com15c0fea2012-06-22 12:41:43 +0000905 return temp;
906 }
907
bsalomon@google.com50398bf2011-07-26 20:45:30 +0000908 GrTexture* set(GrContext* context,
909 const GrTextureDesc& desc,
910 GrContext::ScratchTexMatch match =
911 GrContext::kApprox_ScratchTexMatch) {
robertphillips@google.com9ec07532012-06-22 12:01:30 +0000912 this->reset();
913
bsalomon@google.com50398bf2011-07-26 20:45:30 +0000914 fContext = context;
915 if (NULL != fContext) {
robertphillips@google.com1f47f4f2012-08-16 14:49:16 +0000916 fTexture = fContext->lockScratchTexture(desc, match);
917 if (NULL == fTexture) {
bsalomon@google.com50398bf2011-07-26 20:45:30 +0000918 fContext = NULL;
919 }
robertphillips@google.com1f47f4f2012-08-16 14:49:16 +0000920 return fTexture;
bsalomon@google.com50398bf2011-07-26 20:45:30 +0000921 } else {
922 return NULL;
923 }
924 }
925
robertphillips@google.com1f47f4f2012-08-16 14:49:16 +0000926 GrTexture* texture() { return fTexture; }
927
senorblanco@chromium.orgaadd9f82011-07-12 19:44:51 +0000928private:
bsalomon@google.com50398bf2011-07-26 20:45:30 +0000929 GrContext* fContext;
robertphillips@google.com1f47f4f2012-08-16 14:49:16 +0000930 GrTexture* fTexture;
senorblanco@chromium.orgaadd9f82011-07-12 19:44:51 +0000931};
932
bsalomon@google.com27847de2011-02-22 20:59:41 +0000933#endif