blob: d27b963d9255559ed60f0f1ab0faa07b5013fca1 [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
13#include "GrClip.h"
bsalomon@google.com27847de2011-02-22 20:59:41 +000014#include "GrPaint.h"
bsalomon@google.comc287a892011-08-19 14:49:36 +000015// not strictly needed but requires WK change in LayerTextureUpdaterCanvas to
16// remove.
17#include "GrRenderTarget.h"
bsalomon@google.com27847de2011-02-22 20:59:41 +000018
bsalomon@google.com583a1e32011-08-17 13:42:46 +000019class GrDrawTarget;
bsalomon@google.com27847de2011-02-22 20:59:41 +000020class GrFontCache;
bsalomon@google.com05ef5102011-05-02 21:14:59 +000021class GrGpu;
22struct GrGpuStats;
bsalomon@google.com583a1e32011-08-17 13:42:46 +000023class GrIndexBuffer;
bsalomon@google.com27847de2011-02-22 20:59:41 +000024class GrIndexBufferAllocPool;
25class GrInOrderDrawBuffer;
bsalomon@google.com583a1e32011-08-17 13:42:46 +000026class GrPathRenderer;
bsalomon@google.com30085192011-08-19 15:42:31 +000027class GrPathRendererChain;
bsalomon@google.com50398bf2011-07-26 20:45:30 +000028class GrResourceEntry;
29class GrResourceCache;
bsalomon@google.com558a75b2011-08-08 17:01:14 +000030class GrStencilBuffer;
bsalomon@google.com583a1e32011-08-17 13:42:46 +000031class GrVertexBuffer;
bsalomon@google.com50398bf2011-07-26 20:45:30 +000032class GrVertexBufferAllocPool;
33
bsalomon@google.com91826102011-03-21 19:51:57 +000034class GR_API GrContext : public GrRefCnt {
bsalomon@google.com27847de2011-02-22 20:59:41 +000035public:
36 /**
37 * Creates a GrContext from within a 3D context.
38 */
bsalomon@google.com05ef5102011-05-02 21:14:59 +000039 static GrContext* Create(GrEngine engine,
40 GrPlatform3DContext context3D);
bsalomon@google.com27847de2011-02-22 20:59:41 +000041
bsalomon@google.com27847de2011-02-22 20:59:41 +000042 virtual ~GrContext();
43
44 /**
45 * The GrContext normally assumes that no outsider is setting state
46 * within the underlying 3D API's context/device/whatever. This call informs
47 * the context that the state was modified and it should resend. Shouldn't
48 * be called frequently for good performance.
49 */
50 void resetContext();
51
bsalomon@google.com8fe72472011-03-30 21:26:44 +000052 /**
53 * Abandons all gpu resources, assumes 3D API state is unknown. Call this
54 * if you have lost the associated GPU context, and thus internal texture,
55 * buffer, etc. references/IDs are now invalid. Should be called even when
56 * GrContext is no longer going to be used for two reasons:
57 * 1) ~GrContext will not try to free the objects in the 3D API.
58 * 2) If you've created GrResources that outlive the GrContext they will
59 * be marked as invalid (GrResource::isValid()) and won't attempt to
60 * free their underlying resource in the 3D API.
61 * Content drawn since the last GrContext::flush() may be lost.
62 */
63 void contextLost();
bsalomon@google.com27847de2011-02-22 20:59:41 +000064
65 /**
junov@google.com53a55842011-06-08 22:55:10 +000066 * Similar to contextLost, but makes no attempt to reset state.
67 * Use this method when GrContext destruction is pending, but
68 * the graphics context is destroyed first.
69 */
70 void contextDestroyed();
71
72 /**
bsalomon@google.com8fe72472011-03-30 21:26:44 +000073 * Frees gpu created by the context. Can be called to reduce GPU memory
74 * pressure.
bsalomon@google.com27847de2011-02-22 20:59:41 +000075 */
bsalomon@google.com8fe72472011-03-30 21:26:44 +000076 void freeGpuResources();
77
78 ///////////////////////////////////////////////////////////////////////////
79 // Textures
bsalomon@google.com27847de2011-02-22 20:59:41 +000080
81 /**
bsalomon@google.com50398bf2011-07-26 20:45:30 +000082 * Token that refers to an entry in the texture cache. Returned by
83 * functions that lock textures. Passed to unlockTexture.
bsalomon@google.com27847de2011-02-22 20:59:41 +000084 */
bsalomon@google.com50398bf2011-07-26 20:45:30 +000085 class TextureCacheEntry {
86 public:
87 TextureCacheEntry() : fEntry(NULL) {}
88 TextureCacheEntry(const TextureCacheEntry& e) : fEntry(e.fEntry) {}
89 TextureCacheEntry& operator= (const TextureCacheEntry& e) {
90 fEntry = e.fEntry;
91 return *this;
92 }
93 GrTexture* texture() const;
94 void reset() { fEntry = NULL; }
95 private:
96 explicit TextureCacheEntry(GrResourceEntry* entry) { fEntry = entry; }
97 void set(GrResourceEntry* entry) { fEntry = entry; }
98 GrResourceEntry* cacheEntry() { return fEntry; }
99 GrResourceEntry* fEntry;
100 friend class GrContext;
101 };
bsalomon@google.com27847de2011-02-22 20:59:41 +0000102
bsalomon@google.com50398bf2011-07-26 20:45:30 +0000103 /**
104 * Key generated by client. Should be a unique key on the texture data.
105 * Does not need to consider that width and height of the texture. Two
106 * textures with the same TextureKey but different bounds will not collide.
107 */
108 typedef uint64_t TextureKey;
109
110 /**
bsalomon@google.com1fadb202011-12-12 16:10:08 +0000111 * Create a new entry, based on the specified key and texture, and return
112 * its "locked" entry. Must call be balanced with an unlockTexture() call.
113 *
114 * @param key A client-generated key that identifies the contents
115 * of the texture. Respecified to findAndLockTexture
116 * for subsequent uses of the texture.
117 * @param sampler The sampler state used to draw a texture may be used
118 * to determine how to store the pixel data in the texture
119 * cache. (e.g. different versions may exist for different
120 * wrap modes on GPUs with limited or no NPOT texture
121 * support). Only the wrap and filter fields are used. NULL
122 * implies clamp wrap modes and nearest filtering.
123 * @param desc Description of the texture properties.
124 * @param srcData Pointer to the pixel values.
125 * @param rowBytes The number of bytes between rows of the texture. Zero
126 * implies tightly packed rows.
127 */
128 TextureCacheEntry createAndLockTexture(TextureKey key,
129 const GrSamplerState* sampler,
130 const GrTextureDesc& desc,
131 void* srcData, size_t rowBytes);
132
133 /**
bsalomon@google.com50398bf2011-07-26 20:45:30 +0000134 * Search for an entry based on key and dimensions. If found, "lock" it and
135 * return it. The entry's texture() function will return NULL if not found.
bsalomon@google.com1fadb202011-12-12 16:10:08 +0000136 * Must be balanced with an unlockTexture() call.
137 *
138 * @param key A client-generated key that identifies the contents
139 * of the texture.
140 * @param width The width of the texture in pixels as specifed in
141 * the GrTextureDesc originally passed to
142 * createAndLockTexture
143 * @param width The height of the texture in pixels as specifed in
144 * the GrTextureDesc originally passed to
145 * createAndLockTexture
146 * @param sampler The sampler state used to draw a texture may be used
147 * to determine the cache entry used. (e.g. different
148 * versions may exist for different wrap modes on GPUs with
149 * limited or no NPOT texture support). Only the wrap and
150 * filter fields are used. NULL implies clamp wrap modes
151 * and nearest filtering.
bsalomon@google.com50398bf2011-07-26 20:45:30 +0000152 */
153 TextureCacheEntry findAndLockTexture(TextureKey key,
154 int width,
155 int height,
bsalomon@google.com1fadb202011-12-12 16:10:08 +0000156 const GrSamplerState* sampler);
bsalomon@google.comfb309512011-11-30 14:13:48 +0000157 /**
158 * Determines whether a texture is in the cache. If the texture is found it
159 * will not be locked or returned. This call does not affect the priority of
160 * the texture for deletion.
161 */
162 bool isTextureInCache(TextureKey key,
163 int width,
164 int height,
bsalomon@google.com1fadb202011-12-12 16:10:08 +0000165 const GrSamplerState*) const;
bsalomon@google.com50398bf2011-07-26 20:45:30 +0000166
167 /**
168 * Enum that determines how closely a returned scratch texture must match
169 * a provided GrTextureDesc.
170 */
171 enum ScratchTexMatch {
172 /**
173 * Finds a texture that exactly matches the descriptor.
174 */
175 kExact_ScratchTexMatch,
176 /**
177 * Finds a texture that approximately matches the descriptor. Will be
178 * at least as large in width and height as desc specifies. If desc
179 * specifies that texture is a render target then result will be a
180 * render target. If desc specifies a render target and doesn't set the
181 * no stencil flag then result will have a stencil. Format and aa level
182 * will always match.
183 */
184 kApprox_ScratchTexMatch
185 };
bsalomon@google.com27847de2011-02-22 20:59:41 +0000186
187 /**
bsalomon@google.comfea37b52011-04-25 15:51:06 +0000188 * Returns a texture matching the desc. It's contents are unknown. Subsequent
189 * requests with the same descriptor are not guaranteed to return the same
190 * texture. The same texture is guaranteed not be returned again until it is
bsalomon@google.com50398bf2011-07-26 20:45:30 +0000191 * unlocked. Must call be balanced with an unlockTexture() call.
bsalomon@google.coma39f4042011-04-26 13:18:16 +0000192 *
193 * Textures created by createAndLockTexture() hide the complications of
194 * tiling non-power-of-two textures on APIs that don't support this (e.g.
bsalomon@google.com50398bf2011-07-26 20:45:30 +0000195 * unextended GLES2). Tiling a npot texture created by lockScratchTexture on
bsalomon@google.coma39f4042011-04-26 13:18:16 +0000196 * such an API will create gaps in the tiling pattern. This includes clamp
197 * mode. (This may be addressed in a future update.)
bsalomon@google.comfea37b52011-04-25 15:51:06 +0000198 */
bsalomon@google.com50398bf2011-07-26 20:45:30 +0000199 TextureCacheEntry lockScratchTexture(const GrTextureDesc& desc, ScratchTexMatch match);
bsalomon@google.comb5b31682011-06-16 18:05:35 +0000200
201 /**
bsalomon@google.com27847de2011-02-22 20:59:41 +0000202 * When done with an entry, call unlockTexture(entry) on it, which returns
203 * it to the cache, where it may be purged.
204 */
bsalomon@google.com50398bf2011-07-26 20:45:30 +0000205 void unlockTexture(TextureCacheEntry entry);
bsalomon@google.com27847de2011-02-22 20:59:41 +0000206
207 /**
bsalomon@google.com27847de2011-02-22 20:59:41 +0000208 * Creates a texture that is outside the cache. Does not count against
209 * cache's budget.
210 */
bsalomon@google.comfea37b52011-04-25 15:51:06 +0000211 GrTexture* createUncachedTexture(const GrTextureDesc&,
bsalomon@google.com27847de2011-02-22 20:59:41 +0000212 void* srcData,
213 size_t rowBytes);
214
215 /**
216 * Returns true if the specified use of an indexed texture is supported.
217 */
bsalomon@google.com1fadb202011-12-12 16:10:08 +0000218 bool supportsIndex8PixelConfig(const GrSamplerState*,
bsalomon@google.com1f221a72011-08-23 20:54:07 +0000219 int width,
220 int height) const;
bsalomon@google.com27847de2011-02-22 20:59:41 +0000221
222 /**
223 * Return the current texture cache limits.
224 *
225 * @param maxTextures If non-null, returns maximum number of textures that
226 * can be held in the cache.
227 * @param maxTextureBytes If non-null, returns maximum number of bytes of
228 * texture memory that can be held in the cache.
229 */
230 void getTextureCacheLimits(int* maxTextures, size_t* maxTextureBytes) const;
231
232 /**
233 * Specify the texture cache limits. If the current cache exceeds either
234 * of these, it will be purged (LRU) to keep the cache within these limits.
235 *
236 * @param maxTextures The maximum number of textures that can be held in
237 * the cache.
238 * @param maxTextureBytes The maximum number of bytes of texture memory
239 * that can be held in the cache.
240 */
241 void setTextureCacheLimits(int maxTextures, size_t maxTextureBytes);
242
243 /**
244 * Return the max width or height of a texture supported by the current gpu
245 */
bsalomon@google.com91958362011-06-13 17:58:13 +0000246 int getMaxTextureSize() const;
247
248 /**
249 * Return the max width or height of a render target supported by the
250 * current gpu
251 */
252 int getMaxRenderTargetSize() const;
bsalomon@google.com27847de2011-02-22 20:59:41 +0000253
254 ///////////////////////////////////////////////////////////////////////////
255 // Render targets
256
257 /**
bsalomon@google.com5877ffd2011-04-11 17:58:48 +0000258 * Sets the render target.
259 * @param target the render target to set. (should not be NULL.)
260 */
261 void setRenderTarget(GrRenderTarget* target);
262
263 /**
264 * Gets the current render target.
265 * @return the currently bound render target. Should never be NULL.
266 */
267 const GrRenderTarget* getRenderTarget() const;
268 GrRenderTarget* getRenderTarget();
269
270 ///////////////////////////////////////////////////////////////////////////
271 // Platform Surfaces
272
bsalomon@google.com5877ffd2011-04-11 17:58:48 +0000273 /**
bsalomon@google.come269f212011-11-07 13:29:52 +0000274 * Wraps an existing texture with a GrTexture object.
275 *
276 * OpenGL: if the object is a texture Gr may change its GL texture params
277 * when it is drawn.
278 *
279 * @param desc description of the object to create.
280 *
281 * @return GrTexture object or NULL on failure.
282 */
283 GrTexture* createPlatformTexture(const GrPlatformTextureDesc& desc);
284
285 /**
286 * Wraps an existing render target with a GrRenderTarget object. It is
287 * similar to createPlatformTexture but can be used to draw into surfaces
288 * that are not also textures (e.g. FBO 0 in OpenGL, or an MSAA buffer that
289 * the client will resolve to a texture).
290 *
291 * @param desc description of the object to create.
292 *
293 * @return GrTexture object or NULL on failure.
294 */
295 GrRenderTarget* createPlatformRenderTarget(
296 const GrPlatformRenderTargetDesc& desc);
297
bsalomon@google.com27847de2011-02-22 20:59:41 +0000298 ///////////////////////////////////////////////////////////////////////////
299 // Matrix state
300
301 /**
302 * Gets the current transformation matrix.
303 * @return the current matrix.
304 */
305 const GrMatrix& getMatrix() const;
306
307 /**
308 * Sets the transformation matrix.
309 * @param m the matrix to set.
310 */
311 void setMatrix(const GrMatrix& m);
312
313 /**
314 * Concats the current matrix. The passed matrix is applied before the
315 * current matrix.
316 * @param m the matrix to concat.
317 */
318 void concatMatrix(const GrMatrix& m) const;
319
320
321 ///////////////////////////////////////////////////////////////////////////
322 // Clip state
323 /**
324 * Gets the current clip.
325 * @return the current clip.
326 */
bsalomon@google.com05ef5102011-05-02 21:14:59 +0000327 const GrClip& getClip() const;
bsalomon@google.com27847de2011-02-22 20:59:41 +0000328
329 /**
330 * Sets the clip.
331 * @param clip the clip to set.
332 */
333 void setClip(const GrClip& clip);
334
335 /**
336 * Convenience method for setting the clip to a rect.
337 * @param rect the rect to set as the new clip.
338 */
339 void setClip(const GrIRect& rect);
340
341 ///////////////////////////////////////////////////////////////////////////
342 // Draws
343
344 /**
bsalomon@google.com6aa25c32011-04-27 19:55:29 +0000345 * Clear the entire or rect of the render target, ignoring any clips.
346 * @param rect the rect to clear or the whole thing if rect is NULL.
347 * @param color the color to clear to.
bsalomon@google.com27847de2011-02-22 20:59:41 +0000348 */
bsalomon@google.com6aa25c32011-04-27 19:55:29 +0000349 void clear(const GrIRect* rect, GrColor color);
bsalomon@google.com27847de2011-02-22 20:59:41 +0000350
351 /**
352 * Draw everywhere (respecting the clip) with the paint.
353 */
354 void drawPaint(const GrPaint& paint);
355
356 /**
357 * Draw the rect using a paint.
358 * @param paint describes how to color pixels.
359 * @param strokeWidth If strokeWidth < 0, then the rect is filled, else
360 * the rect is mitered stroked based on strokeWidth. If
361 * strokeWidth == 0, then the stroke is always a single
362 * pixel thick.
363 * @param matrix Optional matrix applied to the rect. Applied before
364 * context's matrix or the paint's matrix.
365 * The rects coords are used to access the paint (through texture matrix)
366 */
367 void drawRect(const GrPaint& paint,
368 const GrRect&,
369 GrScalar strokeWidth = -1,
370 const GrMatrix* matrix = NULL);
371
372 /**
373 * Maps a rect of paint coordinates onto the a rect of destination
374 * coordinates. Each rect can optionally be transformed. The srcRect
375 * is stretched over the dstRect. The dstRect is transformed by the
376 * context's matrix and the srcRect is transformed by the paint's matrix.
377 * Additional optional matrices can be provided by parameters.
378 *
379 * @param paint describes how to color pixels.
380 * @param dstRect the destination rect to draw.
381 * @param srcRect rect of paint coordinates to be mapped onto dstRect
382 * @param dstMatrix Optional matrix to transform dstRect. Applied before
383 * context's matrix.
384 * @param srcMatrix Optional matrix to transform srcRect Applied before
385 * paint's matrix.
386 */
387 void drawRectToRect(const GrPaint& paint,
388 const GrRect& dstRect,
389 const GrRect& srcRect,
390 const GrMatrix* dstMatrix = NULL,
391 const GrMatrix* srcMatrix = NULL);
392
393 /**
bsalomon@google.comd302f142011-03-03 13:54:13 +0000394 * Draws a path.
bsalomon@google.com27847de2011-02-22 20:59:41 +0000395 *
396 * @param paint describes how to color pixels.
reed@google.com07f3ee12011-05-16 17:21:57 +0000397 * @param path the path to draw
bsalomon@google.com27847de2011-02-22 20:59:41 +0000398 * @param fill the path filling rule to use.
399 * @param translate optional additional translation applied to the
400 * path.
401 */
reed@google.com07f3ee12011-05-16 17:21:57 +0000402 void drawPath(const GrPaint& paint, const GrPath& path, GrPathFill fill,
bsalomon@google.comd302f142011-03-03 13:54:13 +0000403 const GrPoint* translate = NULL);
reed@google.com07f3ee12011-05-16 17:21:57 +0000404
bsalomon@google.com27847de2011-02-22 20:59:41 +0000405 /**
406 * Draws vertices with a paint.
407 *
408 * @param paint describes how to color pixels.
409 * @param primitiveType primitives type to draw.
410 * @param vertexCount number of vertices.
411 * @param positions array of vertex positions, required.
412 * @param texCoords optional array of texture coordinates used
413 * to access the paint.
414 * @param colors optional array of per-vertex colors, supercedes
415 * the paint's color field.
416 * @param indices optional array of indices. If NULL vertices
417 * are drawn non-indexed.
418 * @param indexCount if indices is non-null then this is the
419 * number of indices.
420 */
421 void drawVertices(const GrPaint& paint,
422 GrPrimitiveType primitiveType,
423 int vertexCount,
424 const GrPoint positions[],
425 const GrPoint texs[],
426 const GrColor colors[],
427 const uint16_t indices[],
428 int indexCount);
429
bsalomon@google.com27847de2011-02-22 20:59:41 +0000430 ///////////////////////////////////////////////////////////////////////////
431 // Misc.
432
433 /**
bsalomon@google.coma7f84e12011-03-10 14:13:19 +0000434 * Flags that affect flush() behavior.
435 */
436 enum FlushBits {
437 /**
438 * A client may want Gr to bind a GrRenderTarget in the 3D API so that
439 * it can be rendered to directly. However, Gr lazily sets state. Simply
440 * calling setRenderTarget() followed by flush() without flags may not
441 * bind the render target. This flag forces the context to bind the last
442 * set render target in the 3D API.
443 */
444 kForceCurrentRenderTarget_FlushBit = 0x1,
445 /**
446 * A client may reach a point where it has partially rendered a frame
447 * through a GrContext that it knows the user will never see. This flag
448 * causes the flush to skip submission of deferred content to the 3D API
449 * during the flush.
450 */
451 kDiscard_FlushBit = 0x2,
452 };
453
454 /**
bsalomon@google.com27847de2011-02-22 20:59:41 +0000455 * Call to ensure all drawing to the context has been issued to the
456 * underlying 3D API.
bsalomon@google.coma7f84e12011-03-10 14:13:19 +0000457 * @param flagsBitfield flags that control the flushing behavior. See
458 * FlushBits.
bsalomon@google.com27847de2011-02-22 20:59:41 +0000459 */
bsalomon@google.com8fe72472011-03-30 21:26:44 +0000460 void flush(int flagsBitfield = 0);
bsalomon@google.com6f379512011-11-16 20:36:03 +0000461
bsalomon@google.com27847de2011-02-22 20:59:41 +0000462 /**
bsalomon@google.com669fdc42011-04-05 17:08:27 +0000463 * Reads a rectangle of pixels from a render target.
bsalomon@google.com6f379512011-11-16 20:36:03 +0000464 * @param target the render target to read from. NULL means the
bsalomon@google.com669fdc42011-04-05 17:08:27 +0000465 * current render target.
466 * @param left left edge of the rectangle to read (inclusive)
467 * @param top top edge of the rectangle to read (inclusive)
468 * @param width width of rectangle to read in pixels.
469 * @param height height of rectangle to read in pixels.
470 * @param config the pixel config of the destination buffer
471 * @param buffer memory to read the rectangle into.
bsalomon@google.com6f379512011-11-16 20:36:03 +0000472 * @param rowBytes number of bytes bewtween consecutive rows. Zero
bsalomon@google.comc6980972011-11-02 19:57:21 +0000473 * means rows are tightly packed.
bsalomon@google.com669fdc42011-04-05 17:08:27 +0000474 *
475 * @return true if the read succeeded, false if not. The read can fail
bsalomon@google.com6f379512011-11-16 20:36:03 +0000476 * because of an unsupported pixel config or because no render
bsalomon@google.com669fdc42011-04-05 17:08:27 +0000477 * target is currently set.
bsalomon@google.com27847de2011-02-22 20:59:41 +0000478 */
bsalomon@google.com669fdc42011-04-05 17:08:27 +0000479 bool readRenderTargetPixels(GrRenderTarget* target,
480 int left, int top, int width, int height,
bsalomon@google.comc6980972011-11-02 19:57:21 +0000481 GrPixelConfig config, void* buffer,
bsalomon@google.com6f379512011-11-16 20:36:03 +0000482 size_t rowBytes) {
483 return this->internalReadRenderTargetPixels(target, left, top,
484 width, height,
485 config, buffer,
486 rowBytes, 0);
487 }
488
489 /**
490 * Copy the src pixels [buffer, rowbytes, pixelconfig] into a render target
491 * at the specified rectangle.
492 * @param target the render target to write into. NULL means the
493 * current render target.
494 * @param left left edge of the rectangle to write (inclusive)
495 * @param top top edge of the rectangle to write (inclusive)
496 * @param width width of rectangle to write in pixels.
497 * @param height height of rectangle to write in pixels.
498 * @param config the pixel config of the source buffer
499 * @param buffer memory to read the rectangle from.
500 * @param rowBytes number of bytes bewtween consecutive rows. Zero
501 * means rows are tightly packed.
502 */
503 void writeRenderTargetPixels(GrRenderTarget* target,
504 int left, int top, int width, int height,
505 GrPixelConfig config, const void* buffer,
506 size_t rowBytes) {
507 this->internalWriteRenderTargetPixels(target, left, top, width, height,
508 config, buffer, rowBytes, 0);
509 }
bsalomon@google.com669fdc42011-04-05 17:08:27 +0000510
511 /**
512 * Reads a rectangle of pixels from a texture.
bsalomon@google.com6f379512011-11-16 20:36:03 +0000513 * @param texture the texture to read from.
bsalomon@google.com669fdc42011-04-05 17:08:27 +0000514 * @param left left edge of the rectangle to read (inclusive)
515 * @param top top edge of the rectangle to read (inclusive)
516 * @param width width of rectangle to read in pixels.
517 * @param height height of rectangle to read in pixels.
518 * @param config the pixel config of the destination buffer
519 * @param buffer memory to read the rectangle into.
bsalomon@google.com6f379512011-11-16 20:36:03 +0000520 * @param rowBytes number of bytes bewtween consecutive rows. Zero
521 * means rows are tightly packed.
bsalomon@google.com669fdc42011-04-05 17:08:27 +0000522 *
523 * @return true if the read succeeded, false if not. The read can fail
bsalomon@google.com6f379512011-11-16 20:36:03 +0000524 * because of an unsupported pixel config.
bsalomon@google.com669fdc42011-04-05 17:08:27 +0000525 */
bsalomon@google.com6f379512011-11-16 20:36:03 +0000526 bool readTexturePixels(GrTexture* texture,
bsalomon@google.com669fdc42011-04-05 17:08:27 +0000527 int left, int top, int width, int height,
bsalomon@google.com6f379512011-11-16 20:36:03 +0000528 GrPixelConfig config, void* buffer,
529 size_t rowBytes) {
530 return this->internalReadTexturePixels(texture, left, top,
531 width, height,
532 config, buffer, rowBytes, 0);
533 }
bsalomon@google.com27847de2011-02-22 20:59:41 +0000534
535 /**
bsalomon@google.com6f379512011-11-16 20:36:03 +0000536 * Writes a rectangle of pixels to a texture.
537 * @param texture the render target to read from.
538 * @param left left edge of the rectangle to write (inclusive)
539 * @param top top edge of the rectangle to write (inclusive)
540 * @param width width of rectangle to write in pixels.
541 * @param height height of rectangle to write in pixels.
542 * @param config the pixel config of the source buffer
543 * @param buffer memory to read pixels from
544 * @param rowBytes number of bytes bewtween consecutive rows. Zero
545 * means rows are tightly packed.
bsalomon@google.com27847de2011-02-22 20:59:41 +0000546 */
bsalomon@google.com6f379512011-11-16 20:36:03 +0000547 void writeTexturePixels(GrTexture* texture,
548 int left, int top, int width, int height,
549 GrPixelConfig config, const void* buffer,
550 size_t rowBytes) {
551 this->internalWriteTexturePixels(texture, left, top, width, height,
552 config, buffer, rowBytes, 0);
553 }
senorblanco@chromium.org027de5f2011-07-08 18:03:33 +0000554 /**
senorblanco@chromium.orgef843cd2011-12-02 19:11:17 +0000555 * Copies all texels from one texture to another.
556 * @param src the texture to copy from.
557 * @param dst the render target to copy to.
558 */
559 void copyTexture(GrTexture* src, GrRenderTarget* dst);
560 /**
senorblanco@chromium.orgaadd9f82011-07-12 19:44:51 +0000561 * Applies a 1D convolution kernel in the X direction to a rectangle of
562 * pixels from a given texture.
563 * @param texture the texture to read from
564 * @param rect the destination rectangle
senorblanco@chromium.org027de5f2011-07-08 18:03:33 +0000565 * @param kernel the convolution kernel (kernelWidth elements)
566 * @param kernelWidth the width of the convolution kernel
567 */
senorblanco@chromium.orgaadd9f82011-07-12 19:44:51 +0000568 void convolveInX(GrTexture* texture,
569 const SkRect& rect,
570 const float* kernel,
571 int kernelWidth);
572 /**
573 * Applies a 1D convolution kernel in the Y direction to a rectangle of
574 * pixels from a given texture.
575 * direction.
576 * @param texture the texture to read from
577 * @param rect the destination rectangle
578 * @param kernel the convolution kernel (kernelWidth elements)
579 * @param kernelWidth the width of the convolution kernel
580 */
581 void convolveInY(GrTexture* texture,
582 const SkRect& rect,
583 const float* kernel,
584 int kernelWidth);
bsalomon@google.com27847de2011-02-22 20:59:41 +0000585 ///////////////////////////////////////////////////////////////////////////
586 // Helpers
587
588 class AutoRenderTarget : ::GrNoncopyable {
589 public:
590 AutoRenderTarget(GrContext* context, GrRenderTarget* target) {
591 fContext = NULL;
592 fPrevTarget = context->getRenderTarget();
593 if (fPrevTarget != target) {
594 context->setRenderTarget(target);
595 fContext = context;
596 }
597 }
598 ~AutoRenderTarget() {
599 if (fContext) {
600 fContext->setRenderTarget(fPrevTarget);
601 }
602 }
603 private:
604 GrContext* fContext;
605 GrRenderTarget* fPrevTarget;
606 };
607
608
609 ///////////////////////////////////////////////////////////////////////////
610 // Functions intended for internal use only.
611 GrGpu* getGpu() { return fGpu; }
bsalomon@google.com1f221a72011-08-23 20:54:07 +0000612 const GrGpu* getGpu() const { return fGpu; }
bsalomon@google.com27847de2011-02-22 20:59:41 +0000613 GrFontCache* getFontCache() { return fFontCache; }
614 GrDrawTarget* getTextTarget(const GrPaint& paint);
615 void flushText();
616 const GrIndexBuffer* getQuadIndexBuffer() const;
bsalomon@google.com05ef5102011-05-02 21:14:59 +0000617 void resetStats();
618 const GrGpuStats& getStats() const;
619 void printStats() const;
bsalomon@google.com558a75b2011-08-08 17:01:14 +0000620 /**
621 * Stencil buffers add themselves to the cache using
622 * addAndLockStencilBuffer. When a SB's RT-attachment count
623 * reaches zero the SB unlocks itself using unlockStencilBuffer and is
624 * eligible for purging. findStencilBuffer is called to check the cache for
625 * a SB that matching an RT's criteria. If a match is found that has been
626 * unlocked (its attachment count has reached 0) then it will be relocked.
627 */
628 GrResourceEntry* addAndLockStencilBuffer(GrStencilBuffer* sb);
629 void unlockStencilBuffer(GrResourceEntry* sbEntry);
630 GrStencilBuffer* findStencilBuffer(int width, int height, int sampleCnt);
bsalomon@google.com27847de2011-02-22 20:59:41 +0000631
632private:
633 // used to keep track of when we need to flush the draw buffer
634 enum DrawCategory {
635 kBuffered_DrawCategory, // last draw was inserted in draw buffer
636 kUnbuffered_DrawCategory, // last draw was not inserted in the draw buffer
637 kText_DrawCategory // text context was last to draw
638 };
639 DrawCategory fLastDrawCategory;
640
bsalomon@google.com50398bf2011-07-26 20:45:30 +0000641 GrGpu* fGpu;
642 GrResourceCache* fTextureCache;
643 GrFontCache* fFontCache;
bsalomon@google.comdfe75bc2011-03-25 12:31:16 +0000644
bsalomon@google.com30085192011-08-19 15:42:31 +0000645 GrPathRendererChain* fPathRendererChain;
bsalomon@google.com27847de2011-02-22 20:59:41 +0000646
647 GrVertexBufferAllocPool* fDrawBufferVBAllocPool;
648 GrIndexBufferAllocPool* fDrawBufferIBAllocPool;
649 GrInOrderDrawBuffer* fDrawBuffer;
650
bsalomon@google.com205d4602011-04-25 12:43:45 +0000651 GrIndexBuffer* fAAFillRectIndexBuffer;
652 GrIndexBuffer* fAAStrokeRectIndexBuffer;
bsalomon@google.com91958362011-06-13 17:58:13 +0000653 int fMaxOffscreenAASize;
bsalomon@google.com205d4602011-04-25 12:43:45 +0000654
bsalomon@google.com27847de2011-02-22 20:59:41 +0000655 GrContext(GrGpu* gpu);
bsalomon@google.comdfe75bc2011-03-25 12:31:16 +0000656
bsalomon@google.com205d4602011-04-25 12:43:45 +0000657 void fillAARect(GrDrawTarget* target,
bsalomon@google.coma3108262011-10-10 14:08:47 +0000658 const GrRect& devRect,
659 bool useVertexCoverage);
bsalomon@google.com205d4602011-04-25 12:43:45 +0000660
661 void strokeAARect(GrDrawTarget* target,
bsalomon@google.com205d4602011-04-25 12:43:45 +0000662 const GrRect& devRect,
bsalomon@google.coma3108262011-10-10 14:08:47 +0000663 const GrVec& devStrokeSize,
664 bool useVertexCoverage);
bsalomon@google.com205d4602011-04-25 12:43:45 +0000665
666 inline int aaFillRectIndexCount() const;
667 GrIndexBuffer* aaFillRectIndexBuffer();
668
669 inline int aaStrokeRectIndexCount() const;
670 GrIndexBuffer* aaStrokeRectIndexBuffer();
671
bsalomon@google.com8fe72472011-03-30 21:26:44 +0000672 void setupDrawBuffer();
673
bsalomon@google.com27847de2011-02-22 20:59:41 +0000674 void flushDrawBuffer();
675
bsalomon@google.combc4b6542011-11-19 13:56:11 +0000676 void setPaint(const GrPaint& paint, GrDrawTarget* target);
bsalomon@google.com27847de2011-02-22 20:59:41 +0000677
bsalomon@google.com27847de2011-02-22 20:59:41 +0000678 GrDrawTarget* prepareToDraw(const GrPaint& paint, DrawCategory drawType);
679
bsalomon@google.com289533a2011-10-27 12:34:25 +0000680 GrPathRenderer* getPathRenderer(const GrPath& path,
681 GrPathFill fill,
682 bool antiAlias);
bsalomon@google.comdfe75bc2011-03-25 12:31:16 +0000683
bsalomon@google.com06afe7b2011-04-26 15:31:40 +0000684 struct OffscreenRecord;
bsalomon@google.com06afe7b2011-04-26 15:31:40 +0000685
bsalomon@google.com91958362011-06-13 17:58:13 +0000686 // determines whether offscreen AA should be applied
bsalomon@google.comd46e2422011-09-23 17:40:07 +0000687 bool doOffscreenAA(GrDrawTarget* target,
bsalomon@google.com471d4712011-08-23 15:45:25 +0000688 bool isHairLines) const;
bsalomon@google.com8295dc12011-05-02 12:53:34 +0000689
bsalomon@google.com91958362011-06-13 17:58:13 +0000690 // attempts to setup offscreen AA. All paint state must be transferred to
691 // target by the time this is called.
692 bool prepareForOffscreenAA(GrDrawTarget* target,
bsalomon@google.com06afe7b2011-04-26 15:31:40 +0000693 bool requireStencil,
bsalomon@google.com8295dc12011-05-02 12:53:34 +0000694 const GrIRect& boundRect,
tomhudson@google.comd22b6e42011-06-24 15:53:40 +0000695 GrPathRenderer* pr,
bsalomon@google.com06afe7b2011-04-26 15:31:40 +0000696 OffscreenRecord* record);
697
bsalomon@google.com91958362011-06-13 17:58:13 +0000698 // sets up target to draw coverage to the supersampled render target
699 void setupOffscreenAAPass1(GrDrawTarget* target,
700 const GrIRect& boundRect,
701 int tileX, int tileY,
702 OffscreenRecord* record);
703
bsalomon@google.com06afe7b2011-04-26 15:31:40 +0000704 // sets up target to sample coverage of supersampled render target back
705 // to the main render target using stage kOffscreenStage.
bsalomon@google.com91958362011-06-13 17:58:13 +0000706 void doOffscreenAAPass2(GrDrawTarget* target,
707 const GrPaint& paint,
708 const GrIRect& boundRect,
709 int tileX, int tileY,
710 OffscreenRecord* record);
711
712 // restored the draw target state and releases offscreen target to cache
tomhudson@google.comd22b6e42011-06-24 15:53:40 +0000713 void cleanupOffscreenAA(GrDrawTarget* target,
714 GrPathRenderer* pr,
715 OffscreenRecord* record);
senorblanco@chromium.orgaadd9f82011-07-12 19:44:51 +0000716
717 void convolve(GrTexture* texture,
718 const SkRect& rect,
719 float imageIncrement[2],
720 const float* kernel,
721 int kernelWidth);
bsalomon@google.com6f379512011-11-16 20:36:03 +0000722
723 /**
724 * Flags to the internal read/write pixels funcs
725 */
726 enum PixelOpsFlags {
727 kDontFlush_PixelOpsFlag = 0x1,
728 };
729
730 bool internalReadRenderTargetPixels(GrRenderTarget* target,
731 int left, int top,
732 int width, int height,
733 GrPixelConfig config, void* buffer,
734 size_t rowBytes, uint32_t flags);
735
736 void internalWriteRenderTargetPixels(GrRenderTarget* target,
737 int left, int top,
738 int width, int height,
739 GrPixelConfig, const void* buffer,
740 size_t rowBytes, uint32_t flags);
741
742 bool internalReadTexturePixels(GrTexture* texture,
743 int left, int top,
744 int width, int height,
745 GrPixelConfig config, void* buffer,
746 size_t rowBytes, uint32_t flags);
747
748 void internalWriteTexturePixels(GrTexture* texture,
749 int left, int top,
750 int width, int height,
751 GrPixelConfig config, const void* buffer,
752 size_t rowBytes, uint32_t flags);
753 // needed for access to internalWriteTexturePixels. TODO: make GrContext
754 // be a facade for an internal class. Then functions that are public on the
755 // internal class would have only be callable in src/gpu. The facade would
756 // only have to functions necessary for clients.
757 friend class GrAtlas;
758
bsalomon@google.com26c2d0a2011-05-17 20:15:30 +0000759 // computes vertex layout bits based on the paint. If paint expresses
760 // a texture for a stage, the stage coords will be bound to postitions
761 // unless hasTexCoords[s]==true in which case stage s's input coords
762 // are bound to tex coord index s. hasTexCoords == NULL is a shortcut
763 // for an array where all the values are false.
764 static int PaintStageVertexLayoutBits(
765 const GrPaint& paint,
766 const bool hasTexCoords[GrPaint::kTotalStages]);
767
bsalomon@google.com27847de2011-02-22 20:59:41 +0000768};
769
770/**
771 * Save/restore the view-matrix in the context.
772 */
773class GrAutoMatrix : GrNoncopyable {
774public:
bsalomon@google.com4f83be82011-09-12 13:52:51 +0000775 GrAutoMatrix() : fContext(NULL) {}
bsalomon@google.com27847de2011-02-22 20:59:41 +0000776 GrAutoMatrix(GrContext* ctx) : fContext(ctx) {
777 fMatrix = ctx->getMatrix();
778 }
779 GrAutoMatrix(GrContext* ctx, const GrMatrix& matrix) : fContext(ctx) {
780 fMatrix = ctx->getMatrix();
781 ctx->setMatrix(matrix);
782 }
bsalomon@google.com4f83be82011-09-12 13:52:51 +0000783 void set(GrContext* ctx) {
784 if (NULL != fContext) {
785 fContext->setMatrix(fMatrix);
786 }
787 fMatrix = ctx->getMatrix();
788 fContext = ctx;
789 }
790 void set(GrContext* ctx, const GrMatrix& matrix) {
791 if (NULL != fContext) {
792 fContext->setMatrix(fMatrix);
793 }
794 fMatrix = ctx->getMatrix();
795 ctx->setMatrix(matrix);
796 fContext = ctx;
797 }
bsalomon@google.com27847de2011-02-22 20:59:41 +0000798 ~GrAutoMatrix() {
bsalomon@google.com4f83be82011-09-12 13:52:51 +0000799 if (NULL != fContext) {
800 fContext->setMatrix(fMatrix);
801 }
bsalomon@google.com27847de2011-02-22 20:59:41 +0000802 }
803
804private:
805 GrContext* fContext;
806 GrMatrix fMatrix;
807};
808
senorblanco@chromium.orgaadd9f82011-07-12 19:44:51 +0000809/**
bsalomon@google.com50398bf2011-07-26 20:45:30 +0000810 * Gets and locks a scratch texture from a descriptor using
811 * either exact or approximate criteria. Unlocks texture in
812 * the destructor.
senorblanco@chromium.orgaadd9f82011-07-12 19:44:51 +0000813 */
bsalomon@google.com50398bf2011-07-26 20:45:30 +0000814class GrAutoScratchTexture : ::GrNoncopyable {
senorblanco@chromium.orgaadd9f82011-07-12 19:44:51 +0000815public:
bsalomon@google.com50398bf2011-07-26 20:45:30 +0000816 GrAutoScratchTexture()
817 : fContext(NULL) {
senorblanco@chromium.orgaadd9f82011-07-12 19:44:51 +0000818 }
bsalomon@google.com50398bf2011-07-26 20:45:30 +0000819
820 GrAutoScratchTexture(GrContext* context,
821 const GrTextureDesc& desc,
822 GrContext::ScratchTexMatch match =
823 GrContext::kApprox_ScratchTexMatch)
824 : fContext(NULL) {
825 this->set(context, desc, match);
826 }
827
828 ~GrAutoScratchTexture() {
829 if (NULL != fContext) {
senorblanco@chromium.orgaadd9f82011-07-12 19:44:51 +0000830 fContext->unlockTexture(fEntry);
831 }
832 }
bsalomon@google.com84223112011-07-14 14:45:44 +0000833
bsalomon@google.com50398bf2011-07-26 20:45:30 +0000834 GrTexture* set(GrContext* context,
835 const GrTextureDesc& desc,
836 GrContext::ScratchTexMatch match =
837 GrContext::kApprox_ScratchTexMatch) {
838 if (NULL != fContext) {
839 fContext->unlockTexture(fEntry);
840 }
841 fContext = context;
842 if (NULL != fContext) {
843 fEntry = fContext->lockScratchTexture(desc, match);
844 GrTexture* ret = fEntry.texture();
845 if (NULL == ret) {
846 fContext = NULL;
847 }
848 return ret;
849 } else {
850 return NULL;
851 }
852 }
853
854 GrTexture* texture() { return fEntry.texture(); }
senorblanco@chromium.orgaadd9f82011-07-12 19:44:51 +0000855private:
bsalomon@google.com50398bf2011-07-26 20:45:30 +0000856 GrContext* fContext;
857 GrContext::TextureCacheEntry fEntry;
senorblanco@chromium.orgaadd9f82011-07-12 19:44:51 +0000858};
859
bsalomon@google.com27847de2011-02-22 20:59:41 +0000860#endif
861