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