blob: 5b48c0b2bf12954e41143aae5b97c7ec5cb53579 [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 /**
111 * Search for an entry based on key and dimensions. If found, "lock" it and
112 * return it. The entry's texture() function will return NULL if not found.
113 * Must call be balanced with an unlockTexture() call.
114 */
115 TextureCacheEntry findAndLockTexture(TextureKey key,
116 int width,
117 int height,
118 const GrSamplerState&);
bsalomon@google.comfb309512011-11-30 14:13:48 +0000119 /**
120 * Determines whether a texture is in the cache. If the texture is found it
121 * will not be locked or returned. This call does not affect the priority of
122 * the texture for deletion.
123 */
124 bool isTextureInCache(TextureKey key,
125 int width,
126 int height,
127 const GrSamplerState&) const;
bsalomon@google.com27847de2011-02-22 20:59:41 +0000128
129 /**
130 * Create a new entry, based on the specified key and texture, and return
bsalomon@google.com50398bf2011-07-26 20:45:30 +0000131 * its "locked" entry. Must call be balanced with an unlockTexture() call.
bsalomon@google.com27847de2011-02-22 20:59:41 +0000132 */
bsalomon@google.com50398bf2011-07-26 20:45:30 +0000133 TextureCacheEntry createAndLockTexture(TextureKey key,
134 const GrSamplerState&,
135 const GrTextureDesc&,
136 void* srcData, size_t rowBytes);
137
138 /**
139 * Enum that determines how closely a returned scratch texture must match
140 * a provided GrTextureDesc.
141 */
142 enum ScratchTexMatch {
143 /**
144 * Finds a texture that exactly matches the descriptor.
145 */
146 kExact_ScratchTexMatch,
147 /**
148 * Finds a texture that approximately matches the descriptor. Will be
149 * at least as large in width and height as desc specifies. If desc
150 * specifies that texture is a render target then result will be a
151 * render target. If desc specifies a render target and doesn't set the
152 * no stencil flag then result will have a stencil. Format and aa level
153 * will always match.
154 */
155 kApprox_ScratchTexMatch
156 };
bsalomon@google.com27847de2011-02-22 20:59:41 +0000157
158 /**
bsalomon@google.comfea37b52011-04-25 15:51:06 +0000159 * Returns a texture matching the desc. It's contents are unknown. Subsequent
160 * requests with the same descriptor are not guaranteed to return the same
161 * texture. The same texture is guaranteed not be returned again until it is
bsalomon@google.com50398bf2011-07-26 20:45:30 +0000162 * unlocked. Must call be balanced with an unlockTexture() call.
bsalomon@google.coma39f4042011-04-26 13:18:16 +0000163 *
164 * Textures created by createAndLockTexture() hide the complications of
165 * tiling non-power-of-two textures on APIs that don't support this (e.g.
bsalomon@google.com50398bf2011-07-26 20:45:30 +0000166 * unextended GLES2). Tiling a npot texture created by lockScratchTexture on
bsalomon@google.coma39f4042011-04-26 13:18:16 +0000167 * such an API will create gaps in the tiling pattern. This includes clamp
168 * mode. (This may be addressed in a future update.)
bsalomon@google.comfea37b52011-04-25 15:51:06 +0000169 */
bsalomon@google.com50398bf2011-07-26 20:45:30 +0000170 TextureCacheEntry lockScratchTexture(const GrTextureDesc& desc, ScratchTexMatch match);
bsalomon@google.comb5b31682011-06-16 18:05:35 +0000171
172 /**
bsalomon@google.com27847de2011-02-22 20:59:41 +0000173 * When done with an entry, call unlockTexture(entry) on it, which returns
174 * it to the cache, where it may be purged.
175 */
bsalomon@google.com50398bf2011-07-26 20:45:30 +0000176 void unlockTexture(TextureCacheEntry entry);
bsalomon@google.com27847de2011-02-22 20:59:41 +0000177
178 /**
bsalomon@google.com27847de2011-02-22 20:59:41 +0000179 * Creates a texture that is outside the cache. Does not count against
180 * cache's budget.
181 */
bsalomon@google.comfea37b52011-04-25 15:51:06 +0000182 GrTexture* createUncachedTexture(const GrTextureDesc&,
bsalomon@google.com27847de2011-02-22 20:59:41 +0000183 void* srcData,
184 size_t rowBytes);
185
186 /**
187 * Returns true if the specified use of an indexed texture is supported.
188 */
bsalomon@google.com1f221a72011-08-23 20:54:07 +0000189 bool supportsIndex8PixelConfig(const GrSamplerState&,
190 int width,
191 int height) const;
bsalomon@google.com27847de2011-02-22 20:59:41 +0000192
193 /**
194 * Return the current texture cache limits.
195 *
196 * @param maxTextures If non-null, returns maximum number of textures that
197 * can be held in the cache.
198 * @param maxTextureBytes If non-null, returns maximum number of bytes of
199 * texture memory that can be held in the cache.
200 */
201 void getTextureCacheLimits(int* maxTextures, size_t* maxTextureBytes) const;
202
203 /**
204 * Specify the texture cache limits. If the current cache exceeds either
205 * of these, it will be purged (LRU) to keep the cache within these limits.
206 *
207 * @param maxTextures The maximum number of textures that can be held in
208 * the cache.
209 * @param maxTextureBytes The maximum number of bytes of texture memory
210 * that can be held in the cache.
211 */
212 void setTextureCacheLimits(int maxTextures, size_t maxTextureBytes);
213
214 /**
215 * Return the max width or height of a texture supported by the current gpu
216 */
bsalomon@google.com91958362011-06-13 17:58:13 +0000217 int getMaxTextureSize() const;
218
219 /**
220 * Return the max width or height of a render target supported by the
221 * current gpu
222 */
223 int getMaxRenderTargetSize() const;
bsalomon@google.com27847de2011-02-22 20:59:41 +0000224
225 ///////////////////////////////////////////////////////////////////////////
226 // Render targets
227
228 /**
bsalomon@google.com5877ffd2011-04-11 17:58:48 +0000229 * Sets the render target.
230 * @param target the render target to set. (should not be NULL.)
231 */
232 void setRenderTarget(GrRenderTarget* target);
233
234 /**
235 * Gets the current render target.
236 * @return the currently bound render target. Should never be NULL.
237 */
238 const GrRenderTarget* getRenderTarget() const;
239 GrRenderTarget* getRenderTarget();
240
241 ///////////////////////////////////////////////////////////////////////////
242 // Platform Surfaces
243
bsalomon@google.com5877ffd2011-04-11 17:58:48 +0000244 /**
bsalomon@google.come269f212011-11-07 13:29:52 +0000245 * Wraps an existing texture with a GrTexture object.
246 *
247 * OpenGL: if the object is a texture Gr may change its GL texture params
248 * when it is drawn.
249 *
250 * @param desc description of the object to create.
251 *
252 * @return GrTexture object or NULL on failure.
253 */
254 GrTexture* createPlatformTexture(const GrPlatformTextureDesc& desc);
255
256 /**
257 * Wraps an existing render target with a GrRenderTarget object. It is
258 * similar to createPlatformTexture but can be used to draw into surfaces
259 * that are not also textures (e.g. FBO 0 in OpenGL, or an MSAA buffer that
260 * the client will resolve to a texture).
261 *
262 * @param desc description of the object to create.
263 *
264 * @return GrTexture object or NULL on failure.
265 */
266 GrRenderTarget* createPlatformRenderTarget(
267 const GrPlatformRenderTargetDesc& desc);
268
269 /**
270 * This interface is depracted and will be removed in a future revision.
271 * Callers should use createPlatformTexture or createPlatformRenderTarget
272 * instead.
273 *
bsalomon@google.com5877ffd2011-04-11 17:58:48 +0000274 * Wraps an existing 3D API surface in a GrObject. desc.fFlags determines
275 * the type of object returned. If kIsTexture is set the returned object
276 * will be a GrTexture*. Otherwise, it will be a GrRenderTarget*. If both
277 * are set the render target object is accessible by
278 * GrTexture::asRenderTarget().
279 *
280 * GL: if the object is a texture Gr may change its GL texture parameters
281 * when it is drawn.
282 *
283 * @param desc description of the object to create.
284 * @return either a GrTexture* or GrRenderTarget* depending on desc. NULL
285 * on failure.
286 */
287 GrResource* createPlatformSurface(const GrPlatformSurfaceDesc& desc);
bsalomon@google.com50398bf2011-07-26 20:45:30 +0000288
bsalomon@google.com27847de2011-02-22 20:59:41 +0000289 ///////////////////////////////////////////////////////////////////////////
290 // Matrix state
291
292 /**
293 * Gets the current transformation matrix.
294 * @return the current matrix.
295 */
296 const GrMatrix& getMatrix() const;
297
298 /**
299 * Sets the transformation matrix.
300 * @param m the matrix to set.
301 */
302 void setMatrix(const GrMatrix& m);
303
304 /**
305 * Concats the current matrix. The passed matrix is applied before the
306 * current matrix.
307 * @param m the matrix to concat.
308 */
309 void concatMatrix(const GrMatrix& m) const;
310
311
312 ///////////////////////////////////////////////////////////////////////////
313 // Clip state
314 /**
315 * Gets the current clip.
316 * @return the current clip.
317 */
bsalomon@google.com05ef5102011-05-02 21:14:59 +0000318 const GrClip& getClip() const;
bsalomon@google.com27847de2011-02-22 20:59:41 +0000319
320 /**
321 * Sets the clip.
322 * @param clip the clip to set.
323 */
324 void setClip(const GrClip& clip);
325
326 /**
327 * Convenience method for setting the clip to a rect.
328 * @param rect the rect to set as the new clip.
329 */
330 void setClip(const GrIRect& rect);
331
332 ///////////////////////////////////////////////////////////////////////////
333 // Draws
334
335 /**
bsalomon@google.com6aa25c32011-04-27 19:55:29 +0000336 * Clear the entire or rect of the render target, ignoring any clips.
337 * @param rect the rect to clear or the whole thing if rect is NULL.
338 * @param color the color to clear to.
bsalomon@google.com27847de2011-02-22 20:59:41 +0000339 */
bsalomon@google.com6aa25c32011-04-27 19:55:29 +0000340 void clear(const GrIRect* rect, GrColor color);
bsalomon@google.com27847de2011-02-22 20:59:41 +0000341
342 /**
343 * Draw everywhere (respecting the clip) with the paint.
344 */
345 void drawPaint(const GrPaint& paint);
346
347 /**
348 * Draw the rect using a paint.
349 * @param paint describes how to color pixels.
350 * @param strokeWidth If strokeWidth < 0, then the rect is filled, else
351 * the rect is mitered stroked based on strokeWidth. If
352 * strokeWidth == 0, then the stroke is always a single
353 * pixel thick.
354 * @param matrix Optional matrix applied to the rect. Applied before
355 * context's matrix or the paint's matrix.
356 * The rects coords are used to access the paint (through texture matrix)
357 */
358 void drawRect(const GrPaint& paint,
359 const GrRect&,
360 GrScalar strokeWidth = -1,
361 const GrMatrix* matrix = NULL);
362
363 /**
364 * Maps a rect of paint coordinates onto the a rect of destination
365 * coordinates. Each rect can optionally be transformed. The srcRect
366 * is stretched over the dstRect. The dstRect is transformed by the
367 * context's matrix and the srcRect is transformed by the paint's matrix.
368 * Additional optional matrices can be provided by parameters.
369 *
370 * @param paint describes how to color pixels.
371 * @param dstRect the destination rect to draw.
372 * @param srcRect rect of paint coordinates to be mapped onto dstRect
373 * @param dstMatrix Optional matrix to transform dstRect. Applied before
374 * context's matrix.
375 * @param srcMatrix Optional matrix to transform srcRect Applied before
376 * paint's matrix.
377 */
378 void drawRectToRect(const GrPaint& paint,
379 const GrRect& dstRect,
380 const GrRect& srcRect,
381 const GrMatrix* dstMatrix = NULL,
382 const GrMatrix* srcMatrix = NULL);
383
384 /**
bsalomon@google.comd302f142011-03-03 13:54:13 +0000385 * Draws a path.
bsalomon@google.com27847de2011-02-22 20:59:41 +0000386 *
387 * @param paint describes how to color pixels.
reed@google.com07f3ee12011-05-16 17:21:57 +0000388 * @param path the path to draw
bsalomon@google.com27847de2011-02-22 20:59:41 +0000389 * @param fill the path filling rule to use.
390 * @param translate optional additional translation applied to the
391 * path.
392 */
reed@google.com07f3ee12011-05-16 17:21:57 +0000393 void drawPath(const GrPaint& paint, const GrPath& path, GrPathFill fill,
bsalomon@google.comd302f142011-03-03 13:54:13 +0000394 const GrPoint* translate = NULL);
reed@google.com07f3ee12011-05-16 17:21:57 +0000395
bsalomon@google.com27847de2011-02-22 20:59:41 +0000396 /**
397 * Draws vertices with a paint.
398 *
399 * @param paint describes how to color pixels.
400 * @param primitiveType primitives type to draw.
401 * @param vertexCount number of vertices.
402 * @param positions array of vertex positions, required.
403 * @param texCoords optional array of texture coordinates used
404 * to access the paint.
405 * @param colors optional array of per-vertex colors, supercedes
406 * the paint's color field.
407 * @param indices optional array of indices. If NULL vertices
408 * are drawn non-indexed.
409 * @param indexCount if indices is non-null then this is the
410 * number of indices.
411 */
412 void drawVertices(const GrPaint& paint,
413 GrPrimitiveType primitiveType,
414 int vertexCount,
415 const GrPoint positions[],
416 const GrPoint texs[],
417 const GrColor colors[],
418 const uint16_t indices[],
419 int indexCount);
420
bsalomon@google.com27847de2011-02-22 20:59:41 +0000421 ///////////////////////////////////////////////////////////////////////////
422 // Misc.
423
424 /**
bsalomon@google.com1f221a72011-08-23 20:54:07 +0000425 * Currently needed by SkGpuDevice. Ideally this shouldn't be exposed.
426 */
427 bool supportsShaders() const;
428
429 /**
bsalomon@google.coma7f84e12011-03-10 14:13:19 +0000430 * Flags that affect flush() behavior.
431 */
432 enum FlushBits {
433 /**
434 * A client may want Gr to bind a GrRenderTarget in the 3D API so that
435 * it can be rendered to directly. However, Gr lazily sets state. Simply
436 * calling setRenderTarget() followed by flush() without flags may not
437 * bind the render target. This flag forces the context to bind the last
438 * set render target in the 3D API.
439 */
440 kForceCurrentRenderTarget_FlushBit = 0x1,
441 /**
442 * A client may reach a point where it has partially rendered a frame
443 * through a GrContext that it knows the user will never see. This flag
444 * causes the flush to skip submission of deferred content to the 3D API
445 * during the flush.
446 */
447 kDiscard_FlushBit = 0x2,
448 };
449
450 /**
bsalomon@google.com27847de2011-02-22 20:59:41 +0000451 * Call to ensure all drawing to the context has been issued to the
452 * underlying 3D API.
bsalomon@google.coma7f84e12011-03-10 14:13:19 +0000453 * @param flagsBitfield flags that control the flushing behavior. See
454 * FlushBits.
bsalomon@google.com27847de2011-02-22 20:59:41 +0000455 */
bsalomon@google.com8fe72472011-03-30 21:26:44 +0000456 void flush(int flagsBitfield = 0);
bsalomon@google.com6f379512011-11-16 20:36:03 +0000457
bsalomon@google.com27847de2011-02-22 20:59:41 +0000458 /**
bsalomon@google.com669fdc42011-04-05 17:08:27 +0000459 * Reads a rectangle of pixels from a render target.
bsalomon@google.com6f379512011-11-16 20:36:03 +0000460 * @param target the render target to read from. NULL means the
bsalomon@google.com669fdc42011-04-05 17:08:27 +0000461 * current render target.
462 * @param left left edge of the rectangle to read (inclusive)
463 * @param top top edge of the rectangle to read (inclusive)
464 * @param width width of rectangle to read in pixels.
465 * @param height height of rectangle to read in pixels.
466 * @param config the pixel config of the destination buffer
467 * @param buffer memory to read the rectangle into.
bsalomon@google.com6f379512011-11-16 20:36:03 +0000468 * @param rowBytes number of bytes bewtween consecutive rows. Zero
bsalomon@google.comc6980972011-11-02 19:57:21 +0000469 * means rows are tightly packed.
bsalomon@google.com669fdc42011-04-05 17:08:27 +0000470 *
471 * @return true if the read succeeded, false if not. The read can fail
bsalomon@google.com6f379512011-11-16 20:36:03 +0000472 * because of an unsupported pixel config or because no render
bsalomon@google.com669fdc42011-04-05 17:08:27 +0000473 * target is currently set.
bsalomon@google.com27847de2011-02-22 20:59:41 +0000474 */
bsalomon@google.com669fdc42011-04-05 17:08:27 +0000475 bool readRenderTargetPixels(GrRenderTarget* target,
476 int left, int top, int width, int height,
bsalomon@google.comc6980972011-11-02 19:57:21 +0000477 GrPixelConfig config, void* buffer,
bsalomon@google.com6f379512011-11-16 20:36:03 +0000478 size_t rowBytes) {
479 return this->internalReadRenderTargetPixels(target, left, top,
480 width, height,
481 config, buffer,
482 rowBytes, 0);
483 }
484
485 /**
486 * Copy the src pixels [buffer, rowbytes, pixelconfig] into a render target
487 * at the specified rectangle.
488 * @param target the render target to write into. NULL means the
489 * current render target.
490 * @param left left edge of the rectangle to write (inclusive)
491 * @param top top edge of the rectangle to write (inclusive)
492 * @param width width of rectangle to write in pixels.
493 * @param height height of rectangle to write in pixels.
494 * @param config the pixel config of the source buffer
495 * @param buffer memory to read the rectangle from.
496 * @param rowBytes number of bytes bewtween consecutive rows. Zero
497 * means rows are tightly packed.
498 */
499 void writeRenderTargetPixels(GrRenderTarget* target,
500 int left, int top, int width, int height,
501 GrPixelConfig config, const void* buffer,
502 size_t rowBytes) {
503 this->internalWriteRenderTargetPixels(target, left, top, width, height,
504 config, buffer, rowBytes, 0);
505 }
bsalomon@google.com669fdc42011-04-05 17:08:27 +0000506
507 /**
508 * Reads a rectangle of pixels from a texture.
bsalomon@google.com6f379512011-11-16 20:36:03 +0000509 * @param texture the texture to read from.
bsalomon@google.com669fdc42011-04-05 17:08:27 +0000510 * @param left left edge of the rectangle to read (inclusive)
511 * @param top top edge of the rectangle to read (inclusive)
512 * @param width width of rectangle to read in pixels.
513 * @param height height of rectangle to read in pixels.
514 * @param config the pixel config of the destination buffer
515 * @param buffer memory to read the rectangle into.
bsalomon@google.com6f379512011-11-16 20:36:03 +0000516 * @param rowBytes number of bytes bewtween consecutive rows. Zero
517 * means rows are tightly packed.
bsalomon@google.com669fdc42011-04-05 17:08:27 +0000518 *
519 * @return true if the read succeeded, false if not. The read can fail
bsalomon@google.com6f379512011-11-16 20:36:03 +0000520 * because of an unsupported pixel config.
bsalomon@google.com669fdc42011-04-05 17:08:27 +0000521 */
bsalomon@google.com6f379512011-11-16 20:36:03 +0000522 bool readTexturePixels(GrTexture* texture,
bsalomon@google.com669fdc42011-04-05 17:08:27 +0000523 int left, int top, int width, int height,
bsalomon@google.com6f379512011-11-16 20:36:03 +0000524 GrPixelConfig config, void* buffer,
525 size_t rowBytes) {
526 return this->internalReadTexturePixels(texture, left, top,
527 width, height,
528 config, buffer, rowBytes, 0);
529 }
bsalomon@google.com27847de2011-02-22 20:59:41 +0000530
531 /**
bsalomon@google.com6f379512011-11-16 20:36:03 +0000532 * Writes a rectangle of pixels to a texture.
533 * @param texture the render target to read from.
534 * @param left left edge of the rectangle to write (inclusive)
535 * @param top top edge of the rectangle to write (inclusive)
536 * @param width width of rectangle to write in pixels.
537 * @param height height of rectangle to write in pixels.
538 * @param config the pixel config of the source buffer
539 * @param buffer memory to read pixels from
540 * @param rowBytes number of bytes bewtween consecutive rows. Zero
541 * means rows are tightly packed.
bsalomon@google.com27847de2011-02-22 20:59:41 +0000542 */
bsalomon@google.com6f379512011-11-16 20:36:03 +0000543 void writeTexturePixels(GrTexture* texture,
544 int left, int top, int width, int height,
545 GrPixelConfig config, const void* buffer,
546 size_t rowBytes) {
547 this->internalWriteTexturePixels(texture, left, top, width, height,
548 config, buffer, rowBytes, 0);
549 }
senorblanco@chromium.org027de5f2011-07-08 18:03:33 +0000550 /**
senorblanco@chromium.orgef843cd2011-12-02 19:11:17 +0000551 * Copies all texels from one texture to another.
552 * @param src the texture to copy from.
553 * @param dst the render target to copy to.
554 */
555 void copyTexture(GrTexture* src, GrRenderTarget* dst);
556 /**
senorblanco@chromium.orgaadd9f82011-07-12 19:44:51 +0000557 * Applies a 1D convolution kernel in the X direction to a rectangle of
558 * pixels from a given texture.
559 * @param texture the texture to read from
560 * @param rect the destination rectangle
senorblanco@chromium.org027de5f2011-07-08 18:03:33 +0000561 * @param kernel the convolution kernel (kernelWidth elements)
562 * @param kernelWidth the width of the convolution kernel
563 */
senorblanco@chromium.orgaadd9f82011-07-12 19:44:51 +0000564 void convolveInX(GrTexture* texture,
565 const SkRect& rect,
566 const float* kernel,
567 int kernelWidth);
568 /**
569 * Applies a 1D convolution kernel in the Y direction to a rectangle of
570 * pixels from a given texture.
571 * direction.
572 * @param texture the texture to read from
573 * @param rect the destination rectangle
574 * @param kernel the convolution kernel (kernelWidth elements)
575 * @param kernelWidth the width of the convolution kernel
576 */
577 void convolveInY(GrTexture* texture,
578 const SkRect& rect,
579 const float* kernel,
580 int kernelWidth);
bsalomon@google.com27847de2011-02-22 20:59:41 +0000581 ///////////////////////////////////////////////////////////////////////////
582 // Helpers
583
584 class AutoRenderTarget : ::GrNoncopyable {
585 public:
586 AutoRenderTarget(GrContext* context, GrRenderTarget* target) {
587 fContext = NULL;
588 fPrevTarget = context->getRenderTarget();
589 if (fPrevTarget != target) {
590 context->setRenderTarget(target);
591 fContext = context;
592 }
593 }
594 ~AutoRenderTarget() {
595 if (fContext) {
596 fContext->setRenderTarget(fPrevTarget);
597 }
598 }
599 private:
600 GrContext* fContext;
601 GrRenderTarget* fPrevTarget;
602 };
603
604
605 ///////////////////////////////////////////////////////////////////////////
606 // Functions intended for internal use only.
607 GrGpu* getGpu() { return fGpu; }
bsalomon@google.com1f221a72011-08-23 20:54:07 +0000608 const GrGpu* getGpu() const { return fGpu; }
bsalomon@google.com27847de2011-02-22 20:59:41 +0000609 GrFontCache* getFontCache() { return fFontCache; }
610 GrDrawTarget* getTextTarget(const GrPaint& paint);
611 void flushText();
612 const GrIndexBuffer* getQuadIndexBuffer() const;
bsalomon@google.com05ef5102011-05-02 21:14:59 +0000613 void resetStats();
614 const GrGpuStats& getStats() const;
615 void printStats() const;
bsalomon@google.com558a75b2011-08-08 17:01:14 +0000616 /**
617 * Stencil buffers add themselves to the cache using
618 * addAndLockStencilBuffer. When a SB's RT-attachment count
619 * reaches zero the SB unlocks itself using unlockStencilBuffer and is
620 * eligible for purging. findStencilBuffer is called to check the cache for
621 * a SB that matching an RT's criteria. If a match is found that has been
622 * unlocked (its attachment count has reached 0) then it will be relocked.
623 */
624 GrResourceEntry* addAndLockStencilBuffer(GrStencilBuffer* sb);
625 void unlockStencilBuffer(GrResourceEntry* sbEntry);
626 GrStencilBuffer* findStencilBuffer(int width, int height, int sampleCnt);
bsalomon@google.com27847de2011-02-22 20:59:41 +0000627
628private:
629 // used to keep track of when we need to flush the draw buffer
630 enum DrawCategory {
631 kBuffered_DrawCategory, // last draw was inserted in draw buffer
632 kUnbuffered_DrawCategory, // last draw was not inserted in the draw buffer
633 kText_DrawCategory // text context was last to draw
634 };
635 DrawCategory fLastDrawCategory;
636
bsalomon@google.com50398bf2011-07-26 20:45:30 +0000637 GrGpu* fGpu;
638 GrResourceCache* fTextureCache;
639 GrFontCache* fFontCache;
bsalomon@google.comdfe75bc2011-03-25 12:31:16 +0000640
bsalomon@google.com30085192011-08-19 15:42:31 +0000641 GrPathRendererChain* fPathRendererChain;
bsalomon@google.com27847de2011-02-22 20:59:41 +0000642
643 GrVertexBufferAllocPool* fDrawBufferVBAllocPool;
644 GrIndexBufferAllocPool* fDrawBufferIBAllocPool;
645 GrInOrderDrawBuffer* fDrawBuffer;
646
bsalomon@google.com205d4602011-04-25 12:43:45 +0000647 GrIndexBuffer* fAAFillRectIndexBuffer;
648 GrIndexBuffer* fAAStrokeRectIndexBuffer;
bsalomon@google.com91958362011-06-13 17:58:13 +0000649 int fMaxOffscreenAASize;
bsalomon@google.com205d4602011-04-25 12:43:45 +0000650
bsalomon@google.com27847de2011-02-22 20:59:41 +0000651 GrContext(GrGpu* gpu);
bsalomon@google.comdfe75bc2011-03-25 12:31:16 +0000652
bsalomon@google.com205d4602011-04-25 12:43:45 +0000653 void fillAARect(GrDrawTarget* target,
bsalomon@google.coma3108262011-10-10 14:08:47 +0000654 const GrRect& devRect,
655 bool useVertexCoverage);
bsalomon@google.com205d4602011-04-25 12:43:45 +0000656
657 void strokeAARect(GrDrawTarget* target,
bsalomon@google.com205d4602011-04-25 12:43:45 +0000658 const GrRect& devRect,
bsalomon@google.coma3108262011-10-10 14:08:47 +0000659 const GrVec& devStrokeSize,
660 bool useVertexCoverage);
bsalomon@google.com205d4602011-04-25 12:43:45 +0000661
662 inline int aaFillRectIndexCount() const;
663 GrIndexBuffer* aaFillRectIndexBuffer();
664
665 inline int aaStrokeRectIndexCount() const;
666 GrIndexBuffer* aaStrokeRectIndexBuffer();
667
bsalomon@google.com8fe72472011-03-30 21:26:44 +0000668 void setupDrawBuffer();
669
bsalomon@google.com27847de2011-02-22 20:59:41 +0000670 void flushDrawBuffer();
671
bsalomon@google.combc4b6542011-11-19 13:56:11 +0000672 void setPaint(const GrPaint& paint, GrDrawTarget* target);
bsalomon@google.com27847de2011-02-22 20:59:41 +0000673
bsalomon@google.com27847de2011-02-22 20:59:41 +0000674 GrDrawTarget* prepareToDraw(const GrPaint& paint, DrawCategory drawType);
675
bsalomon@google.com289533a2011-10-27 12:34:25 +0000676 GrPathRenderer* getPathRenderer(const GrPath& path,
677 GrPathFill fill,
678 bool antiAlias);
bsalomon@google.comdfe75bc2011-03-25 12:31:16 +0000679
bsalomon@google.com06afe7b2011-04-26 15:31:40 +0000680 struct OffscreenRecord;
bsalomon@google.com06afe7b2011-04-26 15:31:40 +0000681
bsalomon@google.com91958362011-06-13 17:58:13 +0000682 // determines whether offscreen AA should be applied
bsalomon@google.comd46e2422011-09-23 17:40:07 +0000683 bool doOffscreenAA(GrDrawTarget* target,
bsalomon@google.com471d4712011-08-23 15:45:25 +0000684 bool isHairLines) const;
bsalomon@google.com8295dc12011-05-02 12:53:34 +0000685
bsalomon@google.com91958362011-06-13 17:58:13 +0000686 // attempts to setup offscreen AA. All paint state must be transferred to
687 // target by the time this is called.
688 bool prepareForOffscreenAA(GrDrawTarget* target,
bsalomon@google.com06afe7b2011-04-26 15:31:40 +0000689 bool requireStencil,
bsalomon@google.com8295dc12011-05-02 12:53:34 +0000690 const GrIRect& boundRect,
tomhudson@google.comd22b6e42011-06-24 15:53:40 +0000691 GrPathRenderer* pr,
bsalomon@google.com06afe7b2011-04-26 15:31:40 +0000692 OffscreenRecord* record);
693
bsalomon@google.com91958362011-06-13 17:58:13 +0000694 // sets up target to draw coverage to the supersampled render target
695 void setupOffscreenAAPass1(GrDrawTarget* target,
696 const GrIRect& boundRect,
697 int tileX, int tileY,
698 OffscreenRecord* record);
699
bsalomon@google.com06afe7b2011-04-26 15:31:40 +0000700 // sets up target to sample coverage of supersampled render target back
701 // to the main render target using stage kOffscreenStage.
bsalomon@google.com91958362011-06-13 17:58:13 +0000702 void doOffscreenAAPass2(GrDrawTarget* target,
703 const GrPaint& paint,
704 const GrIRect& boundRect,
705 int tileX, int tileY,
706 OffscreenRecord* record);
707
708 // restored the draw target state and releases offscreen target to cache
tomhudson@google.comd22b6e42011-06-24 15:53:40 +0000709 void cleanupOffscreenAA(GrDrawTarget* target,
710 GrPathRenderer* pr,
711 OffscreenRecord* record);
senorblanco@chromium.orgaadd9f82011-07-12 19:44:51 +0000712
713 void convolve(GrTexture* texture,
714 const SkRect& rect,
715 float imageIncrement[2],
716 const float* kernel,
717 int kernelWidth);
bsalomon@google.com6f379512011-11-16 20:36:03 +0000718
719 /**
720 * Flags to the internal read/write pixels funcs
721 */
722 enum PixelOpsFlags {
723 kDontFlush_PixelOpsFlag = 0x1,
724 };
725
726 bool internalReadRenderTargetPixels(GrRenderTarget* target,
727 int left, int top,
728 int width, int height,
729 GrPixelConfig config, void* buffer,
730 size_t rowBytes, uint32_t flags);
731
732 void internalWriteRenderTargetPixels(GrRenderTarget* target,
733 int left, int top,
734 int width, int height,
735 GrPixelConfig, const void* buffer,
736 size_t rowBytes, uint32_t flags);
737
738 bool internalReadTexturePixels(GrTexture* texture,
739 int left, int top,
740 int width, int height,
741 GrPixelConfig config, void* buffer,
742 size_t rowBytes, uint32_t flags);
743
744 void internalWriteTexturePixels(GrTexture* texture,
745 int left, int top,
746 int width, int height,
747 GrPixelConfig config, const void* buffer,
748 size_t rowBytes, uint32_t flags);
749 // needed for access to internalWriteTexturePixels. TODO: make GrContext
750 // be a facade for an internal class. Then functions that are public on the
751 // internal class would have only be callable in src/gpu. The facade would
752 // only have to functions necessary for clients.
753 friend class GrAtlas;
754
bsalomon@google.com26c2d0a2011-05-17 20:15:30 +0000755 // computes vertex layout bits based on the paint. If paint expresses
756 // a texture for a stage, the stage coords will be bound to postitions
757 // unless hasTexCoords[s]==true in which case stage s's input coords
758 // are bound to tex coord index s. hasTexCoords == NULL is a shortcut
759 // for an array where all the values are false.
760 static int PaintStageVertexLayoutBits(
761 const GrPaint& paint,
762 const bool hasTexCoords[GrPaint::kTotalStages]);
763
bsalomon@google.com27847de2011-02-22 20:59:41 +0000764};
765
766/**
767 * Save/restore the view-matrix in the context.
768 */
769class GrAutoMatrix : GrNoncopyable {
770public:
bsalomon@google.com4f83be82011-09-12 13:52:51 +0000771 GrAutoMatrix() : fContext(NULL) {}
bsalomon@google.com27847de2011-02-22 20:59:41 +0000772 GrAutoMatrix(GrContext* ctx) : fContext(ctx) {
773 fMatrix = ctx->getMatrix();
774 }
775 GrAutoMatrix(GrContext* ctx, const GrMatrix& matrix) : fContext(ctx) {
776 fMatrix = ctx->getMatrix();
777 ctx->setMatrix(matrix);
778 }
bsalomon@google.com4f83be82011-09-12 13:52:51 +0000779 void set(GrContext* ctx) {
780 if (NULL != fContext) {
781 fContext->setMatrix(fMatrix);
782 }
783 fMatrix = ctx->getMatrix();
784 fContext = ctx;
785 }
786 void set(GrContext* ctx, const GrMatrix& matrix) {
787 if (NULL != fContext) {
788 fContext->setMatrix(fMatrix);
789 }
790 fMatrix = ctx->getMatrix();
791 ctx->setMatrix(matrix);
792 fContext = ctx;
793 }
bsalomon@google.com27847de2011-02-22 20:59:41 +0000794 ~GrAutoMatrix() {
bsalomon@google.com4f83be82011-09-12 13:52:51 +0000795 if (NULL != fContext) {
796 fContext->setMatrix(fMatrix);
797 }
bsalomon@google.com27847de2011-02-22 20:59:41 +0000798 }
799
800private:
801 GrContext* fContext;
802 GrMatrix fMatrix;
803};
804
senorblanco@chromium.orgaadd9f82011-07-12 19:44:51 +0000805/**
bsalomon@google.com50398bf2011-07-26 20:45:30 +0000806 * Gets and locks a scratch texture from a descriptor using
807 * either exact or approximate criteria. Unlocks texture in
808 * the destructor.
senorblanco@chromium.orgaadd9f82011-07-12 19:44:51 +0000809 */
bsalomon@google.com50398bf2011-07-26 20:45:30 +0000810class GrAutoScratchTexture : ::GrNoncopyable {
senorblanco@chromium.orgaadd9f82011-07-12 19:44:51 +0000811public:
bsalomon@google.com50398bf2011-07-26 20:45:30 +0000812 GrAutoScratchTexture()
813 : fContext(NULL) {
senorblanco@chromium.orgaadd9f82011-07-12 19:44:51 +0000814 }
bsalomon@google.com50398bf2011-07-26 20:45:30 +0000815
816 GrAutoScratchTexture(GrContext* context,
817 const GrTextureDesc& desc,
818 GrContext::ScratchTexMatch match =
819 GrContext::kApprox_ScratchTexMatch)
820 : fContext(NULL) {
821 this->set(context, desc, match);
822 }
823
824 ~GrAutoScratchTexture() {
825 if (NULL != fContext) {
senorblanco@chromium.orgaadd9f82011-07-12 19:44:51 +0000826 fContext->unlockTexture(fEntry);
827 }
828 }
bsalomon@google.com84223112011-07-14 14:45:44 +0000829
bsalomon@google.com50398bf2011-07-26 20:45:30 +0000830 GrTexture* set(GrContext* context,
831 const GrTextureDesc& desc,
832 GrContext::ScratchTexMatch match =
833 GrContext::kApprox_ScratchTexMatch) {
834 if (NULL != fContext) {
835 fContext->unlockTexture(fEntry);
836 }
837 fContext = context;
838 if (NULL != fContext) {
839 fEntry = fContext->lockScratchTexture(desc, match);
840 GrTexture* ret = fEntry.texture();
841 if (NULL == ret) {
842 fContext = NULL;
843 }
844 return ret;
845 } else {
846 return NULL;
847 }
848 }
849
850 GrTexture* texture() { return fEntry.texture(); }
senorblanco@chromium.orgaadd9f82011-07-12 19:44:51 +0000851private:
bsalomon@google.com50398bf2011-07-26 20:45:30 +0000852 GrContext* fContext;
853 GrContext::TextureCacheEntry fEntry;
senorblanco@chromium.orgaadd9f82011-07-12 19:44:51 +0000854};
855
bsalomon@google.com27847de2011-02-22 20:59:41 +0000856#endif
857