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 11bcf0a52d4f4221b158e68a06ba0c4cc4db011060bsalomon#include "GrResourceKey.h" 12bcf0a52d4f4221b158e68a06ba0c4cc4db011060bsalomon#include "GrTypesPriv.h" 135756aff40921e700dc40f2a1757291a64acddeaajunov#include "SkData.h" 14c44be0e9e4cee5402909c06370a630eee188a8f3bsalomon#include "SkInstCnt.h" 159474ed06176fe24c77091b0d75f35442e851073frobertphillips@google.com 16f7b5c1ebfdad1a77d301d1676235e79f8006883ebsalomon@google.comclass GrContext; 1737dd331b20a92ce79cc26556e065dec98a66cb0bbsalomonclass GrGpu; 180ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomonclass GrResourceCache; 198fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com 2076b7fcc79ee47db6ebea4f27e0070c467684418absalomon@google.com/** 2100b76bd750e668a6989dd497313e715d1b476fdcbsalomon * Base class for GrGpuResource. Handles the various types of refs we need. Separated out as a base 2200b76bd750e668a6989dd497313e715d1b476fdcbsalomon * class to isolate the ref-cnting behavior and provide friendship without exposing all of 2300b76bd750e668a6989dd497313e715d1b476fdcbsalomon * GrGpuResource. 246f07665768dc84453316e7b2bbd6049576764cb1mtklein * 2500b76bd750e668a6989dd497313e715d1b476fdcbsalomon * Gpu resources can have three types of refs: 2600b76bd750e668a6989dd497313e715d1b476fdcbsalomon * 1) Normal ref (+ by ref(), - by unref()): These are used by code that is issuing draw calls 2700b76bd750e668a6989dd497313e715d1b476fdcbsalomon * that read and write the resource via GrDrawTarget and by any object that must own a 2800b76bd750e668a6989dd497313e715d1b476fdcbsalomon * GrGpuResource and is itself owned (directly or indirectly) by Skia-client code. 29bcf0a52d4f4221b158e68a06ba0c4cc4db011060bsalomon * 2) Pending read (+ by addPendingRead(), - by completedRead()): GrContext has scheduled a read 3000b76bd750e668a6989dd497313e715d1b476fdcbsalomon * of the resource by the GPU as a result of a skia API call but hasn't executed it yet. 31bcf0a52d4f4221b158e68a06ba0c4cc4db011060bsalomon * 3) Pending write (+ by addPendingWrite(), - by completedWrite()): GrContext has scheduled a 3200b76bd750e668a6989dd497313e715d1b476fdcbsalomon * write to the resource by the GPU as a result of a skia API call but hasn't executed it yet. 3300b76bd750e668a6989dd497313e715d1b476fdcbsalomon * 3400b76bd750e668a6989dd497313e715d1b476fdcbsalomon * The latter two ref types are private and intended only for Gr core code. 35bcf0a52d4f4221b158e68a06ba0c4cc4db011060bsalomon * 363f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon * When all the ref/io counts reach zero DERIVED::notifyAllCntsAreZero() will be called (static poly 373f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon * morphism using CRTP). Similarly when the ref (but not necessarily pending read/write) count 383f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon * reaches 0 DERIVED::notifyRefCountIsZero() will be called. In the case when an unref() causes both 393f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon * the ref cnt to reach zero and the other counts are zero, notifyRefCountIsZero() will be called 403f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon * before notifyIsPurgeable(). Moreover, if notifyRefCountIsZero() returns false then 413f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon * notifyAllRefCntsAreZero() won't be called at all. notifyRefCountIsZero() must return false if the 423f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon * object may be deleted after notifyRefCntIsZero() returns. 433f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon * 443f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon * GrIORef and GrGpuResource are separate classes for organizational reasons and to be 45bcf0a52d4f4221b158e68a06ba0c4cc4db011060bsalomon * able to give access via friendship to only the functions related to pending IO operations. 4676b7fcc79ee47db6ebea4f27e0070c467684418absalomon@google.com */ 47bcf0a52d4f4221b158e68a06ba0c4cc4db011060bsalomontemplate <typename DERIVED> class GrIORef : public SkNoncopyable { 488fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.compublic: 496f07665768dc84453316e7b2bbd6049576764cb1mtklein SK_DECLARE_INST_COUNT(GrIORef) 50c44be0e9e4cee5402909c06370a630eee188a8f3bsalomon 5100b76bd750e668a6989dd497313e715d1b476fdcbsalomon // Some of the signatures are written to mirror SkRefCnt so that GrGpuResource can work with 5200b76bd750e668a6989dd497313e715d1b476fdcbsalomon // templated helper classes (e.g. SkAutoTUnref). However, we have different categories of 5300b76bd750e668a6989dd497313e715d1b476fdcbsalomon // refs (e.g. pending reads). We also don't require thread safety as GrCacheable objects are 5400b76bd750e668a6989dd497313e715d1b476fdcbsalomon // not intended to cross thread boundaries. 5500b76bd750e668a6989dd497313e715d1b476fdcbsalomon void ref() const { 569323b8b8e16df4adcd63ee8496a6382e8df535c9Brian Salomon this->validate(); 57bcf0a52d4f4221b158e68a06ba0c4cc4db011060bsalomon ++fRefCnt; 5800b76bd750e668a6989dd497313e715d1b476fdcbsalomon } 5900b76bd750e668a6989dd497313e715d1b476fdcbsalomon 6000b76bd750e668a6989dd497313e715d1b476fdcbsalomon void unref() const { 6100b76bd750e668a6989dd497313e715d1b476fdcbsalomon this->validate(); 623f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon 633f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon if (!(--fRefCnt)) { 643f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon if (!static_cast<const DERIVED*>(this)->notifyRefCountIsZero()) { 653f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon return; 663f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon } 673f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon } 683f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon 693f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon this->didRemoveRefOrPendingIO(kRef_CntType); 7000b76bd750e668a6989dd497313e715d1b476fdcbsalomon } 7100b76bd750e668a6989dd497313e715d1b476fdcbsalomon 72c44be0e9e4cee5402909c06370a630eee188a8f3bsalomon void validate() const { 7300b76bd750e668a6989dd497313e715d1b476fdcbsalomon#ifdef SK_DEBUG 7400b76bd750e668a6989dd497313e715d1b476fdcbsalomon SkASSERT(fRefCnt >= 0); 7500b76bd750e668a6989dd497313e715d1b476fdcbsalomon SkASSERT(fPendingReads >= 0); 7600b76bd750e668a6989dd497313e715d1b476fdcbsalomon SkASSERT(fPendingWrites >= 0); 7712299ab7a1be5f4b99284ecf289d46107ef0a946bsalomon SkASSERT(fRefCnt + fPendingReads + fPendingWrites >= 0); 78c44be0e9e4cee5402909c06370a630eee188a8f3bsalomon#endif 7900b76bd750e668a6989dd497313e715d1b476fdcbsalomon } 8000b76bd750e668a6989dd497313e715d1b476fdcbsalomon 8100b76bd750e668a6989dd497313e715d1b476fdcbsalomonprotected: 821e2530babb65a883a01df5ee87147432f6707ce3bsalomon GrIORef() : fRefCnt(1), fPendingReads(0), fPendingWrites(0) { } 8300b76bd750e668a6989dd497313e715d1b476fdcbsalomon 843f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon enum CntType { 853f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon kRef_CntType, 863f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon kPendingRead_CntType, 873f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon kPendingWrite_CntType, 883f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon }; 893f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon 9063c992f6c05ea728b5386de61d279f10eb7e08d9bsalomon bool isPurgeable() const { return !this->internalHasRef() && !this->internalHasPendingIO(); } 9112299ab7a1be5f4b99284ecf289d46107ef0a946bsalomon 928d034a154fec81167ecb696c07da389b98cc02a7bsalomon bool internalHasPendingRead() const { return SkToBool(fPendingReads); } 938d034a154fec81167ecb696c07da389b98cc02a7bsalomon bool internalHasPendingWrite() const { return SkToBool(fPendingWrites); } 948d034a154fec81167ecb696c07da389b98cc02a7bsalomon bool internalHasPendingIO() const { return SkToBool(fPendingWrites | fPendingReads); } 958d034a154fec81167ecb696c07da389b98cc02a7bsalomon 966d4488c5e03010c94200b3706631d34ec3201411bsalomon bool internalHasRef() const { return SkToBool(fRefCnt); } 976d4488c5e03010c94200b3706631d34ec3201411bsalomon 9800b76bd750e668a6989dd497313e715d1b476fdcbsalomonprivate: 9900b76bd750e668a6989dd497313e715d1b476fdcbsalomon void addPendingRead() const { 10000b76bd750e668a6989dd497313e715d1b476fdcbsalomon this->validate(); 10100b76bd750e668a6989dd497313e715d1b476fdcbsalomon ++fPendingReads; 10200b76bd750e668a6989dd497313e715d1b476fdcbsalomon } 10300b76bd750e668a6989dd497313e715d1b476fdcbsalomon 10400b76bd750e668a6989dd497313e715d1b476fdcbsalomon void completedRead() const { 10500b76bd750e668a6989dd497313e715d1b476fdcbsalomon this->validate(); 10600b76bd750e668a6989dd497313e715d1b476fdcbsalomon --fPendingReads; 1073f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon this->didRemoveRefOrPendingIO(kPendingRead_CntType); 10800b76bd750e668a6989dd497313e715d1b476fdcbsalomon } 10900b76bd750e668a6989dd497313e715d1b476fdcbsalomon 11000b76bd750e668a6989dd497313e715d1b476fdcbsalomon void addPendingWrite() const { 11100b76bd750e668a6989dd497313e715d1b476fdcbsalomon this->validate(); 11200b76bd750e668a6989dd497313e715d1b476fdcbsalomon ++fPendingWrites; 11300b76bd750e668a6989dd497313e715d1b476fdcbsalomon } 11400b76bd750e668a6989dd497313e715d1b476fdcbsalomon 11500b76bd750e668a6989dd497313e715d1b476fdcbsalomon void completedWrite() const { 11600b76bd750e668a6989dd497313e715d1b476fdcbsalomon this->validate(); 11700b76bd750e668a6989dd497313e715d1b476fdcbsalomon --fPendingWrites; 1183f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon this->didRemoveRefOrPendingIO(kPendingWrite_CntType); 11900b76bd750e668a6989dd497313e715d1b476fdcbsalomon } 12000b76bd750e668a6989dd497313e715d1b476fdcbsalomon 12100b76bd750e668a6989dd497313e715d1b476fdcbsalomonprivate: 1223f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon void didRemoveRefOrPendingIO(CntType cntTypeRemoved) const { 12312299ab7a1be5f4b99284ecf289d46107ef0a946bsalomon if (0 == fPendingReads && 0 == fPendingWrites && 0 == fRefCnt) { 1243f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon static_cast<const DERIVED*>(this)->notifyAllCntsAreZero(cntTypeRemoved); 125bcf0a52d4f4221b158e68a06ba0c4cc4db011060bsalomon } 126bcf0a52d4f4221b158e68a06ba0c4cc4db011060bsalomon } 127bcf0a52d4f4221b158e68a06ba0c4cc4db011060bsalomon 12800b76bd750e668a6989dd497313e715d1b476fdcbsalomon mutable int32_t fRefCnt; 12900b76bd750e668a6989dd497313e715d1b476fdcbsalomon mutable int32_t fPendingReads; 13000b76bd750e668a6989dd497313e715d1b476fdcbsalomon mutable int32_t fPendingWrites; 13100b76bd750e668a6989dd497313e715d1b476fdcbsalomon 132ac8d6193eaa29e02d1786fe56efa98eefee74e50bsalomon // This class is used to manage conversion of refs to pending reads/writes. 133f96ba02513eadd9fa24d75396ec9f2d6682e464cbsalomon friend class GrGpuResourceRef; 1340ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon friend class GrResourceCache; // to check IO ref counts. 135bcf0a52d4f4221b158e68a06ba0c4cc4db011060bsalomon 136bcf0a52d4f4221b158e68a06ba0c4cc4db011060bsalomon template <typename, GrIOType> friend class GrPendingIOResource; 13700b76bd750e668a6989dd497313e715d1b476fdcbsalomon}; 13800b76bd750e668a6989dd497313e715d1b476fdcbsalomon 13900b76bd750e668a6989dd497313e715d1b476fdcbsalomon/** 1400ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon * Base class for objects that can be kept in the GrResourceCache. 14100b76bd750e668a6989dd497313e715d1b476fdcbsalomon */ 142544fe2338ff7459dbd887549aca31b8fc4cde7f4bsalomonclass SK_API GrGpuResource : public GrIORef<GrGpuResource> { 14300b76bd750e668a6989dd497313e715d1b476fdcbsalomonpublic: 14400b76bd750e668a6989dd497313e715d1b476fdcbsalomon SK_DECLARE_INST_COUNT(GrGpuResource) 145977b9c8af3ef1b9a2fa2a0037cf3734cf2ba13d9robertphillips@google.com 1465236cf480daf82b2f36e42795abdbbc915533a59bsalomon enum LifeCycle { 1475236cf480daf82b2f36e42795abdbbc915533a59bsalomon /** 1485236cf480daf82b2f36e42795abdbbc915533a59bsalomon * The resource is cached and owned by Skia. Resources with this status may be kept alive 1498718aafec239c93485e45bbe8fed19d9a8def079bsalomon * by the cache as either scratch or unique resources even when there are no refs to them. 1505236cf480daf82b2f36e42795abdbbc915533a59bsalomon * The cache may release them whenever there are no refs. 1515236cf480daf82b2f36e42795abdbbc915533a59bsalomon */ 1525236cf480daf82b2f36e42795abdbbc915533a59bsalomon kCached_LifeCycle, 1535236cf480daf82b2f36e42795abdbbc915533a59bsalomon /** 1545236cf480daf82b2f36e42795abdbbc915533a59bsalomon * The resource is uncached. As soon as there are no more refs to it, it is released. Under 1555236cf480daf82b2f36e42795abdbbc915533a59bsalomon * the hood the cache may opaquely recycle it as a cached resource. 1565236cf480daf82b2f36e42795abdbbc915533a59bsalomon */ 1575236cf480daf82b2f36e42795abdbbc915533a59bsalomon kUncached_LifeCycle, 1585236cf480daf82b2f36e42795abdbbc915533a59bsalomon /** 1595236cf480daf82b2f36e42795abdbbc915533a59bsalomon * Similar to uncached, but Skia does not manage the lifetime of the underlying backend 1605236cf480daf82b2f36e42795abdbbc915533a59bsalomon * 3D API object(s). The client is responsible for freeing those. Used to inject client- 1615236cf480daf82b2f36e42795abdbbc915533a59bsalomon * created GPU resources into Skia (e.g. to render to a client-created texture). 1625236cf480daf82b2f36e42795abdbbc915533a59bsalomon */ 1635236cf480daf82b2f36e42795abdbbc915533a59bsalomon kWrapped_LifeCycle, 1645236cf480daf82b2f36e42795abdbbc915533a59bsalomon }; 1655236cf480daf82b2f36e42795abdbbc915533a59bsalomon 1668fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com /** 167089a780c3355129eefc942246534bc1f126b8ccbcommit-bot@chromium.org * Tests whether a object has been abandoned or released. All objects will 168089a780c3355129eefc942246534bc1f126b8ccbcommit-bot@chromium.org * be in this state after their creating GrContext is destroyed or has 169089a780c3355129eefc942246534bc1f126b8ccbcommit-bot@chromium.org * contextLost called. It's up to the client to test wasDestroyed() before 170089a780c3355129eefc942246534bc1f126b8ccbcommit-bot@chromium.org * attempting to use an object if it holds refs on objects across 1718fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com * ~GrContext, freeResources with the force flag, or contextLost. 1728fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com * 173089a780c3355129eefc942246534bc1f126b8ccbcommit-bot@chromium.org * @return true if the object has been released or abandoned, 1748fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com * false otherwise. 1758fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com */ 176089a780c3355129eefc942246534bc1f126b8ccbcommit-bot@chromium.org bool wasDestroyed() const { return NULL == fGpu; } 1778fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com 178cee661af926cc977addc6e039b7022975a448acebsalomon@google.com /** 179089a780c3355129eefc942246534bc1f126b8ccbcommit-bot@chromium.org * Retrieves the context that owns the object. Note that it is possible for 180089a780c3355129eefc942246534bc1f126b8ccbcommit-bot@chromium.org * this to return NULL. When objects have been release()ed or abandon()ed 181089a780c3355129eefc942246534bc1f126b8ccbcommit-bot@chromium.org * they no longer have an owning context. Destroying a GrContext 182089a780c3355129eefc942246534bc1f126b8ccbcommit-bot@chromium.org * automatically releases all its resources. 183838f6e18fb13cd295f2c4d1e673cb03458f4e0a8bsalomon@google.com */ 1841f47f4f7325971dd53991e2bb02da94fa7c6d962robertphillips@google.com const GrContext* getContext() const; 1851f47f4f7325971dd53991e2bb02da94fa7c6d962robertphillips@google.com GrContext* getContext(); 1861f47f4f7325971dd53991e2bb02da94fa7c6d962robertphillips@google.com 187c44be0e9e4cee5402909c06370a630eee188a8f3bsalomon /** 188c44be0e9e4cee5402909c06370a630eee188a8f3bsalomon * Retrieves the amount of GPU memory used by this resource in bytes. It is 189c44be0e9e4cee5402909c06370a630eee188a8f3bsalomon * approximate since we aren't aware of additional padding or copies made 190c44be0e9e4cee5402909c06370a630eee188a8f3bsalomon * by the driver. 191c44be0e9e4cee5402909c06370a630eee188a8f3bsalomon * 192c44be0e9e4cee5402909c06370a630eee188a8f3bsalomon * @return the amount of GPU memory used in bytes 193c44be0e9e4cee5402909c06370a630eee188a8f3bsalomon */ 19469ed47f42d4877c178fdc0031cb01af2966ae235bsalomon size_t gpuMemorySize() const { 19569ed47f42d4877c178fdc0031cb01af2966ae235bsalomon if (kInvalidGpuMemorySize == fGpuMemorySize) { 19669ed47f42d4877c178fdc0031cb01af2966ae235bsalomon fGpuMemorySize = this->onGpuMemorySize(); 19769ed47f42d4877c178fdc0031cb01af2966ae235bsalomon SkASSERT(kInvalidGpuMemorySize != fGpuMemorySize); 19869ed47f42d4877c178fdc0031cb01af2966ae235bsalomon } 19969ed47f42d4877c178fdc0031cb01af2966ae235bsalomon return fGpuMemorySize; 20069ed47f42d4877c178fdc0031cb01af2966ae235bsalomon } 201c44be0e9e4cee5402909c06370a630eee188a8f3bsalomon 202728302281920727b96e6cec0bfc7575900f34a8bbsalomon@google.com /** 20352e9d63f7110ac691609660342cdab32082a4235bsalomon * Gets an id that is unique for this GrGpuResource object. It is static in that it does 20452e9d63f7110ac691609660342cdab32082a4235bsalomon * not change when the content of the GrGpuResource object changes. This will never return 205c44be0e9e4cee5402909c06370a630eee188a8f3bsalomon * 0. 206728302281920727b96e6cec0bfc7575900f34a8bbsalomon@google.com */ 207c44be0e9e4cee5402909c06370a630eee188a8f3bsalomon uint32_t getUniqueID() const { return fUniqueID; } 208c44be0e9e4cee5402909c06370a630eee188a8f3bsalomon 2098718aafec239c93485e45bbe8fed19d9a8def079bsalomon /** Returns the current unique key for the resource. It will be invalid if the resource has no 2108718aafec239c93485e45bbe8fed19d9a8def079bsalomon associated unique key. */ 2118718aafec239c93485e45bbe8fed19d9a8def079bsalomon const GrUniqueKey& getUniqueKey() const { return fUniqueKey; } 212563ff60b33fa50b9c6a48dd048b8b36a88596668bsalomon 213453cf40ac7702722695bb09ae2c6df44c19d008bbsalomon /** 2145756aff40921e700dc40f2a1757291a64acddeaajunov * Attach a custom data object to this resource. The data will remain attached 2155756aff40921e700dc40f2a1757291a64acddeaajunov * for the lifetime of this resource (until it is abandoned or released). 2165756aff40921e700dc40f2a1757291a64acddeaajunov * Takes a ref on data. Previously attached data, if any, is unrefed. 2175756aff40921e700dc40f2a1757291a64acddeaajunov * Returns the data argument, for convenience. 2185756aff40921e700dc40f2a1757291a64acddeaajunov */ 2195756aff40921e700dc40f2a1757291a64acddeaajunov const SkData* setCustomData(const SkData* data); 2205756aff40921e700dc40f2a1757291a64acddeaajunov 2215756aff40921e700dc40f2a1757291a64acddeaajunov /** 2225756aff40921e700dc40f2a1757291a64acddeaajunov * Returns the custom data object that was attached to this resource by 2235756aff40921e700dc40f2a1757291a64acddeaajunov * calling setCustomData. 2245756aff40921e700dc40f2a1757291a64acddeaajunov */ 2255756aff40921e700dc40f2a1757291a64acddeaajunov const SkData* getCustomData() const { return fData.get(); } 2265756aff40921e700dc40f2a1757291a64acddeaajunov 2275756aff40921e700dc40f2a1757291a64acddeaajunov /** 2283582d3ee9fffdec715f5e4949a241ab08e6271ecbsalomon * Internal-only helper class used for manipulations of the resource by the cache. 229453cf40ac7702722695bb09ae2c6df44c19d008bbsalomon */ 230453cf40ac7702722695bb09ae2c6df44c19d008bbsalomon class CacheAccess; 231453cf40ac7702722695bb09ae2c6df44c19d008bbsalomon inline CacheAccess cacheAccess(); 232453cf40ac7702722695bb09ae2c6df44c19d008bbsalomon inline const CacheAccess cacheAccess() const; 233453cf40ac7702722695bb09ae2c6df44c19d008bbsalomon 234436293a3308d58ce494d9667bd13428dd6e35236junov /** 2353582d3ee9fffdec715f5e4949a241ab08e6271ecbsalomon * Internal-only helper class used for manipulations of the resource by internal code. 2363582d3ee9fffdec715f5e4949a241ab08e6271ecbsalomon */ 2373582d3ee9fffdec715f5e4949a241ab08e6271ecbsalomon class ResourcePriv; 2383582d3ee9fffdec715f5e4949a241ab08e6271ecbsalomon inline ResourcePriv resourcePriv(); 2393582d3ee9fffdec715f5e4949a241ab08e6271ecbsalomon inline const ResourcePriv resourcePriv() const; 2403582d3ee9fffdec715f5e4949a241ab08e6271ecbsalomon 2413582d3ee9fffdec715f5e4949a241ab08e6271ecbsalomon /** 242436293a3308d58ce494d9667bd13428dd6e35236junov * Removes references to objects in the underlying 3D API without freeing them. 243436293a3308d58ce494d9667bd13428dd6e35236junov * Called by CacheAccess. 244436293a3308d58ce494d9667bd13428dd6e35236junov * In general this method should not be called outside of skia. It was 245436293a3308d58ce494d9667bd13428dd6e35236junov * made by public for a special case where it needs to be called in Blink 246436293a3308d58ce494d9667bd13428dd6e35236junov * when a texture becomes unsafe to use after having been shared through 247436293a3308d58ce494d9667bd13428dd6e35236junov * a texture mailbox. 248436293a3308d58ce494d9667bd13428dd6e35236junov */ 249436293a3308d58ce494d9667bd13428dd6e35236junov void abandon(); 250436293a3308d58ce494d9667bd13428dd6e35236junov 251c44be0e9e4cee5402909c06370a630eee188a8f3bsalomonprotected: 252169612621f00b3fe9f71014079991287d311751absalomon // This must be called by every GrGpuObject. It should be called once the object is fully 253169612621f00b3fe9f71014079991287d311751absalomon // initialized (i.e. not in a base class constructor). 254169612621f00b3fe9f71014079991287d311751absalomon void registerWithCache(); 255169612621f00b3fe9f71014079991287d311751absalomon 2565236cf480daf82b2f36e42795abdbbc915533a59bsalomon GrGpuResource(GrGpu*, LifeCycle); 2576d3fe022d68fd6dd32c0fab30e24fa5a4f048946bsalomon virtual ~GrGpuResource(); 25876b7fcc79ee47db6ebea4f27e0070c467684418absalomon@google.com 25976b7fcc79ee47db6ebea4f27e0070c467684418absalomon@google.com GrGpu* getGpu() const { return fGpu; } 2608fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com 26112299ab7a1be5f4b99284ecf289d46107ef0a946bsalomon /** Overridden to free GPU resources in the backend API. */ 26212299ab7a1be5f4b99284ecf289d46107ef0a946bsalomon virtual void onRelease() { } 26312299ab7a1be5f4b99284ecf289d46107ef0a946bsalomon /** Overridden to abandon any internal handles, ptrs, etc to backend API resources. 26412299ab7a1be5f4b99284ecf289d46107ef0a946bsalomon This may be called when the underlying 3D context is no longer valid and so no 26512299ab7a1be5f4b99284ecf289d46107ef0a946bsalomon backend API calls should be made. */ 26612299ab7a1be5f4b99284ecf289d46107ef0a946bsalomon virtual void onAbandon() { } 2678fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com 2685236cf480daf82b2f36e42795abdbbc915533a59bsalomon bool isWrapped() const { return kWrapped_LifeCycle == fLifeCycle; } 269a292112154f803feb9f5cc002bbfab559f7cb633bsalomon@google.com 270c44be0e9e4cee5402909c06370a630eee188a8f3bsalomon /** 27169ed47f42d4877c178fdc0031cb01af2966ae235bsalomon * This entry point should be called whenever gpuMemorySize() should report a different size. 27269ed47f42d4877c178fdc0031cb01af2966ae235bsalomon * The cache will call gpuMemorySize() to update the current size of the resource. 273c44be0e9e4cee5402909c06370a630eee188a8f3bsalomon */ 274c44be0e9e4cee5402909c06370a630eee188a8f3bsalomon void didChangeGpuMemorySize() const; 275c44be0e9e4cee5402909c06370a630eee188a8f3bsalomon 276744998e666073166307d2522847b2536000a7619bsalomon /** 277744998e666073166307d2522847b2536000a7619bsalomon * Optionally called by the GrGpuResource subclass if the resource can be used as scratch. 278744998e666073166307d2522847b2536000a7619bsalomon * By default resources are not usable as scratch. This should only be called once. 279744998e666073166307d2522847b2536000a7619bsalomon **/ 2807775c85611c734a2af709b3a9c127939a4296c48bsalomon void setScratchKey(const GrScratchKey& scratchKey); 281744998e666073166307d2522847b2536000a7619bsalomon 2828fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.comprivate: 28312299ab7a1be5f4b99284ecf289d46107ef0a946bsalomon /** 28412299ab7a1be5f4b99284ecf289d46107ef0a946bsalomon * Frees the object in the underlying 3D API. Called by CacheAccess. 28512299ab7a1be5f4b99284ecf289d46107ef0a946bsalomon */ 28612299ab7a1be5f4b99284ecf289d46107ef0a946bsalomon void release(); 28712299ab7a1be5f4b99284ecf289d46107ef0a946bsalomon 28869ed47f42d4877c178fdc0031cb01af2966ae235bsalomon virtual size_t onGpuMemorySize() const = 0; 28969ed47f42d4877c178fdc0031cb01af2966ae235bsalomon 2909f2d1571ed1f0ed579e5d7779c46a90e20f30f22bsalomon // See comments in CacheAccess and ResourcePriv. 291f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon void setUniqueKey(const GrUniqueKey&); 2928718aafec239c93485e45bbe8fed19d9a8def079bsalomon void removeUniqueKey(); 2933f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon void notifyAllCntsAreZero(CntType) const; 2943f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon bool notifyRefCountIsZero() const; 29510e23caea3106be125acea10a637789e5a15c728bsalomon void removeScratchKey(); 296afe3005be3392e43bc51eb7eb2017eefaed85ad1bsalomon void makeBudgeted(); 297c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon void makeUnbudgeted(); 298bcf0a52d4f4221b158e68a06ba0c4cc4db011060bsalomon 299515dcd36032997ce335daa0163c6d67e851bcad1commit-bot@chromium.org#ifdef SK_DEBUG 3009474ed06176fe24c77091b0d75f35442e851073frobertphillips@google.com friend class GrGpu; // for assert in GrGpu to access getGpu 3019474ed06176fe24c77091b0d75f35442e851073frobertphillips@google.com#endif 3028fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com 303c44be0e9e4cee5402909c06370a630eee188a8f3bsalomon static uint32_t CreateUniqueID(); 304c44be0e9e4cee5402909c06370a630eee188a8f3bsalomon 305f320e04c50a1c8a861bc1d8f50bf732044ff9843bsalomon // An index into a heap when this resource is purgeable or an array when not. This is maintained 306f320e04c50a1c8a861bc1d8f50bf732044ff9843bsalomon // by the cache. 3079f2d1571ed1f0ed579e5d7779c46a90e20f30f22bsalomon int fCacheArrayIndex; 3089f2d1571ed1f0ed579e5d7779c46a90e20f30f22bsalomon // This value reflects how recently this resource was accessed in the cache. This is maintained 3099f2d1571ed1f0ed579e5d7779c46a90e20f30f22bsalomon // by the cache. 3109f2d1571ed1f0ed579e5d7779c46a90e20f30f22bsalomon uint32_t fTimestamp; 311c8dc1f74b6cdda9a43a638292a608c59c1d72d80bsalomon 31284c8e62fad59f0e19b40ac718467f5b7884b431dbsalomon static const size_t kInvalidGpuMemorySize = ~static_cast<size_t>(0); 31324db3b1c35fb935660229da164fc5ad31977387fbsalomon GrScratchKey fScratchKey; 3148718aafec239c93485e45bbe8fed19d9a8def079bsalomon GrUniqueKey fUniqueKey; 31584c8e62fad59f0e19b40ac718467f5b7884b431dbsalomon 31684c8e62fad59f0e19b40ac718467f5b7884b431dbsalomon // This is not ref'ed but abandon() or release() will be called before the GrGpu object 31784c8e62fad59f0e19b40ac718467f5b7884b431dbsalomon // is destroyed. Those calls set will this to NULL. 31824db3b1c35fb935660229da164fc5ad31977387fbsalomon GrGpu* fGpu; 31924db3b1c35fb935660229da164fc5ad31977387fbsalomon mutable size_t fGpuMemorySize; 32084c8e62fad59f0e19b40ac718467f5b7884b431dbsalomon 32124db3b1c35fb935660229da164fc5ad31977387fbsalomon LifeCycle fLifeCycle; 32224db3b1c35fb935660229da164fc5ad31977387fbsalomon const uint32_t fUniqueID; 323744998e666073166307d2522847b2536000a7619bsalomon 32424db3b1c35fb935660229da164fc5ad31977387fbsalomon SkAutoTUnref<const SkData> fData; 3255756aff40921e700dc40f2a1757291a64acddeaajunov 326bcf0a52d4f4221b158e68a06ba0c4cc4db011060bsalomon typedef GrIORef<GrGpuResource> INHERITED; 3273f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon friend class GrIORef<GrGpuResource>; // to access notifyAllCntsAreZero and notifyRefCntIsZero. 3288fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com}; 3298fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com 3308fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com#endif 331