GrContext.h revision 50a035ddbb068446645b0978f4c092dec87a1a02
1
2/*
3 * Copyright 2010 Google Inc.
4 *
5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
7 */
8
9
10#ifndef GrContext_DEFINED
11#define GrContext_DEFINED
12
13#include "GrConfig.h"
14#include "GrPaint.h"
15#include "GrAARectRenderer.h"
16#include "GrClipData.h"
17// not strictly needed but requires WK change in LayerTextureUpdaterCanvas to
18// remove.
19#include "GrRenderTarget.h"
20#include "SkClipStack.h"
21
22class GrAutoScratchTexture;
23class GrCacheKey;
24class GrDrawState;
25class GrDrawTarget;
26class GrFontCache;
27class GrGpu;
28class GrIndexBuffer;
29class GrIndexBufferAllocPool;
30class GrInOrderDrawBuffer;
31class GrPathRenderer;
32class GrPathRendererChain;
33class GrResourceEntry;
34class GrResourceCache;
35class GrStencilBuffer;
36class GrVertexBuffer;
37class GrVertexBufferAllocPool;
38class GrSoftwarePathRenderer;
39
40class GR_API GrContext : public GrRefCnt {
41public:
42    SK_DECLARE_INST_COUNT(GrContext)
43
44    /**
45     * Creates a GrContext from within a 3D context.
46     */
47    static GrContext* Create(GrEngine engine,
48                             GrPlatform3DContext context3D);
49
50    /**
51     * Returns the number of GrContext instances for the current thread.
52     */
53    static int GetThreadInstanceCount();
54
55    virtual ~GrContext();
56
57    /**
58     * The GrContext normally assumes that no outsider is setting state
59     * within the underlying 3D API's context/device/whatever. This call informs
60     * the context that the state was modified and it should resend. Shouldn't
61     * be called frequently for good performance.
62     */
63    void resetContext();
64
65    /**
66     * Abandons all gpu resources, assumes 3D API state is unknown. Call this
67     * if you have lost the associated GPU context, and thus internal texture,
68     * buffer, etc. references/IDs are now invalid. Should be called even when
69     * GrContext is no longer going to be used for two reasons:
70     *  1) ~GrContext will not try to free the objects in the 3D API.
71     *  2) If you've created GrResources that outlive the GrContext they will
72     *     be marked as invalid (GrResource::isValid()) and won't attempt to
73     *     free their underlying resource in the 3D API.
74     * Content drawn since the last GrContext::flush() may be lost.
75     */
76    void contextLost();
77
78    /**
79     * Similar to contextLost, but makes no attempt to reset state.
80     * Use this method when GrContext destruction is pending, but
81     * the graphics context is destroyed first.
82     */
83    void contextDestroyed();
84
85    /**
86     * Frees gpu created by the context. Can be called to reduce GPU memory
87     * pressure.
88     */
89    void freeGpuResources();
90
91    /**
92     * Returns the number of bytes of GPU memory hosted by the texture cache.
93     */
94    size_t getGpuTextureCacheBytes() const;
95
96    ///////////////////////////////////////////////////////////////////////////
97    // Textures
98
99    /**
100     *  Create a new entry, based on the specified key and texture, and return
101     *  a "locked" texture. Must call be balanced with an unlockTexture() call.
102     *
103     * @param params    The tex params used to draw a texture may help determine
104     *                  the cache entry used. (e.g. different versions may exist
105     *                  for different wrap modes on GPUs with limited NPOT
106     *                  texture support). NULL implies clamp wrap modes.
107     * @param desc      Description of the texture properties.
108     * @param cacheData Cache-specific properties (e.g., texture gen ID)
109     * @param srcData   Pointer to the pixel values.
110     * @param rowBytes  The number of bytes between rows of the texture. Zero
111     *                  implies tightly packed rows.
112     */
113    GrTexture* createAndLockTexture(const GrTextureParams* params,
114                                    const GrTextureDesc& desc,
115                                    const GrCacheData& cacheData,
116                                    void* srcData, size_t rowBytes);
117
118    /**
119     * Look for a texture that matches 'key' in the cache. If not found,
120     * return NULL.
121     */
122    GrTexture* findTexture(const GrCacheKey& key);
123
124    /**
125     *  Search for an entry based on key and dimensions. If found, "lock" it and
126     *  return it. The return value will be NULL if not found.
127     *  Must be balanced with an unlockTexture() call.
128     *
129     *  @param desc     Description of the texture properties.
130     *  @param cacheData Cache-specific properties (e.g., texture gen ID)
131     *  @param params   The tex params used to draw a texture may help determine
132     *                  the cache entry used. (e.g. different versions may exist
133     *                  for different wrap modes on GPUs with limited NPOT
134     *                  texture support). NULL implies clamp wrap modes.
135     */
136    GrTexture* findAndLockTexture(const GrTextureDesc& desc,
137                                  const GrCacheData& cacheData,
138                                  const GrTextureParams* params);
139    /**
140     * Determines whether a texture is in the cache. If the texture is found it
141     * will not be locked or returned. This call does not affect the priority of
142     * the texture for deletion.
143     */
144    bool isTextureInCache(const GrTextureDesc& desc,
145                          const GrCacheData& cacheData,
146                          const GrTextureParams* params) const;
147
148    /**
149     * Enum that determines how closely a returned scratch texture must match
150     * a provided GrTextureDesc.
151     */
152    enum ScratchTexMatch {
153        /**
154         * Finds a texture that exactly matches the descriptor.
155         */
156        kExact_ScratchTexMatch,
157        /**
158         * Finds a texture that approximately matches the descriptor. Will be
159         * at least as large in width and height as desc specifies. If desc
160         * specifies that texture is a render target then result will be a
161         * render target. If desc specifies a render target and doesn't set the
162         * no stencil flag then result will have a stencil. Format and aa level
163         * will always match.
164         */
165        kApprox_ScratchTexMatch
166    };
167
168    /**
169     * Returns a texture matching the desc. It's contents are unknown. Subsequent
170     * requests with the same descriptor are not guaranteed to return the same
171     * texture. The same texture is guaranteed not be returned again until it is
172     * unlocked. Call must be balanced with an unlockTexture() call.
173     *
174     * Textures created by createAndLockTexture() hide the complications of
175     * tiling non-power-of-two textures on APIs that don't support this (e.g.
176     * unextended GLES2). Tiling a npot texture created by lockScratchTexture on
177     * such an API will create gaps in the tiling pattern. This includes clamp
178     * mode. (This may be addressed in a future update.)
179     */
180    GrTexture* lockScratchTexture(const GrTextureDesc& desc,
181                                  ScratchTexMatch match);
182
183    /**
184     * Make a texture un-purgeable in the cache
185     */
186    void lockTexture(GrTexture* texture);
187
188    /**
189     *  When done with an entry, call unlockTexture(entry) on it, which returns
190     *  it to the cache, where it may be purged.
191     */
192    void unlockTexture(GrTexture* texture);
193
194    /**
195     * This method should be called whenever a GrTexture is unreffed or
196     * switched from exclusive to non-exclusive. This
197     * gives the resource cache a chance to discard unneeded textures.
198     */
199    void purgeCache();
200
201    /**
202     * Creates a texture that is outside the cache. Does not count against
203     * cache's budget.
204     */
205    GrTexture* createUncachedTexture(const GrTextureDesc& desc,
206                                     void* srcData,
207                                     size_t rowBytes);
208
209    /**
210     * Returns true if the specified use of an indexed texture is supported.
211     * Support may depend upon whether the texture params indicate that the
212     * texture will be tiled. Passing NULL for the texture params indicates
213     * clamp mode.
214     */
215    bool supportsIndex8PixelConfig(const GrTextureParams*,
216                                   int width,
217                                   int height) const;
218
219    /**
220     *  Return the current texture cache limits.
221     *
222     *  @param maxTextures If non-null, returns maximum number of textures that
223     *                     can be held in the cache.
224     *  @param maxTextureBytes If non-null, returns maximum number of bytes of
225     *                         texture memory that can be held in the cache.
226     */
227    void getTextureCacheLimits(int* maxTextures, size_t* maxTextureBytes) const;
228
229    /**
230     *  Specify the texture cache limits. If the current cache exceeds either
231     *  of these, it will be purged (LRU) to keep the cache within these limits.
232     *
233     *  @param maxTextures The maximum number of textures that can be held in
234     *                     the cache.
235     *  @param maxTextureBytes The maximum number of bytes of texture memory
236     *                         that can be held in the cache.
237     */
238    void setTextureCacheLimits(int maxTextures, size_t maxTextureBytes);
239
240    /**
241     *  Return the max width or height of a texture supported by the current gpu
242     */
243    int getMaxTextureSize() const;
244
245    /**
246     * Return the max width or height of a render target supported by the
247     * current gpu
248     */
249    int getMaxRenderTargetSize() const;
250
251    ///////////////////////////////////////////////////////////////////////////
252    // Render targets
253
254    /**
255     * Sets the render target.
256     * @param target    the render target to set. (should not be NULL.)
257     */
258    void setRenderTarget(GrRenderTarget* target);
259
260    /**
261     * Gets the current render target.
262     * @return the currently bound render target. Should never be NULL.
263     */
264    const GrRenderTarget* getRenderTarget() const;
265    GrRenderTarget* getRenderTarget();
266
267    GrAARectRenderer* getAARectRenderer() { return fAARectRenderer; }
268
269    /**
270     * Can the provided configuration act as a color render target?
271     */
272    bool isConfigRenderable(GrPixelConfig config) const;
273
274    ///////////////////////////////////////////////////////////////////////////
275    // Platform Surfaces
276
277    /**
278     * Wraps an existing texture with a GrTexture object.
279     *
280     * OpenGL: if the object is a texture Gr may change its GL texture params
281     *         when it is drawn.
282     *
283     * @param  desc     description of the object to create.
284     *
285     * @return GrTexture object or NULL on failure.
286     */
287    GrTexture* createPlatformTexture(const GrPlatformTextureDesc& desc);
288
289    /**
290     * Wraps an existing render target with a GrRenderTarget object. It is
291     * similar to createPlatformTexture but can be used to draw into surfaces
292     * that are not also textures (e.g. FBO 0 in OpenGL, or an MSAA buffer that
293     * the client will resolve to a texture).
294     *
295     * @param  desc     description of the object to create.
296     *
297     * @return GrTexture object or NULL on failure.
298     */
299     GrRenderTarget* createPlatformRenderTarget(
300                                    const GrPlatformRenderTargetDesc& desc);
301
302    ///////////////////////////////////////////////////////////////////////////
303    // Matrix state
304
305    /**
306     * Gets the current transformation matrix.
307     * @return the current matrix.
308     */
309    const GrMatrix& getMatrix() const;
310
311    /**
312     * Sets the transformation matrix.
313     * @param m the matrix to set.
314     */
315    void setMatrix(const GrMatrix& m);
316
317    /**
318     * Concats the current matrix. The passed matrix is applied before the
319     * current matrix.
320     * @param m the matrix to concat.
321     */
322    void concatMatrix(const GrMatrix& m) const;
323
324
325    ///////////////////////////////////////////////////////////////////////////
326    // Clip state
327    /**
328     * Gets the current clip.
329     * @return the current clip.
330     */
331    const GrClipData* getClip() const;
332
333    /**
334     * Sets the clip.
335     * @param clipData  the clip to set.
336     */
337    void setClip(const GrClipData* clipData);
338
339    ///////////////////////////////////////////////////////////////////////////
340    // Draws
341
342    /**
343     * Clear the entire or rect of the render target, ignoring any clips.
344     * @param rect  the rect to clear or the whole thing if rect is NULL.
345     * @param color the color to clear to.
346     * @param target if non-NULL, the render target to clear otherwise clear
347     *               the current render target
348     */
349    void clear(const GrIRect* rect, GrColor color,
350               GrRenderTarget* target = NULL);
351
352    /**
353     *  Draw everywhere (respecting the clip) with the paint.
354     */
355    void drawPaint(const GrPaint& paint);
356
357    /**
358     *  Draw the rect using a paint.
359     *  @param paint        describes how to color pixels.
360     *  @param strokeWidth  If strokeWidth < 0, then the rect is filled, else
361     *                      the rect is mitered stroked based on strokeWidth. If
362     *                      strokeWidth == 0, then the stroke is always a single
363     *                      pixel thick.
364     *  @param matrix       Optional matrix applied to the rect. Applied before
365     *                      context's matrix or the paint's matrix.
366     *  The rects coords are used to access the paint (through texture matrix)
367     */
368    void drawRect(const GrPaint& paint,
369                  const GrRect&,
370                  GrScalar strokeWidth = -1,
371                  const GrMatrix* matrix = NULL);
372
373    /**
374     * Maps a rect of paint coordinates onto the a rect of destination
375     * coordinates. Each rect can optionally be transformed. The srcRect
376     * is stretched over the dstRect. The dstRect is transformed by the
377     * context's matrix and the srcRect is transformed by the paint's matrix.
378     * Additional optional matrices can be provided by parameters.
379     *
380     * @param paint     describes how to color pixels.
381     * @param dstRect   the destination rect to draw.
382     * @param srcRect   rect of paint coordinates to be mapped onto dstRect
383     * @param dstMatrix Optional matrix to transform dstRect. Applied before
384     *                  context's matrix.
385     * @param srcMatrix Optional matrix to transform srcRect Applied before
386     *                  paint's matrix.
387     */
388    void drawRectToRect(const GrPaint& paint,
389                        const GrRect& dstRect,
390                        const GrRect& srcRect,
391                        const GrMatrix* dstMatrix = NULL,
392                        const GrMatrix* srcMatrix = NULL);
393
394    /**
395     * Draws a path.
396     *
397     * @param paint         describes how to color pixels.
398     * @param path          the path to draw
399     * @param fill          the path filling rule to use.
400     * @param translate     optional additional translation applied to the
401     *                      path.
402     */
403    void drawPath(const GrPaint& paint, const SkPath& path, GrPathFill fill,
404                  const GrPoint* translate = NULL);
405
406    /**
407     * Draws vertices with a paint.
408     *
409     * @param   paint           describes how to color pixels.
410     * @param   primitiveType   primitives type to draw.
411     * @param   vertexCount     number of vertices.
412     * @param   positions       array of vertex positions, required.
413     * @param   texCoords       optional array of texture coordinates used
414     *                          to access the paint.
415     * @param   colors          optional array of per-vertex colors, supercedes
416     *                          the paint's color field.
417     * @param   indices         optional array of indices. If NULL vertices
418     *                          are drawn non-indexed.
419     * @param   indexCount      if indices is non-null then this is the
420     *                          number of indices.
421     */
422    void drawVertices(const GrPaint& paint,
423                      GrPrimitiveType primitiveType,
424                      int vertexCount,
425                      const GrPoint positions[],
426                      const GrPoint texs[],
427                      const GrColor colors[],
428                      const uint16_t indices[],
429                      int indexCount);
430
431    /**
432     * Draws an oval.
433     *
434     * @param paint         describes how to color pixels.
435     * @param rect          the bounding rect of the oval.
436     * @param strokeWidth   if strokeWidth < 0, then the oval is filled, else
437     *                      the rect is stroked based on strokeWidth. If
438     *                      strokeWidth == 0, then the stroke is always a single
439     *                      pixel thick.
440     */
441    void drawOval(const GrPaint& paint,
442                  const GrRect& rect,
443                  SkScalar strokeWidth);
444
445    ///////////////////////////////////////////////////////////////////////////
446    // Misc.
447
448    /**
449     * Flags that affect flush() behavior.
450     */
451    enum FlushBits {
452        /**
453         * A client may want Gr to bind a GrRenderTarget in the 3D API so that
454         * it can be rendered to directly. However, Gr lazily sets state. Simply
455         * calling setRenderTarget() followed by flush() without flags may not
456         * bind the render target. This flag forces the context to bind the last
457         * set render target in the 3D API.
458         */
459        kForceCurrentRenderTarget_FlushBit   = 0x1,
460        /**
461         * A client may reach a point where it has partially rendered a frame
462         * through a GrContext that it knows the user will never see. This flag
463         * causes the flush to skip submission of deferred content to the 3D API
464         * during the flush.
465         */
466        kDiscard_FlushBit                    = 0x2,
467    };
468
469    /**
470     * Call to ensure all drawing to the context has been issued to the
471     * underlying 3D API.
472     * @param flagsBitfield     flags that control the flushing behavior. See
473     *                          FlushBits.
474     */
475    void flush(int flagsBitfield = 0);
476
477   /**
478    * These flags can be used with the read/write pixels functions below.
479    */
480    enum PixelOpsFlags {
481        /** The GrContext will not be flushed. This means that the read or write may occur before
482            previous draws have executed. */
483        kDontFlush_PixelOpsFlag = 0x1,
484        /** The src for write or dst read is unpremultiplied. This is only respected if both the
485            config src and dst configs are an RGBA/BGRA 8888 format. */
486        kUnpremul_PixelOpsFlag  = 0x2,
487    };
488
489    /**
490     * Reads a rectangle of pixels from a render target.
491     * @param target        the render target to read from. NULL means the current render target.
492     * @param left          left edge of the rectangle to read (inclusive)
493     * @param top           top edge of the rectangle to read (inclusive)
494     * @param width         width of rectangle to read in pixels.
495     * @param height        height of rectangle to read in pixels.
496     * @param config        the pixel config of the destination buffer
497     * @param buffer        memory to read the rectangle into.
498     * @param rowBytes      number of bytes bewtween consecutive rows. Zero means rows are tightly
499     *                      packed.
500     * @param pixelOpsFlags see PixelOpsFlags enum above.
501     *
502     * @return true if the read succeeded, false if not. The read can fail because of an unsupported
503     *         pixel config or because no render target is currently set and NULL was passed for
504     *         target.
505     */
506    bool readRenderTargetPixels(GrRenderTarget* target,
507                                int left, int top, int width, int height,
508                                GrPixelConfig config, void* buffer,
509                                size_t rowBytes = 0,
510                                uint32_t pixelOpsFlags = 0);
511
512    /**
513     * Copy the src pixels [buffer, rowbytes, pixelconfig] into a render target at the specified
514     * rectangle.
515     * @param target        the render target to write into. NULL means the current render target.
516     * @param left          left edge of the rectangle to write (inclusive)
517     * @param top           top edge of the rectangle to write (inclusive)
518     * @param width         width of rectangle to write in pixels.
519     * @param height        height of rectangle to write in pixels.
520     * @param config        the pixel config of the source buffer
521     * @param buffer        memory to read the rectangle from.
522     * @param rowBytes      number of bytes bewtween consecutive rows. Zero means rows are tightly
523     *                      packed.
524     * @param pixelOpsFlags see PixelOpsFlags enum above.
525     */
526    void writeRenderTargetPixels(GrRenderTarget* target,
527                                 int left, int top, int width, int height,
528                                 GrPixelConfig config, const void* buffer,
529                                 size_t rowBytes = 0,
530                                 uint32_t pixelOpsFlags = 0);
531
532    /**
533     * Reads a rectangle of pixels from a texture.
534     * @param texture       the texture to read from.
535     * @param left          left edge of the rectangle to read (inclusive)
536     * @param top           top edge of the rectangle to read (inclusive)
537     * @param width         width of rectangle to read in pixels.
538     * @param height        height of rectangle to read in pixels.
539     * @param config        the pixel config of the destination buffer
540     * @param buffer        memory to read the rectangle into.
541     * @param rowBytes      number of bytes bewtween consecutive rows. Zero means rows are tightly
542     *                      packed.
543     * @param pixelOpsFlags see PixelOpsFlags enum above.
544     *
545     * @return true if the read succeeded, false if not. The read can fail because of an unsupported
546     *         pixel config.
547     */
548    bool readTexturePixels(GrTexture* texture,
549                           int left, int top, int width, int height,
550                           GrPixelConfig config, void* buffer,
551                           size_t rowBytes = 0,
552                           uint32_t pixelOpsFlags = 0);
553
554    /**
555     * Writes a rectangle of pixels to a texture.
556     * @param texture       the render target to read from.
557     * @param left          left edge of the rectangle to write (inclusive)
558     * @param top           top edge of the rectangle to write (inclusive)
559     * @param width         width of rectangle to write in pixels.
560     * @param height        height of rectangle to write in pixels.
561     * @param config        the pixel config of the source buffer
562     * @param buffer        memory to read pixels from
563     * @param rowBytes      number of bytes bewtween consecutive rows. Zero
564     *                      means rows are tightly packed.
565     * @param pixelOpsFlags see PixelOpsFlags enum above.
566     */
567    void writeTexturePixels(GrTexture* texture,
568                            int left, int top, int width, int height,
569                            GrPixelConfig config, const void* buffer,
570                            size_t rowBytes,
571                            uint32_t pixelOpsFlags = 0);
572
573
574    /**
575     * Copies all texels from one texture to another.
576     * @param src           the texture to copy from.
577     * @param dst           the render target to copy to.
578     */
579    void copyTexture(GrTexture* src, GrRenderTarget* dst);
580
581    /**
582     * Resolves a render target that has MSAA. The intermediate MSAA buffer is
583     * downsampled to the associated GrTexture (accessible via
584     * GrRenderTarget::asTexture()). Any pending draws to the render target will
585     * be executed before the resolve.
586     *
587     * This is only necessary when a client wants to access the object directly
588     * using the underlying graphics API. GrContext will detect when it must
589     * perform a resolve to a GrTexture used as the source of a draw or before
590     * reading pixels back from a GrTexture or GrRenderTarget.
591     */
592    void resolveRenderTarget(GrRenderTarget* target);
593
594    /**
595     * Applies a 2D Gaussian blur to a given texture.
596     * @param srcTexture      The source texture to be blurred.
597     * @param canClobberSrc   If true, srcTexture may be overwritten, and
598     *                        may be returned as the result.
599     * @param rect            The destination rectangle.
600     * @param sigmaX          The blur's standard deviation in X.
601     * @param sigmaY          The blur's standard deviation in Y.
602     * @return the blurred texture, which may be srcTexture ref'ed, or a
603     * new texture.  It is the caller's responsibility to unref this texture.
604     */
605     GrTexture* gaussianBlur(GrTexture* srcTexture,
606                             bool canClobberSrc,
607                             const SkRect& rect,
608                             float sigmaX, float sigmaY);
609
610    /**
611     * Zooms a subset of the texture to a larger size with a nice edge.
612     * The inner rectangle is a simple scaling of the texture by a factor of
613     * |zoom|.  The outer |inset| pixels transition from the background texture
614     * to the zoomed coordinate system at a rate of
615     * (distance_to_edge / inset) ^2, producing a rounded lens effect.
616     * @param srcTexture      The source texture to be zoomed.
617     * @param dstRect         The destination rectangle.
618     * @param srcRect         The source rectangle.  Must be smaller than
619     *                        dstRect
620     * @param inset           Number of pixels to blend along the edges.
621     * @return the zoomed texture, which is dstTexture.
622     */
623     GrTexture* zoom(GrTexture* srcTexture,
624                     const SkRect& dstRect, const SkRect& srcRect, float inset);
625
626    ///////////////////////////////////////////////////////////////////////////
627    // Helpers
628
629    class AutoRenderTarget : ::GrNoncopyable {
630    public:
631        AutoRenderTarget(GrContext* context, GrRenderTarget* target) {
632            fPrevTarget = context->getRenderTarget();
633            context->setRenderTarget(target);
634            fContext = context;
635        }
636        AutoRenderTarget(GrContext* context) {
637            fPrevTarget = context->getRenderTarget();
638            fContext = context;
639        }
640        ~AutoRenderTarget() {
641            if (fContext) {
642                fContext->setRenderTarget(fPrevTarget);
643            }
644        }
645    private:
646        GrContext*      fContext;
647        GrRenderTarget* fPrevTarget;
648    };
649
650    /**
651     *  Save/restore the view-matrix in the context.
652     */
653    class AutoMatrix : GrNoncopyable {
654    public:
655        enum InitialMatrix {
656            kPreserve_InitialMatrix,
657            kIdentity_InitialMatrix,
658        };
659
660        AutoMatrix() : fContext(NULL) {}
661
662        AutoMatrix(GrContext* ctx, InitialMatrix initialState) : fContext(ctx) {
663            fMatrix = ctx->getMatrix();
664            switch (initialState) {
665                case kPreserve_InitialMatrix:
666                    break;
667                case kIdentity_InitialMatrix:
668                    ctx->setMatrix(GrMatrix::I());
669                    break;
670                default:
671                    GrCrash("Unexpected initial matrix state");
672            }
673        }
674
675        AutoMatrix(GrContext* ctx, const GrMatrix& matrix) : fContext(ctx) {
676            fMatrix = ctx->getMatrix();
677            ctx->setMatrix(matrix);
678        }
679
680        void set(GrContext* ctx) {
681            if (NULL != fContext) {
682                fContext->setMatrix(fMatrix);
683            }
684            fMatrix = ctx->getMatrix();
685            fContext = ctx;
686        }
687
688        void set(GrContext* ctx, const GrMatrix& matrix) {
689            if (NULL != fContext) {
690                fContext->setMatrix(fMatrix);
691            }
692            fMatrix = ctx->getMatrix();
693            ctx->setMatrix(matrix);
694            fContext = ctx;
695        }
696
697        ~AutoMatrix() {
698            if (NULL != fContext) {
699                fContext->setMatrix(fMatrix);
700            }
701        }
702
703    private:
704        GrContext*  fContext;
705        GrMatrix    fMatrix;
706    };
707
708    class AutoClip : GrNoncopyable {
709    public:
710        // This enum exists to require a caller of the constructor to acknowledge that the clip will
711        // initially be wide open. It also could be extended if there are other desirable initial
712        // clip states.
713        enum InitialClip {
714            kWideOpen_InitialClip,
715        };
716
717        AutoClip(GrContext* context, InitialClip initialState) {
718            GrAssert(kWideOpen_InitialClip == initialState);
719            fOldClip = context->getClip();
720            fNewClipData.fClipStack = &fNewClipStack;
721            context->setClip(&fNewClipData);
722            fContext = context;
723        }
724
725        AutoClip(GrContext* context, const GrRect& newClipRect)
726        : fContext(context)
727        , fNewClipStack(newClipRect) {
728            fNewClipData.fClipStack = &fNewClipStack;
729
730            fOldClip = fContext->getClip();
731            fContext->setClip(&fNewClipData);
732        }
733
734        ~AutoClip() {
735            if (NULL != fContext) {
736                fContext->setClip(fOldClip);
737            }
738        }
739    private:
740        GrContext*        fContext;
741        const GrClipData* fOldClip;
742
743        SkClipStack       fNewClipStack;
744        GrClipData        fNewClipData;
745    };
746
747    class AutoWideOpenIdentityDraw {
748    public:
749        AutoWideOpenIdentityDraw(GrContext* ctx, GrRenderTarget* rt)
750            : fAutoClip(ctx, AutoClip::kWideOpen_InitialClip)
751            , fAutoRT(ctx, rt)
752            , fAutoMatrix(ctx, AutoMatrix::kIdentity_InitialMatrix) {
753        }
754    private:
755        AutoClip fAutoClip;
756        AutoRenderTarget fAutoRT;
757        AutoMatrix fAutoMatrix;
758    };
759
760    ///////////////////////////////////////////////////////////////////////////
761    // Functions intended for internal use only.
762    GrGpu* getGpu() { return fGpu; }
763    const GrGpu* getGpu() const { return fGpu; }
764    GrFontCache* getFontCache() { return fFontCache; }
765    GrDrawTarget* getTextTarget(const GrPaint& paint);
766    const GrIndexBuffer* getQuadIndexBuffer() const;
767
768    /**
769     * Stencil buffers add themselves to the cache using
770     * addAndLockStencilBuffer. When a SB's RT-attachment count
771     * reaches zero the SB unlocks itself using unlockStencilBuffer and is
772     * eligible for purging. findAndLockStencilBuffer is called to check the
773     * cache for a SB that matches an RT's criteria.
774     */
775    void addAndLockStencilBuffer(GrStencilBuffer* sb);
776    void unlockStencilBuffer(GrStencilBuffer* sb);
777    GrStencilBuffer* findAndLockStencilBuffer(int width, int height, int sampleCnt);
778
779    GrPathRenderer* getPathRenderer(const SkPath& path,
780                                    GrPathFill fill,
781                                    const GrDrawTarget* target,
782                                    bool antiAlias,
783                                    bool allowSW);
784
785#if GR_CACHE_STATS
786    void printCacheStats() const;
787#endif
788
789private:
790    // Used to indicate whether a draw should be performed immediately or queued in fDrawBuffer.
791    enum BufferedDraw {
792        kYes_BufferedDraw,
793        kNo_BufferedDraw,
794    };
795    BufferedDraw fLastDrawWasBuffered;
796
797    GrGpu*              fGpu;
798    GrDrawState*        fDrawState;
799
800    GrResourceCache*    fTextureCache;
801    GrFontCache*        fFontCache;
802
803    GrPathRendererChain*        fPathRendererChain;
804    GrSoftwarePathRenderer*     fSoftwarePathRenderer;
805
806    GrVertexBufferAllocPool*    fDrawBufferVBAllocPool;
807    GrIndexBufferAllocPool*     fDrawBufferIBAllocPool;
808    GrInOrderDrawBuffer*        fDrawBuffer;
809
810    GrAARectRenderer*           fAARectRenderer;
811
812    bool                        fDidTestPMConversions;
813    int                         fPMToUPMConversion;
814    int                         fUPMToPMConversion;
815
816    GrContext(GrGpu* gpu);
817
818    void setupDrawBuffer();
819
820    void flushDrawBuffer();
821
822    void setPaint(const GrPaint& paint);
823
824    /// Sets the paint and returns the target to draw into. The paint can be NULL in which case the
825    /// draw state is left unmodified.
826    GrDrawTarget* prepareToDraw(const GrPaint*, BufferedDraw);
827
828    void internalDrawPath(const GrPaint& paint, const SkPath& path,
829                          GrPathFill fill, const GrPoint* translate);
830
831    GrTexture* createResizedTexture(const GrTextureDesc& desc,
832                                    const GrCacheData& cacheData,
833                                    void* srcData,
834                                    size_t rowBytes,
835                                    bool needsFiltering);
836
837    // Needed so GrTexture's returnToCache helper function can call
838    // addExistingTextureToCache
839    friend class GrTexture;
840
841    // Add an existing texture to the texture cache. This is intended solely
842    // for use with textures released from an GrAutoScratchTexture.
843    void addExistingTextureToCache(GrTexture* texture);
844
845    GrCustomStage* createPMToUPMEffect(GrTexture* texture, bool swapRAndB);
846    GrCustomStage* createUPMToPMEffect(GrTexture* texture, bool swapRAndB);
847
848    typedef GrRefCnt INHERITED;
849};
850
851/**
852 * Gets and locks a scratch texture from a descriptor using
853 * either exact or approximate criteria. Unlocks texture in
854 * the destructor.
855 */
856class GrAutoScratchTexture : ::GrNoncopyable {
857public:
858    GrAutoScratchTexture()
859        : fContext(NULL)
860        , fTexture(NULL) {
861    }
862
863    GrAutoScratchTexture(GrContext* context,
864                         const GrTextureDesc& desc,
865                         GrContext::ScratchTexMatch match =
866                            GrContext::kApprox_ScratchTexMatch)
867      : fContext(NULL)
868      , fTexture(NULL) {
869      this->set(context, desc, match);
870    }
871
872    ~GrAutoScratchTexture() {
873        this->reset();
874    }
875
876    void reset() {
877        if (NULL != fContext && NULL != fTexture) {
878            fContext->unlockTexture(fTexture);
879            fTexture = NULL;
880        }
881    }
882
883    /*
884     * When detaching a texture we do not unlock it in the texture cache but
885     * we do set the returnToCache flag. In this way the texture remains
886     * "locked" in the texture cache until it is freed and recycled in
887     * GrTexture::internal_dispose. In reality, the texture has been removed
888     * from the cache (because this is in AutoScratchTexture) and by not
889     * calling unlockTexture we simply don't re-add it. It will be reattached
890     * in GrTexture::internal_dispose.
891     *
892     * Note that the caller is assumed to accept and manage the ref to the
893     * returned texture.
894     */
895    GrTexture* detach() {
896        GrTexture* temp = fTexture;
897
898        // Conceptually the texture's cache entry loses its ref to the
899        // texture while the caller of this method gets a ref.
900        GrAssert(NULL != temp->getCacheEntry());
901
902        fTexture = NULL;
903
904        temp->setFlag((GrTextureFlags) GrTexture::kReturnToCache_FlagBit);
905        return temp;
906    }
907
908    GrTexture* set(GrContext* context,
909                   const GrTextureDesc& desc,
910                   GrContext::ScratchTexMatch match =
911                        GrContext::kApprox_ScratchTexMatch) {
912        this->reset();
913
914        fContext = context;
915        if (NULL != fContext) {
916            fTexture = fContext->lockScratchTexture(desc, match);
917            if (NULL == fTexture) {
918                fContext = NULL;
919            }
920            return fTexture;
921        } else {
922            return NULL;
923        }
924    }
925
926    GrTexture* texture() { return fTexture; }
927
928private:
929    GrContext*                    fContext;
930    GrTexture*                    fTexture;
931};
932
933#endif
934