GrGpuResource.h revision c8dc1f74b6cdda9a43a638292a608c59c1d72d80
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
11c44be0e9e4cee5402909c06370a630eee188a8f3bsalomon#include "SkInstCnt.h"
1242619d8df206b0bcd36d952909d972b8961e75debsalomon@google.com#include "SkTInternalLList.h"
139474ed06176fe24c77091b0d75f35442e851073frobertphillips@google.com
14c44be0e9e4cee5402909c06370a630eee188a8f3bsalomonclass GrResourceCacheEntry;
15c8dc1f74b6cdda9a43a638292a608c59c1d72d80bsalomonclass GrResourceCache2;
168fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.comclass GrGpu;
17f7b5c1ebfdad1a77d301d1676235e79f8006883ebsalomon@google.comclass GrContext;
188fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com
1976b7fcc79ee47db6ebea4f27e0070c467684418absalomon@google.com/**
20c44be0e9e4cee5402909c06370a630eee188a8f3bsalomon * Base class for objects that can be kept in the GrResourceCache.
2176b7fcc79ee47db6ebea4f27e0070c467684418absalomon@google.com */
226d3fe022d68fd6dd32c0fab30e24fa5a4f048946bsalomonclass GrGpuResource : public SkNoncopyable {
238fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.compublic:
246d3fe022d68fd6dd32c0fab30e24fa5a4f048946bsalomon    SK_DECLARE_INST_COUNT_ROOT(GrGpuResource)
25c44be0e9e4cee5402909c06370a630eee188a8f3bsalomon
26c44be0e9e4cee5402909c06370a630eee188a8f3bsalomon    // These method signatures are written to mirror SkRefCnt. However, we don't require
27c44be0e9e4cee5402909c06370a630eee188a8f3bsalomon    // thread safety as GrCacheable objects are not intended to cross thread boundaries.
28c44be0e9e4cee5402909c06370a630eee188a8f3bsalomon    // internal_dispose() exists because of GrTexture's reliance on it. It will be removed
29c44be0e9e4cee5402909c06370a630eee188a8f3bsalomon    // soon.
30c44be0e9e4cee5402909c06370a630eee188a8f3bsalomon    void ref() const { ++fRefCnt; }
31c44be0e9e4cee5402909c06370a630eee188a8f3bsalomon    void unref() const { --fRefCnt; if (0 == fRefCnt) { this->internal_dispose(); } }
32c44be0e9e4cee5402909c06370a630eee188a8f3bsalomon    virtual void internal_dispose() const { SkDELETE(this); }
33c44be0e9e4cee5402909c06370a630eee188a8f3bsalomon    bool unique() const { return 1 == fRefCnt; }
34c44be0e9e4cee5402909c06370a630eee188a8f3bsalomon#ifdef SK_DEBUG
35c44be0e9e4cee5402909c06370a630eee188a8f3bsalomon    void validate() const {
36c44be0e9e4cee5402909c06370a630eee188a8f3bsalomon        SkASSERT(fRefCnt > 0);
37c44be0e9e4cee5402909c06370a630eee188a8f3bsalomon    }
38c44be0e9e4cee5402909c06370a630eee188a8f3bsalomon#endif
39977b9c8af3ef1b9a2fa2a0037cf3734cf2ba13d9robertphillips@google.com
408fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com    /**
41089a780c3355129eefc942246534bc1f126b8ccbcommit-bot@chromium.org     * Frees the object in the underlying 3D API. It must be safe to call this
42089a780c3355129eefc942246534bc1f126b8ccbcommit-bot@chromium.org     * when the object has been previously abandoned.
438fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com     */
448fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com    void release();
458fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com
468fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com    /**
478fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com     * Removes references to objects in the underlying 3D API without freeing
488fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com     * them. Used when the API context has been torn down before the GrContext.
498fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com     */
508fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com    void abandon();
518fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com
528fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com    /**
53089a780c3355129eefc942246534bc1f126b8ccbcommit-bot@chromium.org     * Tests whether a object has been abandoned or released. All objects will
54089a780c3355129eefc942246534bc1f126b8ccbcommit-bot@chromium.org     * be in this state after their creating GrContext is destroyed or has
55089a780c3355129eefc942246534bc1f126b8ccbcommit-bot@chromium.org     * contextLost called. It's up to the client to test wasDestroyed() before
56089a780c3355129eefc942246534bc1f126b8ccbcommit-bot@chromium.org     * attempting to use an object if it holds refs on objects across
578fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com     * ~GrContext, freeResources with the force flag, or contextLost.
588fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com     *
59089a780c3355129eefc942246534bc1f126b8ccbcommit-bot@chromium.org     * @return true if the object has been released or abandoned,
608fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com     *         false otherwise.
618fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com     */
62089a780c3355129eefc942246534bc1f126b8ccbcommit-bot@chromium.org    bool wasDestroyed() const { return NULL == fGpu; }
638fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com
64cee661af926cc977addc6e039b7022975a448acebsalomon@google.com    /**
65089a780c3355129eefc942246534bc1f126b8ccbcommit-bot@chromium.org     * Retrieves the context that owns the object. Note that it is possible for
66089a780c3355129eefc942246534bc1f126b8ccbcommit-bot@chromium.org     * this to return NULL. When objects have been release()ed or abandon()ed
67089a780c3355129eefc942246534bc1f126b8ccbcommit-bot@chromium.org     * they no longer have an owning context. Destroying a GrContext
68089a780c3355129eefc942246534bc1f126b8ccbcommit-bot@chromium.org     * automatically releases all its resources.
69838f6e18fb13cd295f2c4d1e673cb03458f4e0a8bsalomon@google.com     */
701f47f4f7325971dd53991e2bb02da94fa7c6d962robertphillips@google.com    const GrContext* getContext() const;
711f47f4f7325971dd53991e2bb02da94fa7c6d962robertphillips@google.com    GrContext* getContext();
721f47f4f7325971dd53991e2bb02da94fa7c6d962robertphillips@google.com
73c44be0e9e4cee5402909c06370a630eee188a8f3bsalomon    /**
74c44be0e9e4cee5402909c06370a630eee188a8f3bsalomon     * Retrieves the amount of GPU memory used by this resource in bytes. It is
75c44be0e9e4cee5402909c06370a630eee188a8f3bsalomon     * approximate since we aren't aware of additional padding or copies made
76c44be0e9e4cee5402909c06370a630eee188a8f3bsalomon     * by the driver.
77c44be0e9e4cee5402909c06370a630eee188a8f3bsalomon     *
78c44be0e9e4cee5402909c06370a630eee188a8f3bsalomon     * @return the amount of GPU memory used in bytes
79c44be0e9e4cee5402909c06370a630eee188a8f3bsalomon     */
80c44be0e9e4cee5402909c06370a630eee188a8f3bsalomon    virtual size_t gpuMemorySize() const = 0;
81c44be0e9e4cee5402909c06370a630eee188a8f3bsalomon
82c44be0e9e4cee5402909c06370a630eee188a8f3bsalomon    void setCacheEntry(GrResourceCacheEntry* cacheEntry) { fCacheEntry = cacheEntry; }
83c44be0e9e4cee5402909c06370a630eee188a8f3bsalomon    GrResourceCacheEntry* getCacheEntry() { return fCacheEntry; }
84089a780c3355129eefc942246534bc1f126b8ccbcommit-bot@chromium.org
85728302281920727b96e6cec0bfc7575900f34a8bbsalomon@google.com    /**
86c44be0e9e4cee5402909c06370a630eee188a8f3bsalomon     * Gets an id that is unique for this GrCacheable object. It is static in that it does
87c44be0e9e4cee5402909c06370a630eee188a8f3bsalomon     * not change when the content of the GrCacheable object changes. This will never return
88c44be0e9e4cee5402909c06370a630eee188a8f3bsalomon     * 0.
89728302281920727b96e6cec0bfc7575900f34a8bbsalomon@google.com     */
90c44be0e9e4cee5402909c06370a630eee188a8f3bsalomon    uint32_t getUniqueID() const { return fUniqueID; }
91c44be0e9e4cee5402909c06370a630eee188a8f3bsalomon
92c44be0e9e4cee5402909c06370a630eee188a8f3bsalomonprotected:
936d3fe022d68fd6dd32c0fab30e24fa5a4f048946bsalomon    GrGpuResource(GrGpu*, bool isWrapped);
946d3fe022d68fd6dd32c0fab30e24fa5a4f048946bsalomon    virtual ~GrGpuResource();
9576b7fcc79ee47db6ebea4f27e0070c467684418absalomon@google.com
96c44be0e9e4cee5402909c06370a630eee188a8f3bsalomon    bool isInCache() const { return NULL != fCacheEntry; }
97c44be0e9e4cee5402909c06370a630eee188a8f3bsalomon
9876b7fcc79ee47db6ebea4f27e0070c467684418absalomon@google.com    GrGpu* getGpu() const { return fGpu; }
998fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com
100d364554bcfd391c3b6111af8bff963a35ab87ba7robertphillips@google.com    // Derived classes should always call their parent class' onRelease
101d364554bcfd391c3b6111af8bff963a35ab87ba7robertphillips@google.com    // and onAbandon methods in their overrides.
102d364554bcfd391c3b6111af8bff963a35ab87ba7robertphillips@google.com    virtual void onRelease() {};
103d364554bcfd391c3b6111af8bff963a35ab87ba7robertphillips@google.com    virtual void onAbandon() {};
1048fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com
1059ef0426e7c126f6ad6ba833d4543b92a197c95afrobertphillips@google.com    bool isWrapped() const { return kWrapped_FlagBit & fFlags; }
106a292112154f803feb9f5cc002bbfab559f7cb633bsalomon@google.com
107c44be0e9e4cee5402909c06370a630eee188a8f3bsalomon    /**
108c44be0e9e4cee5402909c06370a630eee188a8f3bsalomon     * This entry point should be called whenever gpuMemorySize() begins
109c44be0e9e4cee5402909c06370a630eee188a8f3bsalomon     * reporting a different size. If the object is in the cache, it will call
110c44be0e9e4cee5402909c06370a630eee188a8f3bsalomon     * gpuMemorySize() immediately and pass the new size on to the resource
111c44be0e9e4cee5402909c06370a630eee188a8f3bsalomon     * cache.
112c44be0e9e4cee5402909c06370a630eee188a8f3bsalomon     */
113c44be0e9e4cee5402909c06370a630eee188a8f3bsalomon    void didChangeGpuMemorySize() const;
114c44be0e9e4cee5402909c06370a630eee188a8f3bsalomon
1158fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.comprivate:
116515dcd36032997ce335daa0163c6d67e851bcad1commit-bot@chromium.org#ifdef SK_DEBUG
1179474ed06176fe24c77091b0d75f35442e851073frobertphillips@google.com    friend class GrGpu; // for assert in GrGpu to access getGpu
1189474ed06176fe24c77091b0d75f35442e851073frobertphillips@google.com#endif
1198fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com
120c44be0e9e4cee5402909c06370a630eee188a8f3bsalomon    static uint32_t CreateUniqueID();
121c44be0e9e4cee5402909c06370a630eee188a8f3bsalomon
122c8dc1f74b6cdda9a43a638292a608c59c1d72d80bsalomon    // We're in an internal doubly linked list owned by GrResourceCache2
1236d3fe022d68fd6dd32c0fab30e24fa5a4f048946bsalomon    SK_DECLARE_INTERNAL_LLIST_INTERFACE(GrGpuResource);
1248fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com
125c8dc1f74b6cdda9a43a638292a608c59c1d72d80bsalomon    // This is not ref'ed but abandon() or release() will be called before the GrGpu object
126c8dc1f74b6cdda9a43a638292a608c59c1d72d80bsalomon    // is destroyed. Those calls set will this to NULL.
127c8dc1f74b6cdda9a43a638292a608c59c1d72d80bsalomon    GrGpu* fGpu;
128c8dc1f74b6cdda9a43a638292a608c59c1d72d80bsalomon
129728302281920727b96e6cec0bfc7575900f34a8bbsalomon@google.com    enum Flags {
1309ef0426e7c126f6ad6ba833d4543b92a197c95afrobertphillips@google.com        /**
131089a780c3355129eefc942246534bc1f126b8ccbcommit-bot@chromium.org         * This object wraps a GPU object given to us by the user.
132b77f0f4ae560e97cc4cd2758752d955549017c3cskia.committer@gmail.com         * Lifetime management is left up to the user (i.e., we will not
1339ef0426e7c126f6ad6ba833d4543b92a197c95afrobertphillips@google.com         * free it).
1349ef0426e7c126f6ad6ba833d4543b92a197c95afrobertphillips@google.com         */
1359ef0426e7c126f6ad6ba833d4543b92a197c95afrobertphillips@google.com        kWrapped_FlagBit         = 0x1,
136728302281920727b96e6cec0bfc7575900f34a8bbsalomon@google.com    };
137728302281920727b96e6cec0bfc7575900f34a8bbsalomon@google.com
138c44be0e9e4cee5402909c06370a630eee188a8f3bsalomon    uint32_t                fFlags;
139c44be0e9e4cee5402909c06370a630eee188a8f3bsalomon
140c44be0e9e4cee5402909c06370a630eee188a8f3bsalomon    mutable int32_t         fRefCnt;
141c44be0e9e4cee5402909c06370a630eee188a8f3bsalomon    GrResourceCacheEntry*   fCacheEntry;  // NULL if not in cache
142c44be0e9e4cee5402909c06370a630eee188a8f3bsalomon    const uint32_t          fUniqueID;
143c44be0e9e4cee5402909c06370a630eee188a8f3bsalomon
144c44be0e9e4cee5402909c06370a630eee188a8f3bsalomon    typedef SkNoncopyable INHERITED;
1458fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com};
1468fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com
1478fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com#endif
148