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 "GrColor.h"
     14 #include "GrAARectRenderer.h"
     15 #include "GrClipData.h"
     16 #include "SkMatrix.h"
     17 #include "GrPaint.h"
     18 #include "GrPathRendererChain.h"
     19 // not strictly needed but requires WK change in LayerTextureUpdaterCanvas to
     20 // remove.
     21 #include "GrRenderTarget.h"
     22 #include "GrRefCnt.h"
     23 #include "GrTexture.h"
     24 
     25 class GrAutoScratchTexture;
     26 class GrDrawState;
     27 class GrDrawTarget;
     28 class GrEffect;
     29 class GrFontCache;
     30 class GrGpu;
     31 class GrIndexBuffer;
     32 class GrIndexBufferAllocPool;
     33 class GrInOrderDrawBuffer;
     34 class GrPathRenderer;
     35 class GrResourceEntry;
     36 class GrResourceCache;
     37 class GrStencilBuffer;
     38 class GrTextureParams;
     39 class GrVertexBuffer;
     40 class GrVertexBufferAllocPool;
     41 class GrSoftwarePathRenderer;
     42 class SkStrokeRec;
     43 
     44 class GR_API GrContext : public GrRefCnt {
     45 public:
     46     SK_DECLARE_INST_COUNT(GrContext)
     47 
     48     /**
     49      * Creates a GrContext for a backend context.
     50      */
     51     static GrContext* Create(GrBackend, GrBackendContext);
     52 
     53     /**
     54      * Returns the number of GrContext instances for the current thread.
     55      */
     56     static int GetThreadInstanceCount();
     57 
     58     virtual ~GrContext();
     59 
     60     /**
     61      * The GrContext normally assumes that no outsider is setting state
     62      * within the underlying 3D API's context/device/whatever. This call informs
     63      * the context that the state was modified and it should resend. Shouldn't
     64      * be called frequently for good performance.
     65      */
     66     void resetContext();
     67 
     68     /**
     69      * Callback function to allow classes to cleanup on GrContext destruction.
     70      * The 'info' field is filled in with the 'info' passed to addCleanUp.
     71      */
     72     typedef void (*PFCleanUpFunc)(const GrContext* context, void* info);
     73 
     74     /**
     75      * Add a function to be called from within GrContext's destructor.
     76      * This gives classes a chance to free resources held on a per context basis.
     77      * The 'info' parameter will be stored and passed to the callback function.
     78      */
     79     void addCleanUp(PFCleanUpFunc cleanUp, void* info) {
     80         CleanUpData* entry = fCleanUpData.push();
     81 
     82         entry->fFunc = cleanUp;
     83         entry->fInfo = info;
     84     }
     85 
     86     /**
     87      * Abandons all GPU resources, assumes 3D API state is unknown. Call this
     88      * if you have lost the associated GPU context, and thus internal texture,
     89      * buffer, etc. references/IDs are now invalid. Should be called even when
     90      * GrContext is no longer going to be used for two reasons:
     91      *  1) ~GrContext will not try to free the objects in the 3D API.
     92      *  2) If you've created GrResources that outlive the GrContext they will
     93      *     be marked as invalid (GrResource::isValid()) and won't attempt to
     94      *     free their underlying resource in the 3D API.
     95      * Content drawn since the last GrContext::flush() may be lost.
     96      */
     97     void contextLost();
     98 
     99     /**
    100      * Similar to contextLost, but makes no attempt to reset state.
    101      * Use this method when GrContext destruction is pending, but
    102      * the graphics context is destroyed first.
    103      */
    104     void contextDestroyed();
    105 
    106     /**
    107      * Frees GPU created by the context. Can be called to reduce GPU memory
    108      * pressure.
    109      */
    110     void freeGpuResources();
    111 
    112     /**
    113      * Returns the number of bytes of GPU memory hosted by the texture cache.
    114      */
    115     size_t getGpuTextureCacheBytes() const;
    116 
    117     ///////////////////////////////////////////////////////////////////////////
    118     // Textures
    119 
    120     /**
    121      * Creates a new entry, based on the specified key and texture and returns it. The caller owns a
    122      * ref on the returned texture which must be balanced by a call to unref.
    123      *
    124      * @param params    The texture params used to draw a texture may help determine
    125      *                  the cache entry used. (e.g. different versions may exist
    126      *                  for different wrap modes on GPUs with limited NPOT
    127      *                  texture support). NULL implies clamp wrap modes.
    128      * @param desc      Description of the texture properties.
    129      * @param cacheID Cache-specific properties (e.g., texture gen ID)
    130      * @param srcData   Pointer to the pixel values.
    131      * @param rowBytes  The number of bytes between rows of the texture. Zero
    132      *                  implies tightly packed rows.
    133      */
    134     GrTexture* createTexture(const GrTextureParams* params,
    135                              const GrTextureDesc& desc,
    136                              const GrCacheID& cacheID,
    137                              void* srcData, size_t rowBytes);
    138 
    139     /**
    140      * Search for an entry based on key and dimensions. If found, ref it and return it. The return
    141      * value will be NULL if not found. The caller must balance with a call to unref.
    142      *
    143      *  @param desc     Description of the texture properties.
    144      *  @param cacheID Cache-specific properties (e.g., texture gen ID)
    145      *  @param params   The texture params used to draw a texture may help determine
    146      *                  the cache entry used. (e.g. different versions may exist
    147      *                  for different wrap modes on GPUs with limited NPOT
    148      *                  texture support). NULL implies clamp wrap modes.
    149      */
    150     GrTexture* findAndRefTexture(const GrTextureDesc& desc,
    151                                  const GrCacheID& cacheID,
    152                                  const GrTextureParams* params);
    153     /**
    154      * Determines whether a texture is in the cache. If the texture is found it
    155      * will not be locked or returned. This call does not affect the priority of
    156      * the texture for deletion.
    157      */
    158     bool isTextureInCache(const GrTextureDesc& desc,
    159                           const GrCacheID& cacheID,
    160                           const GrTextureParams* params) const;
    161 
    162     /**
    163      * Enum that determines how closely a returned scratch texture must match
    164      * a provided GrTextureDesc.
    165      */
    166     enum ScratchTexMatch {
    167         /**
    168          * Finds a texture that exactly matches the descriptor.
    169          */
    170         kExact_ScratchTexMatch,
    171         /**
    172          * Finds a texture that approximately matches the descriptor. Will be
    173          * at least as large in width and height as desc specifies. If desc
    174          * specifies that texture is a render target then result will be a
    175          * render target. If desc specifies a render target and doesn't set the
    176          * no stencil flag then result will have a stencil. Format and aa level
    177          * will always match.
    178          */
    179         kApprox_ScratchTexMatch
    180     };
    181 
    182     /**
    183      * Returns a texture matching the desc. It's contents are unknown. Subsequent
    184      * requests with the same descriptor are not guaranteed to return the same
    185      * texture. The same texture is guaranteed not be returned again until it is
    186      * unlocked. Call must be balanced with an unlockTexture() call. The caller
    187      * owns a ref on the returned texture and must balance with a call to unref.
    188      *
    189      * Textures created by createAndLockTexture() hide the complications of
    190      * tiling non-power-of-two textures on APIs that don't support this (e.g.
    191      * unextended GLES2). Tiling a NPOT texture created by lockScratchTexture on
    192      * such an API will create gaps in the tiling pattern. This includes clamp
    193      * mode. (This may be addressed in a future update.)
    194      */
    195     GrTexture* lockAndRefScratchTexture(const GrTextureDesc&, ScratchTexMatch match);
    196 
    197     /**
    198      *  When done with an entry, call unlockScratchTexture(entry) on it, which returns
    199      *  it to the cache, where it may be purged. This does not unref the texture.
    200      */
    201     void unlockScratchTexture(GrTexture* texture);
    202 
    203     /**
    204      * This method should be called whenever a GrTexture is unreffed or
    205      * switched from exclusive to non-exclusive. This
    206      * gives the resource cache a chance to discard unneeded textures.
    207      * Note: this entry point will be removed once totally ref-driven
    208      * cache maintenance is implemented
    209      */
    210     void purgeCache();
    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& desc,
    217                                      void* srcData,
    218                                      size_t rowBytes);
    219 
    220     /**
    221      * Returns true if the specified use of an indexed texture is supported.
    222      * Support may depend upon whether the texture params indicate that the
    223      * texture will be tiled. Passing NULL for the texture params indicates
    224      * clamp mode.
    225      */
    226     bool supportsIndex8PixelConfig(const GrTextureParams*,
    227                                    int width,
    228                                    int height) const;
    229 
    230     /**
    231      *  Return the current texture cache limits.
    232      *
    233      *  @param maxTextures If non-null, returns maximum number of textures that
    234      *                     can be held in the cache.
    235      *  @param maxTextureBytes If non-null, returns maximum number of bytes of
    236      *                         texture memory that can be held in the cache.
    237      */
    238     void getTextureCacheLimits(int* maxTextures, size_t* maxTextureBytes) const;
    239 
    240     /**
    241      *  Specify the texture cache limits. If the current cache exceeds either
    242      *  of these, it will be purged (LRU) to keep the cache within these limits.
    243      *
    244      *  @param maxTextures The maximum number of textures that can be held in
    245      *                     the cache.
    246      *  @param maxTextureBytes The maximum number of bytes of texture memory
    247      *                         that can be held in the cache.
    248      */
    249     void setTextureCacheLimits(int maxTextures, size_t maxTextureBytes);
    250 
    251     /**
    252      *  Return the max width or height of a texture supported by the current GPU.
    253      */
    254     int getMaxTextureSize() const;
    255 
    256     /**
    257      * Return the max width or height of a render target supported by the
    258      * current GPU.
    259      */
    260     int getMaxRenderTargetSize() const;
    261 
    262     ///////////////////////////////////////////////////////////////////////////
    263     // Render targets
    264 
    265     /**
    266      * Sets the render target.
    267      * @param target    the render target to set. (should not be NULL.)
    268      */
    269     void setRenderTarget(GrRenderTarget* target);
    270 
    271     /**
    272      * Gets the current render target.
    273      * @return the currently bound render target. Should never be NULL.
    274      */
    275     const GrRenderTarget* getRenderTarget() const;
    276     GrRenderTarget* getRenderTarget();
    277 
    278     GrAARectRenderer* getAARectRenderer() { return fAARectRenderer; }
    279 
    280     /**
    281      * Can the provided configuration act as a color render target?
    282      */
    283     bool isConfigRenderable(GrPixelConfig config) const;
    284 
    285     ///////////////////////////////////////////////////////////////////////////
    286     // Backend Surfaces
    287 
    288     /**
    289      * Wraps an existing texture with a GrTexture object.
    290      *
    291      * OpenGL: if the object is a texture Gr may change its GL texture params
    292      *         when it is drawn.
    293      *
    294      * @param  desc     description of the object to create.
    295      *
    296      * @return GrTexture object or NULL on failure.
    297      */
    298     GrTexture* wrapBackendTexture(const GrBackendTextureDesc& desc);
    299 
    300     /**
    301      * Wraps an existing render target with a GrRenderTarget object. It is
    302      * similar to wrapBackendTexture but can be used to draw into surfaces
    303      * that are not also textures (e.g. FBO 0 in OpenGL, or an MSAA buffer that
    304      * the client will resolve to a texture).
    305      *
    306      * @param  desc     description of the object to create.
    307      *
    308      * @return GrTexture object or NULL on failure.
    309      */
    310      GrRenderTarget* wrapBackendRenderTarget(const GrBackendRenderTargetDesc& desc);
    311 
    312     ///////////////////////////////////////////////////////////////////////////
    313     // Matrix state
    314 
    315     /**
    316      * Gets the current transformation matrix.
    317      * @return the current matrix.
    318      */
    319     const SkMatrix& getMatrix() const;
    320 
    321     /**
    322      * Sets the transformation matrix.
    323      * @param m the matrix to set.
    324      */
    325     void setMatrix(const SkMatrix& m);
    326 
    327     /**
    328      * Sets the current transformation matrix to identity.
    329      */
    330     void setIdentityMatrix();
    331 
    332     /**
    333      * Concats the current matrix. The passed matrix is applied before the
    334      * current matrix.
    335      * @param m the matrix to concat.
    336      */
    337     void concatMatrix(const SkMatrix& m) const;
    338 
    339 
    340     ///////////////////////////////////////////////////////////////////////////
    341     // Clip state
    342     /**
    343      * Gets the current clip.
    344      * @return the current clip.
    345      */
    346     const GrClipData* getClip() const;
    347 
    348     /**
    349      * Sets the clip.
    350      * @param clipData  the clip to set.
    351      */
    352     void setClip(const GrClipData* clipData);
    353 
    354     ///////////////////////////////////////////////////////////////////////////
    355     // Draws
    356 
    357     /**
    358      * Clear the entire or rect of the render target, ignoring any clips.
    359      * @param rect  the rect to clear or the whole thing if rect is NULL.
    360      * @param color the color to clear to.
    361      * @param target if non-NULL, the render target to clear otherwise clear
    362      *               the current render target
    363      */
    364     void clear(const GrIRect* rect, GrColor color,
    365                GrRenderTarget* target = NULL);
    366 
    367     /**
    368      *  Draw everywhere (respecting the clip) with the paint.
    369      */
    370     void drawPaint(const GrPaint& paint);
    371 
    372     /**
    373      *  Draw the rect using a paint.
    374      *  @param paint        describes how to color pixels.
    375      *  @param strokeWidth  If strokeWidth < 0, then the rect is filled, else
    376      *                      the rect is mitered stroked based on strokeWidth. If
    377      *                      strokeWidth == 0, then the stroke is always a single
    378      *                      pixel thick.
    379      *  @param matrix       Optional matrix applied to the rect. Applied before
    380      *                      context's matrix or the paint's matrix.
    381      *  The rects coords are used to access the paint (through texture matrix)
    382      */
    383     void drawRect(const GrPaint& paint,
    384                   const GrRect&,
    385                   SkScalar strokeWidth = -1,
    386                   const SkMatrix* matrix = NULL);
    387 
    388     /**
    389      * Maps a rect of paint coordinates onto the a rect of destination
    390      * coordinates. Each rect can optionally be transformed. The srcRect
    391      * is stretched over the dstRect. The dstRect is transformed by the
    392      * context's matrix and the srcRect is transformed by the paint's matrix.
    393      * Additional optional matrices can be provided by parameters.
    394      *
    395      * @param paint     describes how to color pixels.
    396      * @param dstRect   the destination rect to draw.
    397      * @param srcRect   rect of paint coordinates to be mapped onto dstRect
    398      * @param dstMatrix Optional matrix to transform dstRect. Applied before
    399      *                  context's matrix.
    400      * @param srcMatrix Optional matrix to transform srcRect Applied before
    401      *                  paint's matrix.
    402      */
    403     void drawRectToRect(const GrPaint& paint,
    404                         const GrRect& dstRect,
    405                         const GrRect& srcRect,
    406                         const SkMatrix* dstMatrix = NULL,
    407                         const SkMatrix* srcMatrix = NULL);
    408 
    409     /**
    410      * Draws a path.
    411      *
    412      * @param paint         describes how to color pixels.
    413      * @param path          the path to draw
    414      * @param stroke        the stroke information (width, join, cap)
    415      */
    416     void drawPath(const GrPaint& paint, const SkPath& path, const SkStrokeRec& stroke);
    417 
    418     /**
    419      * Draws vertices with a paint.
    420      *
    421      * @param   paint           describes how to color pixels.
    422      * @param   primitiveType   primitives type to draw.
    423      * @param   vertexCount     number of vertices.
    424      * @param   positions       array of vertex positions, required.
    425      * @param   texCoords       optional array of texture coordinates used
    426      *                          to access the paint.
    427      * @param   colors          optional array of per-vertex colors, supercedes
    428      *                          the paint's color field.
    429      * @param   indices         optional array of indices. If NULL vertices
    430      *                          are drawn non-indexed.
    431      * @param   indexCount      if indices is non-null then this is the
    432      *                          number of indices.
    433      */
    434     void drawVertices(const GrPaint& paint,
    435                       GrPrimitiveType primitiveType,
    436                       int vertexCount,
    437                       const GrPoint positions[],
    438                       const GrPoint texs[],
    439                       const GrColor colors[],
    440                       const uint16_t indices[],
    441                       int indexCount);
    442 
    443     /**
    444      * Draws an oval.
    445      *
    446      * @param paint         describes how to color pixels.
    447      * @param oval          the bounding rect of the oval.
    448      * @param stroke        the stroke information (width, style)
    449      */
    450     void drawOval(const GrPaint& paint,
    451                   const GrRect& oval,
    452                   const SkStrokeRec& stroke);
    453 
    454     ///////////////////////////////////////////////////////////////////////////
    455     // Misc.
    456 
    457     /**
    458      * Flags that affect flush() behavior.
    459      */
    460     enum FlushBits {
    461         /**
    462          * A client may want Gr to bind a GrRenderTarget in the 3D API so that
    463          * it can be rendered to directly. However, Gr lazily sets state. Simply
    464          * calling setRenderTarget() followed by flush() without flags may not
    465          * bind the render target. This flag forces the context to bind the last
    466          * set render target in the 3D API.
    467          */
    468         kForceCurrentRenderTarget_FlushBit   = 0x1,
    469         /**
    470          * A client may reach a point where it has partially rendered a frame
    471          * through a GrContext that it knows the user will never see. This flag
    472          * causes the flush to skip submission of deferred content to the 3D API
    473          * during the flush.
    474          */
    475         kDiscard_FlushBit                    = 0x2,
    476     };
    477 
    478     /**
    479      * Call to ensure all drawing to the context has been issued to the
    480      * underlying 3D API.
    481      * @param flagsBitfield     flags that control the flushing behavior. See
    482      *                          FlushBits.
    483      */
    484     void flush(int flagsBitfield = 0);
    485 
    486    /**
    487     * These flags can be used with the read/write pixels functions below.
    488     */
    489     enum PixelOpsFlags {
    490         /** The GrContext will not be flushed. This means that the read or write may occur before
    491             previous draws have executed. */
    492         kDontFlush_PixelOpsFlag = 0x1,
    493         /** The src for write or dst read is unpremultiplied. This is only respected if both the
    494             config src and dst configs are an RGBA/BGRA 8888 format. */
    495         kUnpremul_PixelOpsFlag  = 0x2,
    496     };
    497 
    498     /**
    499      * Reads a rectangle of pixels from a render target.
    500      * @param target        the render target to read from. NULL means the current render target.
    501      * @param left          left edge of the rectangle to read (inclusive)
    502      * @param top           top edge of the rectangle to read (inclusive)
    503      * @param width         width of rectangle to read in pixels.
    504      * @param height        height of rectangle to read in pixels.
    505      * @param config        the pixel config of the destination buffer
    506      * @param buffer        memory to read the rectangle into.
    507      * @param rowBytes      number of bytes bewtween consecutive rows. Zero means rows are tightly
    508      *                      packed.
    509      * @param pixelOpsFlags see PixelOpsFlags enum above.
    510      *
    511      * @return true if the read succeeded, false if not. The read can fail because of an unsupported
    512      *         pixel config or because no render target is currently set and NULL was passed for
    513      *         target.
    514      */
    515     bool readRenderTargetPixels(GrRenderTarget* target,
    516                                 int left, int top, int width, int height,
    517                                 GrPixelConfig config, void* buffer,
    518                                 size_t rowBytes = 0,
    519                                 uint32_t pixelOpsFlags = 0);
    520 
    521     /**
    522      * Copy the src pixels [buffer, row bytes, pixel config] into a render target at the specified
    523      * rectangle.
    524      * @param target        the render target to write into. NULL means the current render target.
    525      * @param left          left edge of the rectangle to write (inclusive)
    526      * @param top           top edge of the rectangle to write (inclusive)
    527      * @param width         width of rectangle to write in pixels.
    528      * @param height        height of rectangle to write in pixels.
    529      * @param config        the pixel config of the source buffer
    530      * @param buffer        memory to read the rectangle from.
    531      * @param rowBytes      number of bytes between consecutive rows. Zero means rows are tightly
    532      *                      packed.
    533      * @param pixelOpsFlags see PixelOpsFlags enum above.
    534      */
    535     void writeRenderTargetPixels(GrRenderTarget* target,
    536                                  int left, int top, int width, int height,
    537                                  GrPixelConfig config, const void* buffer,
    538                                  size_t rowBytes = 0,
    539                                  uint32_t pixelOpsFlags = 0);
    540 
    541     /**
    542      * Reads a rectangle of pixels from a texture.
    543      * @param texture       the texture to read from.
    544      * @param left          left edge of the rectangle to read (inclusive)
    545      * @param top           top edge of the rectangle to read (inclusive)
    546      * @param width         width of rectangle to read in pixels.
    547      * @param height        height of rectangle to read in pixels.
    548      * @param config        the pixel config of the destination buffer
    549      * @param buffer        memory to read the rectangle into.
    550      * @param rowBytes      number of bytes between consecutive rows. Zero means rows are tightly
    551      *                      packed.
    552      * @param pixelOpsFlags see PixelOpsFlags enum above.
    553      *
    554      * @return true if the read succeeded, false if not. The read can fail because of an unsupported
    555      *         pixel config.
    556      */
    557     bool readTexturePixels(GrTexture* texture,
    558                            int left, int top, int width, int height,
    559                            GrPixelConfig config, void* buffer,
    560                            size_t rowBytes = 0,
    561                            uint32_t pixelOpsFlags = 0);
    562 
    563     /**
    564      * Writes a rectangle of pixels to a texture.
    565      * @param texture       the render target to read from.
    566      * @param left          left edge of the rectangle to write (inclusive)
    567      * @param top           top edge of the rectangle to write (inclusive)
    568      * @param width         width of rectangle to write in pixels.
    569      * @param height        height of rectangle to write in pixels.
    570      * @param config        the pixel config of the source buffer
    571      * @param buffer        memory to read pixels from
    572      * @param rowBytes      number of bytes between consecutive rows. Zero
    573      *                      means rows are tightly packed.
    574      * @param pixelOpsFlags see PixelOpsFlags enum above.
    575      */
    576     void writeTexturePixels(GrTexture* texture,
    577                             int left, int top, int width, int height,
    578                             GrPixelConfig config, const void* buffer,
    579                             size_t rowBytes,
    580                             uint32_t pixelOpsFlags = 0);
    581 
    582 
    583     /**
    584      * Copies a rectangle of texels from src to dst. The size of dst is the size of the rectangle
    585      * copied and topLeft is the position of the rect in src. The rectangle is clipped to src's
    586      * bounds.
    587      * @param src           the texture to copy from.
    588      * @param dst           the render target to copy to.
    589      * @param topLeft       the point in src that will be copied to the top-left of dst. If NULL,
    590      *                      (0, 0) will be used.
    591      */
    592     void copyTexture(GrTexture* src, GrRenderTarget* dst, const SkIPoint* topLeft = NULL);
    593 
    594     /**
    595      * Resolves a render target that has MSAA. The intermediate MSAA buffer is
    596      * down-sampled to the associated GrTexture (accessible via
    597      * GrRenderTarget::asTexture()). Any pending draws to the render target will
    598      * be executed before the resolve.
    599      *
    600      * This is only necessary when a client wants to access the object directly
    601      * using the backend API directly. GrContext will detect when it must
    602      * perform a resolve to a GrTexture used as the source of a draw or before
    603      * reading pixels back from a GrTexture or GrRenderTarget.
    604      */
    605     void resolveRenderTarget(GrRenderTarget* target);
    606 
    607     /**
    608      * Applies a 2D Gaussian blur to a given texture.
    609      * @param srcTexture      The source texture to be blurred.
    610      * @param canClobberSrc   If true, srcTexture may be overwritten, and
    611      *                        may be returned as the result.
    612      * @param rect            The destination rectangle.
    613      * @param sigmaX          The blur's standard deviation in X.
    614      * @param sigmaY          The blur's standard deviation in Y.
    615      * @return the blurred texture, which may be srcTexture reffed, or a
    616      * new texture.  It is the caller's responsibility to unref this texture.
    617      */
    618      GrTexture* gaussianBlur(GrTexture* srcTexture,
    619                              bool canClobberSrc,
    620                              const SkRect& rect,
    621                              float sigmaX, float sigmaY);
    622 
    623     ///////////////////////////////////////////////////////////////////////////
    624     // Helpers
    625 
    626     class AutoRenderTarget : public ::GrNoncopyable {
    627     public:
    628         AutoRenderTarget(GrContext* context, GrRenderTarget* target) {
    629             fPrevTarget = context->getRenderTarget();
    630             GrSafeRef(fPrevTarget);
    631             context->setRenderTarget(target);
    632             fContext = context;
    633         }
    634         AutoRenderTarget(GrContext* context) {
    635             fPrevTarget = context->getRenderTarget();
    636             GrSafeRef(fPrevTarget);
    637             fContext = context;
    638         }
    639         ~AutoRenderTarget() {
    640             if (NULL != fContext) {
    641                 fContext->setRenderTarget(fPrevTarget);
    642             }
    643             GrSafeUnref(fPrevTarget);
    644         }
    645     private:
    646         GrContext*      fContext;
    647         GrRenderTarget* fPrevTarget;
    648     };
    649 
    650     /**
    651      * Save/restore the view-matrix in the context. It can optionally adjust a paint to account
    652      * for a coordinate system change. Here is an example of how the paint param can be used:
    653      *
    654      * A GrPaint is setup with GrEffects. The stages will have access to the pre-matrix source
    655      * geometry positions when the draw is executed. Later on a decision is made to transform the
    656      * geometry to device space on the CPU. The effects now need to know that the space in which
    657      * the geometry will be specified has changed.
    658      *
    659      * Note that when restore is called (or in the destructor) the context's matrix will be
    660      * restored. However, the paint will not be restored. The caller must make a copy of the
    661      * paint if necessary. Hint: use SkTCopyOnFirstWrite if the AutoMatrix is conditionally
    662      * initialized.
    663      */
    664     class AutoMatrix : GrNoncopyable {
    665     public:
    666         AutoMatrix() : fContext(NULL) {}
    667 
    668         ~AutoMatrix() { this->restore(); }
    669 
    670         /**
    671          * Initializes by pre-concat'ing the context's current matrix with the preConcat param.
    672          */
    673         void setPreConcat(GrContext* context, const SkMatrix& preConcat, GrPaint* paint = NULL) {
    674             GrAssert(NULL != context);
    675 
    676             this->restore();
    677 
    678             fContext = context;
    679             fMatrix = context->getMatrix();
    680             this->preConcat(preConcat, paint);
    681         }
    682 
    683         /**
    684          * Sets the context's matrix to identity. Returns false if the inverse matrix is required to
    685          * update a paint but the matrix cannot be inverted.
    686          */
    687         bool setIdentity(GrContext* context, GrPaint* paint = NULL) {
    688             GrAssert(NULL != context);
    689 
    690             this->restore();
    691 
    692             if (NULL != paint) {
    693                 if (!paint->sourceCoordChangeByInverse(context->getMatrix())) {
    694                     return false;
    695                 }
    696             }
    697             fMatrix = context->getMatrix();
    698             fContext = context;
    699             context->setIdentityMatrix();
    700             return true;
    701         }
    702 
    703         /**
    704          * Replaces the context's matrix with a new matrix. Returns false if the inverse matrix is
    705          * required to update a paint but the matrix cannot be inverted.
    706          */
    707         bool set(GrContext* context, const SkMatrix& newMatrix, GrPaint* paint = NULL) {
    708             if (NULL != paint) {
    709                 if (!this->setIdentity(context, paint)) {
    710                     return false;
    711                 }
    712                 this->preConcat(newMatrix, paint);
    713             } else {
    714                 this->restore();
    715                 fContext = context;
    716                 fMatrix = context->getMatrix();
    717                 context->setMatrix(newMatrix);
    718             }
    719             return true;
    720         }
    721 
    722         /**
    723          * If this has been initialized then the context's matrix will be further updated by
    724          * pre-concat'ing the preConcat param. The matrix that will be restored remains unchanged.
    725          * The paint is assumed to be relative to the context's matrix at the time this call is
    726          * made, not the matrix at the time AutoMatrix was first initialized. In other words, this
    727          * performs an incremental update of the paint.
    728          */
    729         void preConcat(const SkMatrix& preConcat, GrPaint* paint = NULL) {
    730             if (NULL != paint) {
    731                 paint->sourceCoordChange(preConcat);
    732             }
    733             fContext->concatMatrix(preConcat);
    734         }
    735 
    736         /**
    737          * Returns false if never initialized or the inverse matrix was required to update a paint
    738          * but the matrix could not be inverted.
    739          */
    740         bool succeeded() const { return NULL != fContext; }
    741 
    742         /**
    743          * If this has been initialized then the context's original matrix is restored.
    744          */
    745         void restore() {
    746             if (NULL != fContext) {
    747                 fContext->setMatrix(fMatrix);
    748                 fContext = NULL;
    749             }
    750         }
    751 
    752     private:
    753         GrContext*  fContext;
    754         SkMatrix    fMatrix;
    755     };
    756 
    757     class AutoClip : GrNoncopyable {
    758     public:
    759         // This enum exists to require a caller of the constructor to acknowledge that the clip will
    760         // initially be wide open. It also could be extended if there are other desirable initial
    761         // clip states.
    762         enum InitialClip {
    763             kWideOpen_InitialClip,
    764         };
    765 
    766         AutoClip(GrContext* context, InitialClip initialState)
    767         : fContext(context) {
    768             GrAssert(kWideOpen_InitialClip == initialState);
    769             fNewClipData.fClipStack = &fNewClipStack;
    770 
    771             fOldClip = context->getClip();
    772             context->setClip(&fNewClipData);
    773         }
    774 
    775         AutoClip(GrContext* context, const GrRect& newClipRect)
    776         : fContext(context)
    777         , fNewClipStack(newClipRect) {
    778             fNewClipData.fClipStack = &fNewClipStack;
    779 
    780             fOldClip = fContext->getClip();
    781             fContext->setClip(&fNewClipData);
    782         }
    783 
    784         ~AutoClip() {
    785             if (NULL != fContext) {
    786                 fContext->setClip(fOldClip);
    787             }
    788         }
    789     private:
    790         GrContext*        fContext;
    791         const GrClipData* fOldClip;
    792 
    793         SkClipStack       fNewClipStack;
    794         GrClipData        fNewClipData;
    795     };
    796 
    797     class AutoWideOpenIdentityDraw {
    798     public:
    799         AutoWideOpenIdentityDraw(GrContext* ctx, GrRenderTarget* rt)
    800             : fAutoClip(ctx, AutoClip::kWideOpen_InitialClip)
    801             , fAutoRT(ctx, rt) {
    802             fAutoMatrix.setIdentity(ctx);
    803             // should never fail with no paint param.
    804             GrAssert(fAutoMatrix.succeeded());
    805         }
    806 
    807     private:
    808         AutoClip fAutoClip;
    809         AutoRenderTarget fAutoRT;
    810         AutoMatrix fAutoMatrix;
    811     };
    812 
    813     ///////////////////////////////////////////////////////////////////////////
    814     // Functions intended for internal use only.
    815     GrGpu* getGpu() { return fGpu; }
    816     const GrGpu* getGpu() const { return fGpu; }
    817     GrFontCache* getFontCache() { return fFontCache; }
    818     GrDrawTarget* getTextTarget(const GrPaint& paint);
    819     const GrIndexBuffer* getQuadIndexBuffer() const;
    820 
    821     /**
    822      * Stencil buffers add themselves to the cache using addStencilBuffer. findStencilBuffer is
    823      * called to check the cache for a SB that matches an RT's criteria.
    824      */
    825     void addStencilBuffer(GrStencilBuffer* sb);
    826     GrStencilBuffer* findStencilBuffer(int width, int height, int sampleCnt);
    827 
    828     GrPathRenderer* getPathRenderer(
    829                     const SkPath& path,
    830                     const SkStrokeRec& stroke,
    831                     const GrDrawTarget* target,
    832                     bool allowSW,
    833                     GrPathRendererChain::DrawType drawType = GrPathRendererChain::kColor_DrawType,
    834                     GrPathRendererChain::StencilSupport* stencilSupport = NULL);
    835 
    836 #if GR_CACHE_STATS
    837     void printCacheStats() const;
    838 #endif
    839 
    840     ///////////////////////////////////////////////////////////////////////////
    841     // Legacy names that will be kept until WebKit can be updated.
    842     GrTexture* createPlatformTexture(const GrPlatformTextureDesc& desc) {
    843         return this->wrapBackendTexture(desc);
    844     }
    845 
    846     GrRenderTarget* createPlatformRenderTarget(const GrPlatformRenderTargetDesc& desc) {
    847         return wrapBackendRenderTarget(desc);
    848     }
    849 
    850 private:
    851     // Used to indicate whether a draw should be performed immediately or queued in fDrawBuffer.
    852     enum BufferedDraw {
    853         kYes_BufferedDraw,
    854         kNo_BufferedDraw,
    855     };
    856     BufferedDraw fLastDrawWasBuffered;
    857 
    858     GrGpu*              fGpu;
    859     GrDrawState*        fDrawState;
    860 
    861     GrResourceCache*    fTextureCache;
    862     GrFontCache*        fFontCache;
    863 
    864     GrPathRendererChain*        fPathRendererChain;
    865     GrSoftwarePathRenderer*     fSoftwarePathRenderer;
    866 
    867     GrVertexBufferAllocPool*    fDrawBufferVBAllocPool;
    868     GrIndexBufferAllocPool*     fDrawBufferIBAllocPool;
    869     GrInOrderDrawBuffer*        fDrawBuffer;
    870 
    871     GrAARectRenderer*           fAARectRenderer;
    872 
    873     bool                        fDidTestPMConversions;
    874     int                         fPMToUPMConversion;
    875     int                         fUPMToPMConversion;
    876 
    877     struct CleanUpData {
    878         PFCleanUpFunc fFunc;
    879         void*         fInfo;
    880     };
    881 
    882     SkTDArray<CleanUpData>      fCleanUpData;
    883 
    884     GrContext(GrGpu* gpu);
    885 
    886     void setupDrawBuffer();
    887 
    888     void flushDrawBuffer();
    889 
    890     /// Sets the paint and returns the target to draw into. The paint can be NULL in which case the
    891     /// draw state is left unmodified.
    892     GrDrawTarget* prepareToDraw(const GrPaint*, BufferedDraw);
    893 
    894     void internalDrawPath(const GrPaint& paint, const SkPath& path, const SkStrokeRec& stroke);
    895 
    896     void internalDrawOval(const GrPaint& paint, const GrRect& oval, const SkStrokeRec& stroke);
    897     bool canDrawOval(const GrPaint& paint, const GrRect& oval, const SkStrokeRec& stroke) const;
    898 
    899     GrTexture* createResizedTexture(const GrTextureDesc& desc,
    900                                     const GrCacheID& cacheID,
    901                                     void* srcData,
    902                                     size_t rowBytes,
    903                                     bool needsFiltering);
    904 
    905     // Needed so GrTexture's returnToCache helper function can call
    906     // addExistingTextureToCache
    907     friend class GrTexture;
    908 
    909     // Add an existing texture to the texture cache. This is intended solely
    910     // for use with textures released from an GrAutoScratchTexture.
    911     void addExistingTextureToCache(GrTexture* texture);
    912 
    913     /**
    914      * These functions create premul <-> unpremul effects if it is possible to generate a pair
    915      * of effects that make a readToUPM->writeToPM->readToUPM cycle invariant. Otherwise, they
    916      * return NULL.
    917      */
    918     const GrEffectRef* createPMToUPMEffect(GrTexture* texture,
    919                                            bool swapRAndB,
    920                                            const SkMatrix& matrix);
    921     const GrEffectRef* createUPMToPMEffect(GrTexture* texture,
    922                                            bool swapRAndB,
    923                                            const SkMatrix& matrix);
    924 
    925     typedef GrRefCnt INHERITED;
    926 };
    927 
    928 /**
    929  * Gets and locks a scratch texture from a descriptor using either exact or approximate criteria.
    930  * Unlocks texture in the destructor.
    931  */
    932 class GrAutoScratchTexture : ::GrNoncopyable {
    933 public:
    934     GrAutoScratchTexture()
    935         : fContext(NULL)
    936         , fTexture(NULL) {
    937     }
    938 
    939     GrAutoScratchTexture(GrContext* context,
    940                          const GrTextureDesc& desc,
    941                          GrContext::ScratchTexMatch match = GrContext::kApprox_ScratchTexMatch)
    942       : fContext(NULL)
    943       , fTexture(NULL) {
    944       this->set(context, desc, match);
    945     }
    946 
    947     ~GrAutoScratchTexture() {
    948         this->reset();
    949     }
    950 
    951     void reset() {
    952         if (NULL != fContext && NULL != fTexture) {
    953             fContext->unlockScratchTexture(fTexture);
    954             fTexture->unref();
    955             fTexture = NULL;
    956         }
    957     }
    958 
    959     /*
    960      * When detaching a texture we do not unlock it in the texture cache but
    961      * we do set the returnToCache flag. In this way the texture remains
    962      * "locked" in the texture cache until it is freed and recycled in
    963      * GrTexture::internal_dispose. In reality, the texture has been removed
    964      * from the cache (because this is in AutoScratchTexture) and by not
    965      * calling unlockScratchTexture we simply don't re-add it. It will be
    966      * reattached in GrTexture::internal_dispose.
    967      *
    968      * Note that the caller is assumed to accept and manage the ref to the
    969      * returned texture.
    970      */
    971     GrTexture* detach() {
    972         GrTexture* texture = fTexture;
    973         fTexture = NULL;
    974 
    975         // This GrAutoScratchTexture has a ref from lockAndRefScratchTexture, which we give up now.
    976         // The cache also has a ref which we are lending to the caller of detach(). When the caller
    977         // lets go of the ref and the ref count goes to 0 internal_dispose will see this flag is
    978         // set and re-ref the texture, thereby restoring the cache's ref.
    979         GrAssert(texture->getRefCnt() > 1);
    980         texture->setFlag((GrTextureFlags) GrTexture::kReturnToCache_FlagBit);
    981         texture->unref();
    982         GrAssert(NULL != texture->getCacheEntry());
    983 
    984         return texture;
    985     }
    986 
    987     GrTexture* set(GrContext* context,
    988                    const GrTextureDesc& desc,
    989                    GrContext::ScratchTexMatch match = GrContext::kApprox_ScratchTexMatch) {
    990         this->reset();
    991 
    992         fContext = context;
    993         if (NULL != fContext) {
    994             fTexture = fContext->lockAndRefScratchTexture(desc, match);
    995             if (NULL == fTexture) {
    996                 fContext = NULL;
    997             }
    998             return fTexture;
    999         } else {
   1000             return NULL;
   1001         }
   1002     }
   1003 
   1004     GrTexture* texture() { return fTexture; }
   1005 
   1006 private:
   1007     GrContext*                    fContext;
   1008     GrTexture*                    fTexture;
   1009 };
   1010 
   1011 #endif
   1012