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