Sat, 03 Jan 2015 20:18:00 +0100
Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.
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 */
8 #ifndef GrContext_DEFINED
9 #define GrContext_DEFINED
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"
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;
44 class SK_API GrContext : public SkRefCnt {
45 public:
46 SK_DECLARE_INST_COUNT(GrContext)
48 /**
49 * Creates a GrContext for a backend context.
50 */
51 static GrContext* Create(GrBackend, GrBackendContext);
53 virtual ~GrContext();
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);
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);
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();
79 entry->fFunc = cleanUp;
80 entry->fInfo = info;
81 }
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();
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();
103 /**
104 * Frees GPU created by the context. Can be called to reduce GPU memory
105 * pressure.
106 */
107 void freeGpuResources();
109 /**
110 * Returns the number of bytes of GPU memory hosted by the texture cache.
111 */
112 size_t getGpuTextureCacheBytes() const;
114 ///////////////////////////////////////////////////////////////////////////
115 // Textures
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);
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;
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 };
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);
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);
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();
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();
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);
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;
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;
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);
258 /**
259 * Return the max width or height of a texture supported by the current GPU.
260 */
261 int getMaxTextureSize() const;
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);
272 ///////////////////////////////////////////////////////////////////////////
273 // Render targets
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 }
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(); }
290 GrAARectRenderer* getAARectRenderer() { return fAARectRenderer; }
292 /**
293 * Can the provided configuration act as a color render target?
294 */
295 bool isConfigRenderable(GrPixelConfig config, bool withMSAA) const;
297 /**
298 * Return the max width or height of a render target supported by the
299 * current GPU.
300 */
301 int getMaxRenderTargetSize() const;
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;
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;
322 ///////////////////////////////////////////////////////////////////////////
323 // Backend Surfaces
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);
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);
349 ///////////////////////////////////////////////////////////////////////////
350 // Matrix state
352 /**
353 * Gets the current transformation matrix.
354 * @return the current matrix.
355 */
356 const SkMatrix& getMatrix() const { return fViewMatrix; }
358 /**
359 * Sets the transformation matrix.
360 * @param m the matrix to set.
361 */
362 void setMatrix(const SkMatrix& m) { fViewMatrix = m; }
364 /**
365 * Sets the current transformation matrix to identity.
366 */
367 void setIdentityMatrix() { fViewMatrix.reset(); }
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); }
377 ///////////////////////////////////////////////////////////////////////////
378 // Clip state
379 /**
380 * Gets the current clip.
381 * @return the current clip.
382 */
383 const GrClipData* getClip() const { return fClip; }
385 /**
386 * Sets the clip.
387 * @param clipData the clip to set.
388 */
389 void setClip(const GrClipData* clipData) { fClip = clipData; }
391 ///////////////////////////////////////////////////////////////////////////
392 // Draws
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);
406 /**
407 * Draw everywhere (respecting the clip) with the paint.
408 */
409 void drawPaint(const GrPaint& paint);
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);
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);
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);
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);
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);
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);
503 ///////////////////////////////////////////////////////////////////////////
504 // Misc.
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 };
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);
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 };
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);
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);
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);
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);
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);
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);
653 #ifdef SK_DEVELOPER
654 void dumpFontCache() const;
655 #endif
657 ///////////////////////////////////////////////////////////////////////////
658 // Helpers
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 };
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) {}
702 ~AutoMatrix() { this->restore(); }
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);
710 this->restore();
712 fContext = context;
713 fMatrix = context->getMatrix();
714 this->preConcat(preConcat, paint);
715 }
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);
724 this->restore();
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 }
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 }
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 }
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; }
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 }
786 private:
787 GrContext* fContext;
788 SkMatrix fMatrix;
789 };
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 };
800 AutoClip(GrContext* context, InitialClip initialState)
801 : fContext(context) {
802 SkASSERT(kWideOpen_InitialClip == initialState);
803 fNewClipData.fClipStack = &fNewClipStack;
805 fOldClip = context->getClip();
806 context->setClip(&fNewClipData);
807 }
809 AutoClip(GrContext* context, const SkRect& newClipRect)
810 : fContext(context)
811 , fNewClipStack(newClipRect) {
812 fNewClipData.fClipStack = &fNewClipStack;
814 fOldClip = fContext->getClip();
815 fContext->setClip(&fNewClipData);
816 }
818 ~AutoClip() {
819 if (NULL != fContext) {
820 fContext->setClip(fOldClip);
821 }
822 }
823 private:
824 GrContext* fContext;
825 const GrClipData* fOldClip;
827 SkClipStack fNewClipStack;
828 GrClipData fNewClipData;
829 };
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 }
841 private:
842 AutoClip fAutoClip;
843 AutoRenderTarget fAutoRT;
844 AutoMatrix fAutoMatrix;
845 };
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;
855 // Called by tests that draw directly to the context via GrDrawTarget
856 void getTestTarget(GrTestTarget*);
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);
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);
874 #if GR_CACHE_STATS
875 void printCacheStats() const;
876 #endif
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;
886 GrGpu* fGpu;
887 SkMatrix fViewMatrix;
888 SkAutoTUnref<GrRenderTarget> fRenderTarget;
889 const GrClipData* fClip; // TODO: make this ref counted
890 GrDrawState* fDrawState;
892 GrResourceCache* fTextureCache;
893 GrFontCache* fFontCache;
895 GrPathRendererChain* fPathRendererChain;
896 GrSoftwarePathRenderer* fSoftwarePathRenderer;
898 GrVertexBufferAllocPool* fDrawBufferVBAllocPool;
899 GrIndexBufferAllocPool* fDrawBufferIBAllocPool;
900 GrInOrderDrawBuffer* fDrawBuffer;
902 // Set by OverbudgetCB() to request that GrContext flush before exiting a draw.
903 bool fFlushToReduceCacheSize;
905 GrAARectRenderer* fAARectRenderer;
906 GrOvalRenderer* fOvalRenderer;
908 bool fDidTestPMConversions;
909 int fPMToUPMConversion;
910 int fUPMToPMConversion;
912 struct CleanUpData {
913 PFCleanUpFunc fFunc;
914 void* fInfo;
915 };
917 SkTDArray<CleanUpData> fCleanUpData;
919 int fMaxTextureSizeOverride;
921 GrContext(); // init must be called after the constructor.
922 bool init(GrBackend, GrBackendContext);
924 void setupDrawBuffer();
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*);
932 void internalDrawPath(GrDrawTarget* target, bool useAA, const SkPath& path,
933 const SkStrokeRec& stroke);
935 GrTexture* createResizedTexture(const GrTextureDesc& desc,
936 const GrCacheID& cacheID,
937 void* srcData,
938 size_t rowBytes,
939 bool filter);
941 // Needed so GrTexture's returnToCache helper function can call
942 // addExistingTextureToCache
943 friend class GrTexture;
944 friend class GrStencilAndCoverPathRenderer;
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);
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);
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);
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);
977 typedef SkRefCnt INHERITED;
978 };
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 }
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 }
999 ~GrAutoScratchTexture() {
1000 this->reset();
1001 }
1003 void reset() {
1004 if (NULL != fContext && NULL != fTexture) {
1005 fContext->unlockScratchTexture(fTexture);
1006 fTexture->unref();
1007 fTexture = NULL;
1008 }
1009 }
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;
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());
1039 return texture;
1040 }
1042 GrTexture* set(GrContext* context,
1043 const GrTextureDesc& desc,
1044 GrContext::ScratchTexMatch match = GrContext::kApprox_ScratchTexMatch) {
1045 this->reset();
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 }
1059 GrTexture* texture() { return fTexture; }
1061 private:
1062 GrContext* fContext;
1063 GrTexture* fTexture;
1064 };
1066 #endif