1ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com/*
2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2011 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
8089a780c3355129eefc942246534bc1f126b8ccbcommit-bot@chromium.org#ifndef GrGpuObject_DEFINED
9089a780c3355129eefc942246534bc1f126b8ccbcommit-bot@chromium.org#define GrGpuObject_DEFINED
108fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com
11089a780c3355129eefc942246534bc1f126b8ccbcommit-bot@chromium.org#include "GrCacheable.h"
1242619d8df206b0bcd36d952909d972b8961e75debsalomon@google.com#include "SkTInternalLList.h"
139474ed06176fe24c77091b0d75f35442e851073frobertphillips@google.com
148fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.comclass GrGpu;
15f7b5c1ebfdad1a77d301d1676235e79f8006883ebsalomon@google.comclass GrContext;
168fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com
1776b7fcc79ee47db6ebea4f27e0070c467684418absalomon@google.com/**
18089a780c3355129eefc942246534bc1f126b8ccbcommit-bot@chromium.org * Base class for the GPU objects created by a GrContext.
1976b7fcc79ee47db6ebea4f27e0070c467684418absalomon@google.com */
20089a780c3355129eefc942246534bc1f126b8ccbcommit-bot@chromium.orgclass GrGpuObject : public GrCacheable {
218fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.compublic:
22089a780c3355129eefc942246534bc1f126b8ccbcommit-bot@chromium.org    SK_DECLARE_INST_COUNT(GrGpuObject)
23977b9c8af3ef1b9a2fa2a0037cf3734cf2ba13d9robertphillips@google.com
248fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com    /**
25089a780c3355129eefc942246534bc1f126b8ccbcommit-bot@chromium.org     * Frees the object in the underlying 3D API. It must be safe to call this
26089a780c3355129eefc942246534bc1f126b8ccbcommit-bot@chromium.org     * when the object has been previously abandoned.
278fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com     */
288fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com    void release();
298fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com
308fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com    /**
318fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com     * Removes references to objects in the underlying 3D API without freeing
328fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com     * them. Used when the API context has been torn down before the GrContext.
338fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com     */
348fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com    void abandon();
358fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com
368fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com    /**
37089a780c3355129eefc942246534bc1f126b8ccbcommit-bot@chromium.org     * Tests whether a object has been abandoned or released. All objects will
38089a780c3355129eefc942246534bc1f126b8ccbcommit-bot@chromium.org     * be in this state after their creating GrContext is destroyed or has
39089a780c3355129eefc942246534bc1f126b8ccbcommit-bot@chromium.org     * contextLost called. It's up to the client to test wasDestroyed() before
40089a780c3355129eefc942246534bc1f126b8ccbcommit-bot@chromium.org     * attempting to use an object if it holds refs on objects across
418fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com     * ~GrContext, freeResources with the force flag, or contextLost.
428fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com     *
43089a780c3355129eefc942246534bc1f126b8ccbcommit-bot@chromium.org     * @return true if the object has been released or abandoned,
448fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com     *         false otherwise.
458fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com     */
46089a780c3355129eefc942246534bc1f126b8ccbcommit-bot@chromium.org    bool wasDestroyed() const { return NULL == fGpu; }
478fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com
48cee661af926cc977addc6e039b7022975a448acebsalomon@google.com    /**
49089a780c3355129eefc942246534bc1f126b8ccbcommit-bot@chromium.org     * Retrieves the context that owns the object. Note that it is possible for
50089a780c3355129eefc942246534bc1f126b8ccbcommit-bot@chromium.org     * this to return NULL. When objects have been release()ed or abandon()ed
51089a780c3355129eefc942246534bc1f126b8ccbcommit-bot@chromium.org     * they no longer have an owning context. Destroying a GrContext
52089a780c3355129eefc942246534bc1f126b8ccbcommit-bot@chromium.org     * automatically releases all its resources.
53838f6e18fb13cd295f2c4d1e673cb03458f4e0a8bsalomon@google.com     */
541f47f4f7325971dd53991e2bb02da94fa7c6d962robertphillips@google.com    const GrContext* getContext() const;
551f47f4f7325971dd53991e2bb02da94fa7c6d962robertphillips@google.com    GrContext* getContext();
561f47f4f7325971dd53991e2bb02da94fa7c6d962robertphillips@google.com
57b77f0f4ae560e97cc4cd2758752d955549017c3cskia.committer@gmail.com    void incDeferredRefCount() const {
58b77f0f4ae560e97cc4cd2758752d955549017c3cskia.committer@gmail.com        SkASSERT(fDeferredRefCount >= 0);
59b77f0f4ae560e97cc4cd2758752d955549017c3cskia.committer@gmail.com        ++fDeferredRefCount;
609ef0426e7c126f6ad6ba833d4543b92a197c95afrobertphillips@google.com    }
619ef0426e7c126f6ad6ba833d4543b92a197c95afrobertphillips@google.com
62b77f0f4ae560e97cc4cd2758752d955549017c3cskia.committer@gmail.com    void decDeferredRefCount() const {
63b77f0f4ae560e97cc4cd2758752d955549017c3cskia.committer@gmail.com        SkASSERT(fDeferredRefCount > 0);
64b77f0f4ae560e97cc4cd2758752d955549017c3cskia.committer@gmail.com        --fDeferredRefCount;
659ef0426e7c126f6ad6ba833d4543b92a197c95afrobertphillips@google.com        if (0 == fDeferredRefCount && this->needsDeferredUnref()) {
669ef0426e7c126f6ad6ba833d4543b92a197c95afrobertphillips@google.com            SkASSERT(this->getRefCnt() > 1);
679ef0426e7c126f6ad6ba833d4543b92a197c95afrobertphillips@google.com            this->unref();
689ef0426e7c126f6ad6ba833d4543b92a197c95afrobertphillips@google.com        }
699ef0426e7c126f6ad6ba833d4543b92a197c95afrobertphillips@google.com    }
709ef0426e7c126f6ad6ba833d4543b92a197c95afrobertphillips@google.com
710255a5d2fe37f5b5b4e7c4cdb2ec3ab18a53deafrobertphillips@google.com    int getDeferredRefCount() const { return fDeferredRefCount; }
72838f6e18fb13cd295f2c4d1e673cb03458f4e0a8bsalomon@google.com
739ef0426e7c126f6ad6ba833d4543b92a197c95afrobertphillips@google.com    void setNeedsDeferredUnref() { fFlags |= kDeferredUnref_FlagBit; }
749ef0426e7c126f6ad6ba833d4543b92a197c95afrobertphillips@google.com
75089a780c3355129eefc942246534bc1f126b8ccbcommit-bot@chromium.org    virtual bool isValidOnGpu() const SK_OVERRIDE { return !this->wasDestroyed(); }
76089a780c3355129eefc942246534bc1f126b8ccbcommit-bot@chromium.org
778fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.comprotected:
78728302281920727b96e6cec0bfc7575900f34a8bbsalomon@google.com    /**
79089a780c3355129eefc942246534bc1f126b8ccbcommit-bot@chromium.org     * isWrapped indicates we have wrapped a client-created backend object in a GrGpuObject. If it
80089a780c3355129eefc942246534bc1f126b8ccbcommit-bot@chromium.org     * is true then the client is responsible for the lifetime of the underlying backend object.
81089a780c3355129eefc942246534bc1f126b8ccbcommit-bot@chromium.org     * Otherwise, our onRelease() should free the object.
82728302281920727b96e6cec0bfc7575900f34a8bbsalomon@google.com     */
83089a780c3355129eefc942246534bc1f126b8ccbcommit-bot@chromium.org    GrGpuObject(GrGpu* gpu, bool isWrapped);
84089a780c3355129eefc942246534bc1f126b8ccbcommit-bot@chromium.org    virtual ~GrGpuObject();
8576b7fcc79ee47db6ebea4f27e0070c467684418absalomon@google.com
8676b7fcc79ee47db6ebea4f27e0070c467684418absalomon@google.com    GrGpu* getGpu() const { return fGpu; }
878fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com
88d364554bcfd391c3b6111af8bff963a35ab87ba7robertphillips@google.com    // Derived classes should always call their parent class' onRelease
89d364554bcfd391c3b6111af8bff963a35ab87ba7robertphillips@google.com    // and onAbandon methods in their overrides.
90d364554bcfd391c3b6111af8bff963a35ab87ba7robertphillips@google.com    virtual void onRelease() {};
91d364554bcfd391c3b6111af8bff963a35ab87ba7robertphillips@google.com    virtual void onAbandon() {};
928fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com
939ef0426e7c126f6ad6ba833d4543b92a197c95afrobertphillips@google.com    bool isWrapped() const { return kWrapped_FlagBit & fFlags; }
949ef0426e7c126f6ad6ba833d4543b92a197c95afrobertphillips@google.com    bool needsDeferredUnref() const { return SkToBool(kDeferredUnref_FlagBit & fFlags); }
95a292112154f803feb9f5cc002bbfab559f7cb633bsalomon@google.com
968fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.comprivate:
97515dcd36032997ce335daa0163c6d67e851bcad1commit-bot@chromium.org#ifdef SK_DEBUG
989474ed06176fe24c77091b0d75f35442e851073frobertphillips@google.com    friend class GrGpu; // for assert in GrGpu to access getGpu
999474ed06176fe24c77091b0d75f35442e851073frobertphillips@google.com#endif
1008fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com
10142619d8df206b0bcd36d952909d972b8961e75debsalomon@google.com    // We're in an internal doubly linked list
102089a780c3355129eefc942246534bc1f126b8ccbcommit-bot@chromium.org    SK_DECLARE_INTERNAL_LLIST_INTERFACE(GrGpuObject);
1038fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com
104838f6e18fb13cd295f2c4d1e673cb03458f4e0a8bsalomon@google.com    GrGpu*              fGpu;               // not reffed. The GrGpu can be deleted while there
105089a780c3355129eefc942246534bc1f126b8ccbcommit-bot@chromium.org                                            // are still live GrGpuObjects. It will call
106089a780c3355129eefc942246534bc1f126b8ccbcommit-bot@chromium.org                                            // release() on all such objects in its destructor.
107838f6e18fb13cd295f2c4d1e673cb03458f4e0a8bsalomon@google.com    mutable int         fDeferredRefCount;  // How many references in deferred drawing buffers.
1081f47f4f7325971dd53991e2bb02da94fa7c6d962robertphillips@google.com
109728302281920727b96e6cec0bfc7575900f34a8bbsalomon@google.com    enum Flags {
1109ef0426e7c126f6ad6ba833d4543b92a197c95afrobertphillips@google.com        /**
111089a780c3355129eefc942246534bc1f126b8ccbcommit-bot@chromium.org         * This object wraps a GPU object given to us by the user.
112b77f0f4ae560e97cc4cd2758752d955549017c3cskia.committer@gmail.com         * Lifetime management is left up to the user (i.e., we will not
1139ef0426e7c126f6ad6ba833d4543b92a197c95afrobertphillips@google.com         * free it).
1149ef0426e7c126f6ad6ba833d4543b92a197c95afrobertphillips@google.com         */
1159ef0426e7c126f6ad6ba833d4543b92a197c95afrobertphillips@google.com        kWrapped_FlagBit         = 0x1,
1169ef0426e7c126f6ad6ba833d4543b92a197c95afrobertphillips@google.com
1179ef0426e7c126f6ad6ba833d4543b92a197c95afrobertphillips@google.com        /**
1189ef0426e7c126f6ad6ba833d4543b92a197c95afrobertphillips@google.com         * This texture should be de-refed when the deferred ref count goes
119089a780c3355129eefc942246534bc1f126b8ccbcommit-bot@chromium.org         * to zero. An object gets into this state when the resource cache
1209ef0426e7c126f6ad6ba833d4543b92a197c95afrobertphillips@google.com         * is holding a ref-of-obligation (i.e., someone needs to own it but
1219ef0426e7c126f6ad6ba833d4543b92a197c95afrobertphillips@google.com         * no one else wants to) but doesn't really want to keep it around.
1229ef0426e7c126f6ad6ba833d4543b92a197c95afrobertphillips@google.com         */
1239ef0426e7c126f6ad6ba833d4543b92a197c95afrobertphillips@google.com        kDeferredUnref_FlagBit  = 0x2,
124728302281920727b96e6cec0bfc7575900f34a8bbsalomon@google.com    };
125728302281920727b96e6cec0bfc7575900f34a8bbsalomon@google.com    uint32_t         fFlags;
126728302281920727b96e6cec0bfc7575900f34a8bbsalomon@google.com
127089a780c3355129eefc942246534bc1f126b8ccbcommit-bot@chromium.org    typedef GrCacheable INHERITED;
1288fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com};
1298fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com
1308fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com#endif
131