1fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot/*
2fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * Copyright 2014 Google Inc.
3fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot *
4fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * Use of this source code is governed by a BSD-style license that can be
5fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * found in the LICENSE file.
6fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot */
7fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
8fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#ifndef GrGpuResource_DEFINED
9fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#define GrGpuResource_DEFINED
10fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
11fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "../private/GrTypesPriv.h"
12fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "GrResourceKey.h"
13fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
14fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotclass GrContext;
15fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotclass GrGpu;
16fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotclass GrResourceCache;
17fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotclass SkTraceMemoryDump;
18fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
19fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot/**
20fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * Base class for GrGpuResource. Handles the various types of refs we need. Separated out as a base
21fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * class to isolate the ref-cnting behavior and provide friendship without exposing all of
22fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * GrGpuResource.
23fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot *
24fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * Gpu resources can have three types of refs:
25fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot *   1) Normal ref (+ by ref(), - by unref()): These are used by code that is issuing draw calls
26fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot *      that read and write the resource via GrOpList and by any object that must own a
27fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot *      GrGpuResource and is itself owned (directly or indirectly) by Skia-client code.
28fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot *   2) Pending read (+ by addPendingRead(), - by completedRead()): GrContext has scheduled a read
29fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot *      of the resource by the GPU as a result of a skia API call but hasn't executed it yet.
30fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot *   3) Pending write (+ by addPendingWrite(), - by completedWrite()): GrContext has scheduled a
31fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot *      write to the resource by the GPU as a result of a skia API call but hasn't executed it yet.
32fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot *
33fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * The latter two ref types are private and intended only for Gr core code.
34fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot *
35fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * When all the ref/io counts reach zero DERIVED::notifyAllCntsAreZero() will be called (static poly
36fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * morphism using CRTP). Similarly when the ref (but not necessarily pending read/write) count
37fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * reaches 0 DERIVED::notifyRefCountIsZero() will be called. In the case when an unref() causes both
38fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * the ref cnt to reach zero and the other counts are zero, notifyRefCountIsZero() will be called
39fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * before notifyIsPurgeable(). Moreover, if notifyRefCountIsZero() returns false then
40fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * notifyAllRefCntsAreZero() won't be called at all. notifyRefCountIsZero() must return false if the
41fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * object may be deleted after notifyRefCntIsZero() returns.
42fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot *
43fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * GrIORef and GrGpuResource are separate classes for organizational reasons and to be
44fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * able to give access via friendship to only the functions related to pending IO operations.
45fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot */
46fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robottemplate <typename DERIVED> class GrIORef : public SkNoncopyable {
47fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotpublic:
48fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // Some of the signatures are written to mirror SkRefCnt so that GrGpuResource can work with
49fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // templated helper classes (e.g. sk_sp). However, we have different categories of
50fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // refs (e.g. pending reads). We also don't require thread safety as GrCacheable objects are
51fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // not intended to cross thread boundaries.
52fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void ref() const {
53fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        this->validate();
54fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        ++fRefCnt;
55fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
56fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
57fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void unref() const {
58fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        this->validate();
59fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
60fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (!(--fRefCnt)) {
61fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            if (!static_cast<const DERIVED*>(this)->notifyRefCountIsZero()) {
62fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                return;
63fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            }
64fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
65fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
66fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        this->didRemoveRefOrPendingIO(kRef_CntType);
67fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
68fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
69fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void validate() const {
70fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#ifdef SK_DEBUG
71fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkASSERT(fRefCnt >= 0);
72fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkASSERT(fPendingReads >= 0);
73fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkASSERT(fPendingWrites >= 0);
74fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkASSERT(fRefCnt + fPendingReads + fPendingWrites >= 0);
75fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#endif
76fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
77fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
78fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotprotected:
79fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    GrIORef() : fRefCnt(1), fPendingReads(0), fPendingWrites(0) { }
80fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
81fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    enum CntType {
82fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        kRef_CntType,
83fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        kPendingRead_CntType,
84fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        kPendingWrite_CntType,
85fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    };
86fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
87fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool isPurgeable() const { return !this->internalHasRef() && !this->internalHasPendingIO(); }
88fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
89fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool internalHasPendingRead() const { return SkToBool(fPendingReads); }
90fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool internalHasPendingWrite() const { return SkToBool(fPendingWrites); }
91fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool internalHasPendingIO() const { return SkToBool(fPendingWrites | fPendingReads); }
92fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
93fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool internalHasRef() const { return SkToBool(fRefCnt); }
94fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool internalHasUniqueRef() const { return fRefCnt == 1; }
95fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
96fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotprivate:
97fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    friend class GrIORefProxy; // needs to forward on wrapped IO calls
98fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // This is for a unit test.
99fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    template <typename T>
100fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    friend void testingOnly_getIORefCnts(const T*, int* refCnt, int* readCnt, int* writeCnt);
101fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
102fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void addPendingRead() const {
103fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        this->validate();
104fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        ++fPendingReads;
105fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
106fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
107fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void completedRead() const {
108fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        this->validate();
109fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        --fPendingReads;
110fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        this->didRemoveRefOrPendingIO(kPendingRead_CntType);
111fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
112fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
113fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void addPendingWrite() const {
114fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        this->validate();
115fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        ++fPendingWrites;
116fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
117fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
118fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void completedWrite() const {
119fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        this->validate();
120fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        --fPendingWrites;
121fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        this->didRemoveRefOrPendingIO(kPendingWrite_CntType);
122fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
123fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
124fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotprivate:
125fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void didRemoveRefOrPendingIO(CntType cntTypeRemoved) const {
126fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (0 == fPendingReads && 0 == fPendingWrites && 0 == fRefCnt) {
127fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            static_cast<const DERIVED*>(this)->notifyAllCntsAreZero(cntTypeRemoved);
128fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
129fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
130fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
131fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    mutable int32_t fRefCnt;
132fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    mutable int32_t fPendingReads;
133fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    mutable int32_t fPendingWrites;
134fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
135fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // This class is used to manage conversion of refs to pending reads/writes.
136fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    friend class GrGpuResourceRef;
137fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    friend class GrResourceCache; // to check IO ref counts.
138fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
139fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    template <typename, GrIOType> friend class GrPendingIOResource;
140fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot};
141fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
142fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot/**
143fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * Base class for objects that can be kept in the GrResourceCache.
144fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot */
145fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotclass SK_API GrGpuResource : public GrIORef<GrGpuResource> {
146fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotpublic:
147fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
148fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    /**
149fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot     * Tests whether a object has been abandoned or released. All objects will
150fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot     * be in this state after their creating GrContext is destroyed or has
151fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot     * contextLost called. It's up to the client to test wasDestroyed() before
152fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot     * attempting to use an object if it holds refs on objects across
153fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot     * ~GrContext, freeResources with the force flag, or contextLost.
154fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot     *
155fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot     * @return true if the object has been released or abandoned,
156fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot     *         false otherwise.
157fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot     */
158fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool wasDestroyed() const { return nullptr == fGpu; }
159fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
160fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    /**
161fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot     * Retrieves the context that owns the object. Note that it is possible for
162fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot     * this to return NULL. When objects have been release()ed or abandon()ed
163fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot     * they no longer have an owning context. Destroying a GrContext
164fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot     * automatically releases all its resources.
165fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot     */
166fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    const GrContext* getContext() const;
167fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    GrContext* getContext();
168fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
169fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    /**
170fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot     * Retrieves the amount of GPU memory used by this resource in bytes. It is
171fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot     * approximate since we aren't aware of additional padding or copies made
172fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot     * by the driver.
173fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot     *
174fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot     * @return the amount of GPU memory used in bytes
175fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot     */
176fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    size_t gpuMemorySize() const {
177fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (kInvalidGpuMemorySize == fGpuMemorySize) {
178fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            fGpuMemorySize = this->onGpuMemorySize();
179fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            SkASSERT(kInvalidGpuMemorySize != fGpuMemorySize);
180fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
181fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        return fGpuMemorySize;
182fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
183fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
184fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    class UniqueID {
185fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    public:
186fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        static UniqueID InvalidID() {
187fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            return UniqueID(uint32_t(SK_InvalidUniqueID));
188fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
189fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
190fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        UniqueID() {}
191fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
192fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        explicit UniqueID(uint32_t id) : fID(id) {}
193fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
194fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        uint32_t asUInt() const { return fID; }
195fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
196fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        bool operator==(const UniqueID& other) const {
197fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            return fID == other.fID;
198fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
199fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        bool operator!=(const UniqueID& other) const {
200fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            return !(*this == other);
201fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
202fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
203fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        void makeInvalid() { fID = SK_InvalidUniqueID; }
204fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        bool isInvalid() const { return SK_InvalidUniqueID == fID; }
205fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
206fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    protected:
207fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        uint32_t fID;
208fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    };
209fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
210fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    /**
211fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot     * Gets an id that is unique for this GrGpuResource object. It is static in that it does
212fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot     * not change when the content of the GrGpuResource object changes. This will never return
213fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot     * 0.
214fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot     */
215fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    UniqueID uniqueID() const { return fUniqueID; }
216fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
217fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    /** Returns the current unique key for the resource. It will be invalid if the resource has no
218fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        associated unique key. */
219fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    const GrUniqueKey& getUniqueKey() const { return fUniqueKey; }
220fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
221fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    /**
222fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot     * Internal-only helper class used for manipulations of the resource by the cache.
223fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot     */
224fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    class CacheAccess;
225fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    inline CacheAccess cacheAccess();
226fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    inline const CacheAccess cacheAccess() const;
227fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
228fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    /**
229fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot     * Internal-only helper class used for manipulations of the resource by internal code.
230fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot     */
231fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    class ResourcePriv;
232fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    inline ResourcePriv resourcePriv();
233fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    inline const ResourcePriv resourcePriv() const;
234fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
235fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    /**
236fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot     * Removes references to objects in the underlying 3D API without freeing them.
237fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot     * Called by CacheAccess.
238fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot     * In general this method should not be called outside of skia. It was
239fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot     * made by public for a special case where it needs to be called in Blink
240fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot     * when a texture becomes unsafe to use after having been shared through
241fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot     * a texture mailbox.
242fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot     */
243fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void abandon();
244fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
245fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    /**
246fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot     * Dumps memory usage information for this GrGpuResource to traceMemoryDump.
247fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot     * Typically, subclasses should not need to override this, and should only
248fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot     * need to override setMemoryBacking.
249fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot     **/
250fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    virtual void dumpMemoryStatistics(SkTraceMemoryDump* traceMemoryDump) const;
251fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
252fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    static uint32_t CreateUniqueID();
253fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
254fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotprotected:
255fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // This must be called by every non-wrapped GrGpuObject. It should be called once the object is
256fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // fully initialized (i.e. only from the constructors of the final class).
257fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void registerWithCache(SkBudgeted);
258fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
259fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // This must be called by every GrGpuObject that references any wrapped backend objects. It
260fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // should be called once the object is fully initialized (i.e. only from the constructors of the
261fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // final class).
262fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void registerWithCacheWrapped();
263fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
264fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    GrGpuResource(GrGpu*);
265fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    virtual ~GrGpuResource();
266fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
267fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    GrGpu* getGpu() const { return fGpu; }
268fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
269fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    /** Overridden to free GPU resources in the backend API. */
270fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    virtual void onRelease() { }
271fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    /** Overridden to abandon any internal handles, ptrs, etc to backend API resources.
272fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        This may be called when the underlying 3D context is no longer valid and so no
273fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        backend API calls should be made. */
274fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    virtual void onAbandon() { }
275fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
276fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    /**
277fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot     * This entry point should be called whenever gpuMemorySize() should report a different size.
278fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot     * The cache will call gpuMemorySize() to update the current size of the resource.
279fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot     */
280fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void didChangeGpuMemorySize() const;
281fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
282fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    /**
283fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot     * Allows subclasses to add additional backing information to the SkTraceMemoryDump. Called by
284fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot     * onMemoryDump. The default implementation adds no backing information.
285fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot     **/
286fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    virtual void setMemoryBacking(SkTraceMemoryDump*, const SkString&) const {}
287fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
288fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotprivate:
289fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    /**
290fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot     * Called by the registerWithCache if the resource is available to be used as scratch.
291fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot     * Resource subclasses should override this if the instances should be recycled as scratch
292fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot     * resources and populate the scratchKey with the key.
293fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot     * By default resources are not recycled as scratch.
294fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot     **/
295fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    virtual void computeScratchKey(GrScratchKey*) const { }
296fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
297fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    /**
298fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot     * Frees the object in the underlying 3D API. Called by CacheAccess.
299fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot     */
300fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void release();
301fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
302fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    virtual size_t onGpuMemorySize() const = 0;
303fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
304fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // See comments in CacheAccess and ResourcePriv.
305fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void setUniqueKey(const GrUniqueKey&);
306fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void removeUniqueKey();
307fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void notifyAllCntsAreZero(CntType) const;
308fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool notifyRefCountIsZero() const;
309fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void removeScratchKey();
310fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void makeBudgeted();
311fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void makeUnbudgeted();
312fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
313fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#ifdef SK_DEBUG
314fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    friend class GrGpu;  // for assert in GrGpu to access getGpu
315fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#endif
316fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
317fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // An index into a heap when this resource is purgeable or an array when not. This is maintained
318fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // by the cache.
319fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    int fCacheArrayIndex;
320fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // This value reflects how recently this resource was accessed in the cache. This is maintained
321fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // by the cache.
322fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    uint32_t fTimestamp;
323fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    uint32_t fExternalFlushCntWhenBecamePurgeable;
324fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    GrStdSteadyClock::time_point fTimeWhenBecamePurgeable;
325fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
326fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    static const size_t kInvalidGpuMemorySize = ~static_cast<size_t>(0);
327fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    GrScratchKey fScratchKey;
328fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    GrUniqueKey fUniqueKey;
329fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
330fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // This is not ref'ed but abandon() or release() will be called before the GrGpu object
331fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // is destroyed. Those calls set will this to NULL.
332fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    GrGpu* fGpu;
333fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    mutable size_t fGpuMemorySize;
334fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
335fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkBudgeted fBudgeted;
336fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool fRefsWrappedObjects;
337fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    const UniqueID fUniqueID;
338fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
339fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    typedef GrIORef<GrGpuResource> INHERITED;
340fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    friend class GrIORef<GrGpuResource>; // to access notifyAllCntsAreZero and notifyRefCntIsZero.
341fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot};
342fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
343fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#endif
344