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