GrGpuResource.h revision 6f07665768dc84453316e7b2bbd6049576764cb1
1ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com/*
2c44be0e9e4cee5402909c06370a630eee188a8f3bsalomon * Copyright 2014 Google Inc.
3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com *
4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be
5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file.
68fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com */
78fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com
86d3fe022d68fd6dd32c0fab30e24fa5a4f048946bsalomon#ifndef GrGpuResource_DEFINED
96d3fe022d68fd6dd32c0fab30e24fa5a4f048946bsalomon#define GrGpuResource_DEFINED
108fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com
11bcf0a52d4f4221b158e68a06ba0c4cc4db011060bsalomon#include "GrResourceKey.h"
12bcf0a52d4f4221b158e68a06ba0c4cc4db011060bsalomon#include "GrTypesPriv.h"
135756aff40921e700dc40f2a1757291a64acddeaajunov#include "SkData.h"
14c44be0e9e4cee5402909c06370a630eee188a8f3bsalomon#include "SkInstCnt.h"
1542619d8df206b0bcd36d952909d972b8961e75debsalomon@google.com#include "SkTInternalLList.h"
169474ed06176fe24c77091b0d75f35442e851073frobertphillips@google.com
17f7b5c1ebfdad1a77d301d1676235e79f8006883ebsalomon@google.comclass GrContext;
1837dd331b20a92ce79cc26556e065dec98a66cb0bbsalomonclass GrGpu;
1937dd331b20a92ce79cc26556e065dec98a66cb0bbsalomonclass GrResourceCache2;
208fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com
2176b7fcc79ee47db6ebea4f27e0070c467684418absalomon@google.com/**
2200b76bd750e668a6989dd497313e715d1b476fdcbsalomon * Base class for GrGpuResource. Handles the various types of refs we need. Separated out as a base
2300b76bd750e668a6989dd497313e715d1b476fdcbsalomon * class to isolate the ref-cnting behavior and provide friendship without exposing all of
2400b76bd750e668a6989dd497313e715d1b476fdcbsalomon * GrGpuResource.
256f07665768dc84453316e7b2bbd6049576764cb1mtklein *
2600b76bd750e668a6989dd497313e715d1b476fdcbsalomon * Gpu resources can have three types of refs:
2700b76bd750e668a6989dd497313e715d1b476fdcbsalomon *   1) Normal ref (+ by ref(), - by unref()): These are used by code that is issuing draw calls
2800b76bd750e668a6989dd497313e715d1b476fdcbsalomon *      that read and write the resource via GrDrawTarget and by any object that must own a
2900b76bd750e668a6989dd497313e715d1b476fdcbsalomon *      GrGpuResource and is itself owned (directly or indirectly) by Skia-client code.
30bcf0a52d4f4221b158e68a06ba0c4cc4db011060bsalomon *   2) Pending read (+ by addPendingRead(), - by completedRead()): GrContext has scheduled a read
3100b76bd750e668a6989dd497313e715d1b476fdcbsalomon *      of the resource by the GPU as a result of a skia API call but hasn't executed it yet.
32bcf0a52d4f4221b158e68a06ba0c4cc4db011060bsalomon *   3) Pending write (+ by addPendingWrite(), - by completedWrite()): GrContext has scheduled a
3300b76bd750e668a6989dd497313e715d1b476fdcbsalomon *      write to the resource by the GPU as a result of a skia API call but hasn't executed it yet.
3400b76bd750e668a6989dd497313e715d1b476fdcbsalomon *
3500b76bd750e668a6989dd497313e715d1b476fdcbsalomon * The latter two ref types are private and intended only for Gr core code.
36bcf0a52d4f4221b158e68a06ba0c4cc4db011060bsalomon *
37bcf0a52d4f4221b158e68a06ba0c4cc4db011060bsalomon * When an item is purgable DERIVED:notifyIsPurgable() will be called (static poly morphism using
38bcf0a52d4f4221b158e68a06ba0c4cc4db011060bsalomon * CRTP). GrIORef and GrGpuResource are separate classes for organizational reasons and to be
39bcf0a52d4f4221b158e68a06ba0c4cc4db011060bsalomon * able to give access via friendship to only the functions related to pending IO operations.
4076b7fcc79ee47db6ebea4f27e0070c467684418absalomon@google.com */
41bcf0a52d4f4221b158e68a06ba0c4cc4db011060bsalomontemplate <typename DERIVED> class GrIORef : public SkNoncopyable {
428fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.compublic:
436f07665768dc84453316e7b2bbd6049576764cb1mtklein    SK_DECLARE_INST_COUNT(GrIORef)
44c44be0e9e4cee5402909c06370a630eee188a8f3bsalomon
4500b76bd750e668a6989dd497313e715d1b476fdcbsalomon    // Some of the signatures are written to mirror SkRefCnt so that GrGpuResource can work with
4600b76bd750e668a6989dd497313e715d1b476fdcbsalomon    // templated helper classes (e.g. SkAutoTUnref). However, we have different categories of
4700b76bd750e668a6989dd497313e715d1b476fdcbsalomon    // refs (e.g. pending reads). We also don't require thread safety as GrCacheable objects are
4800b76bd750e668a6989dd497313e715d1b476fdcbsalomon    // not intended to cross thread boundaries.
4900b76bd750e668a6989dd497313e715d1b476fdcbsalomon    void ref() const {
509323b8b8e16df4adcd63ee8496a6382e8df535c9Brian Salomon        this->validate();
51bcf0a52d4f4221b158e68a06ba0c4cc4db011060bsalomon        ++fRefCnt;
5200b76bd750e668a6989dd497313e715d1b476fdcbsalomon    }
5300b76bd750e668a6989dd497313e715d1b476fdcbsalomon
5400b76bd750e668a6989dd497313e715d1b476fdcbsalomon    void unref() const {
5500b76bd750e668a6989dd497313e715d1b476fdcbsalomon        this->validate();
5600b76bd750e668a6989dd497313e715d1b476fdcbsalomon        --fRefCnt;
57bcf0a52d4f4221b158e68a06ba0c4cc4db011060bsalomon        this->didUnref();
5800b76bd750e668a6989dd497313e715d1b476fdcbsalomon    }
5900b76bd750e668a6989dd497313e715d1b476fdcbsalomon
60c44be0e9e4cee5402909c06370a630eee188a8f3bsalomon    void validate() const {
6100b76bd750e668a6989dd497313e715d1b476fdcbsalomon#ifdef SK_DEBUG
6200b76bd750e668a6989dd497313e715d1b476fdcbsalomon        SkASSERT(fRefCnt >= 0);
6300b76bd750e668a6989dd497313e715d1b476fdcbsalomon        SkASSERT(fPendingReads >= 0);
6400b76bd750e668a6989dd497313e715d1b476fdcbsalomon        SkASSERT(fPendingWrites >= 0);
6512299ab7a1be5f4b99284ecf289d46107ef0a946bsalomon        SkASSERT(fRefCnt + fPendingReads + fPendingWrites >= 0);
66c44be0e9e4cee5402909c06370a630eee188a8f3bsalomon#endif
6700b76bd750e668a6989dd497313e715d1b476fdcbsalomon    }
6800b76bd750e668a6989dd497313e715d1b476fdcbsalomon
6900b76bd750e668a6989dd497313e715d1b476fdcbsalomonprotected:
701e2530babb65a883a01df5ee87147432f6707ce3bsalomon    GrIORef() : fRefCnt(1), fPendingReads(0), fPendingWrites(0) { }
7100b76bd750e668a6989dd497313e715d1b476fdcbsalomon
7212299ab7a1be5f4b99284ecf289d46107ef0a946bsalomon    bool isPurgable() const { return !this->internalHasRef() && !this->internalHasPendingIO(); }
7312299ab7a1be5f4b99284ecf289d46107ef0a946bsalomon
748d034a154fec81167ecb696c07da389b98cc02a7bsalomon    bool internalHasPendingRead() const { return SkToBool(fPendingReads); }
758d034a154fec81167ecb696c07da389b98cc02a7bsalomon    bool internalHasPendingWrite() const { return SkToBool(fPendingWrites); }
768d034a154fec81167ecb696c07da389b98cc02a7bsalomon    bool internalHasPendingIO() const { return SkToBool(fPendingWrites | fPendingReads); }
778d034a154fec81167ecb696c07da389b98cc02a7bsalomon
786d4488c5e03010c94200b3706631d34ec3201411bsalomon    bool internalHasRef() const { return SkToBool(fRefCnt); }
796d4488c5e03010c94200b3706631d34ec3201411bsalomon
8000b76bd750e668a6989dd497313e715d1b476fdcbsalomonprivate:
8100b76bd750e668a6989dd497313e715d1b476fdcbsalomon    void addPendingRead() const {
8200b76bd750e668a6989dd497313e715d1b476fdcbsalomon        this->validate();
8300b76bd750e668a6989dd497313e715d1b476fdcbsalomon        ++fPendingReads;
8400b76bd750e668a6989dd497313e715d1b476fdcbsalomon    }
8500b76bd750e668a6989dd497313e715d1b476fdcbsalomon
8600b76bd750e668a6989dd497313e715d1b476fdcbsalomon    void completedRead() const {
8700b76bd750e668a6989dd497313e715d1b476fdcbsalomon        this->validate();
8800b76bd750e668a6989dd497313e715d1b476fdcbsalomon        --fPendingReads;
89bcf0a52d4f4221b158e68a06ba0c4cc4db011060bsalomon        this->didUnref();
9000b76bd750e668a6989dd497313e715d1b476fdcbsalomon    }
9100b76bd750e668a6989dd497313e715d1b476fdcbsalomon
9200b76bd750e668a6989dd497313e715d1b476fdcbsalomon    void addPendingWrite() const {
9300b76bd750e668a6989dd497313e715d1b476fdcbsalomon        this->validate();
9400b76bd750e668a6989dd497313e715d1b476fdcbsalomon        ++fPendingWrites;
9500b76bd750e668a6989dd497313e715d1b476fdcbsalomon    }
9600b76bd750e668a6989dd497313e715d1b476fdcbsalomon
9700b76bd750e668a6989dd497313e715d1b476fdcbsalomon    void completedWrite() const {
9800b76bd750e668a6989dd497313e715d1b476fdcbsalomon        this->validate();
9900b76bd750e668a6989dd497313e715d1b476fdcbsalomon        --fPendingWrites;
100bcf0a52d4f4221b158e68a06ba0c4cc4db011060bsalomon        this->didUnref();
10100b76bd750e668a6989dd497313e715d1b476fdcbsalomon    }
10200b76bd750e668a6989dd497313e715d1b476fdcbsalomon
10300b76bd750e668a6989dd497313e715d1b476fdcbsalomonprivate:
104bcf0a52d4f4221b158e68a06ba0c4cc4db011060bsalomon    void didUnref() const {
10512299ab7a1be5f4b99284ecf289d46107ef0a946bsalomon        if (0 == fPendingReads && 0 == fPendingWrites && 0 == fRefCnt) {
10612299ab7a1be5f4b99284ecf289d46107ef0a946bsalomon            static_cast<const DERIVED*>(this)->notifyIsPurgable();
107bcf0a52d4f4221b158e68a06ba0c4cc4db011060bsalomon        }
108bcf0a52d4f4221b158e68a06ba0c4cc4db011060bsalomon    }
109bcf0a52d4f4221b158e68a06ba0c4cc4db011060bsalomon
11000b76bd750e668a6989dd497313e715d1b476fdcbsalomon    mutable int32_t fRefCnt;
11100b76bd750e668a6989dd497313e715d1b476fdcbsalomon    mutable int32_t fPendingReads;
11200b76bd750e668a6989dd497313e715d1b476fdcbsalomon    mutable int32_t fPendingWrites;
11300b76bd750e668a6989dd497313e715d1b476fdcbsalomon
114ac8d6193eaa29e02d1786fe56efa98eefee74e50bsalomon    // This class is used to manage conversion of refs to pending reads/writes.
115f96ba02513eadd9fa24d75396ec9f2d6682e464cbsalomon    friend class GrGpuResourceRef;
1161e2530babb65a883a01df5ee87147432f6707ce3bsalomon    friend class GrResourceCache2; // to check IO ref counts.
117bcf0a52d4f4221b158e68a06ba0c4cc4db011060bsalomon
118bcf0a52d4f4221b158e68a06ba0c4cc4db011060bsalomon    template <typename, GrIOType> friend class GrPendingIOResource;
11900b76bd750e668a6989dd497313e715d1b476fdcbsalomon};
12000b76bd750e668a6989dd497313e715d1b476fdcbsalomon
12100b76bd750e668a6989dd497313e715d1b476fdcbsalomon/**
12271cb0c241e439b6ed746b90294d0b6916644a644bsalomon * Base class for objects that can be kept in the GrResourceCache2.
12300b76bd750e668a6989dd497313e715d1b476fdcbsalomon */
124544fe2338ff7459dbd887549aca31b8fc4cde7f4bsalomonclass SK_API GrGpuResource : public GrIORef<GrGpuResource> {
12500b76bd750e668a6989dd497313e715d1b476fdcbsalomonpublic:
12600b76bd750e668a6989dd497313e715d1b476fdcbsalomon    SK_DECLARE_INST_COUNT(GrGpuResource)
127977b9c8af3ef1b9a2fa2a0037cf3734cf2ba13d9robertphillips@google.com
1288fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com    /**
129089a780c3355129eefc942246534bc1f126b8ccbcommit-bot@chromium.org     * Tests whether a object has been abandoned or released. All objects will
130089a780c3355129eefc942246534bc1f126b8ccbcommit-bot@chromium.org     * be in this state after their creating GrContext is destroyed or has
131089a780c3355129eefc942246534bc1f126b8ccbcommit-bot@chromium.org     * contextLost called. It's up to the client to test wasDestroyed() before
132089a780c3355129eefc942246534bc1f126b8ccbcommit-bot@chromium.org     * attempting to use an object if it holds refs on objects across
1338fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com     * ~GrContext, freeResources with the force flag, or contextLost.
1348fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com     *
135089a780c3355129eefc942246534bc1f126b8ccbcommit-bot@chromium.org     * @return true if the object has been released or abandoned,
1368fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com     *         false otherwise.
1378fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com     */
138089a780c3355129eefc942246534bc1f126b8ccbcommit-bot@chromium.org    bool wasDestroyed() const { return NULL == fGpu; }
1398fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com
140cee661af926cc977addc6e039b7022975a448acebsalomon@google.com    /**
141089a780c3355129eefc942246534bc1f126b8ccbcommit-bot@chromium.org     * Retrieves the context that owns the object. Note that it is possible for
142089a780c3355129eefc942246534bc1f126b8ccbcommit-bot@chromium.org     * this to return NULL. When objects have been release()ed or abandon()ed
143089a780c3355129eefc942246534bc1f126b8ccbcommit-bot@chromium.org     * they no longer have an owning context. Destroying a GrContext
144089a780c3355129eefc942246534bc1f126b8ccbcommit-bot@chromium.org     * automatically releases all its resources.
145838f6e18fb13cd295f2c4d1e673cb03458f4e0a8bsalomon@google.com     */
1461f47f4f7325971dd53991e2bb02da94fa7c6d962robertphillips@google.com    const GrContext* getContext() const;
1471f47f4f7325971dd53991e2bb02da94fa7c6d962robertphillips@google.com    GrContext* getContext();
1481f47f4f7325971dd53991e2bb02da94fa7c6d962robertphillips@google.com
149c44be0e9e4cee5402909c06370a630eee188a8f3bsalomon    /**
150c44be0e9e4cee5402909c06370a630eee188a8f3bsalomon     * Retrieves the amount of GPU memory used by this resource in bytes. It is
151c44be0e9e4cee5402909c06370a630eee188a8f3bsalomon     * approximate since we aren't aware of additional padding or copies made
152c44be0e9e4cee5402909c06370a630eee188a8f3bsalomon     * by the driver.
153c44be0e9e4cee5402909c06370a630eee188a8f3bsalomon     *
154c44be0e9e4cee5402909c06370a630eee188a8f3bsalomon     * @return the amount of GPU memory used in bytes
155c44be0e9e4cee5402909c06370a630eee188a8f3bsalomon     */
15669ed47f42d4877c178fdc0031cb01af2966ae235bsalomon    size_t gpuMemorySize() const {
15769ed47f42d4877c178fdc0031cb01af2966ae235bsalomon        if (kInvalidGpuMemorySize == fGpuMemorySize) {
15869ed47f42d4877c178fdc0031cb01af2966ae235bsalomon            fGpuMemorySize = this->onGpuMemorySize();
15969ed47f42d4877c178fdc0031cb01af2966ae235bsalomon            SkASSERT(kInvalidGpuMemorySize != fGpuMemorySize);
16069ed47f42d4877c178fdc0031cb01af2966ae235bsalomon        }
16169ed47f42d4877c178fdc0031cb01af2966ae235bsalomon        return fGpuMemorySize;
16269ed47f42d4877c178fdc0031cb01af2966ae235bsalomon    }
163c44be0e9e4cee5402909c06370a630eee188a8f3bsalomon
164728302281920727b96e6cec0bfc7575900f34a8bbsalomon@google.com    /**
16552e9d63f7110ac691609660342cdab32082a4235bsalomon     * Gets an id that is unique for this GrGpuResource object. It is static in that it does
16652e9d63f7110ac691609660342cdab32082a4235bsalomon     * not change when the content of the GrGpuResource object changes. This will never return
167c44be0e9e4cee5402909c06370a630eee188a8f3bsalomon     * 0.
168728302281920727b96e6cec0bfc7575900f34a8bbsalomon@google.com     */
169c44be0e9e4cee5402909c06370a630eee188a8f3bsalomon    uint32_t getUniqueID() const { return fUniqueID; }
170c44be0e9e4cee5402909c06370a630eee188a8f3bsalomon
171453cf40ac7702722695bb09ae2c6df44c19d008bbsalomon    /**
1725756aff40921e700dc40f2a1757291a64acddeaajunov     * Attach a custom data object to this resource. The data will remain attached
1735756aff40921e700dc40f2a1757291a64acddeaajunov     * for the lifetime of this resource (until it is abandoned or released).
1745756aff40921e700dc40f2a1757291a64acddeaajunov     * Takes a ref on data. Previously attached data, if any, is unrefed.
1755756aff40921e700dc40f2a1757291a64acddeaajunov     * Returns the data argument, for convenience.
1765756aff40921e700dc40f2a1757291a64acddeaajunov     */
1775756aff40921e700dc40f2a1757291a64acddeaajunov    const SkData* setCustomData(const SkData* data);
1785756aff40921e700dc40f2a1757291a64acddeaajunov
1795756aff40921e700dc40f2a1757291a64acddeaajunov    /**
1805756aff40921e700dc40f2a1757291a64acddeaajunov     * Returns the custom data object that was attached to this resource by
1815756aff40921e700dc40f2a1757291a64acddeaajunov     * calling setCustomData.
1825756aff40921e700dc40f2a1757291a64acddeaajunov     */
1835756aff40921e700dc40f2a1757291a64acddeaajunov    const SkData* getCustomData() const { return fData.get(); }
1845756aff40921e700dc40f2a1757291a64acddeaajunov
1855756aff40921e700dc40f2a1757291a64acddeaajunov    /**
186453cf40ac7702722695bb09ae2c6df44c19d008bbsalomon     * Internal-only helper class used for cache manipulations of the reosurce.
187453cf40ac7702722695bb09ae2c6df44c19d008bbsalomon     */
188453cf40ac7702722695bb09ae2c6df44c19d008bbsalomon    class CacheAccess;
189453cf40ac7702722695bb09ae2c6df44c19d008bbsalomon    inline CacheAccess cacheAccess();
190453cf40ac7702722695bb09ae2c6df44c19d008bbsalomon    inline const CacheAccess cacheAccess() const;
191453cf40ac7702722695bb09ae2c6df44c19d008bbsalomon
192436293a3308d58ce494d9667bd13428dd6e35236junov    /**
193436293a3308d58ce494d9667bd13428dd6e35236junov     * Removes references to objects in the underlying 3D API without freeing them.
194436293a3308d58ce494d9667bd13428dd6e35236junov     * Called by CacheAccess.
195436293a3308d58ce494d9667bd13428dd6e35236junov     * In general this method should not be called outside of skia. It was
196436293a3308d58ce494d9667bd13428dd6e35236junov     * made by public for a special case where it needs to be called in Blink
197436293a3308d58ce494d9667bd13428dd6e35236junov     * when a texture becomes unsafe to use after having been shared through
198436293a3308d58ce494d9667bd13428dd6e35236junov     * a texture mailbox.
199436293a3308d58ce494d9667bd13428dd6e35236junov     */
200436293a3308d58ce494d9667bd13428dd6e35236junov    void abandon();
201436293a3308d58ce494d9667bd13428dd6e35236junov
202c44be0e9e4cee5402909c06370a630eee188a8f3bsalomonprotected:
203169612621f00b3fe9f71014079991287d311751absalomon    // This must be called by every GrGpuObject. It should be called once the object is fully
204169612621f00b3fe9f71014079991287d311751absalomon    // initialized (i.e. not in a base class constructor).
205169612621f00b3fe9f71014079991287d311751absalomon    void registerWithCache();
206169612621f00b3fe9f71014079991287d311751absalomon
2076d3fe022d68fd6dd32c0fab30e24fa5a4f048946bsalomon    GrGpuResource(GrGpu*, bool isWrapped);
2086d3fe022d68fd6dd32c0fab30e24fa5a4f048946bsalomon    virtual ~GrGpuResource();
20976b7fcc79ee47db6ebea4f27e0070c467684418absalomon@google.com
21076b7fcc79ee47db6ebea4f27e0070c467684418absalomon@google.com    GrGpu* getGpu() const { return fGpu; }
2118fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com
21212299ab7a1be5f4b99284ecf289d46107ef0a946bsalomon    /** Overridden to free GPU resources in the backend API. */
21312299ab7a1be5f4b99284ecf289d46107ef0a946bsalomon    virtual void onRelease() { }
21412299ab7a1be5f4b99284ecf289d46107ef0a946bsalomon    /** Overridden to abandon any internal handles, ptrs, etc to backend API resources.
21512299ab7a1be5f4b99284ecf289d46107ef0a946bsalomon        This may be called when the underlying 3D context is no longer valid and so no
21612299ab7a1be5f4b99284ecf289d46107ef0a946bsalomon        backend API calls should be made. */
21712299ab7a1be5f4b99284ecf289d46107ef0a946bsalomon    virtual void onAbandon() { }
2188fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com
21984c8e62fad59f0e19b40ac718467f5b7884b431dbsalomon    bool isWrapped() const { return SkToBool(kWrapped_Flag & fFlags); }
220a292112154f803feb9f5cc002bbfab559f7cb633bsalomon@google.com
221c44be0e9e4cee5402909c06370a630eee188a8f3bsalomon    /**
22269ed47f42d4877c178fdc0031cb01af2966ae235bsalomon     * This entry point should be called whenever gpuMemorySize() should report a different size.
22369ed47f42d4877c178fdc0031cb01af2966ae235bsalomon     * The cache will call gpuMemorySize() to update the current size of the resource.
224c44be0e9e4cee5402909c06370a630eee188a8f3bsalomon     */
225c44be0e9e4cee5402909c06370a630eee188a8f3bsalomon    void didChangeGpuMemorySize() const;
226c44be0e9e4cee5402909c06370a630eee188a8f3bsalomon
227744998e666073166307d2522847b2536000a7619bsalomon    /**
228744998e666073166307d2522847b2536000a7619bsalomon     * Optionally called by the GrGpuResource subclass if the resource can be used as scratch.
229744998e666073166307d2522847b2536000a7619bsalomon     * By default resources are not usable as scratch. This should only be called once.
230744998e666073166307d2522847b2536000a7619bsalomon     **/
2317775c85611c734a2af709b3a9c127939a4296c48bsalomon    void setScratchKey(const GrScratchKey& scratchKey);
232744998e666073166307d2522847b2536000a7619bsalomon
2338fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.comprivate:
23412299ab7a1be5f4b99284ecf289d46107ef0a946bsalomon    /**
23512299ab7a1be5f4b99284ecf289d46107ef0a946bsalomon     * Frees the object in the underlying 3D API. Called by CacheAccess.
23612299ab7a1be5f4b99284ecf289d46107ef0a946bsalomon     */
23712299ab7a1be5f4b99284ecf289d46107ef0a946bsalomon    void release();
23812299ab7a1be5f4b99284ecf289d46107ef0a946bsalomon
23969ed47f42d4877c178fdc0031cb01af2966ae235bsalomon    virtual size_t onGpuMemorySize() const = 0;
24069ed47f42d4877c178fdc0031cb01af2966ae235bsalomon
241453cf40ac7702722695bb09ae2c6df44c19d008bbsalomon    // See comments in CacheAccess.
242453cf40ac7702722695bb09ae2c6df44c19d008bbsalomon    bool setContentKey(const GrResourceKey& contentKey);
24384c8e62fad59f0e19b40ac718467f5b7884b431dbsalomon    void setBudgeted(bool countsAgainstBudget);
244bcf0a52d4f4221b158e68a06ba0c4cc4db011060bsalomon    void notifyIsPurgable() const;
24510e23caea3106be125acea10a637789e5a15c728bsalomon    void removeScratchKey();
246bcf0a52d4f4221b158e68a06ba0c4cc4db011060bsalomon
247515dcd36032997ce335daa0163c6d67e851bcad1commit-bot@chromium.org#ifdef SK_DEBUG
2489474ed06176fe24c77091b0d75f35442e851073frobertphillips@google.com    friend class GrGpu; // for assert in GrGpu to access getGpu
2499474ed06176fe24c77091b0d75f35442e851073frobertphillips@google.com#endif
2508fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com
251c44be0e9e4cee5402909c06370a630eee188a8f3bsalomon    static uint32_t CreateUniqueID();
252c44be0e9e4cee5402909c06370a630eee188a8f3bsalomon
253c8dc1f74b6cdda9a43a638292a608c59c1d72d80bsalomon    // We're in an internal doubly linked list owned by GrResourceCache2
2546d3fe022d68fd6dd32c0fab30e24fa5a4f048946bsalomon    SK_DECLARE_INTERNAL_LLIST_INTERFACE(GrGpuResource);
2558fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com
256c8dc1f74b6cdda9a43a638292a608c59c1d72d80bsalomon
25784c8e62fad59f0e19b40ac718467f5b7884b431dbsalomon    static const size_t kInvalidGpuMemorySize = ~static_cast<size_t>(0);
258728302281920727b96e6cec0bfc7575900f34a8bbsalomon@google.com    enum Flags {
2599ef0426e7c126f6ad6ba833d4543b92a197c95afrobertphillips@google.com        /**
26084c8e62fad59f0e19b40ac718467f5b7884b431dbsalomon         * The resource counts against the resource cache's budget.
2619ef0426e7c126f6ad6ba833d4543b92a197c95afrobertphillips@google.com         */
26284c8e62fad59f0e19b40ac718467f5b7884b431dbsalomon        kBudgeted_Flag      = 0x1,
263728302281920727b96e6cec0bfc7575900f34a8bbsalomon@google.com
26484c8e62fad59f0e19b40ac718467f5b7884b431dbsalomon        /**
26584c8e62fad59f0e19b40ac718467f5b7884b431dbsalomon         * This object wraps a GPU object given to us by Skia's client. Skia will not free the
26684c8e62fad59f0e19b40ac718467f5b7884b431dbsalomon         * underlying backend API GPU resources when the GrGpuResource is destroyed. This also
26784c8e62fad59f0e19b40ac718467f5b7884b431dbsalomon         * implies that kBudgeted_Flag is not set.
26884c8e62fad59f0e19b40ac718467f5b7884b431dbsalomon         */
26984c8e62fad59f0e19b40ac718467f5b7884b431dbsalomon        kWrapped_Flag       = 0x2,
270c44be0e9e4cee5402909c06370a630eee188a8f3bsalomon
27184c8e62fad59f0e19b40ac718467f5b7884b431dbsalomon        /**
27284c8e62fad59f0e19b40ac718467f5b7884b431dbsalomon         * If set then fContentKey is valid and the resource is cached based on its content.
27384c8e62fad59f0e19b40ac718467f5b7884b431dbsalomon         */
27484c8e62fad59f0e19b40ac718467f5b7884b431dbsalomon        kContentKeySet_Flag = 0x4,
27584c8e62fad59f0e19b40ac718467f5b7884b431dbsalomon    };
276c44be0e9e4cee5402909c06370a630eee188a8f3bsalomon
2777775c85611c734a2af709b3a9c127939a4296c48bsalomon    GrScratchKey            fScratchKey;
2787775c85611c734a2af709b3a9c127939a4296c48bsalomon    // TODO(bsalomon): Remove GrResourceKey and use different simpler type for content keys.
2796d4488c5e03010c94200b3706631d34ec3201411bsalomon    GrResourceKey           fContentKey;
28084c8e62fad59f0e19b40ac718467f5b7884b431dbsalomon
28184c8e62fad59f0e19b40ac718467f5b7884b431dbsalomon    // This is not ref'ed but abandon() or release() will be called before the GrGpu object
28284c8e62fad59f0e19b40ac718467f5b7884b431dbsalomon    // is destroyed. Those calls set will this to NULL.
28384c8e62fad59f0e19b40ac718467f5b7884b431dbsalomon    GrGpu*                  fGpu;
28484c8e62fad59f0e19b40ac718467f5b7884b431dbsalomon    mutable size_t          fGpuMemorySize;
28584c8e62fad59f0e19b40ac718467f5b7884b431dbsalomon
28684c8e62fad59f0e19b40ac718467f5b7884b431dbsalomon    uint32_t                fFlags;
28784c8e62fad59f0e19b40ac718467f5b7884b431dbsalomon    const uint32_t          fUniqueID;
288744998e666073166307d2522847b2536000a7619bsalomon
2895756aff40921e700dc40f2a1757291a64acddeaajunov    SkAutoTUnref<const SkData> fData;
2905756aff40921e700dc40f2a1757291a64acddeaajunov
291bcf0a52d4f4221b158e68a06ba0c4cc4db011060bsalomon    typedef GrIORef<GrGpuResource> INHERITED;
292bcf0a52d4f4221b158e68a06ba0c4cc4db011060bsalomon    friend class GrIORef<GrGpuResource>; // to access notifyIsPurgable.
2938fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com};
2948fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com
2958fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com#endif
296