aboutsummaryrefslogtreecommitdiffhomepage
path: root/include/gpu/GrResource.h
blob: 93dec58d80632a2bea38303c3a32be994e73f237 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
/*
 * Copyright 2011 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#ifndef GrResource_DEFINED
#define GrResource_DEFINED

#include "SkRefCnt.h"
#include "SkTInternalLList.h"

class GrGpu;
class GrContext;
class GrResourceEntry;

/**
 * Base class for the GPU resources created by a GrContext.
 */
class GrResource : public SkRefCnt {
public:
    SK_DECLARE_INST_COUNT(GrResource)

    /**
     * Frees the resource in the underlying 3D API. It must be safe to call this
     * when the resource has been previously abandoned.
     */
    void release();

    /**
     * Removes references to objects in the underlying 3D API without freeing
     * them. Used when the API context has been torn down before the GrContext.
     */
    void abandon();

    /**
     * Tests whether a resource has been abandoned or released. All resources
     * will be in this state after their creating GrContext is destroyed or has
     * contextLost called. It's up to the client to test isValid() before
     * attempting to use a resource if it holds refs on resources across
     * ~GrContext, freeResources with the force flag, or contextLost.
     *
     * @return true if the resource has been released or abandoned,
     *         false otherwise.
     */
    bool isValid() const { return NULL != fGpu; }

    /**
     * Retrieves the size of the object in GPU memory. This is approximate since
     * we aren't aware of additional padding or copies made by the driver.
     *
     * @return the size of the buffer in bytes
     */
    virtual size_t sizeInBytes() const = 0;

    /**
     * Retrieves the context that owns the resource. Note that it is possible
     * for this to return NULL. When resources have been release()ed or
     * abandon()ed they no longer have an owning context. Destroying a
     * GrContext automatically releases all its resources.
     */
    const GrContext* getContext() const;
    GrContext* getContext();

    void setCacheEntry(GrResourceEntry* cacheEntry) { fCacheEntry = cacheEntry; }
    GrResourceEntry* getCacheEntry() { return fCacheEntry; }

    void incDeferredRefCount() const {
        SkASSERT(fDeferredRefCount >= 0);
        ++fDeferredRefCount;
    }

    void decDeferredRefCount() const {
        SkASSERT(fDeferredRefCount > 0);
        --fDeferredRefCount;
        if (0 == fDeferredRefCount && this->needsDeferredUnref()) {
            SkASSERT(this->getRefCnt() > 1);
            this->unref();
        }
    }

    int getDeferredRefCount() const { return fDeferredRefCount; }

    void setNeedsDeferredUnref() { fFlags |= kDeferredUnref_FlagBit; }

protected:
    /**
     * isWrapped indicates we have wrapped a client-created backend resource in a GrResource. If it
     * is true then the client is responsible for the lifetime of the underlying backend resource.
     * Otherwise, our onRelease() should free the resource.
     */
    GrResource(GrGpu* gpu, bool isWrapped);
    virtual ~GrResource();

    GrGpu* getGpu() const { return fGpu; }

    // Derived classes should always call their parent class' onRelease
    // and onAbandon methods in their overrides.
    virtual void onRelease() {};
    virtual void onAbandon() {};

    bool isInCache() const { return NULL != fCacheEntry; }
    bool isWrapped() const { return kWrapped_FlagBit & fFlags; }
    bool needsDeferredUnref() const { return SkToBool(kDeferredUnref_FlagBit & fFlags); }

private:
#ifdef SK_DEBUG
    friend class GrGpu; // for assert in GrGpu to access getGpu
#endif

    // We're in an internal doubly linked list
    SK_DECLARE_INTERNAL_LLIST_INTERFACE(GrResource);

    GrGpu*              fGpu;               // not reffed. The GrGpu can be deleted while there
                                            // are still live GrResources. It will call
                                            // release() on all such resources in its
                                            // destructor.
    GrResourceEntry*    fCacheEntry;        // NULL if not in cache
    mutable int         fDeferredRefCount;  // How many references in deferred drawing buffers.

    enum Flags {
        /**
         * This resource wraps a GPU resource given to us by the user.
         * Lifetime management is left up to the user (i.e., we will not
         * free it).
         */
        kWrapped_FlagBit         = 0x1,

        /**
         * This texture should be de-refed when the deferred ref count goes
         * to zero. A resource gets into this state when the resource cache
         * is holding a ref-of-obligation (i.e., someone needs to own it but
         * no one else wants to) but doesn't really want to keep it around.
         */
        kDeferredUnref_FlagBit  = 0x2,
    };
    uint32_t         fFlags;

    typedef SkRefCnt INHERITED;
};

#endif