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