
/*
 * Copyright 2010 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */


#ifndef GrContext_DEFINED
#define GrContext_DEFINED

#include "GrClip.h"
#include "GrPaint.h"
// not strictly needed but requires WK change in LayerTextureUpdaterCanvas to
// remove.
#include "GrRenderTarget.h" 

class GrDrawTarget;
class GrFontCache;
class GrGpu;
struct GrGpuStats;
class GrIndexBuffer;
class GrIndexBufferAllocPool;
class GrInOrderDrawBuffer;
class GrPathRenderer;
class GrPathRendererChain;
class GrResourceEntry;
class GrResourceCache;
class GrStencilBuffer;
class GrVertexBuffer;
class GrVertexBufferAllocPool;

class GR_API GrContext : public GrRefCnt {
public:
    /**
     * Creates a GrContext from within a 3D context.
     */
    static GrContext* Create(GrEngine engine,
                             GrPlatform3DContext context3D);

    virtual ~GrContext();

    /**
     * The GrContext normally assumes that no outsider is setting state
     * within the underlying 3D API's context/device/whatever. This call informs
     * the context that the state was modified and it should resend. Shouldn't
     * be called frequently for good performance.
     */
    void resetContext();

    /**
     * Abandons all gpu resources, assumes 3D API state is unknown. Call this
     * if you have lost the associated GPU context, and thus internal texture,
     * buffer, etc. references/IDs are now invalid. Should be called even when
     * GrContext is no longer going to be used for two reasons:
     *  1) ~GrContext will not try to free the objects in the 3D API.
     *  2) If you've created GrResources that outlive the GrContext they will
     *     be marked as invalid (GrResource::isValid()) and won't attempt to
     *     free their underlying resource in the 3D API.
     * Content drawn since the last GrContext::flush() may be lost.
     */
    void contextLost();

    /**
     * Similar to contextLost, but makes no attempt to reset state.
     * Use this method when GrContext destruction is pending, but
     * the graphics context is destroyed first.
     */
    void contextDestroyed();

    /**
     * Frees gpu created by the context. Can be called to reduce GPU memory
     * pressure.
     */
    void freeGpuResources();

    /**
     * Returns the number of bytes of GPU memory hosted by the texture cache.
     */
    size_t getGpuTextureCacheBytes() const;

    ///////////////////////////////////////////////////////////////////////////
    // Textures

    /**
     * Token that refers to an entry in the texture cache. Returned by
     * functions that lock textures. Passed to unlockTexture.
     */
    class TextureCacheEntry {
    public:
        TextureCacheEntry() : fEntry(NULL) {}
        TextureCacheEntry(const TextureCacheEntry& e) : fEntry(e.fEntry) {}
        TextureCacheEntry& operator= (const TextureCacheEntry& e) {
            fEntry = e.fEntry;
            return *this;
        }
        GrTexture* texture() const;
        void reset() { fEntry = NULL; }
    private:
        explicit TextureCacheEntry(GrResourceEntry* entry) { fEntry = entry; }
        void set(GrResourceEntry* entry) { fEntry = entry; }
        GrResourceEntry* cacheEntry() { return fEntry; }
        GrResourceEntry* fEntry;
        friend class GrContext;
    };

    /**
     * Key generated by client. Should be a unique key on the texture data.
     * Does not need to consider that width and height of the texture. Two
     * textures with the same TextureKey but different bounds will not collide.
     */
    typedef uint64_t TextureKey;

    /**
     *  Create a new entry, based on the specified key and texture, and return
     *  its "locked" entry. Must call be balanced with an unlockTexture() call.
     *
     *  @param key      A client-generated key that identifies the contents
     *                  of the texture. Respecified to findAndLockTexture
     *                  for subsequent uses of the texture.
     *  @param sampler  The sampler state used to draw a texture may be used
     *                  to determine how to store the pixel data in the texture
     *                  cache. (e.g. different versions may exist for different
     *                  wrap modes on GPUs with limited or no NPOT texture
     *                  support). Only the wrap and filter fields are used. NULL
     *                  implies clamp wrap modes and nearest filtering.
     * @param desc      Description of the texture properties.
     * @param srcData   Pointer to the pixel values.
     * @param rowBytes  The number of bytes between rows of the texture. Zero
     *                  implies tightly packed rows.
     */
    TextureCacheEntry createAndLockTexture(TextureKey key,
                                           const GrSamplerState* sampler,
                                           const GrTextureDesc& desc,
                                           void* srcData, size_t rowBytes);

    /**
     *  Search for an entry based on key and dimensions. If found, "lock" it and
     *  return it. The entry's texture() function will return NULL if not found.
     *  Must be balanced with an unlockTexture() call.
     *
     *  @param key      A client-generated key that identifies the contents
     *                  of the texture.
     *  @param width    The width of the texture in pixels as specifed in
     *                  the GrTextureDesc originally passed to
     *                  createAndLockTexture
     *  @param width    The height of the texture in pixels as specifed in
     *                  the GrTextureDesc originally passed to
     *                  createAndLockTexture
     *  @param sampler  The sampler state used to draw a texture may be used
     *                  to determine the cache entry used. (e.g. different
     *                  versions may exist for different wrap modes on GPUs with
     *                  limited or no NPOT texture support). Only the wrap and 
     *                  filter fields are used. NULL implies clamp wrap modes
     *                  and nearest filtering.
     */
    TextureCacheEntry findAndLockTexture(TextureKey key,
                                         int width,
                                         int height,
                                         const GrSamplerState* sampler);
    /**
     * Determines whether a texture is in the cache. If the texture is found it
     * will not be locked or returned. This call does not affect the priority of
     * the texture for deletion.
     */
    bool isTextureInCache(TextureKey key,
                          int width,
                          int height,
                          const GrSamplerState*) const;

    /**
     * Enum that determines how closely a returned scratch texture must match
     * a provided GrTextureDesc.
     */
    enum ScratchTexMatch {
        /**
         * Finds a texture that exactly matches the descriptor.
         */
        kExact_ScratchTexMatch,
        /**
         * Finds a texture that approximately matches the descriptor. Will be
         * at least as large in width and height as desc specifies. If desc
         * specifies that texture is a render target then result will be a
         * render target. If desc specifies a render target and doesn't set the
         * no stencil flag then result will have a stencil. Format and aa level
         * will always match.
         */
        kApprox_ScratchTexMatch
    };

    /**
     * Returns a texture matching the desc. It's contents are unknown. Subsequent
     * requests with the same descriptor are not guaranteed to return the same
     * texture. The same texture is guaranteed not be returned again until it is
     * unlocked. Must call be balanced with an unlockTexture() call.
     *
     * Textures created by createAndLockTexture() hide the complications of
     * tiling non-power-of-two textures on APIs that don't support this (e.g. 
     * unextended GLES2). Tiling a npot texture created by lockScratchTexture on
     * such an API will create gaps in the tiling pattern. This includes clamp
     * mode. (This may be addressed in a future update.)
     */
    TextureCacheEntry lockScratchTexture(const GrTextureDesc& desc, ScratchTexMatch match);

    /**
     *  When done with an entry, call unlockTexture(entry) on it, which returns
     *  it to the cache, where it may be purged.
     */
    void unlockTexture(TextureCacheEntry entry);

    /**
     * Creates a texture that is outside the cache. Does not count against
     * cache's budget.
     */
    GrTexture* createUncachedTexture(const GrTextureDesc&,
                                     void* srcData,
                                     size_t rowBytes);

    /**
     *  Returns true if the specified use of an indexed texture is supported.
     */
    bool supportsIndex8PixelConfig(const GrSamplerState*,
                                   int width,
                                   int height) const;

    /**
     *  Return the current texture cache limits.
     *
     *  @param maxTextures If non-null, returns maximum number of textures that
     *                     can be held in the cache.
     *  @param maxTextureBytes If non-null, returns maximum number of bytes of
     *                         texture memory that can be held in the cache.
     */
    void getTextureCacheLimits(int* maxTextures, size_t* maxTextureBytes) const;

    /**
     *  Specify the texture cache limits. If the current cache exceeds either
     *  of these, it will be purged (LRU) to keep the cache within these limits.
     *
     *  @param maxTextures The maximum number of textures that can be held in
     *                     the cache.
     *  @param maxTextureBytes The maximum number of bytes of texture memory
     *                         that can be held in the cache.
     */
    void setTextureCacheLimits(int maxTextures, size_t maxTextureBytes);

    /**
     *  Return the max width or height of a texture supported by the current gpu
     */
    int getMaxTextureSize() const;

    /**
     * Return the max width or height of a render target supported by the 
     * current gpu
     */
    int getMaxRenderTargetSize() const;

    ///////////////////////////////////////////////////////////////////////////
    // Render targets

    /**
     * Sets the render target.
     * @param target    the render target to set. (should not be NULL.)
     */
    void setRenderTarget(GrRenderTarget* target);

    /**
     * Gets the current render target.
     * @return the currently bound render target. Should never be NULL.
     */
    const GrRenderTarget* getRenderTarget() const;
    GrRenderTarget* getRenderTarget();

    ///////////////////////////////////////////////////////////////////////////
    // Platform Surfaces

    /**
     * Wraps an existing texture with a GrTexture object.
     *
     * OpenGL: if the object is a texture Gr may change its GL texture params
     *         when it is drawn.
     *
     * @param  desc     description of the object to create.
     *
     * @return GrTexture object or NULL on failure.
     */
    GrTexture* createPlatformTexture(const GrPlatformTextureDesc& desc);

    /**
     * Wraps an existing render target with a GrRenderTarget object. It is
     * similar to createPlatformTexture but can be used to draw into surfaces
     * that are not also textures (e.g. FBO 0 in OpenGL, or an MSAA buffer that
     * the client will resolve to a texture).
     *
     * @param  desc     description of the object to create.
     *
     * @return GrTexture object or NULL on failure.
     */
     GrRenderTarget* createPlatformRenderTarget(
                                    const GrPlatformRenderTargetDesc& desc);

    ///////////////////////////////////////////////////////////////////////////
    // Matrix state

    /**
     * Gets the current transformation matrix.
     * @return the current matrix.
     */
    const GrMatrix& getMatrix() const;

    /**
     * Sets the transformation matrix.
     * @param m the matrix to set.
     */
    void setMatrix(const GrMatrix& m);

    /**
     * Concats the current matrix. The passed matrix is applied before the
     * current matrix.
     * @param m the matrix to concat.
     */
    void concatMatrix(const GrMatrix& m) const;


    ///////////////////////////////////////////////////////////////////////////
    // Clip state
    /**
     * Gets the current clip.
     * @return the current clip.
     */
    const GrClip& getClip() const;

    /**
     * Sets the clip.
     * @param clip  the clip to set.
     */
    void setClip(const GrClip& clip);

    /**
     * Convenience method for setting the clip to a rect.
     * @param rect  the rect to set as the new clip.
     */
    void setClip(const GrIRect& rect);

    ///////////////////////////////////////////////////////////////////////////
    // Draws

    /**
     * Clear the entire or rect of the render target, ignoring any clips.
     * @param rect  the rect to clear or the whole thing if rect is NULL.
     * @param color the color to clear to.
     */
    void clear(const GrIRect* rect, GrColor color);

    /**
     *  Draw everywhere (respecting the clip) with the paint.
     */
    void drawPaint(const GrPaint& paint);

    /**
     *  Draw the rect using a paint.
     *  @param paint        describes how to color pixels.
     *  @param strokeWidth  If strokeWidth < 0, then the rect is filled, else
     *                      the rect is mitered stroked based on strokeWidth. If
     *                      strokeWidth == 0, then the stroke is always a single
     *                      pixel thick.
     *  @param matrix       Optional matrix applied to the rect. Applied before
     *                      context's matrix or the paint's matrix.
     *  The rects coords are used to access the paint (through texture matrix)
     */
    void drawRect(const GrPaint& paint,
                  const GrRect&,
                  GrScalar strokeWidth = -1,
                  const GrMatrix* matrix = NULL);

    /**
     * Maps a rect of paint coordinates onto the a rect of destination
     * coordinates. Each rect can optionally be transformed. The srcRect
     * is stretched over the dstRect. The dstRect is transformed by the
     * context's matrix and the srcRect is transformed by the paint's matrix.
     * Additional optional matrices can be provided by parameters.
     *
     * @param paint     describes how to color pixels.
     * @param dstRect   the destination rect to draw.
     * @param srcRect   rect of paint coordinates to be mapped onto dstRect
     * @param dstMatrix Optional matrix to transform dstRect. Applied before
     *                  context's matrix.
     * @param srcMatrix Optional matrix to transform srcRect Applied before
     *                  paint's matrix.
     */
    void drawRectToRect(const GrPaint& paint,
                        const GrRect& dstRect,
                        const GrRect& srcRect,
                        const GrMatrix* dstMatrix = NULL,
                        const GrMatrix* srcMatrix = NULL);

    /**
     * Draws a path.
     *
     * @param paint         describes how to color pixels.
     * @param path          the path to draw
     * @param fill          the path filling rule to use.
     * @param translate     optional additional translation applied to the
     *                      path.
     */
    void drawPath(const GrPaint& paint, const GrPath& path, GrPathFill fill,
                  const GrPoint* translate = NULL);

    /**
     * Draws vertices with a paint.
     *
     * @param   paint           describes how to color pixels.
     * @param   primitiveType   primitives type to draw.
     * @param   vertexCount     number of vertices.
     * @param   positions       array of vertex positions, required.
     * @param   texCoords       optional array of texture coordinates used
     *                          to access the paint.
     * @param   colors          optional array of per-vertex colors, supercedes
     *                          the paint's color field.
     * @param   indices         optional array of indices. If NULL vertices
     *                          are drawn non-indexed.
     * @param   indexCount      if indices is non-null then this is the
     *                          number of indices.
     */
    void drawVertices(const GrPaint& paint,
                      GrPrimitiveType primitiveType,
                      int vertexCount,
                      const GrPoint positions[],
                      const GrPoint texs[],
                      const GrColor colors[],
                      const uint16_t indices[],
                      int indexCount);

    ///////////////////////////////////////////////////////////////////////////
    // Misc.

    /**
     * Flags that affect flush() behavior.
     */
    enum FlushBits {
        /**
         * A client may want Gr to bind a GrRenderTarget in the 3D API so that
         * it can be rendered to directly. However, Gr lazily sets state. Simply
         * calling setRenderTarget() followed by flush() without flags may not
         * bind the render target. This flag forces the context to bind the last
         * set render target in the 3D API.
         */
        kForceCurrentRenderTarget_FlushBit   = 0x1,
        /**
         * A client may reach a point where it has partially rendered a frame
         * through a GrContext that it knows the user will never see. This flag
         * causes the flush to skip submission of deferred content to the 3D API
         * during the flush.
         */
        kDiscard_FlushBit                    = 0x2,
    };

    /**
     * Call to ensure all drawing to the context has been issued to the
     * underlying 3D API.
     * @param flagsBitfield     flags that control the flushing behavior. See
     *                          FlushBits.
     */
    void flush(int flagsBitfield = 0);

    /**
     * Reads a rectangle of pixels from a render target.
     * @param target        the render target to read from. NULL means the
     *                      current render target.
     * @param left          left edge of the rectangle to read (inclusive)
     * @param top           top edge of the rectangle to read (inclusive)
     * @param width         width of rectangle to read in pixels.
     * @param height        height of rectangle to read in pixels.
     * @param config        the pixel config of the destination buffer
     * @param buffer        memory to read the rectangle into.
     * @param rowBytes      number of bytes bewtween consecutive rows. Zero
     *                      means rows are tightly packed.
     *
     * @return true if the read succeeded, false if not. The read can fail
     *              because of an unsupported pixel config or because no render
     *              target is currently set.
     */
    bool readRenderTargetPixels(GrRenderTarget* target,
                                int left, int top, int width, int height,
                                GrPixelConfig config, void* buffer, 
                                size_t rowBytes) {
        return this->internalReadRenderTargetPixels(target, left, top,
                                                    width, height,
                                                    config, buffer,
                                                    rowBytes, 0);
    }

    /**
     * Copy the src pixels [buffer, rowbytes, pixelconfig] into a render target
     * at the specified rectangle.
     * @param target        the render target to write into. NULL means the
     *                      current render target.
     * @param left          left edge of the rectangle to write (inclusive)
     * @param top           top edge of the rectangle to write (inclusive)
     * @param width         width of rectangle to write in pixels.
     * @param height        height of rectangle to write in pixels.
     * @param config        the pixel config of the source buffer
     * @param buffer        memory to read the rectangle from.
     * @param rowBytes      number of bytes bewtween consecutive rows. Zero
     *                      means rows are tightly packed.
     */
    void writeRenderTargetPixels(GrRenderTarget* target,
                                 int left, int top, int width, int height,
                                 GrPixelConfig config, const void* buffer,
                                 size_t rowBytes) {
        this->internalWriteRenderTargetPixels(target, left, top, width, height,
                                              config, buffer, rowBytes, 0);
    }

    /**
     * Reads a rectangle of pixels from a texture.
     * @param texture       the texture to read from.
     * @param left          left edge of the rectangle to read (inclusive)
     * @param top           top edge of the rectangle to read (inclusive)
     * @param width         width of rectangle to read in pixels.
     * @param height        height of rectangle to read in pixels.
     * @param config        the pixel config of the destination buffer
     * @param buffer        memory to read the rectangle into.
     * @param rowBytes      number of bytes bewtween consecutive rows. Zero
     *                      means rows are tightly packed.
     *
     * @return true if the read succeeded, false if not. The read can fail
     *              because of an unsupported pixel config.
     */
    bool readTexturePixels(GrTexture* texture,
                           int left, int top, int width, int height,
                           GrPixelConfig config, void* buffer,
                           size_t rowBytes) {
        return this->internalReadTexturePixels(texture, left, top,
                                               width, height,
                                               config, buffer, rowBytes, 0);
    }

    /**
     * Writes a rectangle of pixels to a texture.
     * @param texture       the render target to read from.
     * @param left          left edge of the rectangle to write (inclusive)
     * @param top           top edge of the rectangle to write (inclusive)
     * @param width         width of rectangle to write in pixels.
     * @param height        height of rectangle to write in pixels.
     * @param config        the pixel config of the source buffer
     * @param buffer        memory to read pixels from
     * @param rowBytes      number of bytes bewtween consecutive rows. Zero
     *                      means rows are tightly packed.
     */
    void writeTexturePixels(GrTexture* texture,
                            int left, int top, int width, int height,
                            GrPixelConfig config, const void* buffer,
                            size_t rowBytes) {
        this->internalWriteTexturePixels(texture, left, top, width, height, 
                                         config, buffer, rowBytes, 0);
    }
    /**
     * Copies all texels from one texture to another.
     * @param src           the texture to copy from.
     * @param dst           the render target to copy to.
     */
    void copyTexture(GrTexture* src, GrRenderTarget* dst);
    /**
     * Applies a 1D convolution kernel in the X direction to a rectangle of
     * pixels from a given texture.
     * @param texture         the texture to read from
     * @param rect            the destination rectangle
     * @param kernel          the convolution kernel (kernelWidth elements)
     * @param kernelWidth     the width of the convolution kernel
     */
    void convolveInX(GrTexture* texture,
                     const SkRect& rect,
                     const float* kernel,
                     int kernelWidth);
    /**
     * Applies a 1D convolution kernel in the Y direction to a rectangle of
     * pixels from a given texture.
     * direction.
     * @param texture         the texture to read from
     * @param rect            the destination rectangle
     * @param kernel          the convolution kernel (kernelWidth elements)
     * @param kernelWidth     the width of the convolution kernel
     */
    void convolveInY(GrTexture* texture,
                     const SkRect& rect,
                     const float* kernel,
                     int kernelWidth);
    ///////////////////////////////////////////////////////////////////////////
    // Helpers

    class AutoRenderTarget : ::GrNoncopyable {
    public:
        AutoRenderTarget(GrContext* context, GrRenderTarget* target) {
            fContext = NULL;
            fPrevTarget = context->getRenderTarget();
            if (fPrevTarget != target) {
                context->setRenderTarget(target);
                fContext = context;
            }
        }
        ~AutoRenderTarget() {
            if (fContext) {
                fContext->setRenderTarget(fPrevTarget);
            }
        }
    private:
        GrContext*      fContext;
        GrRenderTarget* fPrevTarget;
    };


    ///////////////////////////////////////////////////////////////////////////
    // Functions intended for internal use only.
    GrGpu* getGpu() { return fGpu; }
    const GrGpu* getGpu() const { return fGpu; }
    GrFontCache* getFontCache() { return fFontCache; }
    GrDrawTarget* getTextTarget(const GrPaint& paint);
    void flushText();
    const GrIndexBuffer* getQuadIndexBuffer() const;
    void resetStats();
    const GrGpuStats& getStats() const;
    void printStats() const;
    /**
     * Stencil buffers add themselves to the cache using
     * addAndLockStencilBuffer. When a SB's RT-attachment count
     * reaches zero the SB unlocks itself using unlockStencilBuffer and is
     * eligible for purging. findStencilBuffer is called to check the cache for
     * a SB that matching an RT's criteria. If a match is found that has been
     * unlocked (its attachment count has reached 0) then it will be relocked.
     */
    GrResourceEntry* addAndLockStencilBuffer(GrStencilBuffer* sb);
    void unlockStencilBuffer(GrResourceEntry* sbEntry);
    GrStencilBuffer* findStencilBuffer(int width, int height, int sampleCnt);

private:
    // used to keep track of when we need to flush the draw buffer
    enum DrawCategory {
        kBuffered_DrawCategory,      // last draw was inserted in draw buffer
        kUnbuffered_DrawCategory,    // last draw was not inserted in the draw buffer
        kText_DrawCategory           // text context was last to draw
    };
    DrawCategory fLastDrawCategory;

    GrGpu*              fGpu;
    GrResourceCache*    fTextureCache;
    GrFontCache*        fFontCache;

    GrPathRendererChain*        fPathRendererChain;

    GrVertexBufferAllocPool*    fDrawBufferVBAllocPool;
    GrIndexBufferAllocPool*     fDrawBufferIBAllocPool;
    GrInOrderDrawBuffer*        fDrawBuffer;

    GrIndexBuffer*              fAAFillRectIndexBuffer;
    GrIndexBuffer*              fAAStrokeRectIndexBuffer;
    int                         fMaxOffscreenAASize;

    GrContext(GrGpu* gpu);

    void fillAARect(GrDrawTarget* target,
                    const GrRect& devRect,
                    bool useVertexCoverage);

    void strokeAARect(GrDrawTarget* target,
                      const GrRect& devRect,
                      const GrVec& devStrokeSize,
                      bool useVertexCoverage);

    inline int aaFillRectIndexCount() const;
    GrIndexBuffer* aaFillRectIndexBuffer();

    inline int aaStrokeRectIndexCount() const;
    GrIndexBuffer* aaStrokeRectIndexBuffer();

    void setupDrawBuffer();

    void flushDrawBuffer();

    void setPaint(const GrPaint& paint, GrDrawTarget* target);

    GrDrawTarget* prepareToDraw(const GrPaint& paint, DrawCategory drawType);

    GrPathRenderer* getPathRenderer(const GrPath& path,
                                    GrPathFill fill,
                                    bool antiAlias);

    struct OffscreenRecord;

    // determines whether offscreen AA should be applied
    bool doOffscreenAA(GrDrawTarget* target,
                       bool isHairLines) const;

    // attempts to setup offscreen AA. All paint state must be transferred to
    // target by the time this is called.
    bool prepareForOffscreenAA(GrDrawTarget* target,
                               bool requireStencil,
                               const GrIRect& boundRect,
                               GrPathRenderer* pr,
                               OffscreenRecord* record);

    // sets up target to draw coverage to the supersampled render target
    void setupOffscreenAAPass1(GrDrawTarget* target,
                               const GrIRect& boundRect,
                               int tileX, int tileY,
                               OffscreenRecord* record);

    // sets up target to sample coverage of supersampled render target back
    // to the main render target using stage kOffscreenStage.
    void doOffscreenAAPass2(GrDrawTarget* target,
                            const GrPaint& paint,
                            const GrIRect& boundRect,
                            int tileX, int tileY,
                            OffscreenRecord* record);

    // restored the draw target state and releases offscreen target to cache
    void cleanupOffscreenAA(GrDrawTarget* target,
                            GrPathRenderer* pr,
                            OffscreenRecord* record);

    void convolve(GrTexture* texture,
                  const SkRect& rect,
                  float imageIncrement[2],
                  const float* kernel,
                  int kernelWidth);

    /**
     * Flags to the internal read/write pixels funcs
     */
    enum PixelOpsFlags {
        kDontFlush_PixelOpsFlag = 0x1,
    };

    bool internalReadRenderTargetPixels(GrRenderTarget* target,
                                        int left, int top,
                                        int width, int height,
                                        GrPixelConfig config, void* buffer, 
                                        size_t rowBytes, uint32_t flags);

    void internalWriteRenderTargetPixels(GrRenderTarget* target,
                                        int left, int top,
                                        int width, int height,
                                        GrPixelConfig, const void* buffer,
                                        size_t rowBytes, uint32_t flags);

    bool internalReadTexturePixels(GrTexture* texture,
                                   int left, int top,
                                   int width, int height,
                                   GrPixelConfig config, void* buffer,
                                   size_t rowBytes, uint32_t flags);

    void internalWriteTexturePixels(GrTexture* texture,
                                    int left, int top,
                                    int width, int height,
                                    GrPixelConfig config, const void* buffer,
                                    size_t rowBytes, uint32_t flags);
    // needed for access to internalWriteTexturePixels. TODO: make GrContext
    // be a facade for an internal class. Then functions that are public on the 
    // internal class would have only be callable in src/gpu. The facade would
    // only have to functions necessary for clients.
    friend class GrAtlas;

    // computes vertex layout bits based on the paint. If paint expresses
    // a texture for a stage, the stage coords will be bound to postitions
    // unless hasTexCoords[s]==true in which case stage s's input coords
    // are bound to tex coord index s. hasTexCoords == NULL is a shortcut
    // for an array where all the values are false.
    static int PaintStageVertexLayoutBits(
                                    const GrPaint& paint,
                                    const bool hasTexCoords[GrPaint::kTotalStages]);
    
};

/**
 *  Save/restore the view-matrix in the context.
 */
class GrAutoMatrix : GrNoncopyable {
public:
    GrAutoMatrix() : fContext(NULL) {}
    GrAutoMatrix(GrContext* ctx) : fContext(ctx) {
        fMatrix = ctx->getMatrix();
    }
    GrAutoMatrix(GrContext* ctx, const GrMatrix& matrix) : fContext(ctx) {
        fMatrix = ctx->getMatrix();
        ctx->setMatrix(matrix);
    }
    void set(GrContext* ctx) {
        if (NULL != fContext) {
            fContext->setMatrix(fMatrix);
        }
        fMatrix = ctx->getMatrix();
        fContext = ctx;
    }
    void set(GrContext* ctx, const GrMatrix& matrix) {
        if (NULL != fContext) {
            fContext->setMatrix(fMatrix);
        }
        fMatrix = ctx->getMatrix();
        ctx->setMatrix(matrix);
        fContext = ctx;
    }
    ~GrAutoMatrix() {
        if (NULL != fContext) {
            fContext->setMatrix(fMatrix);
        }
    }

private:
    GrContext*  fContext;
    GrMatrix    fMatrix;
};

/**
 * Gets and locks a scratch texture from a descriptor using
 * either exact or approximate criteria. Unlocks texture in
 * the destructor.
 */
class GrAutoScratchTexture : ::GrNoncopyable {
public:
    GrAutoScratchTexture()
        : fContext(NULL) {
    }

    GrAutoScratchTexture(GrContext* context,
                         const GrTextureDesc& desc,
                         GrContext::ScratchTexMatch match =
                            GrContext::kApprox_ScratchTexMatch)
      : fContext(NULL) {
      this->set(context, desc, match);
    }
    
    ~GrAutoScratchTexture() {
        if (NULL != fContext) {
            fContext->unlockTexture(fEntry);
        }
    }

    GrTexture* set(GrContext* context,
                   const GrTextureDesc& desc,
                   GrContext::ScratchTexMatch match =
                        GrContext::kApprox_ScratchTexMatch) {
        if (NULL != fContext) {
            fContext->unlockTexture(fEntry);
        }
        fContext = context;
        if (NULL != fContext) {
            fEntry = fContext->lockScratchTexture(desc, match);
            GrTexture* ret = fEntry.texture();
            if (NULL == ret) {
                fContext = NULL;
            }
            return ret;
        } else {
            return NULL;
        }
    }

    GrTexture* texture() { return fEntry.texture(); }
private:
    GrContext*                    fContext;
    GrContext::TextureCacheEntry  fEntry;
};

#endif
