Home | History | Annotate | Download | only in gpu
      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 
     19 class GrDrawTarget;
     20 class GrFontCache;
     21 class GrGpu;
     22 struct GrGpuStats;
     23 class GrIndexBuffer;
     24 class GrIndexBufferAllocPool;
     25 class GrInOrderDrawBuffer;
     26 class GrPathRenderer;
     27 class GrPathRendererChain;
     28 class GrResourceEntry;
     29 class GrResourceCache;
     30 class GrStencilBuffer;
     31 class GrVertexBuffer;
     32 class GrVertexBufferAllocPool;
     33 
     34 class GR_API GrContext : public GrRefCnt {
     35 public:
     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 
    654 private:
    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  */
    756 class GrAutoMatrix : GrNoncopyable {
    757 public:
    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 
    787 private:
    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  */
    797 class GrAutoScratchTexture : ::GrNoncopyable {
    798 public:
    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(); }
    838 private:
    839     GrContext*                    fContext;
    840     GrContext::TextureCacheEntry  fEntry;
    841 };
    842 
    843 #endif
    844