|
1 /* |
|
2 * Copyright 2010 Google Inc. |
|
3 * |
|
4 * Use of this source code is governed by a BSD-style license that can be |
|
5 * found in the LICENSE file. |
|
6 */ |
|
7 |
|
8 #ifndef GrContext_DEFINED |
|
9 #define GrContext_DEFINED |
|
10 |
|
11 #include "GrClipData.h" |
|
12 #include "GrColor.h" |
|
13 #include "GrPaint.h" |
|
14 #include "GrPathRendererChain.h" |
|
15 #include "GrPoint.h" |
|
16 #include "GrRenderTarget.h" |
|
17 #include "GrTexture.h" |
|
18 #include "SkMatrix.h" |
|
19 #include "SkTypes.h" |
|
20 |
|
21 class GrAARectRenderer; |
|
22 class GrAutoScratchTexture; |
|
23 class GrDrawState; |
|
24 class GrDrawTarget; |
|
25 class GrEffect; |
|
26 class GrFontCache; |
|
27 class GrGpu; |
|
28 class GrIndexBuffer; |
|
29 class GrIndexBufferAllocPool; |
|
30 class GrInOrderDrawBuffer; |
|
31 class GrOvalRenderer; |
|
32 class GrPath; |
|
33 class GrPathRenderer; |
|
34 class GrResourceEntry; |
|
35 class GrResourceCache; |
|
36 class GrStencilBuffer; |
|
37 class GrTestTarget; |
|
38 class GrTextureParams; |
|
39 class GrVertexBuffer; |
|
40 class GrVertexBufferAllocPool; |
|
41 class GrSoftwarePathRenderer; |
|
42 class SkStrokeRec; |
|
43 |
|
44 class SK_API GrContext : public SkRefCnt { |
|
45 public: |
|
46 SK_DECLARE_INST_COUNT(GrContext) |
|
47 |
|
48 /** |
|
49 * Creates a GrContext for a backend context. |
|
50 */ |
|
51 static GrContext* Create(GrBackend, GrBackendContext); |
|
52 |
|
53 virtual ~GrContext(); |
|
54 |
|
55 /** |
|
56 * The GrContext normally assumes that no outsider is setting state |
|
57 * within the underlying 3D API's context/device/whatever. This call informs |
|
58 * the context that the state was modified and it should resend. Shouldn't |
|
59 * be called frequently for good performance. |
|
60 * The flag bits, state, is dpendent on which backend is used by the |
|
61 * context, either GL or D3D (possible in future). |
|
62 */ |
|
63 void resetContext(uint32_t state = kAll_GrBackendState); |
|
64 |
|
65 /** |
|
66 * Callback function to allow classes to cleanup on GrContext destruction. |
|
67 * The 'info' field is filled in with the 'info' passed to addCleanUp. |
|
68 */ |
|
69 typedef void (*PFCleanUpFunc)(const GrContext* context, void* info); |
|
70 |
|
71 /** |
|
72 * Add a function to be called from within GrContext's destructor. |
|
73 * This gives classes a chance to free resources held on a per context basis. |
|
74 * The 'info' parameter will be stored and passed to the callback function. |
|
75 */ |
|
76 void addCleanUp(PFCleanUpFunc cleanUp, void* info) { |
|
77 CleanUpData* entry = fCleanUpData.push(); |
|
78 |
|
79 entry->fFunc = cleanUp; |
|
80 entry->fInfo = info; |
|
81 } |
|
82 |
|
83 /** |
|
84 * Abandons all GPU resources, assumes 3D API state is unknown. Call this |
|
85 * if you have lost the associated GPU context, and thus internal texture, |
|
86 * buffer, etc. references/IDs are now invalid. Should be called even when |
|
87 * GrContext is no longer going to be used for two reasons: |
|
88 * 1) ~GrContext will not try to free the objects in the 3D API. |
|
89 * 2) If you've created GrResources that outlive the GrContext they will |
|
90 * be marked as invalid (GrResource::isValid()) and won't attempt to |
|
91 * free their underlying resource in the 3D API. |
|
92 * Content drawn since the last GrContext::flush() may be lost. |
|
93 */ |
|
94 void contextLost(); |
|
95 |
|
96 /** |
|
97 * Similar to contextLost, but makes no attempt to reset state. |
|
98 * Use this method when GrContext destruction is pending, but |
|
99 * the graphics context is destroyed first. |
|
100 */ |
|
101 void contextDestroyed(); |
|
102 |
|
103 /** |
|
104 * Frees GPU created by the context. Can be called to reduce GPU memory |
|
105 * pressure. |
|
106 */ |
|
107 void freeGpuResources(); |
|
108 |
|
109 /** |
|
110 * Returns the number of bytes of GPU memory hosted by the texture cache. |
|
111 */ |
|
112 size_t getGpuTextureCacheBytes() const; |
|
113 |
|
114 /////////////////////////////////////////////////////////////////////////// |
|
115 // Textures |
|
116 |
|
117 /** |
|
118 * Creates a new entry, based on the specified key and texture and returns it. The caller owns a |
|
119 * ref on the returned texture which must be balanced by a call to unref. |
|
120 * |
|
121 * @param params The texture params used to draw a texture may help determine |
|
122 * the cache entry used. (e.g. different versions may exist |
|
123 * for different wrap modes on GPUs with limited NPOT |
|
124 * texture support). NULL implies clamp wrap modes. |
|
125 * @param desc Description of the texture properties. |
|
126 * @param cacheID Cache-specific properties (e.g., texture gen ID) |
|
127 * @param srcData Pointer to the pixel values. |
|
128 * @param rowBytes The number of bytes between rows of the texture. Zero |
|
129 * implies tightly packed rows. |
|
130 * @param cacheKey (optional) If non-NULL, we'll write the cache key we used to cacheKey. |
|
131 */ |
|
132 GrTexture* createTexture(const GrTextureParams* params, |
|
133 const GrTextureDesc& desc, |
|
134 const GrCacheID& cacheID, |
|
135 void* srcData, |
|
136 size_t rowBytes, |
|
137 GrResourceKey* cacheKey = NULL); |
|
138 |
|
139 /** |
|
140 * Search for an entry based on key and dimensions. If found, ref it and return it. The return |
|
141 * value will be NULL if not found. The caller must balance with a call to unref. |
|
142 * |
|
143 * @param desc Description of the texture properties. |
|
144 * @param cacheID Cache-specific properties (e.g., texture gen ID) |
|
145 * @param params The texture params used to draw a texture may help determine |
|
146 * the cache entry used. (e.g. different versions may exist |
|
147 * for different wrap modes on GPUs with limited NPOT |
|
148 * texture support). NULL implies clamp wrap modes. |
|
149 */ |
|
150 GrTexture* findAndRefTexture(const GrTextureDesc& desc, |
|
151 const GrCacheID& cacheID, |
|
152 const GrTextureParams* params); |
|
153 /** |
|
154 * Determines whether a texture is in the cache. If the texture is found it |
|
155 * will not be locked or returned. This call does not affect the priority of |
|
156 * the texture for deletion. |
|
157 */ |
|
158 bool isTextureInCache(const GrTextureDesc& desc, |
|
159 const GrCacheID& cacheID, |
|
160 const GrTextureParams* params) const; |
|
161 |
|
162 /** |
|
163 * Enum that determines how closely a returned scratch texture must match |
|
164 * a provided GrTextureDesc. |
|
165 */ |
|
166 enum ScratchTexMatch { |
|
167 /** |
|
168 * Finds a texture that exactly matches the descriptor. |
|
169 */ |
|
170 kExact_ScratchTexMatch, |
|
171 /** |
|
172 * Finds a texture that approximately matches the descriptor. Will be |
|
173 * at least as large in width and height as desc specifies. If desc |
|
174 * specifies that texture is a render target then result will be a |
|
175 * render target. If desc specifies a render target and doesn't set the |
|
176 * no stencil flag then result will have a stencil. Format and aa level |
|
177 * will always match. |
|
178 */ |
|
179 kApprox_ScratchTexMatch |
|
180 }; |
|
181 |
|
182 /** |
|
183 * Returns a texture matching the desc. It's contents are unknown. Subsequent |
|
184 * requests with the same descriptor are not guaranteed to return the same |
|
185 * texture. The same texture is guaranteed not be returned again until it is |
|
186 * unlocked. Call must be balanced with an unlockTexture() call. The caller |
|
187 * owns a ref on the returned texture and must balance with a call to unref. |
|
188 * |
|
189 * Textures created by createAndLockTexture() hide the complications of |
|
190 * tiling non-power-of-two textures on APIs that don't support this (e.g. |
|
191 * unextended GLES2). Tiling a NPOT texture created by lockScratchTexture on |
|
192 * such an API will create gaps in the tiling pattern. This includes clamp |
|
193 * mode. (This may be addressed in a future update.) |
|
194 */ |
|
195 GrTexture* lockAndRefScratchTexture(const GrTextureDesc&, ScratchTexMatch match); |
|
196 |
|
197 /** |
|
198 * When done with an entry, call unlockScratchTexture(entry) on it, which returns |
|
199 * it to the cache, where it may be purged. This does not unref the texture. |
|
200 */ |
|
201 void unlockScratchTexture(GrTexture* texture); |
|
202 |
|
203 /** |
|
204 * This method should be called whenever a GrTexture is unreffed or |
|
205 * switched from exclusive to non-exclusive. This |
|
206 * gives the resource cache a chance to discard unneeded textures. |
|
207 * Note: this entry point will be removed once totally ref-driven |
|
208 * cache maintenance is implemented |
|
209 */ |
|
210 void purgeCache(); |
|
211 |
|
212 /** |
|
213 * Purge all the unlocked resources from the cache. |
|
214 * This entry point is mainly meant for timing texture uploads |
|
215 * and is not defined in normal builds of Skia. |
|
216 */ |
|
217 void purgeAllUnlockedResources(); |
|
218 |
|
219 /** |
|
220 * Creates a texture that is outside the cache. Does not count against |
|
221 * cache's budget. |
|
222 */ |
|
223 GrTexture* createUncachedTexture(const GrTextureDesc& desc, |
|
224 void* srcData, |
|
225 size_t rowBytes); |
|
226 |
|
227 /** |
|
228 * Returns true if the specified use of an indexed texture is supported. |
|
229 * Support may depend upon whether the texture params indicate that the |
|
230 * texture will be tiled. Passing NULL for the texture params indicates |
|
231 * clamp mode. |
|
232 */ |
|
233 bool supportsIndex8PixelConfig(const GrTextureParams*, |
|
234 int width, |
|
235 int height) const; |
|
236 |
|
237 /** |
|
238 * Return the current texture cache limits. |
|
239 * |
|
240 * @param maxTextures If non-null, returns maximum number of textures that |
|
241 * can be held in the cache. |
|
242 * @param maxTextureBytes If non-null, returns maximum number of bytes of |
|
243 * texture memory that can be held in the cache. |
|
244 */ |
|
245 void getTextureCacheLimits(int* maxTextures, size_t* maxTextureBytes) const; |
|
246 |
|
247 /** |
|
248 * Specify the texture cache limits. If the current cache exceeds either |
|
249 * of these, it will be purged (LRU) to keep the cache within these limits. |
|
250 * |
|
251 * @param maxTextures The maximum number of textures that can be held in |
|
252 * the cache. |
|
253 * @param maxTextureBytes The maximum number of bytes of texture memory |
|
254 * that can be held in the cache. |
|
255 */ |
|
256 void setTextureCacheLimits(int maxTextures, size_t maxTextureBytes); |
|
257 |
|
258 /** |
|
259 * Return the max width or height of a texture supported by the current GPU. |
|
260 */ |
|
261 int getMaxTextureSize() const; |
|
262 |
|
263 /** |
|
264 * Temporarily override the true max texture size. Note: an override |
|
265 * larger then the true max texture size will have no effect. |
|
266 * This entry point is mainly meant for testing texture size dependent |
|
267 * features and is only available if defined outside of Skia (see |
|
268 * bleed GM. |
|
269 */ |
|
270 void setMaxTextureSizeOverride(int maxTextureSizeOverride); |
|
271 |
|
272 /////////////////////////////////////////////////////////////////////////// |
|
273 // Render targets |
|
274 |
|
275 /** |
|
276 * Sets the render target. |
|
277 * @param target the render target to set. |
|
278 */ |
|
279 void setRenderTarget(GrRenderTarget* target) { |
|
280 fRenderTarget.reset(SkSafeRef(target)); |
|
281 } |
|
282 |
|
283 /** |
|
284 * Gets the current render target. |
|
285 * @return the currently bound render target. |
|
286 */ |
|
287 const GrRenderTarget* getRenderTarget() const { return fRenderTarget.get(); } |
|
288 GrRenderTarget* getRenderTarget() { return fRenderTarget.get(); } |
|
289 |
|
290 GrAARectRenderer* getAARectRenderer() { return fAARectRenderer; } |
|
291 |
|
292 /** |
|
293 * Can the provided configuration act as a color render target? |
|
294 */ |
|
295 bool isConfigRenderable(GrPixelConfig config, bool withMSAA) const; |
|
296 |
|
297 /** |
|
298 * Return the max width or height of a render target supported by the |
|
299 * current GPU. |
|
300 */ |
|
301 int getMaxRenderTargetSize() const; |
|
302 |
|
303 /** |
|
304 * Returns the max sample count for a render target. It will be 0 if MSAA |
|
305 * is not supported. |
|
306 */ |
|
307 int getMaxSampleCount() const; |
|
308 |
|
309 /** |
|
310 * Returns the recommended sample count for a render target when using this |
|
311 * context. |
|
312 * |
|
313 * @param config the configuration of the render target. |
|
314 * @param dpi the display density in dots per inch. |
|
315 * |
|
316 * @return sample count that should be perform well and have good enough |
|
317 * rendering quality for the display. Alternatively returns 0 if |
|
318 * MSAA is not supported or recommended to be used by default. |
|
319 */ |
|
320 int getRecommendedSampleCount(GrPixelConfig config, SkScalar dpi) const; |
|
321 |
|
322 /////////////////////////////////////////////////////////////////////////// |
|
323 // Backend Surfaces |
|
324 |
|
325 /** |
|
326 * Wraps an existing texture with a GrTexture object. |
|
327 * |
|
328 * OpenGL: if the object is a texture Gr may change its GL texture params |
|
329 * when it is drawn. |
|
330 * |
|
331 * @param desc description of the object to create. |
|
332 * |
|
333 * @return GrTexture object or NULL on failure. |
|
334 */ |
|
335 GrTexture* wrapBackendTexture(const GrBackendTextureDesc& desc); |
|
336 |
|
337 /** |
|
338 * Wraps an existing render target with a GrRenderTarget object. It is |
|
339 * similar to wrapBackendTexture but can be used to draw into surfaces |
|
340 * that are not also textures (e.g. FBO 0 in OpenGL, or an MSAA buffer that |
|
341 * the client will resolve to a texture). |
|
342 * |
|
343 * @param desc description of the object to create. |
|
344 * |
|
345 * @return GrTexture object or NULL on failure. |
|
346 */ |
|
347 GrRenderTarget* wrapBackendRenderTarget(const GrBackendRenderTargetDesc& desc); |
|
348 |
|
349 /////////////////////////////////////////////////////////////////////////// |
|
350 // Matrix state |
|
351 |
|
352 /** |
|
353 * Gets the current transformation matrix. |
|
354 * @return the current matrix. |
|
355 */ |
|
356 const SkMatrix& getMatrix() const { return fViewMatrix; } |
|
357 |
|
358 /** |
|
359 * Sets the transformation matrix. |
|
360 * @param m the matrix to set. |
|
361 */ |
|
362 void setMatrix(const SkMatrix& m) { fViewMatrix = m; } |
|
363 |
|
364 /** |
|
365 * Sets the current transformation matrix to identity. |
|
366 */ |
|
367 void setIdentityMatrix() { fViewMatrix.reset(); } |
|
368 |
|
369 /** |
|
370 * Concats the current matrix. The passed matrix is applied before the |
|
371 * current matrix. |
|
372 * @param m the matrix to concat. |
|
373 */ |
|
374 void concatMatrix(const SkMatrix& m) { fViewMatrix.preConcat(m); } |
|
375 |
|
376 |
|
377 /////////////////////////////////////////////////////////////////////////// |
|
378 // Clip state |
|
379 /** |
|
380 * Gets the current clip. |
|
381 * @return the current clip. |
|
382 */ |
|
383 const GrClipData* getClip() const { return fClip; } |
|
384 |
|
385 /** |
|
386 * Sets the clip. |
|
387 * @param clipData the clip to set. |
|
388 */ |
|
389 void setClip(const GrClipData* clipData) { fClip = clipData; } |
|
390 |
|
391 /////////////////////////////////////////////////////////////////////////// |
|
392 // Draws |
|
393 |
|
394 /** |
|
395 * Clear the entire or rect of the render target, ignoring any clips. |
|
396 * @param rect the rect to clear or the whole thing if rect is NULL. |
|
397 * @param color the color to clear to. |
|
398 * @param canIgnoreRect allows partial clears to be converted to whole |
|
399 * clears on platforms for which that is cheap |
|
400 * @param target if non-NULL, the render target to clear otherwise clear |
|
401 * the current render target |
|
402 */ |
|
403 void clear(const SkIRect* rect, GrColor color, bool canIgnoreRect, |
|
404 GrRenderTarget* target = NULL); |
|
405 |
|
406 /** |
|
407 * Draw everywhere (respecting the clip) with the paint. |
|
408 */ |
|
409 void drawPaint(const GrPaint& paint); |
|
410 |
|
411 /** |
|
412 * Draw the rect using a paint. |
|
413 * @param paint describes how to color pixels. |
|
414 * @param stroke the stroke information (width, join, cap). |
|
415 * If stroke == NULL, then the rect is filled. |
|
416 * Otherwise, if stroke width == 0, then the stroke |
|
417 * is always a single pixel thick, else the rect is |
|
418 * mitered/beveled stroked based on stroke width. |
|
419 * @param matrix Optional matrix applied to the rect. Applied before |
|
420 * context's matrix or the paint's matrix. |
|
421 * The rects coords are used to access the paint (through texture matrix) |
|
422 */ |
|
423 void drawRect(const GrPaint& paint, |
|
424 const SkRect&, |
|
425 const SkStrokeRec* stroke = NULL, |
|
426 const SkMatrix* matrix = NULL); |
|
427 |
|
428 /** |
|
429 * Maps a rect of local coordinates onto the a rect of destination |
|
430 * coordinates. Each rect can optionally be transformed. The localRect |
|
431 * is stretched over the dstRect. The dstRect is transformed by the |
|
432 * context's matrix. Additional optional matrices for both rects can be |
|
433 * provided by parameters. |
|
434 * |
|
435 * @param paint describes how to color pixels. |
|
436 * @param dstRect the destination rect to draw. |
|
437 * @param localRect rect of local coordinates to be mapped onto dstRect |
|
438 * @param dstMatrix Optional matrix to transform dstRect. Applied before context's matrix. |
|
439 * @param localMatrix Optional matrix to transform localRect. |
|
440 */ |
|
441 void drawRectToRect(const GrPaint& paint, |
|
442 const SkRect& dstRect, |
|
443 const SkRect& localRect, |
|
444 const SkMatrix* dstMatrix = NULL, |
|
445 const SkMatrix* localMatrix = NULL); |
|
446 |
|
447 /** |
|
448 * Draw a roundrect using a paint. |
|
449 * |
|
450 * @param paint describes how to color pixels. |
|
451 * @param rrect the roundrect to draw |
|
452 * @param stroke the stroke information (width, join, cap) |
|
453 */ |
|
454 void drawRRect(const GrPaint& paint, |
|
455 const SkRRect& rrect, |
|
456 const SkStrokeRec& stroke); |
|
457 |
|
458 /** |
|
459 * Draws a path. |
|
460 * |
|
461 * @param paint describes how to color pixels. |
|
462 * @param path the path to draw |
|
463 * @param stroke the stroke information (width, join, cap) |
|
464 */ |
|
465 void drawPath(const GrPaint& paint, const SkPath& path, const SkStrokeRec& stroke); |
|
466 |
|
467 /** |
|
468 * Draws vertices with a paint. |
|
469 * |
|
470 * @param paint describes how to color pixels. |
|
471 * @param primitiveType primitives type to draw. |
|
472 * @param vertexCount number of vertices. |
|
473 * @param positions array of vertex positions, required. |
|
474 * @param texCoords optional array of texture coordinates used |
|
475 * to access the paint. |
|
476 * @param colors optional array of per-vertex colors, supercedes |
|
477 * the paint's color field. |
|
478 * @param indices optional array of indices. If NULL vertices |
|
479 * are drawn non-indexed. |
|
480 * @param indexCount if indices is non-null then this is the |
|
481 * number of indices. |
|
482 */ |
|
483 void drawVertices(const GrPaint& paint, |
|
484 GrPrimitiveType primitiveType, |
|
485 int vertexCount, |
|
486 const GrPoint positions[], |
|
487 const GrPoint texs[], |
|
488 const GrColor colors[], |
|
489 const uint16_t indices[], |
|
490 int indexCount); |
|
491 |
|
492 /** |
|
493 * Draws an oval. |
|
494 * |
|
495 * @param paint describes how to color pixels. |
|
496 * @param oval the bounding rect of the oval. |
|
497 * @param stroke the stroke information (width, style) |
|
498 */ |
|
499 void drawOval(const GrPaint& paint, |
|
500 const SkRect& oval, |
|
501 const SkStrokeRec& stroke); |
|
502 |
|
503 /////////////////////////////////////////////////////////////////////////// |
|
504 // Misc. |
|
505 |
|
506 /** |
|
507 * Flags that affect flush() behavior. |
|
508 */ |
|
509 enum FlushBits { |
|
510 /** |
|
511 * A client may reach a point where it has partially rendered a frame |
|
512 * through a GrContext that it knows the user will never see. This flag |
|
513 * causes the flush to skip submission of deferred content to the 3D API |
|
514 * during the flush. |
|
515 */ |
|
516 kDiscard_FlushBit = 0x2, |
|
517 }; |
|
518 |
|
519 /** |
|
520 * Call to ensure all drawing to the context has been issued to the |
|
521 * underlying 3D API. |
|
522 * @param flagsBitfield flags that control the flushing behavior. See |
|
523 * FlushBits. |
|
524 */ |
|
525 void flush(int flagsBitfield = 0); |
|
526 |
|
527 /** |
|
528 * These flags can be used with the read/write pixels functions below. |
|
529 */ |
|
530 enum PixelOpsFlags { |
|
531 /** The GrContext will not be flushed. This means that the read or write may occur before |
|
532 previous draws have executed. */ |
|
533 kDontFlush_PixelOpsFlag = 0x1, |
|
534 /** The src for write or dst read is unpremultiplied. This is only respected if both the |
|
535 config src and dst configs are an RGBA/BGRA 8888 format. */ |
|
536 kUnpremul_PixelOpsFlag = 0x2, |
|
537 }; |
|
538 |
|
539 /** |
|
540 * Reads a rectangle of pixels from a render target. |
|
541 * @param target the render target to read from. NULL means the current render target. |
|
542 * @param left left edge of the rectangle to read (inclusive) |
|
543 * @param top top edge of the rectangle to read (inclusive) |
|
544 * @param width width of rectangle to read in pixels. |
|
545 * @param height height of rectangle to read in pixels. |
|
546 * @param config the pixel config of the destination buffer |
|
547 * @param buffer memory to read the rectangle into. |
|
548 * @param rowBytes number of bytes bewtween consecutive rows. Zero means rows are tightly |
|
549 * packed. |
|
550 * @param pixelOpsFlags see PixelOpsFlags enum above. |
|
551 * |
|
552 * @return true if the read succeeded, false if not. The read can fail because of an unsupported |
|
553 * pixel config or because no render target is currently set and NULL was passed for |
|
554 * target. |
|
555 */ |
|
556 bool readRenderTargetPixels(GrRenderTarget* target, |
|
557 int left, int top, int width, int height, |
|
558 GrPixelConfig config, void* buffer, |
|
559 size_t rowBytes = 0, |
|
560 uint32_t pixelOpsFlags = 0); |
|
561 |
|
562 /** |
|
563 * Copy the src pixels [buffer, row bytes, pixel config] into a render target at the specified |
|
564 * rectangle. |
|
565 * @param target the render target to write into. NULL means the current render target. |
|
566 * @param left left edge of the rectangle to write (inclusive) |
|
567 * @param top top edge of the rectangle to write (inclusive) |
|
568 * @param width width of rectangle to write in pixels. |
|
569 * @param height height of rectangle to write in pixels. |
|
570 * @param config the pixel config of the source buffer |
|
571 * @param buffer memory to read the rectangle from. |
|
572 * @param rowBytes number of bytes between consecutive rows. Zero means rows are tightly |
|
573 * packed. |
|
574 * @param pixelOpsFlags see PixelOpsFlags enum above. |
|
575 * |
|
576 * @return true if the write succeeded, false if not. The write can fail because of an |
|
577 * unsupported combination of target and pixel configs. |
|
578 */ |
|
579 bool writeRenderTargetPixels(GrRenderTarget* target, |
|
580 int left, int top, int width, int height, |
|
581 GrPixelConfig config, const void* buffer, |
|
582 size_t rowBytes = 0, |
|
583 uint32_t pixelOpsFlags = 0); |
|
584 |
|
585 /** |
|
586 * Reads a rectangle of pixels from a texture. |
|
587 * @param texture the texture to read from. |
|
588 * @param left left edge of the rectangle to read (inclusive) |
|
589 * @param top top edge of the rectangle to read (inclusive) |
|
590 * @param width width of rectangle to read in pixels. |
|
591 * @param height height of rectangle to read in pixels. |
|
592 * @param config the pixel config of the destination buffer |
|
593 * @param buffer memory to read the rectangle into. |
|
594 * @param rowBytes number of bytes between consecutive rows. Zero means rows are tightly |
|
595 * packed. |
|
596 * @param pixelOpsFlags see PixelOpsFlags enum above. |
|
597 * |
|
598 * @return true if the read succeeded, false if not. The read can fail because of an unsupported |
|
599 * pixel config. |
|
600 */ |
|
601 bool readTexturePixels(GrTexture* texture, |
|
602 int left, int top, int width, int height, |
|
603 GrPixelConfig config, void* buffer, |
|
604 size_t rowBytes = 0, |
|
605 uint32_t pixelOpsFlags = 0); |
|
606 |
|
607 /** |
|
608 * Writes a rectangle of pixels to a texture. |
|
609 * @param texture the render target to read from. |
|
610 * @param left left edge of the rectangle to write (inclusive) |
|
611 * @param top top edge of the rectangle to write (inclusive) |
|
612 * @param width width of rectangle to write in pixels. |
|
613 * @param height height of rectangle to write in pixels. |
|
614 * @param config the pixel config of the source buffer |
|
615 * @param buffer memory to read pixels from |
|
616 * @param rowBytes number of bytes between consecutive rows. Zero |
|
617 * means rows are tightly packed. |
|
618 * @param pixelOpsFlags see PixelOpsFlags enum above. |
|
619 * @return true if the write succeeded, false if not. The write can fail because of an |
|
620 * unsupported combination of texture and pixel configs. |
|
621 */ |
|
622 bool writeTexturePixels(GrTexture* texture, |
|
623 int left, int top, int width, int height, |
|
624 GrPixelConfig config, const void* buffer, |
|
625 size_t rowBytes, |
|
626 uint32_t pixelOpsFlags = 0); |
|
627 |
|
628 |
|
629 /** |
|
630 * Copies a rectangle of texels from src to dst. The size of dst is the size of the rectangle |
|
631 * copied and topLeft is the position of the rect in src. The rectangle is clipped to src's |
|
632 * bounds. |
|
633 * @param src the texture to copy from. |
|
634 * @param dst the render target to copy to. |
|
635 * @param topLeft the point in src that will be copied to the top-left of dst. If NULL, |
|
636 * (0, 0) will be used. |
|
637 */ |
|
638 void copyTexture(GrTexture* src, GrRenderTarget* dst, const SkIPoint* topLeft = NULL); |
|
639 |
|
640 /** |
|
641 * Resolves a render target that has MSAA. The intermediate MSAA buffer is |
|
642 * down-sampled to the associated GrTexture (accessible via |
|
643 * GrRenderTarget::asTexture()). Any pending draws to the render target will |
|
644 * be executed before the resolve. |
|
645 * |
|
646 * This is only necessary when a client wants to access the object directly |
|
647 * using the backend API directly. GrContext will detect when it must |
|
648 * perform a resolve to a GrTexture used as the source of a draw or before |
|
649 * reading pixels back from a GrTexture or GrRenderTarget. |
|
650 */ |
|
651 void resolveRenderTarget(GrRenderTarget* target); |
|
652 |
|
653 #ifdef SK_DEVELOPER |
|
654 void dumpFontCache() const; |
|
655 #endif |
|
656 |
|
657 /////////////////////////////////////////////////////////////////////////// |
|
658 // Helpers |
|
659 |
|
660 class AutoRenderTarget : public ::SkNoncopyable { |
|
661 public: |
|
662 AutoRenderTarget(GrContext* context, GrRenderTarget* target) { |
|
663 fPrevTarget = context->getRenderTarget(); |
|
664 SkSafeRef(fPrevTarget); |
|
665 context->setRenderTarget(target); |
|
666 fContext = context; |
|
667 } |
|
668 AutoRenderTarget(GrContext* context) { |
|
669 fPrevTarget = context->getRenderTarget(); |
|
670 SkSafeRef(fPrevTarget); |
|
671 fContext = context; |
|
672 } |
|
673 ~AutoRenderTarget() { |
|
674 if (NULL != fContext) { |
|
675 fContext->setRenderTarget(fPrevTarget); |
|
676 } |
|
677 SkSafeUnref(fPrevTarget); |
|
678 } |
|
679 private: |
|
680 GrContext* fContext; |
|
681 GrRenderTarget* fPrevTarget; |
|
682 }; |
|
683 |
|
684 /** |
|
685 * Save/restore the view-matrix in the context. It can optionally adjust a paint to account |
|
686 * for a coordinate system change. Here is an example of how the paint param can be used: |
|
687 * |
|
688 * A GrPaint is setup with GrEffects. The stages will have access to the pre-matrix source |
|
689 * geometry positions when the draw is executed. Later on a decision is made to transform the |
|
690 * geometry to device space on the CPU. The effects now need to know that the space in which |
|
691 * the geometry will be specified has changed. |
|
692 * |
|
693 * Note that when restore is called (or in the destructor) the context's matrix will be |
|
694 * restored. However, the paint will not be restored. The caller must make a copy of the |
|
695 * paint if necessary. Hint: use SkTCopyOnFirstWrite if the AutoMatrix is conditionally |
|
696 * initialized. |
|
697 */ |
|
698 class AutoMatrix : public ::SkNoncopyable { |
|
699 public: |
|
700 AutoMatrix() : fContext(NULL) {} |
|
701 |
|
702 ~AutoMatrix() { this->restore(); } |
|
703 |
|
704 /** |
|
705 * Initializes by pre-concat'ing the context's current matrix with the preConcat param. |
|
706 */ |
|
707 void setPreConcat(GrContext* context, const SkMatrix& preConcat, GrPaint* paint = NULL) { |
|
708 SkASSERT(NULL != context); |
|
709 |
|
710 this->restore(); |
|
711 |
|
712 fContext = context; |
|
713 fMatrix = context->getMatrix(); |
|
714 this->preConcat(preConcat, paint); |
|
715 } |
|
716 |
|
717 /** |
|
718 * Sets the context's matrix to identity. Returns false if the inverse matrix is required to |
|
719 * update a paint but the matrix cannot be inverted. |
|
720 */ |
|
721 bool setIdentity(GrContext* context, GrPaint* paint = NULL) { |
|
722 SkASSERT(NULL != context); |
|
723 |
|
724 this->restore(); |
|
725 |
|
726 if (NULL != paint) { |
|
727 if (!paint->localCoordChangeInverse(context->getMatrix())) { |
|
728 return false; |
|
729 } |
|
730 } |
|
731 fMatrix = context->getMatrix(); |
|
732 fContext = context; |
|
733 context->setIdentityMatrix(); |
|
734 return true; |
|
735 } |
|
736 |
|
737 /** |
|
738 * Replaces the context's matrix with a new matrix. Returns false if the inverse matrix is |
|
739 * required to update a paint but the matrix cannot be inverted. |
|
740 */ |
|
741 bool set(GrContext* context, const SkMatrix& newMatrix, GrPaint* paint = NULL) { |
|
742 if (NULL != paint) { |
|
743 if (!this->setIdentity(context, paint)) { |
|
744 return false; |
|
745 } |
|
746 this->preConcat(newMatrix, paint); |
|
747 } else { |
|
748 this->restore(); |
|
749 fContext = context; |
|
750 fMatrix = context->getMatrix(); |
|
751 context->setMatrix(newMatrix); |
|
752 } |
|
753 return true; |
|
754 } |
|
755 |
|
756 /** |
|
757 * If this has been initialized then the context's matrix will be further updated by |
|
758 * pre-concat'ing the preConcat param. The matrix that will be restored remains unchanged. |
|
759 * The paint is assumed to be relative to the context's matrix at the time this call is |
|
760 * made, not the matrix at the time AutoMatrix was first initialized. In other words, this |
|
761 * performs an incremental update of the paint. |
|
762 */ |
|
763 void preConcat(const SkMatrix& preConcat, GrPaint* paint = NULL) { |
|
764 if (NULL != paint) { |
|
765 paint->localCoordChange(preConcat); |
|
766 } |
|
767 fContext->concatMatrix(preConcat); |
|
768 } |
|
769 |
|
770 /** |
|
771 * Returns false if never initialized or the inverse matrix was required to update a paint |
|
772 * but the matrix could not be inverted. |
|
773 */ |
|
774 bool succeeded() const { return NULL != fContext; } |
|
775 |
|
776 /** |
|
777 * If this has been initialized then the context's original matrix is restored. |
|
778 */ |
|
779 void restore() { |
|
780 if (NULL != fContext) { |
|
781 fContext->setMatrix(fMatrix); |
|
782 fContext = NULL; |
|
783 } |
|
784 } |
|
785 |
|
786 private: |
|
787 GrContext* fContext; |
|
788 SkMatrix fMatrix; |
|
789 }; |
|
790 |
|
791 class AutoClip : public ::SkNoncopyable { |
|
792 public: |
|
793 // This enum exists to require a caller of the constructor to acknowledge that the clip will |
|
794 // initially be wide open. It also could be extended if there are other desirable initial |
|
795 // clip states. |
|
796 enum InitialClip { |
|
797 kWideOpen_InitialClip, |
|
798 }; |
|
799 |
|
800 AutoClip(GrContext* context, InitialClip initialState) |
|
801 : fContext(context) { |
|
802 SkASSERT(kWideOpen_InitialClip == initialState); |
|
803 fNewClipData.fClipStack = &fNewClipStack; |
|
804 |
|
805 fOldClip = context->getClip(); |
|
806 context->setClip(&fNewClipData); |
|
807 } |
|
808 |
|
809 AutoClip(GrContext* context, const SkRect& newClipRect) |
|
810 : fContext(context) |
|
811 , fNewClipStack(newClipRect) { |
|
812 fNewClipData.fClipStack = &fNewClipStack; |
|
813 |
|
814 fOldClip = fContext->getClip(); |
|
815 fContext->setClip(&fNewClipData); |
|
816 } |
|
817 |
|
818 ~AutoClip() { |
|
819 if (NULL != fContext) { |
|
820 fContext->setClip(fOldClip); |
|
821 } |
|
822 } |
|
823 private: |
|
824 GrContext* fContext; |
|
825 const GrClipData* fOldClip; |
|
826 |
|
827 SkClipStack fNewClipStack; |
|
828 GrClipData fNewClipData; |
|
829 }; |
|
830 |
|
831 class AutoWideOpenIdentityDraw { |
|
832 public: |
|
833 AutoWideOpenIdentityDraw(GrContext* ctx, GrRenderTarget* rt) |
|
834 : fAutoClip(ctx, AutoClip::kWideOpen_InitialClip) |
|
835 , fAutoRT(ctx, rt) { |
|
836 fAutoMatrix.setIdentity(ctx); |
|
837 // should never fail with no paint param. |
|
838 SkASSERT(fAutoMatrix.succeeded()); |
|
839 } |
|
840 |
|
841 private: |
|
842 AutoClip fAutoClip; |
|
843 AutoRenderTarget fAutoRT; |
|
844 AutoMatrix fAutoMatrix; |
|
845 }; |
|
846 |
|
847 /////////////////////////////////////////////////////////////////////////// |
|
848 // Functions intended for internal use only. |
|
849 GrGpu* getGpu() { return fGpu; } |
|
850 const GrGpu* getGpu() const { return fGpu; } |
|
851 GrFontCache* getFontCache() { return fFontCache; } |
|
852 GrDrawTarget* getTextTarget(); |
|
853 const GrIndexBuffer* getQuadIndexBuffer() const; |
|
854 |
|
855 // Called by tests that draw directly to the context via GrDrawTarget |
|
856 void getTestTarget(GrTestTarget*); |
|
857 |
|
858 /** |
|
859 * Stencil buffers add themselves to the cache using addStencilBuffer. findStencilBuffer is |
|
860 * called to check the cache for a SB that matches an RT's criteria. |
|
861 */ |
|
862 void addStencilBuffer(GrStencilBuffer* sb); |
|
863 GrStencilBuffer* findStencilBuffer(int width, int height, int sampleCnt); |
|
864 |
|
865 GrPathRenderer* getPathRenderer( |
|
866 const SkPath& path, |
|
867 const SkStrokeRec& stroke, |
|
868 const GrDrawTarget* target, |
|
869 bool allowSW, |
|
870 GrPathRendererChain::DrawType drawType = GrPathRendererChain::kColor_DrawType, |
|
871 GrPathRendererChain::StencilSupport* stencilSupport = NULL); |
|
872 |
|
873 |
|
874 #if GR_CACHE_STATS |
|
875 void printCacheStats() const; |
|
876 #endif |
|
877 |
|
878 private: |
|
879 // Used to indicate whether a draw should be performed immediately or queued in fDrawBuffer. |
|
880 enum BufferedDraw { |
|
881 kYes_BufferedDraw, |
|
882 kNo_BufferedDraw, |
|
883 }; |
|
884 BufferedDraw fLastDrawWasBuffered; |
|
885 |
|
886 GrGpu* fGpu; |
|
887 SkMatrix fViewMatrix; |
|
888 SkAutoTUnref<GrRenderTarget> fRenderTarget; |
|
889 const GrClipData* fClip; // TODO: make this ref counted |
|
890 GrDrawState* fDrawState; |
|
891 |
|
892 GrResourceCache* fTextureCache; |
|
893 GrFontCache* fFontCache; |
|
894 |
|
895 GrPathRendererChain* fPathRendererChain; |
|
896 GrSoftwarePathRenderer* fSoftwarePathRenderer; |
|
897 |
|
898 GrVertexBufferAllocPool* fDrawBufferVBAllocPool; |
|
899 GrIndexBufferAllocPool* fDrawBufferIBAllocPool; |
|
900 GrInOrderDrawBuffer* fDrawBuffer; |
|
901 |
|
902 // Set by OverbudgetCB() to request that GrContext flush before exiting a draw. |
|
903 bool fFlushToReduceCacheSize; |
|
904 |
|
905 GrAARectRenderer* fAARectRenderer; |
|
906 GrOvalRenderer* fOvalRenderer; |
|
907 |
|
908 bool fDidTestPMConversions; |
|
909 int fPMToUPMConversion; |
|
910 int fUPMToPMConversion; |
|
911 |
|
912 struct CleanUpData { |
|
913 PFCleanUpFunc fFunc; |
|
914 void* fInfo; |
|
915 }; |
|
916 |
|
917 SkTDArray<CleanUpData> fCleanUpData; |
|
918 |
|
919 int fMaxTextureSizeOverride; |
|
920 |
|
921 GrContext(); // init must be called after the constructor. |
|
922 bool init(GrBackend, GrBackendContext); |
|
923 |
|
924 void setupDrawBuffer(); |
|
925 |
|
926 class AutoRestoreEffects; |
|
927 class AutoCheckFlush; |
|
928 /// Sets the paint and returns the target to draw into. The paint can be NULL in which case the |
|
929 /// draw state is left unmodified. |
|
930 GrDrawTarget* prepareToDraw(const GrPaint*, BufferedDraw, AutoRestoreEffects*, AutoCheckFlush*); |
|
931 |
|
932 void internalDrawPath(GrDrawTarget* target, bool useAA, const SkPath& path, |
|
933 const SkStrokeRec& stroke); |
|
934 |
|
935 GrTexture* createResizedTexture(const GrTextureDesc& desc, |
|
936 const GrCacheID& cacheID, |
|
937 void* srcData, |
|
938 size_t rowBytes, |
|
939 bool filter); |
|
940 |
|
941 // Needed so GrTexture's returnToCache helper function can call |
|
942 // addExistingTextureToCache |
|
943 friend class GrTexture; |
|
944 friend class GrStencilAndCoverPathRenderer; |
|
945 |
|
946 // Add an existing texture to the texture cache. This is intended solely |
|
947 // for use with textures released from an GrAutoScratchTexture. |
|
948 void addExistingTextureToCache(GrTexture* texture); |
|
949 |
|
950 /** |
|
951 * These functions create premul <-> unpremul effects if it is possible to generate a pair |
|
952 * of effects that make a readToUPM->writeToPM->readToUPM cycle invariant. Otherwise, they |
|
953 * return NULL. |
|
954 */ |
|
955 const GrEffectRef* createPMToUPMEffect(GrTexture* texture, |
|
956 bool swapRAndB, |
|
957 const SkMatrix& matrix); |
|
958 const GrEffectRef* createUPMToPMEffect(GrTexture* texture, |
|
959 bool swapRAndB, |
|
960 const SkMatrix& matrix); |
|
961 |
|
962 /** |
|
963 * This callback allows the resource cache to callback into the GrContext |
|
964 * when the cache is still overbudget after a purge. |
|
965 */ |
|
966 static bool OverbudgetCB(void* data); |
|
967 |
|
968 /** Creates a new gpu path, based on the specified path and stroke and returns it. |
|
969 * The caller owns a ref on the returned path which must be balanced by a call to unref. |
|
970 * |
|
971 * @param skPath the path geometry. |
|
972 * @param stroke the path stroke. |
|
973 * @return a new path or NULL if the operation is not supported by the backend. |
|
974 */ |
|
975 GrPath* createPath(const SkPath& skPath, const SkStrokeRec& stroke); |
|
976 |
|
977 typedef SkRefCnt INHERITED; |
|
978 }; |
|
979 |
|
980 /** |
|
981 * Gets and locks a scratch texture from a descriptor using either exact or approximate criteria. |
|
982 * Unlocks texture in the destructor. |
|
983 */ |
|
984 class GrAutoScratchTexture : public ::SkNoncopyable { |
|
985 public: |
|
986 GrAutoScratchTexture() |
|
987 : fContext(NULL) |
|
988 , fTexture(NULL) { |
|
989 } |
|
990 |
|
991 GrAutoScratchTexture(GrContext* context, |
|
992 const GrTextureDesc& desc, |
|
993 GrContext::ScratchTexMatch match = GrContext::kApprox_ScratchTexMatch) |
|
994 : fContext(NULL) |
|
995 , fTexture(NULL) { |
|
996 this->set(context, desc, match); |
|
997 } |
|
998 |
|
999 ~GrAutoScratchTexture() { |
|
1000 this->reset(); |
|
1001 } |
|
1002 |
|
1003 void reset() { |
|
1004 if (NULL != fContext && NULL != fTexture) { |
|
1005 fContext->unlockScratchTexture(fTexture); |
|
1006 fTexture->unref(); |
|
1007 fTexture = NULL; |
|
1008 } |
|
1009 } |
|
1010 |
|
1011 /* |
|
1012 * When detaching a texture we do not unlock it in the texture cache but |
|
1013 * we do set the returnToCache flag. In this way the texture remains |
|
1014 * "locked" in the texture cache until it is freed and recycled in |
|
1015 * GrTexture::internal_dispose. In reality, the texture has been removed |
|
1016 * from the cache (because this is in AutoScratchTexture) and by not |
|
1017 * calling unlockScratchTexture we simply don't re-add it. It will be |
|
1018 * reattached in GrTexture::internal_dispose. |
|
1019 * |
|
1020 * Note that the caller is assumed to accept and manage the ref to the |
|
1021 * returned texture. |
|
1022 */ |
|
1023 GrTexture* detach() { |
|
1024 if (NULL == fTexture) { |
|
1025 return NULL; |
|
1026 } |
|
1027 GrTexture* texture = fTexture; |
|
1028 fTexture = NULL; |
|
1029 |
|
1030 // This GrAutoScratchTexture has a ref from lockAndRefScratchTexture, which we give up now. |
|
1031 // The cache also has a ref which we are lending to the caller of detach(). When the caller |
|
1032 // lets go of the ref and the ref count goes to 0 internal_dispose will see this flag is |
|
1033 // set and re-ref the texture, thereby restoring the cache's ref. |
|
1034 SkASSERT(texture->getRefCnt() > 1); |
|
1035 texture->setFlag((GrTextureFlags) GrTexture::kReturnToCache_FlagBit); |
|
1036 texture->unref(); |
|
1037 SkASSERT(NULL != texture->getCacheEntry()); |
|
1038 |
|
1039 return texture; |
|
1040 } |
|
1041 |
|
1042 GrTexture* set(GrContext* context, |
|
1043 const GrTextureDesc& desc, |
|
1044 GrContext::ScratchTexMatch match = GrContext::kApprox_ScratchTexMatch) { |
|
1045 this->reset(); |
|
1046 |
|
1047 fContext = context; |
|
1048 if (NULL != fContext) { |
|
1049 fTexture = fContext->lockAndRefScratchTexture(desc, match); |
|
1050 if (NULL == fTexture) { |
|
1051 fContext = NULL; |
|
1052 } |
|
1053 return fTexture; |
|
1054 } else { |
|
1055 return NULL; |
|
1056 } |
|
1057 } |
|
1058 |
|
1059 GrTexture* texture() { return fTexture; } |
|
1060 |
|
1061 private: |
|
1062 GrContext* fContext; |
|
1063 GrTexture* fTexture; |
|
1064 }; |
|
1065 |
|
1066 #endif |