gfx/skia/trunk/include/gpu/GrContext.h

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/gfx/skia/trunk/include/gpu/GrContext.h	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,1066 @@
     1.4 +/*
     1.5 + * Copyright 2010 Google Inc.
     1.6 + *
     1.7 + * Use of this source code is governed by a BSD-style license that can be
     1.8 + * found in the LICENSE file.
     1.9 + */
    1.10 +
    1.11 +#ifndef GrContext_DEFINED
    1.12 +#define GrContext_DEFINED
    1.13 +
    1.14 +#include "GrClipData.h"
    1.15 +#include "GrColor.h"
    1.16 +#include "GrPaint.h"
    1.17 +#include "GrPathRendererChain.h"
    1.18 +#include "GrPoint.h"
    1.19 +#include "GrRenderTarget.h"
    1.20 +#include "GrTexture.h"
    1.21 +#include "SkMatrix.h"
    1.22 +#include "SkTypes.h"
    1.23 +
    1.24 +class GrAARectRenderer;
    1.25 +class GrAutoScratchTexture;
    1.26 +class GrDrawState;
    1.27 +class GrDrawTarget;
    1.28 +class GrEffect;
    1.29 +class GrFontCache;
    1.30 +class GrGpu;
    1.31 +class GrIndexBuffer;
    1.32 +class GrIndexBufferAllocPool;
    1.33 +class GrInOrderDrawBuffer;
    1.34 +class GrOvalRenderer;
    1.35 +class GrPath;
    1.36 +class GrPathRenderer;
    1.37 +class GrResourceEntry;
    1.38 +class GrResourceCache;
    1.39 +class GrStencilBuffer;
    1.40 +class GrTestTarget;
    1.41 +class GrTextureParams;
    1.42 +class GrVertexBuffer;
    1.43 +class GrVertexBufferAllocPool;
    1.44 +class GrSoftwarePathRenderer;
    1.45 +class SkStrokeRec;
    1.46 +
    1.47 +class SK_API GrContext : public SkRefCnt {
    1.48 +public:
    1.49 +    SK_DECLARE_INST_COUNT(GrContext)
    1.50 +
    1.51 +    /**
    1.52 +     * Creates a GrContext for a backend context.
    1.53 +     */
    1.54 +    static GrContext* Create(GrBackend, GrBackendContext);
    1.55 +
    1.56 +    virtual ~GrContext();
    1.57 +
    1.58 +    /**
    1.59 +     * The GrContext normally assumes that no outsider is setting state
    1.60 +     * within the underlying 3D API's context/device/whatever. This call informs
    1.61 +     * the context that the state was modified and it should resend. Shouldn't
    1.62 +     * be called frequently for good performance.
    1.63 +     * The flag bits, state, is dpendent on which backend is used by the
    1.64 +     * context, either GL or D3D (possible in future).
    1.65 +     */
    1.66 +    void resetContext(uint32_t state = kAll_GrBackendState);
    1.67 +
    1.68 +    /**
    1.69 +     * Callback function to allow classes to cleanup on GrContext destruction.
    1.70 +     * The 'info' field is filled in with the 'info' passed to addCleanUp.
    1.71 +     */
    1.72 +    typedef void (*PFCleanUpFunc)(const GrContext* context, void* info);
    1.73 +
    1.74 +    /**
    1.75 +     * Add a function to be called from within GrContext's destructor.
    1.76 +     * This gives classes a chance to free resources held on a per context basis.
    1.77 +     * The 'info' parameter will be stored and passed to the callback function.
    1.78 +     */
    1.79 +    void addCleanUp(PFCleanUpFunc cleanUp, void* info) {
    1.80 +        CleanUpData* entry = fCleanUpData.push();
    1.81 +
    1.82 +        entry->fFunc = cleanUp;
    1.83 +        entry->fInfo = info;
    1.84 +    }
    1.85 +
    1.86 +    /**
    1.87 +     * Abandons all GPU resources, assumes 3D API state is unknown. Call this
    1.88 +     * if you have lost the associated GPU context, and thus internal texture,
    1.89 +     * buffer, etc. references/IDs are now invalid. Should be called even when
    1.90 +     * GrContext is no longer going to be used for two reasons:
    1.91 +     *  1) ~GrContext will not try to free the objects in the 3D API.
    1.92 +     *  2) If you've created GrResources that outlive the GrContext they will
    1.93 +     *     be marked as invalid (GrResource::isValid()) and won't attempt to
    1.94 +     *     free their underlying resource in the 3D API.
    1.95 +     * Content drawn since the last GrContext::flush() may be lost.
    1.96 +     */
    1.97 +    void contextLost();
    1.98 +
    1.99 +    /**
   1.100 +     * Similar to contextLost, but makes no attempt to reset state.
   1.101 +     * Use this method when GrContext destruction is pending, but
   1.102 +     * the graphics context is destroyed first.
   1.103 +     */
   1.104 +    void contextDestroyed();
   1.105 +
   1.106 +    /**
   1.107 +     * Frees GPU created by the context. Can be called to reduce GPU memory
   1.108 +     * pressure.
   1.109 +     */
   1.110 +    void freeGpuResources();
   1.111 +
   1.112 +    /**
   1.113 +     * Returns the number of bytes of GPU memory hosted by the texture cache.
   1.114 +     */
   1.115 +    size_t getGpuTextureCacheBytes() const;
   1.116 +
   1.117 +    ///////////////////////////////////////////////////////////////////////////
   1.118 +    // Textures
   1.119 +
   1.120 +    /**
   1.121 +     * Creates a new entry, based on the specified key and texture and returns it. The caller owns a
   1.122 +     * ref on the returned texture which must be balanced by a call to unref.
   1.123 +     *
   1.124 +     * @param params    The texture params used to draw a texture may help determine
   1.125 +     *                  the cache entry used. (e.g. different versions may exist
   1.126 +     *                  for different wrap modes on GPUs with limited NPOT
   1.127 +     *                  texture support). NULL implies clamp wrap modes.
   1.128 +     * @param desc      Description of the texture properties.
   1.129 +     * @param cacheID Cache-specific properties (e.g., texture gen ID)
   1.130 +     * @param srcData   Pointer to the pixel values.
   1.131 +     * @param rowBytes  The number of bytes between rows of the texture. Zero
   1.132 +     *                  implies tightly packed rows.
   1.133 +     * @param cacheKey  (optional) If non-NULL, we'll write the cache key we used to cacheKey.
   1.134 +     */
   1.135 +    GrTexture* createTexture(const GrTextureParams* params,
   1.136 +                             const GrTextureDesc& desc,
   1.137 +                             const GrCacheID& cacheID,
   1.138 +                             void* srcData,
   1.139 +                             size_t rowBytes,
   1.140 +                             GrResourceKey* cacheKey = NULL);
   1.141 +
   1.142 +    /**
   1.143 +     * Search for an entry based on key and dimensions. If found, ref it and return it. The return
   1.144 +     * value will be NULL if not found. The caller must balance with a call to unref.
   1.145 +     *
   1.146 +     *  @param desc     Description of the texture properties.
   1.147 +     *  @param cacheID Cache-specific properties (e.g., texture gen ID)
   1.148 +     *  @param params   The texture params used to draw a texture may help determine
   1.149 +     *                  the cache entry used. (e.g. different versions may exist
   1.150 +     *                  for different wrap modes on GPUs with limited NPOT
   1.151 +     *                  texture support). NULL implies clamp wrap modes.
   1.152 +     */
   1.153 +    GrTexture* findAndRefTexture(const GrTextureDesc& desc,
   1.154 +                                 const GrCacheID& cacheID,
   1.155 +                                 const GrTextureParams* params);
   1.156 +    /**
   1.157 +     * Determines whether a texture is in the cache. If the texture is found it
   1.158 +     * will not be locked or returned. This call does not affect the priority of
   1.159 +     * the texture for deletion.
   1.160 +     */
   1.161 +    bool isTextureInCache(const GrTextureDesc& desc,
   1.162 +                          const GrCacheID& cacheID,
   1.163 +                          const GrTextureParams* params) const;
   1.164 +
   1.165 +    /**
   1.166 +     * Enum that determines how closely a returned scratch texture must match
   1.167 +     * a provided GrTextureDesc.
   1.168 +     */
   1.169 +    enum ScratchTexMatch {
   1.170 +        /**
   1.171 +         * Finds a texture that exactly matches the descriptor.
   1.172 +         */
   1.173 +        kExact_ScratchTexMatch,
   1.174 +        /**
   1.175 +         * Finds a texture that approximately matches the descriptor. Will be
   1.176 +         * at least as large in width and height as desc specifies. If desc
   1.177 +         * specifies that texture is a render target then result will be a
   1.178 +         * render target. If desc specifies a render target and doesn't set the
   1.179 +         * no stencil flag then result will have a stencil. Format and aa level
   1.180 +         * will always match.
   1.181 +         */
   1.182 +        kApprox_ScratchTexMatch
   1.183 +    };
   1.184 +
   1.185 +    /**
   1.186 +     * Returns a texture matching the desc. It's contents are unknown. Subsequent
   1.187 +     * requests with the same descriptor are not guaranteed to return the same
   1.188 +     * texture. The same texture is guaranteed not be returned again until it is
   1.189 +     * unlocked. Call must be balanced with an unlockTexture() call. The caller
   1.190 +     * owns a ref on the returned texture and must balance with a call to unref.
   1.191 +     *
   1.192 +     * Textures created by createAndLockTexture() hide the complications of
   1.193 +     * tiling non-power-of-two textures on APIs that don't support this (e.g.
   1.194 +     * unextended GLES2). Tiling a NPOT texture created by lockScratchTexture on
   1.195 +     * such an API will create gaps in the tiling pattern. This includes clamp
   1.196 +     * mode. (This may be addressed in a future update.)
   1.197 +     */
   1.198 +    GrTexture* lockAndRefScratchTexture(const GrTextureDesc&, ScratchTexMatch match);
   1.199 +
   1.200 +    /**
   1.201 +     *  When done with an entry, call unlockScratchTexture(entry) on it, which returns
   1.202 +     *  it to the cache, where it may be purged. This does not unref the texture.
   1.203 +     */
   1.204 +    void unlockScratchTexture(GrTexture* texture);
   1.205 +
   1.206 +    /**
   1.207 +     * This method should be called whenever a GrTexture is unreffed or
   1.208 +     * switched from exclusive to non-exclusive. This
   1.209 +     * gives the resource cache a chance to discard unneeded textures.
   1.210 +     * Note: this entry point will be removed once totally ref-driven
   1.211 +     * cache maintenance is implemented
   1.212 +     */
   1.213 +    void purgeCache();
   1.214 +
   1.215 +    /**
   1.216 +     * Purge all the unlocked resources from the cache.
   1.217 +     * This entry point is mainly meant for timing texture uploads
   1.218 +     * and is not defined in normal builds of Skia.
   1.219 +     */
   1.220 +    void purgeAllUnlockedResources();
   1.221 +
   1.222 +    /**
   1.223 +     * Creates a texture that is outside the cache. Does not count against
   1.224 +     * cache's budget.
   1.225 +     */
   1.226 +    GrTexture* createUncachedTexture(const GrTextureDesc& desc,
   1.227 +                                     void* srcData,
   1.228 +                                     size_t rowBytes);
   1.229 +
   1.230 +    /**
   1.231 +     * Returns true if the specified use of an indexed texture is supported.
   1.232 +     * Support may depend upon whether the texture params indicate that the
   1.233 +     * texture will be tiled. Passing NULL for the texture params indicates
   1.234 +     * clamp mode.
   1.235 +     */
   1.236 +    bool supportsIndex8PixelConfig(const GrTextureParams*,
   1.237 +                                   int width,
   1.238 +                                   int height) const;
   1.239 +
   1.240 +    /**
   1.241 +     *  Return the current texture cache limits.
   1.242 +     *
   1.243 +     *  @param maxTextures If non-null, returns maximum number of textures that
   1.244 +     *                     can be held in the cache.
   1.245 +     *  @param maxTextureBytes If non-null, returns maximum number of bytes of
   1.246 +     *                         texture memory that can be held in the cache.
   1.247 +     */
   1.248 +    void getTextureCacheLimits(int* maxTextures, size_t* maxTextureBytes) const;
   1.249 +
   1.250 +    /**
   1.251 +     *  Specify the texture cache limits. If the current cache exceeds either
   1.252 +     *  of these, it will be purged (LRU) to keep the cache within these limits.
   1.253 +     *
   1.254 +     *  @param maxTextures The maximum number of textures that can be held in
   1.255 +     *                     the cache.
   1.256 +     *  @param maxTextureBytes The maximum number of bytes of texture memory
   1.257 +     *                         that can be held in the cache.
   1.258 +     */
   1.259 +    void setTextureCacheLimits(int maxTextures, size_t maxTextureBytes);
   1.260 +
   1.261 +    /**
   1.262 +     *  Return the max width or height of a texture supported by the current GPU.
   1.263 +     */
   1.264 +    int getMaxTextureSize() const;
   1.265 +
   1.266 +    /**
   1.267 +     *  Temporarily override the true max texture size. Note: an override
   1.268 +     *  larger then the true max texture size will have no effect.
   1.269 +     *  This entry point is mainly meant for testing texture size dependent
   1.270 +     *  features and is only available if defined outside of Skia (see
   1.271 +     *  bleed GM.
   1.272 +     */
   1.273 +    void setMaxTextureSizeOverride(int maxTextureSizeOverride);
   1.274 +
   1.275 +    ///////////////////////////////////////////////////////////////////////////
   1.276 +    // Render targets
   1.277 +
   1.278 +    /**
   1.279 +     * Sets the render target.
   1.280 +     * @param target    the render target to set.
   1.281 +     */
   1.282 +    void setRenderTarget(GrRenderTarget* target) {
   1.283 +        fRenderTarget.reset(SkSafeRef(target));
   1.284 +    }
   1.285 +
   1.286 +    /**
   1.287 +     * Gets the current render target.
   1.288 +     * @return the currently bound render target.
   1.289 +     */
   1.290 +    const GrRenderTarget* getRenderTarget() const { return fRenderTarget.get(); }
   1.291 +    GrRenderTarget* getRenderTarget() { return fRenderTarget.get(); }
   1.292 +
   1.293 +    GrAARectRenderer* getAARectRenderer() { return fAARectRenderer; }
   1.294 +
   1.295 +    /**
   1.296 +     * Can the provided configuration act as a color render target?
   1.297 +     */
   1.298 +    bool isConfigRenderable(GrPixelConfig config, bool withMSAA) const;
   1.299 +
   1.300 +    /**
   1.301 +     * Return the max width or height of a render target supported by the
   1.302 +     * current GPU.
   1.303 +     */
   1.304 +    int getMaxRenderTargetSize() const;
   1.305 +
   1.306 +    /**
   1.307 +     * Returns the max sample count for a render target. It will be 0 if MSAA
   1.308 +     * is not supported.
   1.309 +     */
   1.310 +    int getMaxSampleCount() const;
   1.311 +
   1.312 +    /**
   1.313 +     * Returns the recommended sample count for a render target when using this
   1.314 +     * context.
   1.315 +     *
   1.316 +     * @param  config the configuration of the render target.
   1.317 +     * @param  dpi the display density in dots per inch.
   1.318 +     *
   1.319 +     * @return sample count that should be perform well and have good enough
   1.320 +     *         rendering quality for the display. Alternatively returns 0 if
   1.321 +     *         MSAA is not supported or recommended to be used by default.
   1.322 +     */
   1.323 +    int getRecommendedSampleCount(GrPixelConfig config, SkScalar dpi) const;
   1.324 +
   1.325 +    ///////////////////////////////////////////////////////////////////////////
   1.326 +    // Backend Surfaces
   1.327 +
   1.328 +    /**
   1.329 +     * Wraps an existing texture with a GrTexture object.
   1.330 +     *
   1.331 +     * OpenGL: if the object is a texture Gr may change its GL texture params
   1.332 +     *         when it is drawn.
   1.333 +     *
   1.334 +     * @param  desc     description of the object to create.
   1.335 +     *
   1.336 +     * @return GrTexture object or NULL on failure.
   1.337 +     */
   1.338 +    GrTexture* wrapBackendTexture(const GrBackendTextureDesc& desc);
   1.339 +
   1.340 +    /**
   1.341 +     * Wraps an existing render target with a GrRenderTarget object. It is
   1.342 +     * similar to wrapBackendTexture but can be used to draw into surfaces
   1.343 +     * that are not also textures (e.g. FBO 0 in OpenGL, or an MSAA buffer that
   1.344 +     * the client will resolve to a texture).
   1.345 +     *
   1.346 +     * @param  desc     description of the object to create.
   1.347 +     *
   1.348 +     * @return GrTexture object or NULL on failure.
   1.349 +     */
   1.350 +     GrRenderTarget* wrapBackendRenderTarget(const GrBackendRenderTargetDesc& desc);
   1.351 +
   1.352 +    ///////////////////////////////////////////////////////////////////////////
   1.353 +    // Matrix state
   1.354 +
   1.355 +    /**
   1.356 +     * Gets the current transformation matrix.
   1.357 +     * @return the current matrix.
   1.358 +     */
   1.359 +    const SkMatrix& getMatrix() const { return fViewMatrix; }
   1.360 +
   1.361 +    /**
   1.362 +     * Sets the transformation matrix.
   1.363 +     * @param m the matrix to set.
   1.364 +     */
   1.365 +    void setMatrix(const SkMatrix& m) { fViewMatrix = m; }
   1.366 +
   1.367 +    /**
   1.368 +     * Sets the current transformation matrix to identity.
   1.369 +     */
   1.370 +    void setIdentityMatrix() { fViewMatrix.reset(); }
   1.371 +
   1.372 +    /**
   1.373 +     * Concats the current matrix. The passed matrix is applied before the
   1.374 +     * current matrix.
   1.375 +     * @param m the matrix to concat.
   1.376 +     */
   1.377 +    void concatMatrix(const SkMatrix& m) { fViewMatrix.preConcat(m); }
   1.378 +
   1.379 +
   1.380 +    ///////////////////////////////////////////////////////////////////////////
   1.381 +    // Clip state
   1.382 +    /**
   1.383 +     * Gets the current clip.
   1.384 +     * @return the current clip.
   1.385 +     */
   1.386 +    const GrClipData* getClip() const { return fClip; }
   1.387 +
   1.388 +    /**
   1.389 +     * Sets the clip.
   1.390 +     * @param clipData  the clip to set.
   1.391 +     */
   1.392 +    void setClip(const GrClipData* clipData) { fClip = clipData; }
   1.393 +
   1.394 +    ///////////////////////////////////////////////////////////////////////////
   1.395 +    // Draws
   1.396 +
   1.397 +    /**
   1.398 +     * Clear the entire or rect of the render target, ignoring any clips.
   1.399 +     * @param rect  the rect to clear or the whole thing if rect is NULL.
   1.400 +     * @param color the color to clear to.
   1.401 +     * @param canIgnoreRect allows partial clears to be converted to whole
   1.402 +     *                      clears on platforms for which that is cheap
   1.403 +     * @param target if non-NULL, the render target to clear otherwise clear
   1.404 +     *               the current render target
   1.405 +     */
   1.406 +    void clear(const SkIRect* rect, GrColor color, bool canIgnoreRect,
   1.407 +               GrRenderTarget* target = NULL);
   1.408 +
   1.409 +    /**
   1.410 +     *  Draw everywhere (respecting the clip) with the paint.
   1.411 +     */
   1.412 +    void drawPaint(const GrPaint& paint);
   1.413 +
   1.414 +    /**
   1.415 +     *  Draw the rect using a paint.
   1.416 +     *  @param paint        describes how to color pixels.
   1.417 +     *  @param stroke       the stroke information (width, join, cap).
   1.418 +     *                      If stroke == NULL, then the rect is filled.
   1.419 +     *                      Otherwise, if stroke width == 0, then the stroke
   1.420 +     *                      is always a single pixel thick, else the rect is
   1.421 +     *                      mitered/beveled stroked based on stroke width.
   1.422 +     *  @param matrix       Optional matrix applied to the rect. Applied before
   1.423 +     *                      context's matrix or the paint's matrix.
   1.424 +     *  The rects coords are used to access the paint (through texture matrix)
   1.425 +     */
   1.426 +    void drawRect(const GrPaint& paint,
   1.427 +                  const SkRect&,
   1.428 +                  const SkStrokeRec* stroke = NULL,
   1.429 +                  const SkMatrix* matrix = NULL);
   1.430 +
   1.431 +    /**
   1.432 +     * Maps a rect of local coordinates onto the a rect of destination
   1.433 +     * coordinates. Each rect can optionally be transformed. The localRect
   1.434 +     * is stretched over the dstRect. The dstRect is transformed by the
   1.435 +     * context's matrix. Additional optional matrices for both rects can be
   1.436 +     * provided by parameters.
   1.437 +     *
   1.438 +     * @param paint         describes how to color pixels.
   1.439 +     * @param dstRect       the destination rect to draw.
   1.440 +     * @param localRect     rect of local coordinates to be mapped onto dstRect
   1.441 +     * @param dstMatrix     Optional matrix to transform dstRect. Applied before context's matrix.
   1.442 +     * @param localMatrix   Optional matrix to transform localRect.
   1.443 +     */
   1.444 +    void drawRectToRect(const GrPaint& paint,
   1.445 +                        const SkRect& dstRect,
   1.446 +                        const SkRect& localRect,
   1.447 +                        const SkMatrix* dstMatrix = NULL,
   1.448 +                        const SkMatrix* localMatrix = NULL);
   1.449 +
   1.450 +    /**
   1.451 +     *  Draw a roundrect using a paint.
   1.452 +     *
   1.453 +     *  @param paint        describes how to color pixels.
   1.454 +     *  @param rrect        the roundrect to draw
   1.455 +     *  @param stroke       the stroke information (width, join, cap)
   1.456 +     */
   1.457 +    void drawRRect(const GrPaint& paint,
   1.458 +                   const SkRRect& rrect,
   1.459 +                   const SkStrokeRec& stroke);
   1.460 +
   1.461 +    /**
   1.462 +     * Draws a path.
   1.463 +     *
   1.464 +     * @param paint         describes how to color pixels.
   1.465 +     * @param path          the path to draw
   1.466 +     * @param stroke        the stroke information (width, join, cap)
   1.467 +     */
   1.468 +    void drawPath(const GrPaint& paint, const SkPath& path, const SkStrokeRec& stroke);
   1.469 +
   1.470 +    /**
   1.471 +     * Draws vertices with a paint.
   1.472 +     *
   1.473 +     * @param   paint           describes how to color pixels.
   1.474 +     * @param   primitiveType   primitives type to draw.
   1.475 +     * @param   vertexCount     number of vertices.
   1.476 +     * @param   positions       array of vertex positions, required.
   1.477 +     * @param   texCoords       optional array of texture coordinates used
   1.478 +     *                          to access the paint.
   1.479 +     * @param   colors          optional array of per-vertex colors, supercedes
   1.480 +     *                          the paint's color field.
   1.481 +     * @param   indices         optional array of indices. If NULL vertices
   1.482 +     *                          are drawn non-indexed.
   1.483 +     * @param   indexCount      if indices is non-null then this is the
   1.484 +     *                          number of indices.
   1.485 +     */
   1.486 +    void drawVertices(const GrPaint& paint,
   1.487 +                      GrPrimitiveType primitiveType,
   1.488 +                      int vertexCount,
   1.489 +                      const GrPoint positions[],
   1.490 +                      const GrPoint texs[],
   1.491 +                      const GrColor colors[],
   1.492 +                      const uint16_t indices[],
   1.493 +                      int indexCount);
   1.494 +
   1.495 +    /**
   1.496 +     * Draws an oval.
   1.497 +     *
   1.498 +     * @param paint         describes how to color pixels.
   1.499 +     * @param oval          the bounding rect of the oval.
   1.500 +     * @param stroke        the stroke information (width, style)
   1.501 +     */
   1.502 +    void drawOval(const GrPaint& paint,
   1.503 +                  const SkRect& oval,
   1.504 +                  const SkStrokeRec& stroke);
   1.505 +
   1.506 +    ///////////////////////////////////////////////////////////////////////////
   1.507 +    // Misc.
   1.508 +
   1.509 +    /**
   1.510 +     * Flags that affect flush() behavior.
   1.511 +     */
   1.512 +    enum FlushBits {
   1.513 +        /**
   1.514 +         * A client may reach a point where it has partially rendered a frame
   1.515 +         * through a GrContext that it knows the user will never see. This flag
   1.516 +         * causes the flush to skip submission of deferred content to the 3D API
   1.517 +         * during the flush.
   1.518 +         */
   1.519 +        kDiscard_FlushBit                    = 0x2,
   1.520 +    };
   1.521 +
   1.522 +    /**
   1.523 +     * Call to ensure all drawing to the context has been issued to the
   1.524 +     * underlying 3D API.
   1.525 +     * @param flagsBitfield     flags that control the flushing behavior. See
   1.526 +     *                          FlushBits.
   1.527 +     */
   1.528 +    void flush(int flagsBitfield = 0);
   1.529 +
   1.530 +   /**
   1.531 +    * These flags can be used with the read/write pixels functions below.
   1.532 +    */
   1.533 +    enum PixelOpsFlags {
   1.534 +        /** The GrContext will not be flushed. This means that the read or write may occur before
   1.535 +            previous draws have executed. */
   1.536 +        kDontFlush_PixelOpsFlag = 0x1,
   1.537 +        /** The src for write or dst read is unpremultiplied. This is only respected if both the
   1.538 +            config src and dst configs are an RGBA/BGRA 8888 format. */
   1.539 +        kUnpremul_PixelOpsFlag  = 0x2,
   1.540 +    };
   1.541 +
   1.542 +    /**
   1.543 +     * Reads a rectangle of pixels from a render target.
   1.544 +     * @param target        the render target to read from. NULL means the current render target.
   1.545 +     * @param left          left edge of the rectangle to read (inclusive)
   1.546 +     * @param top           top edge of the rectangle to read (inclusive)
   1.547 +     * @param width         width of rectangle to read in pixels.
   1.548 +     * @param height        height of rectangle to read in pixels.
   1.549 +     * @param config        the pixel config of the destination buffer
   1.550 +     * @param buffer        memory to read the rectangle into.
   1.551 +     * @param rowBytes      number of bytes bewtween consecutive rows. Zero means rows are tightly
   1.552 +     *                      packed.
   1.553 +     * @param pixelOpsFlags see PixelOpsFlags enum above.
   1.554 +     *
   1.555 +     * @return true if the read succeeded, false if not. The read can fail because of an unsupported
   1.556 +     *         pixel config or because no render target is currently set and NULL was passed for
   1.557 +     *         target.
   1.558 +     */
   1.559 +    bool readRenderTargetPixels(GrRenderTarget* target,
   1.560 +                                int left, int top, int width, int height,
   1.561 +                                GrPixelConfig config, void* buffer,
   1.562 +                                size_t rowBytes = 0,
   1.563 +                                uint32_t pixelOpsFlags = 0);
   1.564 +
   1.565 +    /**
   1.566 +     * Copy the src pixels [buffer, row bytes, pixel config] into a render target at the specified
   1.567 +     * rectangle.
   1.568 +     * @param target        the render target to write into. NULL means the current render target.
   1.569 +     * @param left          left edge of the rectangle to write (inclusive)
   1.570 +     * @param top           top edge of the rectangle to write (inclusive)
   1.571 +     * @param width         width of rectangle to write in pixels.
   1.572 +     * @param height        height of rectangle to write in pixels.
   1.573 +     * @param config        the pixel config of the source buffer
   1.574 +     * @param buffer        memory to read the rectangle from.
   1.575 +     * @param rowBytes      number of bytes between consecutive rows. Zero means rows are tightly
   1.576 +     *                      packed.
   1.577 +     * @param pixelOpsFlags see PixelOpsFlags enum above.
   1.578 +     *
   1.579 +     * @return true if the write succeeded, false if not. The write can fail because of an
   1.580 +     *         unsupported combination of target and pixel configs.
   1.581 +     */
   1.582 +    bool writeRenderTargetPixels(GrRenderTarget* target,
   1.583 +                                 int left, int top, int width, int height,
   1.584 +                                 GrPixelConfig config, const void* buffer,
   1.585 +                                 size_t rowBytes = 0,
   1.586 +                                 uint32_t pixelOpsFlags = 0);
   1.587 +
   1.588 +    /**
   1.589 +     * Reads a rectangle of pixels from a texture.
   1.590 +     * @param texture       the texture to read from.
   1.591 +     * @param left          left edge of the rectangle to read (inclusive)
   1.592 +     * @param top           top edge of the rectangle to read (inclusive)
   1.593 +     * @param width         width of rectangle to read in pixels.
   1.594 +     * @param height        height of rectangle to read in pixels.
   1.595 +     * @param config        the pixel config of the destination buffer
   1.596 +     * @param buffer        memory to read the rectangle into.
   1.597 +     * @param rowBytes      number of bytes between consecutive rows. Zero means rows are tightly
   1.598 +     *                      packed.
   1.599 +     * @param pixelOpsFlags see PixelOpsFlags enum above.
   1.600 +     *
   1.601 +     * @return true if the read succeeded, false if not. The read can fail because of an unsupported
   1.602 +     *         pixel config.
   1.603 +     */
   1.604 +    bool readTexturePixels(GrTexture* texture,
   1.605 +                           int left, int top, int width, int height,
   1.606 +                           GrPixelConfig config, void* buffer,
   1.607 +                           size_t rowBytes = 0,
   1.608 +                           uint32_t pixelOpsFlags = 0);
   1.609 +
   1.610 +    /**
   1.611 +     * Writes a rectangle of pixels to a texture.
   1.612 +     * @param texture       the render target to read from.
   1.613 +     * @param left          left edge of the rectangle to write (inclusive)
   1.614 +     * @param top           top edge of the rectangle to write (inclusive)
   1.615 +     * @param width         width of rectangle to write in pixels.
   1.616 +     * @param height        height of rectangle to write in pixels.
   1.617 +     * @param config        the pixel config of the source buffer
   1.618 +     * @param buffer        memory to read pixels from
   1.619 +     * @param rowBytes      number of bytes between consecutive rows. Zero
   1.620 +     *                      means rows are tightly packed.
   1.621 +     * @param pixelOpsFlags see PixelOpsFlags enum above.
   1.622 +     * @return true if the write succeeded, false if not. The write can fail because of an
   1.623 +     *         unsupported combination of texture and pixel configs.
   1.624 +     */
   1.625 +    bool writeTexturePixels(GrTexture* texture,
   1.626 +                            int left, int top, int width, int height,
   1.627 +                            GrPixelConfig config, const void* buffer,
   1.628 +                            size_t rowBytes,
   1.629 +                            uint32_t pixelOpsFlags = 0);
   1.630 +
   1.631 +
   1.632 +    /**
   1.633 +     * Copies a rectangle of texels from src to dst. The size of dst is the size of the rectangle
   1.634 +     * copied and topLeft is the position of the rect in src. The rectangle is clipped to src's
   1.635 +     * bounds.
   1.636 +     * @param src           the texture to copy from.
   1.637 +     * @param dst           the render target to copy to.
   1.638 +     * @param topLeft       the point in src that will be copied to the top-left of dst. If NULL,
   1.639 +     *                      (0, 0) will be used.
   1.640 +     */
   1.641 +    void copyTexture(GrTexture* src, GrRenderTarget* dst, const SkIPoint* topLeft = NULL);
   1.642 +
   1.643 +    /**
   1.644 +     * Resolves a render target that has MSAA. The intermediate MSAA buffer is
   1.645 +     * down-sampled to the associated GrTexture (accessible via
   1.646 +     * GrRenderTarget::asTexture()). Any pending draws to the render target will
   1.647 +     * be executed before the resolve.
   1.648 +     *
   1.649 +     * This is only necessary when a client wants to access the object directly
   1.650 +     * using the backend API directly. GrContext will detect when it must
   1.651 +     * perform a resolve to a GrTexture used as the source of a draw or before
   1.652 +     * reading pixels back from a GrTexture or GrRenderTarget.
   1.653 +     */
   1.654 +    void resolveRenderTarget(GrRenderTarget* target);
   1.655 +
   1.656 +#ifdef SK_DEVELOPER
   1.657 +    void dumpFontCache() const;
   1.658 +#endif
   1.659 +
   1.660 +    ///////////////////////////////////////////////////////////////////////////
   1.661 +    // Helpers
   1.662 +
   1.663 +    class AutoRenderTarget : public ::SkNoncopyable {
   1.664 +    public:
   1.665 +        AutoRenderTarget(GrContext* context, GrRenderTarget* target) {
   1.666 +            fPrevTarget = context->getRenderTarget();
   1.667 +            SkSafeRef(fPrevTarget);
   1.668 +            context->setRenderTarget(target);
   1.669 +            fContext = context;
   1.670 +        }
   1.671 +        AutoRenderTarget(GrContext* context) {
   1.672 +            fPrevTarget = context->getRenderTarget();
   1.673 +            SkSafeRef(fPrevTarget);
   1.674 +            fContext = context;
   1.675 +        }
   1.676 +        ~AutoRenderTarget() {
   1.677 +            if (NULL != fContext) {
   1.678 +                fContext->setRenderTarget(fPrevTarget);
   1.679 +            }
   1.680 +            SkSafeUnref(fPrevTarget);
   1.681 +        }
   1.682 +    private:
   1.683 +        GrContext*      fContext;
   1.684 +        GrRenderTarget* fPrevTarget;
   1.685 +    };
   1.686 +
   1.687 +    /**
   1.688 +     * Save/restore the view-matrix in the context. It can optionally adjust a paint to account
   1.689 +     * for a coordinate system change. Here is an example of how the paint param can be used:
   1.690 +     *
   1.691 +     * A GrPaint is setup with GrEffects. The stages will have access to the pre-matrix source
   1.692 +     * geometry positions when the draw is executed. Later on a decision is made to transform the
   1.693 +     * geometry to device space on the CPU. The effects now need to know that the space in which
   1.694 +     * the geometry will be specified has changed.
   1.695 +     *
   1.696 +     * Note that when restore is called (or in the destructor) the context's matrix will be
   1.697 +     * restored. However, the paint will not be restored. The caller must make a copy of the
   1.698 +     * paint if necessary. Hint: use SkTCopyOnFirstWrite if the AutoMatrix is conditionally
   1.699 +     * initialized.
   1.700 +     */
   1.701 +    class AutoMatrix : public ::SkNoncopyable {
   1.702 +    public:
   1.703 +        AutoMatrix() : fContext(NULL) {}
   1.704 +
   1.705 +        ~AutoMatrix() { this->restore(); }
   1.706 +
   1.707 +        /**
   1.708 +         * Initializes by pre-concat'ing the context's current matrix with the preConcat param.
   1.709 +         */
   1.710 +        void setPreConcat(GrContext* context, const SkMatrix& preConcat, GrPaint* paint = NULL) {
   1.711 +            SkASSERT(NULL != context);
   1.712 +
   1.713 +            this->restore();
   1.714 +
   1.715 +            fContext = context;
   1.716 +            fMatrix = context->getMatrix();
   1.717 +            this->preConcat(preConcat, paint);
   1.718 +        }
   1.719 +
   1.720 +        /**
   1.721 +         * Sets the context's matrix to identity. Returns false if the inverse matrix is required to
   1.722 +         * update a paint but the matrix cannot be inverted.
   1.723 +         */
   1.724 +        bool setIdentity(GrContext* context, GrPaint* paint = NULL) {
   1.725 +            SkASSERT(NULL != context);
   1.726 +
   1.727 +            this->restore();
   1.728 +
   1.729 +            if (NULL != paint) {
   1.730 +                if (!paint->localCoordChangeInverse(context->getMatrix())) {
   1.731 +                    return false;
   1.732 +                }
   1.733 +            }
   1.734 +            fMatrix = context->getMatrix();
   1.735 +            fContext = context;
   1.736 +            context->setIdentityMatrix();
   1.737 +            return true;
   1.738 +        }
   1.739 +
   1.740 +        /**
   1.741 +         * Replaces the context's matrix with a new matrix. Returns false if the inverse matrix is
   1.742 +         * required to update a paint but the matrix cannot be inverted.
   1.743 +         */
   1.744 +        bool set(GrContext* context, const SkMatrix& newMatrix, GrPaint* paint = NULL) {
   1.745 +            if (NULL != paint) {
   1.746 +                if (!this->setIdentity(context, paint)) {
   1.747 +                    return false;
   1.748 +                }
   1.749 +                this->preConcat(newMatrix, paint);
   1.750 +            } else {
   1.751 +                this->restore();
   1.752 +                fContext = context;
   1.753 +                fMatrix = context->getMatrix();
   1.754 +                context->setMatrix(newMatrix);
   1.755 +            }
   1.756 +            return true;
   1.757 +        }
   1.758 +
   1.759 +        /**
   1.760 +         * If this has been initialized then the context's matrix will be further updated by
   1.761 +         * pre-concat'ing the preConcat param. The matrix that will be restored remains unchanged.
   1.762 +         * The paint is assumed to be relative to the context's matrix at the time this call is
   1.763 +         * made, not the matrix at the time AutoMatrix was first initialized. In other words, this
   1.764 +         * performs an incremental update of the paint.
   1.765 +         */
   1.766 +        void preConcat(const SkMatrix& preConcat, GrPaint* paint = NULL) {
   1.767 +            if (NULL != paint) {
   1.768 +                paint->localCoordChange(preConcat);
   1.769 +            }
   1.770 +            fContext->concatMatrix(preConcat);
   1.771 +        }
   1.772 +
   1.773 +        /**
   1.774 +         * Returns false if never initialized or the inverse matrix was required to update a paint
   1.775 +         * but the matrix could not be inverted.
   1.776 +         */
   1.777 +        bool succeeded() const { return NULL != fContext; }
   1.778 +
   1.779 +        /**
   1.780 +         * If this has been initialized then the context's original matrix is restored.
   1.781 +         */
   1.782 +        void restore() {
   1.783 +            if (NULL != fContext) {
   1.784 +                fContext->setMatrix(fMatrix);
   1.785 +                fContext = NULL;
   1.786 +            }
   1.787 +        }
   1.788 +
   1.789 +    private:
   1.790 +        GrContext*  fContext;
   1.791 +        SkMatrix    fMatrix;
   1.792 +    };
   1.793 +
   1.794 +    class AutoClip : public ::SkNoncopyable {
   1.795 +    public:
   1.796 +        // This enum exists to require a caller of the constructor to acknowledge that the clip will
   1.797 +        // initially be wide open. It also could be extended if there are other desirable initial
   1.798 +        // clip states.
   1.799 +        enum InitialClip {
   1.800 +            kWideOpen_InitialClip,
   1.801 +        };
   1.802 +
   1.803 +        AutoClip(GrContext* context, InitialClip initialState)
   1.804 +        : fContext(context) {
   1.805 +            SkASSERT(kWideOpen_InitialClip == initialState);
   1.806 +            fNewClipData.fClipStack = &fNewClipStack;
   1.807 +
   1.808 +            fOldClip = context->getClip();
   1.809 +            context->setClip(&fNewClipData);
   1.810 +        }
   1.811 +
   1.812 +        AutoClip(GrContext* context, const SkRect& newClipRect)
   1.813 +        : fContext(context)
   1.814 +        , fNewClipStack(newClipRect) {
   1.815 +            fNewClipData.fClipStack = &fNewClipStack;
   1.816 +
   1.817 +            fOldClip = fContext->getClip();
   1.818 +            fContext->setClip(&fNewClipData);
   1.819 +        }
   1.820 +
   1.821 +        ~AutoClip() {
   1.822 +            if (NULL != fContext) {
   1.823 +                fContext->setClip(fOldClip);
   1.824 +            }
   1.825 +        }
   1.826 +    private:
   1.827 +        GrContext*        fContext;
   1.828 +        const GrClipData* fOldClip;
   1.829 +
   1.830 +        SkClipStack       fNewClipStack;
   1.831 +        GrClipData        fNewClipData;
   1.832 +    };
   1.833 +
   1.834 +    class AutoWideOpenIdentityDraw {
   1.835 +    public:
   1.836 +        AutoWideOpenIdentityDraw(GrContext* ctx, GrRenderTarget* rt)
   1.837 +            : fAutoClip(ctx, AutoClip::kWideOpen_InitialClip)
   1.838 +            , fAutoRT(ctx, rt) {
   1.839 +            fAutoMatrix.setIdentity(ctx);
   1.840 +            // should never fail with no paint param.
   1.841 +            SkASSERT(fAutoMatrix.succeeded());
   1.842 +        }
   1.843 +
   1.844 +    private:
   1.845 +        AutoClip fAutoClip;
   1.846 +        AutoRenderTarget fAutoRT;
   1.847 +        AutoMatrix fAutoMatrix;
   1.848 +    };
   1.849 +
   1.850 +    ///////////////////////////////////////////////////////////////////////////
   1.851 +    // Functions intended for internal use only.
   1.852 +    GrGpu* getGpu() { return fGpu; }
   1.853 +    const GrGpu* getGpu() const { return fGpu; }
   1.854 +    GrFontCache* getFontCache() { return fFontCache; }
   1.855 +    GrDrawTarget* getTextTarget();
   1.856 +    const GrIndexBuffer* getQuadIndexBuffer() const;
   1.857 +
   1.858 +    // Called by tests that draw directly to the context via GrDrawTarget
   1.859 +    void getTestTarget(GrTestTarget*);
   1.860 +
   1.861 +    /**
   1.862 +     * Stencil buffers add themselves to the cache using addStencilBuffer. findStencilBuffer is
   1.863 +     * called to check the cache for a SB that matches an RT's criteria.
   1.864 +     */
   1.865 +    void addStencilBuffer(GrStencilBuffer* sb);
   1.866 +    GrStencilBuffer* findStencilBuffer(int width, int height, int sampleCnt);
   1.867 +
   1.868 +    GrPathRenderer* getPathRenderer(
   1.869 +                    const SkPath& path,
   1.870 +                    const SkStrokeRec& stroke,
   1.871 +                    const GrDrawTarget* target,
   1.872 +                    bool allowSW,
   1.873 +                    GrPathRendererChain::DrawType drawType = GrPathRendererChain::kColor_DrawType,
   1.874 +                    GrPathRendererChain::StencilSupport* stencilSupport = NULL);
   1.875 +
   1.876 +
   1.877 +#if GR_CACHE_STATS
   1.878 +    void printCacheStats() const;
   1.879 +#endif
   1.880 +
   1.881 +private:
   1.882 +    // Used to indicate whether a draw should be performed immediately or queued in fDrawBuffer.
   1.883 +    enum BufferedDraw {
   1.884 +        kYes_BufferedDraw,
   1.885 +        kNo_BufferedDraw,
   1.886 +    };
   1.887 +    BufferedDraw fLastDrawWasBuffered;
   1.888 +
   1.889 +    GrGpu*                          fGpu;
   1.890 +    SkMatrix                        fViewMatrix;
   1.891 +    SkAutoTUnref<GrRenderTarget>    fRenderTarget;
   1.892 +    const GrClipData*               fClip;  // TODO: make this ref counted
   1.893 +    GrDrawState*                    fDrawState;
   1.894 +
   1.895 +    GrResourceCache*                fTextureCache;
   1.896 +    GrFontCache*                    fFontCache;
   1.897 +
   1.898 +    GrPathRendererChain*            fPathRendererChain;
   1.899 +    GrSoftwarePathRenderer*         fSoftwarePathRenderer;
   1.900 +
   1.901 +    GrVertexBufferAllocPool*        fDrawBufferVBAllocPool;
   1.902 +    GrIndexBufferAllocPool*         fDrawBufferIBAllocPool;
   1.903 +    GrInOrderDrawBuffer*            fDrawBuffer;
   1.904 +
   1.905 +    // Set by OverbudgetCB() to request that GrContext flush before exiting a draw.
   1.906 +    bool                            fFlushToReduceCacheSize;
   1.907 +
   1.908 +    GrAARectRenderer*               fAARectRenderer;
   1.909 +    GrOvalRenderer*                 fOvalRenderer;
   1.910 +
   1.911 +    bool                            fDidTestPMConversions;
   1.912 +    int                             fPMToUPMConversion;
   1.913 +    int                             fUPMToPMConversion;
   1.914 +
   1.915 +    struct CleanUpData {
   1.916 +        PFCleanUpFunc fFunc;
   1.917 +        void*         fInfo;
   1.918 +    };
   1.919 +
   1.920 +    SkTDArray<CleanUpData>          fCleanUpData;
   1.921 +
   1.922 +    int                             fMaxTextureSizeOverride;
   1.923 +
   1.924 +    GrContext(); // init must be called after the constructor.
   1.925 +    bool init(GrBackend, GrBackendContext);
   1.926 +
   1.927 +    void setupDrawBuffer();
   1.928 +
   1.929 +    class AutoRestoreEffects;
   1.930 +    class AutoCheckFlush;
   1.931 +    /// Sets the paint and returns the target to draw into. The paint can be NULL in which case the
   1.932 +    /// draw state is left unmodified.
   1.933 +    GrDrawTarget* prepareToDraw(const GrPaint*, BufferedDraw, AutoRestoreEffects*, AutoCheckFlush*);
   1.934 +
   1.935 +    void internalDrawPath(GrDrawTarget* target, bool useAA, const SkPath& path,
   1.936 +                          const SkStrokeRec& stroke);
   1.937 +
   1.938 +    GrTexture* createResizedTexture(const GrTextureDesc& desc,
   1.939 +                                    const GrCacheID& cacheID,
   1.940 +                                    void* srcData,
   1.941 +                                    size_t rowBytes,
   1.942 +                                    bool filter);
   1.943 +
   1.944 +    // Needed so GrTexture's returnToCache helper function can call
   1.945 +    // addExistingTextureToCache
   1.946 +    friend class GrTexture;
   1.947 +    friend class GrStencilAndCoverPathRenderer;
   1.948 +
   1.949 +    // Add an existing texture to the texture cache. This is intended solely
   1.950 +    // for use with textures released from an GrAutoScratchTexture.
   1.951 +    void addExistingTextureToCache(GrTexture* texture);
   1.952 +
   1.953 +    /**
   1.954 +     * These functions create premul <-> unpremul effects if it is possible to generate a pair
   1.955 +     * of effects that make a readToUPM->writeToPM->readToUPM cycle invariant. Otherwise, they
   1.956 +     * return NULL.
   1.957 +     */
   1.958 +    const GrEffectRef* createPMToUPMEffect(GrTexture* texture,
   1.959 +                                           bool swapRAndB,
   1.960 +                                           const SkMatrix& matrix);
   1.961 +    const GrEffectRef* createUPMToPMEffect(GrTexture* texture,
   1.962 +                                           bool swapRAndB,
   1.963 +                                           const SkMatrix& matrix);
   1.964 +
   1.965 +    /**
   1.966 +     *  This callback allows the resource cache to callback into the GrContext
   1.967 +     *  when the cache is still overbudget after a purge.
   1.968 +     */
   1.969 +    static bool OverbudgetCB(void* data);
   1.970 +
   1.971 +    /** Creates a new gpu path, based on the specified path and stroke and returns it.
   1.972 +     * The caller owns a ref on the returned path which must be balanced by a call to unref.
   1.973 +     *
   1.974 +     * @param skPath the path geometry.
   1.975 +     * @param stroke the path stroke.
   1.976 +     * @return a new path or NULL if the operation is not supported by the backend.
   1.977 +     */
   1.978 +    GrPath* createPath(const SkPath& skPath, const SkStrokeRec& stroke);
   1.979 +
   1.980 +    typedef SkRefCnt INHERITED;
   1.981 +};
   1.982 +
   1.983 +/**
   1.984 + * Gets and locks a scratch texture from a descriptor using either exact or approximate criteria.
   1.985 + * Unlocks texture in the destructor.
   1.986 + */
   1.987 +class GrAutoScratchTexture : public ::SkNoncopyable {
   1.988 +public:
   1.989 +    GrAutoScratchTexture()
   1.990 +        : fContext(NULL)
   1.991 +        , fTexture(NULL) {
   1.992 +    }
   1.993 +
   1.994 +    GrAutoScratchTexture(GrContext* context,
   1.995 +                         const GrTextureDesc& desc,
   1.996 +                         GrContext::ScratchTexMatch match = GrContext::kApprox_ScratchTexMatch)
   1.997 +      : fContext(NULL)
   1.998 +      , fTexture(NULL) {
   1.999 +      this->set(context, desc, match);
  1.1000 +    }
  1.1001 +
  1.1002 +    ~GrAutoScratchTexture() {
  1.1003 +        this->reset();
  1.1004 +    }
  1.1005 +
  1.1006 +    void reset() {
  1.1007 +        if (NULL != fContext && NULL != fTexture) {
  1.1008 +            fContext->unlockScratchTexture(fTexture);
  1.1009 +            fTexture->unref();
  1.1010 +            fTexture = NULL;
  1.1011 +        }
  1.1012 +    }
  1.1013 +
  1.1014 +    /*
  1.1015 +     * When detaching a texture we do not unlock it in the texture cache but
  1.1016 +     * we do set the returnToCache flag. In this way the texture remains
  1.1017 +     * "locked" in the texture cache until it is freed and recycled in
  1.1018 +     * GrTexture::internal_dispose. In reality, the texture has been removed
  1.1019 +     * from the cache (because this is in AutoScratchTexture) and by not
  1.1020 +     * calling unlockScratchTexture we simply don't re-add it. It will be
  1.1021 +     * reattached in GrTexture::internal_dispose.
  1.1022 +     *
  1.1023 +     * Note that the caller is assumed to accept and manage the ref to the
  1.1024 +     * returned texture.
  1.1025 +     */
  1.1026 +    GrTexture* detach() {
  1.1027 +        if (NULL == fTexture) {
  1.1028 +            return NULL;
  1.1029 +        }
  1.1030 +        GrTexture* texture = fTexture;
  1.1031 +        fTexture = NULL;
  1.1032 +
  1.1033 +        // This GrAutoScratchTexture has a ref from lockAndRefScratchTexture, which we give up now.
  1.1034 +        // The cache also has a ref which we are lending to the caller of detach(). When the caller
  1.1035 +        // lets go of the ref and the ref count goes to 0 internal_dispose will see this flag is
  1.1036 +        // set and re-ref the texture, thereby restoring the cache's ref.
  1.1037 +        SkASSERT(texture->getRefCnt() > 1);
  1.1038 +        texture->setFlag((GrTextureFlags) GrTexture::kReturnToCache_FlagBit);
  1.1039 +        texture->unref();
  1.1040 +        SkASSERT(NULL != texture->getCacheEntry());
  1.1041 +
  1.1042 +        return texture;
  1.1043 +    }
  1.1044 +
  1.1045 +    GrTexture* set(GrContext* context,
  1.1046 +                   const GrTextureDesc& desc,
  1.1047 +                   GrContext::ScratchTexMatch match = GrContext::kApprox_ScratchTexMatch) {
  1.1048 +        this->reset();
  1.1049 +
  1.1050 +        fContext = context;
  1.1051 +        if (NULL != fContext) {
  1.1052 +            fTexture = fContext->lockAndRefScratchTexture(desc, match);
  1.1053 +            if (NULL == fTexture) {
  1.1054 +                fContext = NULL;
  1.1055 +            }
  1.1056 +            return fTexture;
  1.1057 +        } else {
  1.1058 +            return NULL;
  1.1059 +        }
  1.1060 +    }
  1.1061 +
  1.1062 +    GrTexture* texture() { return fTexture; }
  1.1063 +
  1.1064 +private:
  1.1065 +    GrContext*                    fContext;
  1.1066 +    GrTexture*                    fTexture;
  1.1067 +};
  1.1068 +
  1.1069 +#endif

mercurial