aboutsummaryrefslogtreecommitdiffhomepage
path: root/include/gpu/GrGpuObject.h
blob: 72d2f892be900a0db02e383c26cd85465c878220 (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
/*
 * 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 GrGpuObject_DEFINED
#define GrGpuObject_DEFINED

#include "GrCacheable.h"
#include "SkTInternalLList.h"

class GrGpu;
class GrContext;

/**
 * Base class for the GPU objects created by a GrContext.
 */
class GrGpuObject : public GrCacheable {
public:
    SK_DECLARE_INST_COUNT(GrGpuObject)

    /**
     * Frees the object in the underlying 3D API. It must be safe to call this
     * when the object 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 object has been abandoned or released. All objects will
     * be in this state after their creating GrContext is destroyed or has
     * contextLost called. It's up to the client to test wasDestroyed() before
     * attempting to use an object if it holds refs on objects across
     * ~GrContext, freeResources with the force flag, or contextLost.
     *
     * @return true if the object has been released or abandoned,
     *         false otherwise.
     */
    bool wasDestroyed() const { return NULL == fGpu; }

    /**
     * Retrieves the context that owns the object. Note that it is possible for
     * this to return NULL. When objects 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 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; }

    virtual bool isValidOnGpu() const SK_OVERRIDE { return !this->wasDestroyed(); }

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

    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 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(GrGpuObject);

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

    enum Flags {
        /**
         * This object wraps a GPU object 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. An object 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 GrCacheable INHERITED;
};

#endif