• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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      */
addCleanUp(PFCleanUpFunc cleanUp,void * info)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      * Creates a texture that is outside the cache. Does not count against
214      * cache's budget.
215      */
216     GrTexture* createUncachedTexture(const GrTextureDesc& desc,
217                                      void* srcData,
218                                      size_t rowBytes);
219 
220     /**
221      * Returns true if the specified use of an indexed texture is supported.
222      * Support may depend upon whether the texture params indicate that the
223      * texture will be tiled. Passing NULL for the texture params indicates
224      * clamp mode.
225      */
226     bool supportsIndex8PixelConfig(const GrTextureParams*,
227                                    int width,
228                                    int height) const;
229 
230     /**
231      *  Return the current texture cache limits.
232      *
233      *  @param maxTextures If non-null, returns maximum number of textures that
234      *                     can be held in the cache.
235      *  @param maxTextureBytes If non-null, returns maximum number of bytes of
236      *                         texture memory that can be held in the cache.
237      */
238     void getTextureCacheLimits(int* maxTextures, size_t* maxTextureBytes) const;
239 
240     /**
241      *  Specify the texture cache limits. If the current cache exceeds either
242      *  of these, it will be purged (LRU) to keep the cache within these limits.
243      *
244      *  @param maxTextures The maximum number of textures that can be held in
245      *                     the cache.
246      *  @param maxTextureBytes The maximum number of bytes of texture memory
247      *                         that can be held in the cache.
248      */
249     void setTextureCacheLimits(int maxTextures, size_t maxTextureBytes);
250 
251     /**
252      *  Return the max width or height of a texture supported by the current GPU.
253      */
254     int getMaxTextureSize() const;
255 
256     /**
257      *  Temporarily override the true max texture size. Note: an override
258      *  larger then the true max texture size will have no effect.
259      *  This entry point is mainly meant for testing texture size dependent
260      *  features and is only available if defined outside of Skia (see
261      *  bleed GM.
262      */
263     void setMaxTextureSizeOverride(int maxTextureSizeOverride);
264 
265     ///////////////////////////////////////////////////////////////////////////
266     // Render targets
267 
268     /**
269      * Sets the render target.
270      * @param target    the render target to set.
271      */
setRenderTarget(GrRenderTarget * target)272     void setRenderTarget(GrRenderTarget* target) {
273         fRenderTarget.reset(SkSafeRef(target));
274     }
275 
276     /**
277      * Gets the current render target.
278      * @return the currently bound render target.
279      */
getRenderTarget()280     const GrRenderTarget* getRenderTarget() const { return fRenderTarget.get(); }
getRenderTarget()281     GrRenderTarget* getRenderTarget() { return fRenderTarget.get(); }
282 
getAARectRenderer()283     GrAARectRenderer* getAARectRenderer() { return fAARectRenderer; }
284 
285     /**
286      * Can the provided configuration act as a color render target?
287      */
288     bool isConfigRenderable(GrPixelConfig config, bool withMSAA) const;
289 
290     /**
291      * Return the max width or height of a render target supported by the
292      * current GPU.
293      */
294     int getMaxRenderTargetSize() const;
295 
296     /**
297      * Returns the max sample count for a render target. It will be 0 if MSAA
298      * is not supported.
299      */
300     int getMaxSampleCount() const;
301 
302     ///////////////////////////////////////////////////////////////////////////
303     // Backend Surfaces
304 
305     /**
306      * Wraps an existing texture with a GrTexture object.
307      *
308      * OpenGL: if the object is a texture Gr may change its GL texture params
309      *         when it is drawn.
310      *
311      * @param  desc     description of the object to create.
312      *
313      * @return GrTexture object or NULL on failure.
314      */
315     GrTexture* wrapBackendTexture(const GrBackendTextureDesc& desc);
316 
317     /**
318      * Wraps an existing render target with a GrRenderTarget object. It is
319      * similar to wrapBackendTexture but can be used to draw into surfaces
320      * that are not also textures (e.g. FBO 0 in OpenGL, or an MSAA buffer that
321      * the client will resolve to a texture).
322      *
323      * @param  desc     description of the object to create.
324      *
325      * @return GrTexture object or NULL on failure.
326      */
327      GrRenderTarget* wrapBackendRenderTarget(const GrBackendRenderTargetDesc& desc);
328 
329     ///////////////////////////////////////////////////////////////////////////
330     // Matrix state
331 
332     /**
333      * Gets the current transformation matrix.
334      * @return the current matrix.
335      */
getMatrix()336     const SkMatrix& getMatrix() const { return fViewMatrix; }
337 
338     /**
339      * Sets the transformation matrix.
340      * @param m the matrix to set.
341      */
setMatrix(const SkMatrix & m)342     void setMatrix(const SkMatrix& m) { fViewMatrix = m; }
343 
344     /**
345      * Sets the current transformation matrix to identity.
346      */
setIdentityMatrix()347     void setIdentityMatrix() { fViewMatrix.reset(); }
348 
349     /**
350      * Concats the current matrix. The passed matrix is applied before the
351      * current matrix.
352      * @param m the matrix to concat.
353      */
concatMatrix(const SkMatrix & m)354     void concatMatrix(const SkMatrix& m) { fViewMatrix.preConcat(m); }
355 
356 
357     ///////////////////////////////////////////////////////////////////////////
358     // Clip state
359     /**
360      * Gets the current clip.
361      * @return the current clip.
362      */
getClip()363     const GrClipData* getClip() const { return fClip; }
364 
365     /**
366      * Sets the clip.
367      * @param clipData  the clip to set.
368      */
setClip(const GrClipData * clipData)369     void setClip(const GrClipData* clipData) { fClip = clipData; }
370 
371     ///////////////////////////////////////////////////////////////////////////
372     // Draws
373 
374     /**
375      * Clear the entire or rect of the render target, ignoring any clips.
376      * @param rect  the rect to clear or the whole thing if rect is NULL.
377      * @param color the color to clear to.
378      * @param canIgnoreRect allows partial clears to be converted to whole
379      *                      clears on platforms for which that is cheap
380      * @param target if non-NULL, the render target to clear otherwise clear
381      *               the current render target
382      */
383     void clear(const SkIRect* rect, GrColor color, bool canIgnoreRect,
384                GrRenderTarget* target = NULL);
385 
386     /**
387      *  Draw everywhere (respecting the clip) with the paint.
388      */
389     void drawPaint(const GrPaint& paint);
390 
391     /**
392      *  Draw the rect using a paint.
393      *  @param paint        describes how to color pixels.
394      *  @param stroke       the stroke information (width, join, cap).
395      *                      If stroke == NULL, then the rect is filled.
396      *                      Otherwise, if stroke width == 0, then the stroke
397      *                      is always a single pixel thick, else the rect is
398      *                      mitered/beveled stroked based on stroke width.
399      *  @param matrix       Optional matrix applied to the rect. Applied before
400      *                      context's matrix or the paint's matrix.
401      *  The rects coords are used to access the paint (through texture matrix)
402      */
403     void drawRect(const GrPaint& paint,
404                   const SkRect&,
405                   const SkStrokeRec* stroke = NULL,
406                   const SkMatrix* matrix = NULL);
407 
408     /**
409      * Maps a rect of local coordinates onto the a rect of destination
410      * coordinates. Each rect can optionally be transformed. The localRect
411      * is stretched over the dstRect. The dstRect is transformed by the
412      * context's matrix. Additional optional matrices for both rects can be
413      * provided by parameters.
414      *
415      * @param paint         describes how to color pixels.
416      * @param dstRect       the destination rect to draw.
417      * @param localRect     rect of local coordinates to be mapped onto dstRect
418      * @param dstMatrix     Optional matrix to transform dstRect. Applied before context's matrix.
419      * @param localMatrix   Optional matrix to transform localRect.
420      */
421     void drawRectToRect(const GrPaint& paint,
422                         const SkRect& dstRect,
423                         const SkRect& localRect,
424                         const SkMatrix* dstMatrix = NULL,
425                         const SkMatrix* localMatrix = NULL);
426 
427     /**
428      *  Draw a roundrect using a paint.
429      *
430      *  @param paint        describes how to color pixels.
431      *  @param rrect        the roundrect to draw
432      *  @param stroke       the stroke information (width, join, cap)
433      */
434     void drawRRect(const GrPaint& paint,
435                    const SkRRect& rrect,
436                    const SkStrokeRec& stroke);
437 
438     /**
439      * Draws a path.
440      *
441      * @param paint         describes how to color pixels.
442      * @param path          the path to draw
443      * @param stroke        the stroke information (width, join, cap)
444      */
445     void drawPath(const GrPaint& paint, const SkPath& path, const SkStrokeRec& stroke);
446 
447     /**
448      * Draws vertices with a paint.
449      *
450      * @param   paint           describes how to color pixels.
451      * @param   primitiveType   primitives type to draw.
452      * @param   vertexCount     number of vertices.
453      * @param   positions       array of vertex positions, required.
454      * @param   texCoords       optional array of texture coordinates used
455      *                          to access the paint.
456      * @param   colors          optional array of per-vertex colors, supercedes
457      *                          the paint's color field.
458      * @param   indices         optional array of indices. If NULL vertices
459      *                          are drawn non-indexed.
460      * @param   indexCount      if indices is non-null then this is the
461      *                          number of indices.
462      */
463     void drawVertices(const GrPaint& paint,
464                       GrPrimitiveType primitiveType,
465                       int vertexCount,
466                       const GrPoint positions[],
467                       const GrPoint texs[],
468                       const GrColor colors[],
469                       const uint16_t indices[],
470                       int indexCount);
471 
472     /**
473      * Draws an oval.
474      *
475      * @param paint         describes how to color pixels.
476      * @param oval          the bounding rect of the oval.
477      * @param stroke        the stroke information (width, style)
478      */
479     void drawOval(const GrPaint& paint,
480                   const SkRect& oval,
481                   const SkStrokeRec& stroke);
482 
483     ///////////////////////////////////////////////////////////////////////////
484     // Misc.
485 
486     /**
487      * Flags that affect flush() behavior.
488      */
489     enum FlushBits {
490         /**
491          * A client may reach a point where it has partially rendered a frame
492          * through a GrContext that it knows the user will never see. This flag
493          * causes the flush to skip submission of deferred content to the 3D API
494          * during the flush.
495          */
496         kDiscard_FlushBit                    = 0x2,
497     };
498 
499     /**
500      * Call to ensure all drawing to the context has been issued to the
501      * underlying 3D API.
502      * @param flagsBitfield     flags that control the flushing behavior. See
503      *                          FlushBits.
504      */
505     void flush(int flagsBitfield = 0);
506 
507    /**
508     * These flags can be used with the read/write pixels functions below.
509     */
510     enum PixelOpsFlags {
511         /** The GrContext will not be flushed. This means that the read or write may occur before
512             previous draws have executed. */
513         kDontFlush_PixelOpsFlag = 0x1,
514         /** The src for write or dst read is unpremultiplied. This is only respected if both the
515             config src and dst configs are an RGBA/BGRA 8888 format. */
516         kUnpremul_PixelOpsFlag  = 0x2,
517     };
518 
519     /**
520      * Reads a rectangle of pixels from a render target.
521      * @param target        the render target to read from. NULL means the current render target.
522      * @param left          left edge of the rectangle to read (inclusive)
523      * @param top           top edge of the rectangle to read (inclusive)
524      * @param width         width of rectangle to read in pixels.
525      * @param height        height of rectangle to read in pixels.
526      * @param config        the pixel config of the destination buffer
527      * @param buffer        memory to read the rectangle into.
528      * @param rowBytes      number of bytes bewtween consecutive rows. Zero means rows are tightly
529      *                      packed.
530      * @param pixelOpsFlags see PixelOpsFlags enum above.
531      *
532      * @return true if the read succeeded, false if not. The read can fail because of an unsupported
533      *         pixel config or because no render target is currently set and NULL was passed for
534      *         target.
535      */
536     bool readRenderTargetPixels(GrRenderTarget* target,
537                                 int left, int top, int width, int height,
538                                 GrPixelConfig config, void* buffer,
539                                 size_t rowBytes = 0,
540                                 uint32_t pixelOpsFlags = 0);
541 
542     /**
543      * Copy the src pixels [buffer, row bytes, pixel config] into a render target at the specified
544      * rectangle.
545      * @param target        the render target to write into. NULL means the current render target.
546      * @param left          left edge of the rectangle to write (inclusive)
547      * @param top           top edge of the rectangle to write (inclusive)
548      * @param width         width of rectangle to write in pixels.
549      * @param height        height of rectangle to write in pixels.
550      * @param config        the pixel config of the source buffer
551      * @param buffer        memory to read the rectangle from.
552      * @param rowBytes      number of bytes between consecutive rows. Zero means rows are tightly
553      *                      packed.
554      * @param pixelOpsFlags see PixelOpsFlags enum above.
555      *
556      * @return true if the write succeeded, false if not. The write can fail because of an
557      *         unsupported combination of target and pixel configs.
558      */
559     bool writeRenderTargetPixels(GrRenderTarget* target,
560                                  int left, int top, int width, int height,
561                                  GrPixelConfig config, const void* buffer,
562                                  size_t rowBytes = 0,
563                                  uint32_t pixelOpsFlags = 0);
564 
565     /**
566      * Reads a rectangle of pixels from a texture.
567      * @param texture       the texture to read from.
568      * @param left          left edge of the rectangle to read (inclusive)
569      * @param top           top edge of the rectangle to read (inclusive)
570      * @param width         width of rectangle to read in pixels.
571      * @param height        height of rectangle to read in pixels.
572      * @param config        the pixel config of the destination buffer
573      * @param buffer        memory to read the rectangle into.
574      * @param rowBytes      number of bytes between consecutive rows. Zero means rows are tightly
575      *                      packed.
576      * @param pixelOpsFlags see PixelOpsFlags enum above.
577      *
578      * @return true if the read succeeded, false if not. The read can fail because of an unsupported
579      *         pixel config.
580      */
581     bool readTexturePixels(GrTexture* texture,
582                            int left, int top, int width, int height,
583                            GrPixelConfig config, void* buffer,
584                            size_t rowBytes = 0,
585                            uint32_t pixelOpsFlags = 0);
586 
587     /**
588      * Writes a rectangle of pixels to a texture.
589      * @param texture       the render target to read from.
590      * @param left          left edge of the rectangle to write (inclusive)
591      * @param top           top edge of the rectangle to write (inclusive)
592      * @param width         width of rectangle to write in pixels.
593      * @param height        height of rectangle to write in pixels.
594      * @param config        the pixel config of the source buffer
595      * @param buffer        memory to read pixels from
596      * @param rowBytes      number of bytes between consecutive rows. Zero
597      *                      means rows are tightly packed.
598      * @param pixelOpsFlags see PixelOpsFlags enum above.
599      * @return true if the write succeeded, false if not. The write can fail because of an
600      *         unsupported combination of texture and pixel configs.
601      */
602     bool writeTexturePixels(GrTexture* texture,
603                             int left, int top, int width, int height,
604                             GrPixelConfig config, const void* buffer,
605                             size_t rowBytes,
606                             uint32_t pixelOpsFlags = 0);
607 
608 
609     /**
610      * Copies a rectangle of texels from src to dst. The size of dst is the size of the rectangle
611      * copied and topLeft is the position of the rect in src. The rectangle is clipped to src's
612      * bounds.
613      * @param src           the texture to copy from.
614      * @param dst           the render target to copy to.
615      * @param topLeft       the point in src that will be copied to the top-left of dst. If NULL,
616      *                      (0, 0) will be used.
617      */
618     void copyTexture(GrTexture* src, GrRenderTarget* dst, const SkIPoint* topLeft = NULL);
619 
620     /**
621      * Resolves a render target that has MSAA. The intermediate MSAA buffer is
622      * down-sampled to the associated GrTexture (accessible via
623      * GrRenderTarget::asTexture()). Any pending draws to the render target will
624      * be executed before the resolve.
625      *
626      * This is only necessary when a client wants to access the object directly
627      * using the backend API directly. GrContext will detect when it must
628      * perform a resolve to a GrTexture used as the source of a draw or before
629      * reading pixels back from a GrTexture or GrRenderTarget.
630      */
631     void resolveRenderTarget(GrRenderTarget* target);
632 
633 #ifdef SK_DEVELOPER
634     void dumpFontCache() const;
635 #endif
636 
637     ///////////////////////////////////////////////////////////////////////////
638     // Helpers
639 
640     class AutoRenderTarget : public ::SkNoncopyable {
641     public:
AutoRenderTarget(GrContext * context,GrRenderTarget * target)642         AutoRenderTarget(GrContext* context, GrRenderTarget* target) {
643             fPrevTarget = context->getRenderTarget();
644             SkSafeRef(fPrevTarget);
645             context->setRenderTarget(target);
646             fContext = context;
647         }
AutoRenderTarget(GrContext * context)648         AutoRenderTarget(GrContext* context) {
649             fPrevTarget = context->getRenderTarget();
650             SkSafeRef(fPrevTarget);
651             fContext = context;
652         }
~AutoRenderTarget()653         ~AutoRenderTarget() {
654             if (NULL != fContext) {
655                 fContext->setRenderTarget(fPrevTarget);
656             }
657             SkSafeUnref(fPrevTarget);
658         }
659     private:
660         GrContext*      fContext;
661         GrRenderTarget* fPrevTarget;
662     };
663 
664     /**
665      * Save/restore the view-matrix in the context. It can optionally adjust a paint to account
666      * for a coordinate system change. Here is an example of how the paint param can be used:
667      *
668      * A GrPaint is setup with GrEffects. The stages will have access to the pre-matrix source
669      * geometry positions when the draw is executed. Later on a decision is made to transform the
670      * geometry to device space on the CPU. The effects now need to know that the space in which
671      * the geometry will be specified has changed.
672      *
673      * Note that when restore is called (or in the destructor) the context's matrix will be
674      * restored. However, the paint will not be restored. The caller must make a copy of the
675      * paint if necessary. Hint: use SkTCopyOnFirstWrite if the AutoMatrix is conditionally
676      * initialized.
677      */
678     class AutoMatrix : public ::SkNoncopyable {
679     public:
AutoMatrix()680         AutoMatrix() : fContext(NULL) {}
681 
~AutoMatrix()682         ~AutoMatrix() { this->restore(); }
683 
684         /**
685          * Initializes by pre-concat'ing the context's current matrix with the preConcat param.
686          */
687         void setPreConcat(GrContext* context, const SkMatrix& preConcat, GrPaint* paint = NULL) {
688             SkASSERT(NULL != context);
689 
690             this->restore();
691 
692             fContext = context;
693             fMatrix = context->getMatrix();
694             this->preConcat(preConcat, paint);
695         }
696 
697         /**
698          * Sets the context's matrix to identity. Returns false if the inverse matrix is required to
699          * update a paint but the matrix cannot be inverted.
700          */
701         bool setIdentity(GrContext* context, GrPaint* paint = NULL) {
702             SkASSERT(NULL != context);
703 
704             this->restore();
705 
706             if (NULL != paint) {
707                 if (!paint->localCoordChangeInverse(context->getMatrix())) {
708                     return false;
709                 }
710             }
711             fMatrix = context->getMatrix();
712             fContext = context;
713             context->setIdentityMatrix();
714             return true;
715         }
716 
717         /**
718          * Replaces the context's matrix with a new matrix. Returns false if the inverse matrix is
719          * required to update a paint but the matrix cannot be inverted.
720          */
721         bool set(GrContext* context, const SkMatrix& newMatrix, GrPaint* paint = NULL) {
722             if (NULL != paint) {
723                 if (!this->setIdentity(context, paint)) {
724                     return false;
725                 }
726                 this->preConcat(newMatrix, paint);
727             } else {
728                 this->restore();
729                 fContext = context;
730                 fMatrix = context->getMatrix();
731                 context->setMatrix(newMatrix);
732             }
733             return true;
734         }
735 
736         /**
737          * If this has been initialized then the context's matrix will be further updated by
738          * pre-concat'ing the preConcat param. The matrix that will be restored remains unchanged.
739          * The paint is assumed to be relative to the context's matrix at the time this call is
740          * made, not the matrix at the time AutoMatrix was first initialized. In other words, this
741          * performs an incremental update of the paint.
742          */
743         void preConcat(const SkMatrix& preConcat, GrPaint* paint = NULL) {
744             if (NULL != paint) {
745                 paint->localCoordChange(preConcat);
746             }
747             fContext->concatMatrix(preConcat);
748         }
749 
750         /**
751          * Returns false if never initialized or the inverse matrix was required to update a paint
752          * but the matrix could not be inverted.
753          */
succeeded()754         bool succeeded() const { return NULL != fContext; }
755 
756         /**
757          * If this has been initialized then the context's original matrix is restored.
758          */
restore()759         void restore() {
760             if (NULL != fContext) {
761                 fContext->setMatrix(fMatrix);
762                 fContext = NULL;
763             }
764         }
765 
766     private:
767         GrContext*  fContext;
768         SkMatrix    fMatrix;
769     };
770 
771     class AutoClip : public ::SkNoncopyable {
772     public:
773         // This enum exists to require a caller of the constructor to acknowledge that the clip will
774         // initially be wide open. It also could be extended if there are other desirable initial
775         // clip states.
776         enum InitialClip {
777             kWideOpen_InitialClip,
778         };
779 
AutoClip(GrContext * context,InitialClip initialState)780         AutoClip(GrContext* context, InitialClip initialState)
781         : fContext(context) {
782             SkASSERT(kWideOpen_InitialClip == initialState);
783             fNewClipData.fClipStack = &fNewClipStack;
784 
785             fOldClip = context->getClip();
786             context->setClip(&fNewClipData);
787         }
788 
AutoClip(GrContext * context,const SkRect & newClipRect)789         AutoClip(GrContext* context, const SkRect& newClipRect)
790         : fContext(context)
791         , fNewClipStack(newClipRect) {
792             fNewClipData.fClipStack = &fNewClipStack;
793 
794             fOldClip = fContext->getClip();
795             fContext->setClip(&fNewClipData);
796         }
797 
~AutoClip()798         ~AutoClip() {
799             if (NULL != fContext) {
800                 fContext->setClip(fOldClip);
801             }
802         }
803     private:
804         GrContext*        fContext;
805         const GrClipData* fOldClip;
806 
807         SkClipStack       fNewClipStack;
808         GrClipData        fNewClipData;
809     };
810 
811     class AutoWideOpenIdentityDraw {
812     public:
AutoWideOpenIdentityDraw(GrContext * ctx,GrRenderTarget * rt)813         AutoWideOpenIdentityDraw(GrContext* ctx, GrRenderTarget* rt)
814             : fAutoClip(ctx, AutoClip::kWideOpen_InitialClip)
815             , fAutoRT(ctx, rt) {
816             fAutoMatrix.setIdentity(ctx);
817             // should never fail with no paint param.
818             SkASSERT(fAutoMatrix.succeeded());
819         }
820 
821     private:
822         AutoClip fAutoClip;
823         AutoRenderTarget fAutoRT;
824         AutoMatrix fAutoMatrix;
825     };
826 
827     ///////////////////////////////////////////////////////////////////////////
828     // Functions intended for internal use only.
getGpu()829     GrGpu* getGpu() { return fGpu; }
getGpu()830     const GrGpu* getGpu() const { return fGpu; }
getFontCache()831     GrFontCache* getFontCache() { return fFontCache; }
832     GrDrawTarget* getTextTarget();
833     const GrIndexBuffer* getQuadIndexBuffer() const;
834 
835     // Called by tests that draw directly to the context via GrDrawTarget
836     void getTestTarget(GrTestTarget*);
837 
838     /**
839      * Stencil buffers add themselves to the cache using addStencilBuffer. findStencilBuffer is
840      * called to check the cache for a SB that matches an RT's criteria.
841      */
842     void addStencilBuffer(GrStencilBuffer* sb);
843     GrStencilBuffer* findStencilBuffer(int width, int height, int sampleCnt);
844 
845     GrPathRenderer* getPathRenderer(
846                     const SkPath& path,
847                     const SkStrokeRec& stroke,
848                     const GrDrawTarget* target,
849                     bool allowSW,
850                     GrPathRendererChain::DrawType drawType = GrPathRendererChain::kColor_DrawType,
851                     GrPathRendererChain::StencilSupport* stencilSupport = NULL);
852 
853 
854 #if GR_CACHE_STATS
855     void printCacheStats() const;
856 #endif
857 
858 private:
859     // Used to indicate whether a draw should be performed immediately or queued in fDrawBuffer.
860     enum BufferedDraw {
861         kYes_BufferedDraw,
862         kNo_BufferedDraw,
863     };
864     BufferedDraw fLastDrawWasBuffered;
865 
866     GrGpu*                          fGpu;
867     SkMatrix                        fViewMatrix;
868     SkAutoTUnref<GrRenderTarget>    fRenderTarget;
869     const GrClipData*               fClip;  // TODO: make this ref counted
870     GrDrawState*                    fDrawState;
871 
872     GrResourceCache*                fTextureCache;
873     GrFontCache*                    fFontCache;
874 
875     GrPathRendererChain*            fPathRendererChain;
876     GrSoftwarePathRenderer*         fSoftwarePathRenderer;
877 
878     GrVertexBufferAllocPool*        fDrawBufferVBAllocPool;
879     GrIndexBufferAllocPool*         fDrawBufferIBAllocPool;
880     GrInOrderDrawBuffer*            fDrawBuffer;
881 
882     // Set by OverbudgetCB() to request that GrContext flush before exiting a draw.
883     bool                            fFlushToReduceCacheSize;
884 
885     GrAARectRenderer*               fAARectRenderer;
886     GrOvalRenderer*                 fOvalRenderer;
887 
888     bool                            fDidTestPMConversions;
889     int                             fPMToUPMConversion;
890     int                             fUPMToPMConversion;
891 
892     struct CleanUpData {
893         PFCleanUpFunc fFunc;
894         void*         fInfo;
895     };
896 
897     SkTDArray<CleanUpData>          fCleanUpData;
898 
899     int                             fMaxTextureSizeOverride;
900 
901     GrContext(); // init must be called after the constructor.
902     bool init(GrBackend, GrBackendContext);
903 
904     void setupDrawBuffer();
905 
906     class AutoRestoreEffects;
907     class AutoCheckFlush;
908     /// Sets the paint and returns the target to draw into. The paint can be NULL in which case the
909     /// draw state is left unmodified.
910     GrDrawTarget* prepareToDraw(const GrPaint*, BufferedDraw, AutoRestoreEffects*, AutoCheckFlush*);
911 
912     void internalDrawPath(GrDrawTarget* target, bool useAA, const SkPath& path,
913                           const SkStrokeRec& stroke);
914 
915     GrTexture* createResizedTexture(const GrTextureDesc& desc,
916                                     const GrCacheID& cacheID,
917                                     void* srcData,
918                                     size_t rowBytes,
919                                     bool filter);
920 
921     // Needed so GrTexture's returnToCache helper function can call
922     // addExistingTextureToCache
923     friend class GrTexture;
924     friend class GrStencilAndCoverPathRenderer;
925 
926     // Add an existing texture to the texture cache. This is intended solely
927     // for use with textures released from an GrAutoScratchTexture.
928     void addExistingTextureToCache(GrTexture* texture);
929 
930     /**
931      * These functions create premul <-> unpremul effects if it is possible to generate a pair
932      * of effects that make a readToUPM->writeToPM->readToUPM cycle invariant. Otherwise, they
933      * return NULL.
934      */
935     const GrEffectRef* createPMToUPMEffect(GrTexture* texture,
936                                            bool swapRAndB,
937                                            const SkMatrix& matrix);
938     const GrEffectRef* createUPMToPMEffect(GrTexture* texture,
939                                            bool swapRAndB,
940                                            const SkMatrix& matrix);
941 
942     /**
943      *  This callback allows the resource cache to callback into the GrContext
944      *  when the cache is still overbudget after a purge.
945      */
946     static bool OverbudgetCB(void* data);
947 
948     /** Creates a new gpu path, based on the specified path and stroke and returns it.
949      * The caller owns a ref on the returned path which must be balanced by a call to unref.
950      *
951      * @param skPath the path geometry.
952      * @param stroke the path stroke.
953      * @return a new path or NULL if the operation is not supported by the backend.
954      */
955     GrPath* createPath(const SkPath& skPath, const SkStrokeRec& stroke);
956 
957     typedef SkRefCnt INHERITED;
958 };
959 
960 /**
961  * Gets and locks a scratch texture from a descriptor using either exact or approximate criteria.
962  * Unlocks texture in the destructor.
963  */
964 class GrAutoScratchTexture : public ::SkNoncopyable {
965 public:
GrAutoScratchTexture()966     GrAutoScratchTexture()
967         : fContext(NULL)
968         , fTexture(NULL) {
969     }
970 
971     GrAutoScratchTexture(GrContext* context,
972                          const GrTextureDesc& desc,
973                          GrContext::ScratchTexMatch match = GrContext::kApprox_ScratchTexMatch)
fContext(NULL)974       : fContext(NULL)
975       , fTexture(NULL) {
976       this->set(context, desc, match);
977     }
978 
~GrAutoScratchTexture()979     ~GrAutoScratchTexture() {
980         this->reset();
981     }
982 
reset()983     void reset() {
984         if (NULL != fContext && NULL != fTexture) {
985             fContext->unlockScratchTexture(fTexture);
986             fTexture->unref();
987             fTexture = NULL;
988         }
989     }
990 
991     /*
992      * When detaching a texture we do not unlock it in the texture cache but
993      * we do set the returnToCache flag. In this way the texture remains
994      * "locked" in the texture cache until it is freed and recycled in
995      * GrTexture::internal_dispose. In reality, the texture has been removed
996      * from the cache (because this is in AutoScratchTexture) and by not
997      * calling unlockScratchTexture we simply don't re-add it. It will be
998      * reattached in GrTexture::internal_dispose.
999      *
1000      * Note that the caller is assumed to accept and manage the ref to the
1001      * returned texture.
1002      */
detach()1003     GrTexture* detach() {
1004         if (NULL == fTexture) {
1005             return NULL;
1006         }
1007         GrTexture* texture = fTexture;
1008         fTexture = NULL;
1009 
1010         // This GrAutoScratchTexture has a ref from lockAndRefScratchTexture, which we give up now.
1011         // The cache also has a ref which we are lending to the caller of detach(). When the caller
1012         // lets go of the ref and the ref count goes to 0 internal_dispose will see this flag is
1013         // set and re-ref the texture, thereby restoring the cache's ref.
1014         SkASSERT(texture->getRefCnt() > 1);
1015         texture->setFlag((GrTextureFlags) GrTexture::kReturnToCache_FlagBit);
1016         texture->unref();
1017         SkASSERT(NULL != texture->getCacheEntry());
1018 
1019         return texture;
1020     }
1021 
1022     GrTexture* set(GrContext* context,
1023                    const GrTextureDesc& desc,
1024                    GrContext::ScratchTexMatch match = GrContext::kApprox_ScratchTexMatch) {
1025         this->reset();
1026 
1027         fContext = context;
1028         if (NULL != fContext) {
1029             fTexture = fContext->lockAndRefScratchTexture(desc, match);
1030             if (NULL == fTexture) {
1031                 fContext = NULL;
1032             }
1033             return fTexture;
1034         } else {
1035             return NULL;
1036         }
1037     }
1038 
texture()1039     GrTexture* texture() { return fTexture; }
1040 
1041 private:
1042     GrContext*                    fContext;
1043     GrTexture*                    fTexture;
1044 };
1045 
1046 #endif
1047