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"
159474ed06176fe24c77091b0d75f35442e851073frobertphillips@google.com
16f7b5c1ebfdad1a77d301d1676235e79f8006883ebsalomon@google.comclass GrContext;
1737dd331b20a92ce79cc26556e065dec98a66cb0bbsalomonclass GrGpu;
180ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomonclass GrResourceCache;
198fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com
2076b7fcc79ee47db6ebea4f27e0070c467684418absalomon@google.com/**
2100b76bd750e668a6989dd497313e715d1b476fdcbsalomon * Base class for GrGpuResource. Handles the various types of refs we need. Separated out as a base
2200b76bd750e668a6989dd497313e715d1b476fdcbsalomon * class to isolate the ref-cnting behavior and provide friendship without exposing all of
2300b76bd750e668a6989dd497313e715d1b476fdcbsalomon * GrGpuResource.
246f07665768dc84453316e7b2bbd6049576764cb1mtklein *
2500b76bd750e668a6989dd497313e715d1b476fdcbsalomon * Gpu resources can have three types of refs:
2600b76bd750e668a6989dd497313e715d1b476fdcbsalomon *   1) Normal ref (+ by ref(), - by unref()): These are used by code that is issuing draw calls
2700b76bd750e668a6989dd497313e715d1b476fdcbsalomon *      that read and write the resource via GrDrawTarget and by any object that must own a
2800b76bd750e668a6989dd497313e715d1b476fdcbsalomon *      GrGpuResource and is itself owned (directly or indirectly) by Skia-client code.
29bcf0a52d4f4221b158e68a06ba0c4cc4db011060bsalomon *   2) Pending read (+ by addPendingRead(), - by completedRead()): GrContext has scheduled a read
3000b76bd750e668a6989dd497313e715d1b476fdcbsalomon *      of the resource by the GPU as a result of a skia API call but hasn't executed it yet.
31bcf0a52d4f4221b158e68a06ba0c4cc4db011060bsalomon *   3) Pending write (+ by addPendingWrite(), - by completedWrite()): GrContext has scheduled a
3200b76bd750e668a6989dd497313e715d1b476fdcbsalomon *      write to the resource by the GPU as a result of a skia API call but hasn't executed it yet.
3300b76bd750e668a6989dd497313e715d1b476fdcbsalomon *
3400b76bd750e668a6989dd497313e715d1b476fdcbsalomon * The latter two ref types are private and intended only for Gr core code.
35bcf0a52d4f4221b158e68a06ba0c4cc4db011060bsalomon *
363f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon * When all the ref/io counts reach zero DERIVED::notifyAllCntsAreZero() will be called (static poly
373f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon * morphism using CRTP). Similarly when the ref (but not necessarily pending read/write) count
383f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon * reaches 0 DERIVED::notifyRefCountIsZero() will be called. In the case when an unref() causes both
393f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon * the ref cnt to reach zero and the other counts are zero, notifyRefCountIsZero() will be called
403f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon * before notifyIsPurgeable(). Moreover, if notifyRefCountIsZero() returns false then
413f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon * notifyAllRefCntsAreZero() won't be called at all. notifyRefCountIsZero() must return false if the
423f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon * object may be deleted after notifyRefCntIsZero() returns.
433f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon *
443f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon * GrIORef and GrGpuResource are separate classes for organizational reasons and to be
45bcf0a52d4f4221b158e68a06ba0c4cc4db011060bsalomon * able to give access via friendship to only the functions related to pending IO operations.
4676b7fcc79ee47db6ebea4f27e0070c467684418absalomon@google.com */
47bcf0a52d4f4221b158e68a06ba0c4cc4db011060bsalomontemplate <typename DERIVED> class GrIORef : public SkNoncopyable {
488fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.compublic:
496f07665768dc84453316e7b2bbd6049576764cb1mtklein    SK_DECLARE_INST_COUNT(GrIORef)
50c44be0e9e4cee5402909c06370a630eee188a8f3bsalomon
5100b76bd750e668a6989dd497313e715d1b476fdcbsalomon    // Some of the signatures are written to mirror SkRefCnt so that GrGpuResource can work with
5200b76bd750e668a6989dd497313e715d1b476fdcbsalomon    // templated helper classes (e.g. SkAutoTUnref). However, we have different categories of
5300b76bd750e668a6989dd497313e715d1b476fdcbsalomon    // refs (e.g. pending reads). We also don't require thread safety as GrCacheable objects are
5400b76bd750e668a6989dd497313e715d1b476fdcbsalomon    // not intended to cross thread boundaries.
5500b76bd750e668a6989dd497313e715d1b476fdcbsalomon    void ref() const {
569323b8b8e16df4adcd63ee8496a6382e8df535c9Brian Salomon        this->validate();
57bcf0a52d4f4221b158e68a06ba0c4cc4db011060bsalomon        ++fRefCnt;
5800b76bd750e668a6989dd497313e715d1b476fdcbsalomon    }
5900b76bd750e668a6989dd497313e715d1b476fdcbsalomon
6000b76bd750e668a6989dd497313e715d1b476fdcbsalomon    void unref() const {
6100b76bd750e668a6989dd497313e715d1b476fdcbsalomon        this->validate();
623f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon
633f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon        if (!(--fRefCnt)) {
643f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon            if (!static_cast<const DERIVED*>(this)->notifyRefCountIsZero()) {
653f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon                return;
663f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon            }
673f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon        }
683f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon
693f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon        this->didRemoveRefOrPendingIO(kRef_CntType);
7000b76bd750e668a6989dd497313e715d1b476fdcbsalomon    }
7100b76bd750e668a6989dd497313e715d1b476fdcbsalomon
72c44be0e9e4cee5402909c06370a630eee188a8f3bsalomon    void validate() const {
7300b76bd750e668a6989dd497313e715d1b476fdcbsalomon#ifdef SK_DEBUG
7400b76bd750e668a6989dd497313e715d1b476fdcbsalomon        SkASSERT(fRefCnt >= 0);
7500b76bd750e668a6989dd497313e715d1b476fdcbsalomon        SkASSERT(fPendingReads >= 0);
7600b76bd750e668a6989dd497313e715d1b476fdcbsalomon        SkASSERT(fPendingWrites >= 0);
7712299ab7a1be5f4b99284ecf289d46107ef0a946bsalomon        SkASSERT(fRefCnt + fPendingReads + fPendingWrites >= 0);
78c44be0e9e4cee5402909c06370a630eee188a8f3bsalomon#endif
7900b76bd750e668a6989dd497313e715d1b476fdcbsalomon    }
8000b76bd750e668a6989dd497313e715d1b476fdcbsalomon
8100b76bd750e668a6989dd497313e715d1b476fdcbsalomonprotected:
821e2530babb65a883a01df5ee87147432f6707ce3bsalomon    GrIORef() : fRefCnt(1), fPendingReads(0), fPendingWrites(0) { }
8300b76bd750e668a6989dd497313e715d1b476fdcbsalomon
843f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon    enum CntType {
853f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon        kRef_CntType,
863f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon        kPendingRead_CntType,
873f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon        kPendingWrite_CntType,
883f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon    };
893f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon
9063c992f6c05ea728b5386de61d279f10eb7e08d9bsalomon    bool isPurgeable() const { return !this->internalHasRef() && !this->internalHasPendingIO(); }
9112299ab7a1be5f4b99284ecf289d46107ef0a946bsalomon
928d034a154fec81167ecb696c07da389b98cc02a7bsalomon    bool internalHasPendingRead() const { return SkToBool(fPendingReads); }
938d034a154fec81167ecb696c07da389b98cc02a7bsalomon    bool internalHasPendingWrite() const { return SkToBool(fPendingWrites); }
948d034a154fec81167ecb696c07da389b98cc02a7bsalomon    bool internalHasPendingIO() const { return SkToBool(fPendingWrites | fPendingReads); }
958d034a154fec81167ecb696c07da389b98cc02a7bsalomon
966d4488c5e03010c94200b3706631d34ec3201411bsalomon    bool internalHasRef() const { return SkToBool(fRefCnt); }
976d4488c5e03010c94200b3706631d34ec3201411bsalomon
9800b76bd750e668a6989dd497313e715d1b476fdcbsalomonprivate:
9900b76bd750e668a6989dd497313e715d1b476fdcbsalomon    void addPendingRead() const {
10000b76bd750e668a6989dd497313e715d1b476fdcbsalomon        this->validate();
10100b76bd750e668a6989dd497313e715d1b476fdcbsalomon        ++fPendingReads;
10200b76bd750e668a6989dd497313e715d1b476fdcbsalomon    }
10300b76bd750e668a6989dd497313e715d1b476fdcbsalomon
10400b76bd750e668a6989dd497313e715d1b476fdcbsalomon    void completedRead() const {
10500b76bd750e668a6989dd497313e715d1b476fdcbsalomon        this->validate();
10600b76bd750e668a6989dd497313e715d1b476fdcbsalomon        --fPendingReads;
1073f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon        this->didRemoveRefOrPendingIO(kPendingRead_CntType);
10800b76bd750e668a6989dd497313e715d1b476fdcbsalomon    }
10900b76bd750e668a6989dd497313e715d1b476fdcbsalomon
11000b76bd750e668a6989dd497313e715d1b476fdcbsalomon    void addPendingWrite() const {
11100b76bd750e668a6989dd497313e715d1b476fdcbsalomon        this->validate();
11200b76bd750e668a6989dd497313e715d1b476fdcbsalomon        ++fPendingWrites;
11300b76bd750e668a6989dd497313e715d1b476fdcbsalomon    }
11400b76bd750e668a6989dd497313e715d1b476fdcbsalomon
11500b76bd750e668a6989dd497313e715d1b476fdcbsalomon    void completedWrite() const {
11600b76bd750e668a6989dd497313e715d1b476fdcbsalomon        this->validate();
11700b76bd750e668a6989dd497313e715d1b476fdcbsalomon        --fPendingWrites;
1183f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon        this->didRemoveRefOrPendingIO(kPendingWrite_CntType);
11900b76bd750e668a6989dd497313e715d1b476fdcbsalomon    }
12000b76bd750e668a6989dd497313e715d1b476fdcbsalomon
12100b76bd750e668a6989dd497313e715d1b476fdcbsalomonprivate:
1223f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon    void didRemoveRefOrPendingIO(CntType cntTypeRemoved) const {
12312299ab7a1be5f4b99284ecf289d46107ef0a946bsalomon        if (0 == fPendingReads && 0 == fPendingWrites && 0 == fRefCnt) {
1243f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon            static_cast<const DERIVED*>(this)->notifyAllCntsAreZero(cntTypeRemoved);
125bcf0a52d4f4221b158e68a06ba0c4cc4db011060bsalomon        }
126bcf0a52d4f4221b158e68a06ba0c4cc4db011060bsalomon    }
127bcf0a52d4f4221b158e68a06ba0c4cc4db011060bsalomon
12800b76bd750e668a6989dd497313e715d1b476fdcbsalomon    mutable int32_t fRefCnt;
12900b76bd750e668a6989dd497313e715d1b476fdcbsalomon    mutable int32_t fPendingReads;
13000b76bd750e668a6989dd497313e715d1b476fdcbsalomon    mutable int32_t fPendingWrites;
13100b76bd750e668a6989dd497313e715d1b476fdcbsalomon
132ac8d6193eaa29e02d1786fe56efa98eefee74e50bsalomon    // This class is used to manage conversion of refs to pending reads/writes.
133f96ba02513eadd9fa24d75396ec9f2d6682e464cbsalomon    friend class GrGpuResourceRef;
1340ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon    friend class GrResourceCache; // to check IO ref counts.
135bcf0a52d4f4221b158e68a06ba0c4cc4db011060bsalomon
136bcf0a52d4f4221b158e68a06ba0c4cc4db011060bsalomon    template <typename, GrIOType> friend class GrPendingIOResource;
13700b76bd750e668a6989dd497313e715d1b476fdcbsalomon};
13800b76bd750e668a6989dd497313e715d1b476fdcbsalomon
13900b76bd750e668a6989dd497313e715d1b476fdcbsalomon/**
1400ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon * Base class for objects that can be kept in the GrResourceCache.
14100b76bd750e668a6989dd497313e715d1b476fdcbsalomon */
142544fe2338ff7459dbd887549aca31b8fc4cde7f4bsalomonclass SK_API GrGpuResource : public GrIORef<GrGpuResource> {
14300b76bd750e668a6989dd497313e715d1b476fdcbsalomonpublic:
14400b76bd750e668a6989dd497313e715d1b476fdcbsalomon    SK_DECLARE_INST_COUNT(GrGpuResource)
145977b9c8af3ef1b9a2fa2a0037cf3734cf2ba13d9robertphillips@google.com
1465236cf480daf82b2f36e42795abdbbc915533a59bsalomon    enum LifeCycle {
1475236cf480daf82b2f36e42795abdbbc915533a59bsalomon        /**
1485236cf480daf82b2f36e42795abdbbc915533a59bsalomon         * The resource is cached and owned by Skia. Resources with this status may be kept alive
1498718aafec239c93485e45bbe8fed19d9a8def079bsalomon         * by the cache as either scratch or unique resources even when there are no refs to them.
1505236cf480daf82b2f36e42795abdbbc915533a59bsalomon         * The cache may release them whenever there are no refs.
1515236cf480daf82b2f36e42795abdbbc915533a59bsalomon         */
1525236cf480daf82b2f36e42795abdbbc915533a59bsalomon        kCached_LifeCycle,
1535236cf480daf82b2f36e42795abdbbc915533a59bsalomon        /**
1545236cf480daf82b2f36e42795abdbbc915533a59bsalomon         * The resource is uncached. As soon as there are no more refs to it, it is released. Under
1555236cf480daf82b2f36e42795abdbbc915533a59bsalomon         * the hood the cache may opaquely recycle it as a cached resource.
1565236cf480daf82b2f36e42795abdbbc915533a59bsalomon         */
1575236cf480daf82b2f36e42795abdbbc915533a59bsalomon        kUncached_LifeCycle,
1585236cf480daf82b2f36e42795abdbbc915533a59bsalomon        /**
1595236cf480daf82b2f36e42795abdbbc915533a59bsalomon         * Similar to uncached, but Skia does not manage the lifetime of the underlying backend
1605236cf480daf82b2f36e42795abdbbc915533a59bsalomon         * 3D API object(s). The client is responsible for freeing those. Used to inject client-
1615236cf480daf82b2f36e42795abdbbc915533a59bsalomon         * created GPU resources into Skia (e.g. to render to a client-created texture).
1625236cf480daf82b2f36e42795abdbbc915533a59bsalomon         */
1635236cf480daf82b2f36e42795abdbbc915533a59bsalomon        kWrapped_LifeCycle,
1645236cf480daf82b2f36e42795abdbbc915533a59bsalomon    };
1655236cf480daf82b2f36e42795abdbbc915533a59bsalomon
1668fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com    /**
167089a780c3355129eefc942246534bc1f126b8ccbcommit-bot@chromium.org     * Tests whether a object has been abandoned or released. All objects will
168089a780c3355129eefc942246534bc1f126b8ccbcommit-bot@chromium.org     * be in this state after their creating GrContext is destroyed or has
169089a780c3355129eefc942246534bc1f126b8ccbcommit-bot@chromium.org     * contextLost called. It's up to the client to test wasDestroyed() before
170089a780c3355129eefc942246534bc1f126b8ccbcommit-bot@chromium.org     * attempting to use an object if it holds refs on objects across
1718fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com     * ~GrContext, freeResources with the force flag, or contextLost.
1728fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com     *
173089a780c3355129eefc942246534bc1f126b8ccbcommit-bot@chromium.org     * @return true if the object has been released or abandoned,
1748fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com     *         false otherwise.
1758fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com     */
176089a780c3355129eefc942246534bc1f126b8ccbcommit-bot@chromium.org    bool wasDestroyed() const { return NULL == fGpu; }
1778fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com
178cee661af926cc977addc6e039b7022975a448acebsalomon@google.com    /**
179089a780c3355129eefc942246534bc1f126b8ccbcommit-bot@chromium.org     * Retrieves the context that owns the object. Note that it is possible for
180089a780c3355129eefc942246534bc1f126b8ccbcommit-bot@chromium.org     * this to return NULL. When objects have been release()ed or abandon()ed
181089a780c3355129eefc942246534bc1f126b8ccbcommit-bot@chromium.org     * they no longer have an owning context. Destroying a GrContext
182089a780c3355129eefc942246534bc1f126b8ccbcommit-bot@chromium.org     * automatically releases all its resources.
183838f6e18fb13cd295f2c4d1e673cb03458f4e0a8bsalomon@google.com     */
1841f47f4f7325971dd53991e2bb02da94fa7c6d962robertphillips@google.com    const GrContext* getContext() const;
1851f47f4f7325971dd53991e2bb02da94fa7c6d962robertphillips@google.com    GrContext* getContext();
1861f47f4f7325971dd53991e2bb02da94fa7c6d962robertphillips@google.com
187c44be0e9e4cee5402909c06370a630eee188a8f3bsalomon    /**
188c44be0e9e4cee5402909c06370a630eee188a8f3bsalomon     * Retrieves the amount of GPU memory used by this resource in bytes. It is
189c44be0e9e4cee5402909c06370a630eee188a8f3bsalomon     * approximate since we aren't aware of additional padding or copies made
190c44be0e9e4cee5402909c06370a630eee188a8f3bsalomon     * by the driver.
191c44be0e9e4cee5402909c06370a630eee188a8f3bsalomon     *
192c44be0e9e4cee5402909c06370a630eee188a8f3bsalomon     * @return the amount of GPU memory used in bytes
193c44be0e9e4cee5402909c06370a630eee188a8f3bsalomon     */
19469ed47f42d4877c178fdc0031cb01af2966ae235bsalomon    size_t gpuMemorySize() const {
19569ed47f42d4877c178fdc0031cb01af2966ae235bsalomon        if (kInvalidGpuMemorySize == fGpuMemorySize) {
19669ed47f42d4877c178fdc0031cb01af2966ae235bsalomon            fGpuMemorySize = this->onGpuMemorySize();
19769ed47f42d4877c178fdc0031cb01af2966ae235bsalomon            SkASSERT(kInvalidGpuMemorySize != fGpuMemorySize);
19869ed47f42d4877c178fdc0031cb01af2966ae235bsalomon        }
19969ed47f42d4877c178fdc0031cb01af2966ae235bsalomon        return fGpuMemorySize;
20069ed47f42d4877c178fdc0031cb01af2966ae235bsalomon    }
201c44be0e9e4cee5402909c06370a630eee188a8f3bsalomon
202728302281920727b96e6cec0bfc7575900f34a8bbsalomon@google.com    /**
20352e9d63f7110ac691609660342cdab32082a4235bsalomon     * Gets an id that is unique for this GrGpuResource object. It is static in that it does
20452e9d63f7110ac691609660342cdab32082a4235bsalomon     * not change when the content of the GrGpuResource object changes. This will never return
205c44be0e9e4cee5402909c06370a630eee188a8f3bsalomon     * 0.
206728302281920727b96e6cec0bfc7575900f34a8bbsalomon@google.com     */
207c44be0e9e4cee5402909c06370a630eee188a8f3bsalomon    uint32_t getUniqueID() const { return fUniqueID; }
208c44be0e9e4cee5402909c06370a630eee188a8f3bsalomon
2098718aafec239c93485e45bbe8fed19d9a8def079bsalomon    /** Returns the current unique key for the resource. It will be invalid if the resource has no
2108718aafec239c93485e45bbe8fed19d9a8def079bsalomon        associated unique key. */
2118718aafec239c93485e45bbe8fed19d9a8def079bsalomon    const GrUniqueKey& getUniqueKey() const { return fUniqueKey; }
212563ff60b33fa50b9c6a48dd048b8b36a88596668bsalomon
213453cf40ac7702722695bb09ae2c6df44c19d008bbsalomon    /**
2145756aff40921e700dc40f2a1757291a64acddeaajunov     * Attach a custom data object to this resource. The data will remain attached
2155756aff40921e700dc40f2a1757291a64acddeaajunov     * for the lifetime of this resource (until it is abandoned or released).
2165756aff40921e700dc40f2a1757291a64acddeaajunov     * Takes a ref on data. Previously attached data, if any, is unrefed.
2175756aff40921e700dc40f2a1757291a64acddeaajunov     * Returns the data argument, for convenience.
2185756aff40921e700dc40f2a1757291a64acddeaajunov     */
2195756aff40921e700dc40f2a1757291a64acddeaajunov    const SkData* setCustomData(const SkData* data);
2205756aff40921e700dc40f2a1757291a64acddeaajunov
2215756aff40921e700dc40f2a1757291a64acddeaajunov    /**
2225756aff40921e700dc40f2a1757291a64acddeaajunov     * Returns the custom data object that was attached to this resource by
2235756aff40921e700dc40f2a1757291a64acddeaajunov     * calling setCustomData.
2245756aff40921e700dc40f2a1757291a64acddeaajunov     */
2255756aff40921e700dc40f2a1757291a64acddeaajunov    const SkData* getCustomData() const { return fData.get(); }
2265756aff40921e700dc40f2a1757291a64acddeaajunov
2275756aff40921e700dc40f2a1757291a64acddeaajunov    /**
2283582d3ee9fffdec715f5e4949a241ab08e6271ecbsalomon     * Internal-only helper class used for manipulations of the resource by the cache.
229453cf40ac7702722695bb09ae2c6df44c19d008bbsalomon     */
230453cf40ac7702722695bb09ae2c6df44c19d008bbsalomon    class CacheAccess;
231453cf40ac7702722695bb09ae2c6df44c19d008bbsalomon    inline CacheAccess cacheAccess();
232453cf40ac7702722695bb09ae2c6df44c19d008bbsalomon    inline const CacheAccess cacheAccess() const;
233453cf40ac7702722695bb09ae2c6df44c19d008bbsalomon
234436293a3308d58ce494d9667bd13428dd6e35236junov    /**
2353582d3ee9fffdec715f5e4949a241ab08e6271ecbsalomon     * Internal-only helper class used for manipulations of the resource by internal code.
2363582d3ee9fffdec715f5e4949a241ab08e6271ecbsalomon     */
2373582d3ee9fffdec715f5e4949a241ab08e6271ecbsalomon    class ResourcePriv;
2383582d3ee9fffdec715f5e4949a241ab08e6271ecbsalomon    inline ResourcePriv resourcePriv();
2393582d3ee9fffdec715f5e4949a241ab08e6271ecbsalomon    inline const ResourcePriv resourcePriv() const;
2403582d3ee9fffdec715f5e4949a241ab08e6271ecbsalomon
2413582d3ee9fffdec715f5e4949a241ab08e6271ecbsalomon    /**
242436293a3308d58ce494d9667bd13428dd6e35236junov     * Removes references to objects in the underlying 3D API without freeing them.
243436293a3308d58ce494d9667bd13428dd6e35236junov     * Called by CacheAccess.
244436293a3308d58ce494d9667bd13428dd6e35236junov     * In general this method should not be called outside of skia. It was
245436293a3308d58ce494d9667bd13428dd6e35236junov     * made by public for a special case where it needs to be called in Blink
246436293a3308d58ce494d9667bd13428dd6e35236junov     * when a texture becomes unsafe to use after having been shared through
247436293a3308d58ce494d9667bd13428dd6e35236junov     * a texture mailbox.
248436293a3308d58ce494d9667bd13428dd6e35236junov     */
249436293a3308d58ce494d9667bd13428dd6e35236junov    void abandon();
250436293a3308d58ce494d9667bd13428dd6e35236junov
251c44be0e9e4cee5402909c06370a630eee188a8f3bsalomonprotected:
252169612621f00b3fe9f71014079991287d311751absalomon    // This must be called by every GrGpuObject. It should be called once the object is fully
253169612621f00b3fe9f71014079991287d311751absalomon    // initialized (i.e. not in a base class constructor).
254169612621f00b3fe9f71014079991287d311751absalomon    void registerWithCache();
255169612621f00b3fe9f71014079991287d311751absalomon
2565236cf480daf82b2f36e42795abdbbc915533a59bsalomon    GrGpuResource(GrGpu*, LifeCycle);
2576d3fe022d68fd6dd32c0fab30e24fa5a4f048946bsalomon    virtual ~GrGpuResource();
25876b7fcc79ee47db6ebea4f27e0070c467684418absalomon@google.com
25976b7fcc79ee47db6ebea4f27e0070c467684418absalomon@google.com    GrGpu* getGpu() const { return fGpu; }
2608fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com
26112299ab7a1be5f4b99284ecf289d46107ef0a946bsalomon    /** Overridden to free GPU resources in the backend API. */
26212299ab7a1be5f4b99284ecf289d46107ef0a946bsalomon    virtual void onRelease() { }
26312299ab7a1be5f4b99284ecf289d46107ef0a946bsalomon    /** Overridden to abandon any internal handles, ptrs, etc to backend API resources.
26412299ab7a1be5f4b99284ecf289d46107ef0a946bsalomon        This may be called when the underlying 3D context is no longer valid and so no
26512299ab7a1be5f4b99284ecf289d46107ef0a946bsalomon        backend API calls should be made. */
26612299ab7a1be5f4b99284ecf289d46107ef0a946bsalomon    virtual void onAbandon() { }
2678fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com
2685236cf480daf82b2f36e42795abdbbc915533a59bsalomon    bool isWrapped() const { return kWrapped_LifeCycle == fLifeCycle; }
269a292112154f803feb9f5cc002bbfab559f7cb633bsalomon@google.com
270c44be0e9e4cee5402909c06370a630eee188a8f3bsalomon    /**
27169ed47f42d4877c178fdc0031cb01af2966ae235bsalomon     * This entry point should be called whenever gpuMemorySize() should report a different size.
27269ed47f42d4877c178fdc0031cb01af2966ae235bsalomon     * The cache will call gpuMemorySize() to update the current size of the resource.
273c44be0e9e4cee5402909c06370a630eee188a8f3bsalomon     */
274c44be0e9e4cee5402909c06370a630eee188a8f3bsalomon    void didChangeGpuMemorySize() const;
275c44be0e9e4cee5402909c06370a630eee188a8f3bsalomon
276744998e666073166307d2522847b2536000a7619bsalomon    /**
277744998e666073166307d2522847b2536000a7619bsalomon     * Optionally called by the GrGpuResource subclass if the resource can be used as scratch.
278744998e666073166307d2522847b2536000a7619bsalomon     * By default resources are not usable as scratch. This should only be called once.
279744998e666073166307d2522847b2536000a7619bsalomon     **/
2807775c85611c734a2af709b3a9c127939a4296c48bsalomon    void setScratchKey(const GrScratchKey& scratchKey);
281744998e666073166307d2522847b2536000a7619bsalomon
2828fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.comprivate:
28312299ab7a1be5f4b99284ecf289d46107ef0a946bsalomon    /**
28412299ab7a1be5f4b99284ecf289d46107ef0a946bsalomon     * Frees the object in the underlying 3D API. Called by CacheAccess.
28512299ab7a1be5f4b99284ecf289d46107ef0a946bsalomon     */
28612299ab7a1be5f4b99284ecf289d46107ef0a946bsalomon    void release();
28712299ab7a1be5f4b99284ecf289d46107ef0a946bsalomon
28869ed47f42d4877c178fdc0031cb01af2966ae235bsalomon    virtual size_t onGpuMemorySize() const = 0;
28969ed47f42d4877c178fdc0031cb01af2966ae235bsalomon
2909f2d1571ed1f0ed579e5d7779c46a90e20f30f22bsalomon    // See comments in CacheAccess and ResourcePriv.
291f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon    void setUniqueKey(const GrUniqueKey&);
2928718aafec239c93485e45bbe8fed19d9a8def079bsalomon    void removeUniqueKey();
2933f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon    void notifyAllCntsAreZero(CntType) const;
2943f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon    bool notifyRefCountIsZero() const;
29510e23caea3106be125acea10a637789e5a15c728bsalomon    void removeScratchKey();
296afe3005be3392e43bc51eb7eb2017eefaed85ad1bsalomon    void makeBudgeted();
297c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon    void makeUnbudgeted();
298bcf0a52d4f4221b158e68a06ba0c4cc4db011060bsalomon
299515dcd36032997ce335daa0163c6d67e851bcad1commit-bot@chromium.org#ifdef SK_DEBUG
3009474ed06176fe24c77091b0d75f35442e851073frobertphillips@google.com    friend class GrGpu; // for assert in GrGpu to access getGpu
3019474ed06176fe24c77091b0d75f35442e851073frobertphillips@google.com#endif
3028fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com
303c44be0e9e4cee5402909c06370a630eee188a8f3bsalomon    static uint32_t CreateUniqueID();
304c44be0e9e4cee5402909c06370a630eee188a8f3bsalomon
305f320e04c50a1c8a861bc1d8f50bf732044ff9843bsalomon    // An index into a heap when this resource is purgeable or an array when not. This is maintained
306f320e04c50a1c8a861bc1d8f50bf732044ff9843bsalomon    // by the cache.
3079f2d1571ed1f0ed579e5d7779c46a90e20f30f22bsalomon    int                         fCacheArrayIndex;
3089f2d1571ed1f0ed579e5d7779c46a90e20f30f22bsalomon    // This value reflects how recently this resource was accessed in the cache. This is maintained
3099f2d1571ed1f0ed579e5d7779c46a90e20f30f22bsalomon    // by the cache.
3109f2d1571ed1f0ed579e5d7779c46a90e20f30f22bsalomon    uint32_t                    fTimestamp;
311c8dc1f74b6cdda9a43a638292a608c59c1d72d80bsalomon
31284c8e62fad59f0e19b40ac718467f5b7884b431dbsalomon    static const size_t kInvalidGpuMemorySize = ~static_cast<size_t>(0);
31324db3b1c35fb935660229da164fc5ad31977387fbsalomon    GrScratchKey                fScratchKey;
3148718aafec239c93485e45bbe8fed19d9a8def079bsalomon    GrUniqueKey                 fUniqueKey;
31584c8e62fad59f0e19b40ac718467f5b7884b431dbsalomon
31684c8e62fad59f0e19b40ac718467f5b7884b431dbsalomon    // This is not ref'ed but abandon() or release() will be called before the GrGpu object
31784c8e62fad59f0e19b40ac718467f5b7884b431dbsalomon    // is destroyed. Those calls set will this to NULL.
31824db3b1c35fb935660229da164fc5ad31977387fbsalomon    GrGpu*                      fGpu;
31924db3b1c35fb935660229da164fc5ad31977387fbsalomon    mutable size_t              fGpuMemorySize;
32084c8e62fad59f0e19b40ac718467f5b7884b431dbsalomon
32124db3b1c35fb935660229da164fc5ad31977387fbsalomon    LifeCycle                   fLifeCycle;
32224db3b1c35fb935660229da164fc5ad31977387fbsalomon    const uint32_t              fUniqueID;
323744998e666073166307d2522847b2536000a7619bsalomon
32424db3b1c35fb935660229da164fc5ad31977387fbsalomon    SkAutoTUnref<const SkData>  fData;
3255756aff40921e700dc40f2a1757291a64acddeaajunov
326bcf0a52d4f4221b158e68a06ba0c4cc4db011060bsalomon    typedef GrIORef<GrGpuResource> INHERITED;
3273f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon    friend class GrIORef<GrGpuResource>; // to access notifyAllCntsAreZero and notifyRefCntIsZero.
3288fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com};
3298fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com
3308fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com#endif
331