195740981c36266e4595ddde2264aa38e3c7e2d02bsalomon/* 295740981c36266e4595ddde2264aa38e3c7e2d02bsalomon * Copyright 2014 Google Inc. 395740981c36266e4595ddde2264aa38e3c7e2d02bsalomon * 495740981c36266e4595ddde2264aa38e3c7e2d02bsalomon * Use of this source code is governed by a BSD-style license that can be 595740981c36266e4595ddde2264aa38e3c7e2d02bsalomon * found in the LICENSE file. 695740981c36266e4595ddde2264aa38e3c7e2d02bsalomon */ 795740981c36266e4595ddde2264aa38e3c7e2d02bsalomon 8f96ba02513eadd9fa24d75396ec9f2d6682e464cbsalomon#ifndef GrGpuResourceRef_DEFINED 9f96ba02513eadd9fa24d75396ec9f2d6682e464cbsalomon#define GrGpuResourceRef_DEFINED 1095740981c36266e4595ddde2264aa38e3c7e2d02bsalomon 1145725db1d82615d43408ec488549aec6218f80e4bsalomon#include "GrGpuResource.h" 1237dd331b20a92ce79cc26556e065dec98a66cb0bbsalomon#include "GrRenderTarget.h" 1337dd331b20a92ce79cc26556e065dec98a66cb0bbsalomon#include "GrTexture.h" 1495740981c36266e4595ddde2264aa38e3c7e2d02bsalomon#include "SkRefCnt.h" 1595740981c36266e4595ddde2264aa38e3c7e2d02bsalomon 1695740981c36266e4595ddde2264aa38e3c7e2d02bsalomon/** 17b3e3a955b6628acc540ef14854b57abb089e62dfbsalomon * This class is intended only for internal use in core Gr code. 18b3e3a955b6628acc540ef14854b57abb089e62dfbsalomon * 1995740981c36266e4595ddde2264aa38e3c7e2d02bsalomon * Class that wraps a resource referenced by a GrProgramElement or GrDrawState. It manages 20b3e3a955b6628acc540ef14854b57abb089e62dfbsalomon * converting refs to pending IO operations. It allows a resource ownership to be in three 21b3e3a955b6628acc540ef14854b57abb089e62dfbsalomon * states: 22b3e3a955b6628acc540ef14854b57abb089e62dfbsalomon * 1. Owns a single ref 23b3e3a955b6628acc540ef14854b57abb089e62dfbsalomon * 2. Owns a single ref and a pending IO operation (read, write, or read-write) 24b3e3a955b6628acc540ef14854b57abb089e62dfbsalomon * 3. Owns a single pending IO operation. 25b3e3a955b6628acc540ef14854b57abb089e62dfbsalomon * 26b3e3a955b6628acc540ef14854b57abb089e62dfbsalomon * It is legal to destroy the GrGpuResourceRef in any of these states. It starts in state 27b3e3a955b6628acc540ef14854b57abb089e62dfbsalomon * 1. Calling markPendingIO() converts it from state 1 to state 2. Calling removeRef() goes from 28b3e3a955b6628acc540ef14854b57abb089e62dfbsalomon * state 2 to state 3. Calling pendingIOComplete() moves from state 2 to state 1. There is no 29b3e3a955b6628acc540ef14854b57abb089e62dfbsalomon * valid way of going from state 3 back to 2 or 1. 30b3e3a955b6628acc540ef14854b57abb089e62dfbsalomon * 31b3e3a955b6628acc540ef14854b57abb089e62dfbsalomon * Like SkAutoTUnref, its constructor and setter adopt a ref from their caller. 32b3e3a955b6628acc540ef14854b57abb089e62dfbsalomon * 33b3e3a955b6628acc540ef14854b57abb089e62dfbsalomon * TODO: Once GrDODrawState no longer exists and therefore GrDrawState and GrOptDrawState no 34b3e3a955b6628acc540ef14854b57abb089e62dfbsalomon * longer share an instance of this class, attempt to make the resource owned by GrGpuResourceRef 35b3e3a955b6628acc540ef14854b57abb089e62dfbsalomon * only settable via the constructor. 3695740981c36266e4595ddde2264aa38e3c7e2d02bsalomon */ 37f96ba02513eadd9fa24d75396ec9f2d6682e464cbsalomonclass GrGpuResourceRef : SkNoncopyable { 3895740981c36266e4595ddde2264aa38e3c7e2d02bsalomonpublic: 396f07665768dc84453316e7b2bbd6049576764cb1mtklein SK_DECLARE_INST_COUNT(GrGpuResourceRef); 40c49233410e7278f0b95b8b0d28a80105a2930a88bsalomon 41f96ba02513eadd9fa24d75396ec9f2d6682e464cbsalomon ~GrGpuResourceRef(); 4295740981c36266e4595ddde2264aa38e3c7e2d02bsalomon 4395740981c36266e4595ddde2264aa38e3c7e2d02bsalomon GrGpuResource* getResource() const { return fResource; } 4495740981c36266e4595ddde2264aa38e3c7e2d02bsalomon 4595740981c36266e4595ddde2264aa38e3c7e2d02bsalomon /** Does this object own a pending read or write on the resource it is wrapping. */ 4695740981c36266e4595ddde2264aa38e3c7e2d02bsalomon bool ownsPendingIO() const { return fPendingIO; } 4795740981c36266e4595ddde2264aa38e3c7e2d02bsalomon 4895740981c36266e4595ddde2264aa38e3c7e2d02bsalomon /** Shortcut for calling setResource() with NULL. It cannot be called after markingPendingIO 4995740981c36266e4595ddde2264aa38e3c7e2d02bsalomon is called. */ 5095740981c36266e4595ddde2264aa38e3c7e2d02bsalomon void reset(); 5195740981c36266e4595ddde2264aa38e3c7e2d02bsalomon 52c49233410e7278f0b95b8b0d28a80105a2930a88bsalomonprotected: 53f96ba02513eadd9fa24d75396ec9f2d6682e464cbsalomon GrGpuResourceRef(); 54c49233410e7278f0b95b8b0d28a80105a2930a88bsalomon 55c49233410e7278f0b95b8b0d28a80105a2930a88bsalomon /** Adopts a ref from the caller. ioType expresses what type of IO operations will be marked as 56c49233410e7278f0b95b8b0d28a80105a2930a88bsalomon pending on the resource when markPendingIO is called. */ 57bcf0a52d4f4221b158e68a06ba0c4cc4db011060bsalomon GrGpuResourceRef(GrGpuResource*, GrIOType); 58c49233410e7278f0b95b8b0d28a80105a2930a88bsalomon 59c49233410e7278f0b95b8b0d28a80105a2930a88bsalomon /** Adopts a ref from the caller. ioType expresses what type of IO operations will be marked as 60c49233410e7278f0b95b8b0d28a80105a2930a88bsalomon pending on the resource when markPendingIO is called. */ 61bcf0a52d4f4221b158e68a06ba0c4cc4db011060bsalomon void setResource(GrGpuResource*, GrIOType); 62c49233410e7278f0b95b8b0d28a80105a2930a88bsalomon 6395740981c36266e4595ddde2264aa38e3c7e2d02bsalomonprivate: 6495740981c36266e4595ddde2264aa38e3c7e2d02bsalomon /** Called by owning GrProgramElement when the program element is first scheduled for 65b3e3a955b6628acc540ef14854b57abb089e62dfbsalomon execution. It can only be called once. */ 6695740981c36266e4595ddde2264aa38e3c7e2d02bsalomon void markPendingIO() const; 6795740981c36266e4595ddde2264aa38e3c7e2d02bsalomon 6895740981c36266e4595ddde2264aa38e3c7e2d02bsalomon /** Called when the program element/draw state is no longer owned by GrDrawTarget-client code. 6995740981c36266e4595ddde2264aa38e3c7e2d02bsalomon This lets the cache know that the drawing code will no longer schedule additional reads or 70b3e3a955b6628acc540ef14854b57abb089e62dfbsalomon writes to the resource using the program element or draw state. It can only be called once. 71b3e3a955b6628acc540ef14854b57abb089e62dfbsalomon */ 7295740981c36266e4595ddde2264aa38e3c7e2d02bsalomon void removeRef() const; 7395740981c36266e4595ddde2264aa38e3c7e2d02bsalomon 74ac8d6193eaa29e02d1786fe56efa98eefee74e50bsalomon /** Called to indicate that the previous pending IO is complete. Useful when the owning object 75f96ba02513eadd9fa24d75396ec9f2d6682e464cbsalomon still has refs, so it is not about to destroy this GrGpuResourceRef, but its previously 76b3e3a955b6628acc540ef14854b57abb089e62dfbsalomon pending executions have been complete. Can only be called if removeRef() was not previously 77b3e3a955b6628acc540ef14854b57abb089e62dfbsalomon called. */ 78ac8d6193eaa29e02d1786fe56efa98eefee74e50bsalomon void pendingIOComplete() const; 79ac8d6193eaa29e02d1786fe56efa98eefee74e50bsalomon 8095740981c36266e4595ddde2264aa38e3c7e2d02bsalomon friend class GrProgramElement; 8195740981c36266e4595ddde2264aa38e3c7e2d02bsalomon 82bcf0a52d4f4221b158e68a06ba0c4cc4db011060bsalomon GrGpuResource* fResource; 83bcf0a52d4f4221b158e68a06ba0c4cc4db011060bsalomon mutable bool fOwnRef; 84bcf0a52d4f4221b158e68a06ba0c4cc4db011060bsalomon mutable bool fPendingIO; 85bcf0a52d4f4221b158e68a06ba0c4cc4db011060bsalomon GrIOType fIOType; 8695740981c36266e4595ddde2264aa38e3c7e2d02bsalomon 8795740981c36266e4595ddde2264aa38e3c7e2d02bsalomon typedef SkNoncopyable INHERITED; 8895740981c36266e4595ddde2264aa38e3c7e2d02bsalomon}; 8995740981c36266e4595ddde2264aa38e3c7e2d02bsalomon 906f07665768dc84453316e7b2bbd6049576764cb1mtklein/** 91b3e3a955b6628acc540ef14854b57abb089e62dfbsalomon * Templated version of GrGpuResourceRef to enforce type safety. 92b3e3a955b6628acc540ef14854b57abb089e62dfbsalomon */ 93f96ba02513eadd9fa24d75396ec9f2d6682e464cbsalomontemplate <typename T> class GrTGpuResourceRef : public GrGpuResourceRef { 94c49233410e7278f0b95b8b0d28a80105a2930a88bsalomonpublic: 95f96ba02513eadd9fa24d75396ec9f2d6682e464cbsalomon GrTGpuResourceRef() {} 96c49233410e7278f0b95b8b0d28a80105a2930a88bsalomon 97c49233410e7278f0b95b8b0d28a80105a2930a88bsalomon /** Adopts a ref from the caller. ioType expresses what type of IO operations will be marked as 98c49233410e7278f0b95b8b0d28a80105a2930a88bsalomon pending on the resource when markPendingIO is called. */ 9937dd331b20a92ce79cc26556e065dec98a66cb0bbsalomon GrTGpuResourceRef(T* resource, GrIOType ioType) : INHERITED(resource, ioType) { } 100c49233410e7278f0b95b8b0d28a80105a2930a88bsalomon 101c49233410e7278f0b95b8b0d28a80105a2930a88bsalomon T* get() const { return static_cast<T*>(this->getResource()); } 102c49233410e7278f0b95b8b0d28a80105a2930a88bsalomon 103c49233410e7278f0b95b8b0d28a80105a2930a88bsalomon /** Adopts a ref from the caller. ioType expresses what type of IO operations will be marked as 104c49233410e7278f0b95b8b0d28a80105a2930a88bsalomon pending on the resource when markPendingIO is called. */ 105bcf0a52d4f4221b158e68a06ba0c4cc4db011060bsalomon void set(T* resource, GrIOType ioType) { this->setResource(resource, ioType); } 106f96ba02513eadd9fa24d75396ec9f2d6682e464cbsalomon 107f96ba02513eadd9fa24d75396ec9f2d6682e464cbsalomonprivate: 108f96ba02513eadd9fa24d75396ec9f2d6682e464cbsalomon typedef GrGpuResourceRef INHERITED; 109c49233410e7278f0b95b8b0d28a80105a2930a88bsalomon}; 110c49233410e7278f0b95b8b0d28a80105a2930a88bsalomon 11137dd331b20a92ce79cc26556e065dec98a66cb0bbsalomon// Specializations for GrTexture and GrRenderTarget because they use virtual inheritance. 11237dd331b20a92ce79cc26556e065dec98a66cb0bbsalomontemplate<> class GrTGpuResourceRef<GrTexture> : public GrGpuResourceRef { 11337dd331b20a92ce79cc26556e065dec98a66cb0bbsalomonpublic: 11437dd331b20a92ce79cc26556e065dec98a66cb0bbsalomon GrTGpuResourceRef() {} 11537dd331b20a92ce79cc26556e065dec98a66cb0bbsalomon 11637dd331b20a92ce79cc26556e065dec98a66cb0bbsalomon GrTGpuResourceRef(GrTexture* texture, GrIOType ioType) : INHERITED(texture, ioType) { } 11737dd331b20a92ce79cc26556e065dec98a66cb0bbsalomon 11837dd331b20a92ce79cc26556e065dec98a66cb0bbsalomon GrTexture* get() const { 11937dd331b20a92ce79cc26556e065dec98a66cb0bbsalomon GrSurface* surface = static_cast<GrSurface*>(this->getResource()); 12037dd331b20a92ce79cc26556e065dec98a66cb0bbsalomon if (surface) { 12137dd331b20a92ce79cc26556e065dec98a66cb0bbsalomon return surface->asTexture(); 12237dd331b20a92ce79cc26556e065dec98a66cb0bbsalomon } else { 12337dd331b20a92ce79cc26556e065dec98a66cb0bbsalomon return NULL; 12437dd331b20a92ce79cc26556e065dec98a66cb0bbsalomon } 12537dd331b20a92ce79cc26556e065dec98a66cb0bbsalomon } 12637dd331b20a92ce79cc26556e065dec98a66cb0bbsalomon 12737dd331b20a92ce79cc26556e065dec98a66cb0bbsalomon void set(GrTexture* texture, GrIOType ioType) { this->setResource(texture, ioType); } 12837dd331b20a92ce79cc26556e065dec98a66cb0bbsalomon 12937dd331b20a92ce79cc26556e065dec98a66cb0bbsalomonprivate: 13037dd331b20a92ce79cc26556e065dec98a66cb0bbsalomon typedef GrGpuResourceRef INHERITED; 13137dd331b20a92ce79cc26556e065dec98a66cb0bbsalomon}; 13237dd331b20a92ce79cc26556e065dec98a66cb0bbsalomon 13337dd331b20a92ce79cc26556e065dec98a66cb0bbsalomontemplate<> class GrTGpuResourceRef<GrRenderTarget> : public GrGpuResourceRef { 13437dd331b20a92ce79cc26556e065dec98a66cb0bbsalomonpublic: 13537dd331b20a92ce79cc26556e065dec98a66cb0bbsalomon GrTGpuResourceRef() {} 13637dd331b20a92ce79cc26556e065dec98a66cb0bbsalomon 13737dd331b20a92ce79cc26556e065dec98a66cb0bbsalomon GrTGpuResourceRef(GrRenderTarget* rt, GrIOType ioType) : INHERITED(rt, ioType) { } 13837dd331b20a92ce79cc26556e065dec98a66cb0bbsalomon 13937dd331b20a92ce79cc26556e065dec98a66cb0bbsalomon GrRenderTarget* get() const { 14037dd331b20a92ce79cc26556e065dec98a66cb0bbsalomon GrSurface* surface = static_cast<GrSurface*>(this->getResource()); 14137dd331b20a92ce79cc26556e065dec98a66cb0bbsalomon if (surface) { 14237dd331b20a92ce79cc26556e065dec98a66cb0bbsalomon return surface->asRenderTarget(); 14337dd331b20a92ce79cc26556e065dec98a66cb0bbsalomon } else { 14437dd331b20a92ce79cc26556e065dec98a66cb0bbsalomon return NULL; 14537dd331b20a92ce79cc26556e065dec98a66cb0bbsalomon } 14637dd331b20a92ce79cc26556e065dec98a66cb0bbsalomon } 14737dd331b20a92ce79cc26556e065dec98a66cb0bbsalomon 14837dd331b20a92ce79cc26556e065dec98a66cb0bbsalomon void set(GrRenderTarget* rt, GrIOType ioType) { this->setResource(rt, ioType); } 14937dd331b20a92ce79cc26556e065dec98a66cb0bbsalomon 15037dd331b20a92ce79cc26556e065dec98a66cb0bbsalomonprivate: 15137dd331b20a92ce79cc26556e065dec98a66cb0bbsalomon typedef GrGpuResourceRef INHERITED; 15237dd331b20a92ce79cc26556e065dec98a66cb0bbsalomon}; 15337dd331b20a92ce79cc26556e065dec98a66cb0bbsalomon 154b3e3a955b6628acc540ef14854b57abb089e62dfbsalomon/** 155b3e3a955b6628acc540ef14854b57abb089e62dfbsalomon * This is similar to GrTGpuResourceRef but can only be in the pending IO state. It never owns a 156b3e3a955b6628acc540ef14854b57abb089e62dfbsalomon * ref. 157b3e3a955b6628acc540ef14854b57abb089e62dfbsalomon */ 158bcf0a52d4f4221b158e68a06ba0c4cc4db011060bsalomontemplate <typename T, GrIOType IO_TYPE> class GrPendingIOResource : SkNoncopyable { 159b3e3a955b6628acc540ef14854b57abb089e62dfbsalomonpublic: 1607eb8c7b00a5d776bebaf33a8687357df95c1aa43joshualitt GrPendingIOResource(T* resource = NULL) : fResource(NULL) { 1617eb8c7b00a5d776bebaf33a8687357df95c1aa43joshualitt this->reset(resource); 1627eb8c7b00a5d776bebaf33a8687357df95c1aa43joshualitt } 1637eb8c7b00a5d776bebaf33a8687357df95c1aa43joshualitt 1647eb8c7b00a5d776bebaf33a8687357df95c1aa43joshualitt void reset(T* resource) { 1657eb8c7b00a5d776bebaf33a8687357df95c1aa43joshualitt if (resource) { 16645725db1d82615d43408ec488549aec6218f80e4bsalomon switch (IO_TYPE) { 167bcf0a52d4f4221b158e68a06ba0c4cc4db011060bsalomon case kRead_GrIOType: 1687eb8c7b00a5d776bebaf33a8687357df95c1aa43joshualitt resource->addPendingRead(); 169b3e3a955b6628acc540ef14854b57abb089e62dfbsalomon break; 170bcf0a52d4f4221b158e68a06ba0c4cc4db011060bsalomon case kWrite_GrIOType: 1717eb8c7b00a5d776bebaf33a8687357df95c1aa43joshualitt resource->addPendingWrite(); 172b3e3a955b6628acc540ef14854b57abb089e62dfbsalomon break; 173bcf0a52d4f4221b158e68a06ba0c4cc4db011060bsalomon case kRW_GrIOType: 1747eb8c7b00a5d776bebaf33a8687357df95c1aa43joshualitt resource->addPendingRead(); 1757eb8c7b00a5d776bebaf33a8687357df95c1aa43joshualitt resource->addPendingWrite(); 176b3e3a955b6628acc540ef14854b57abb089e62dfbsalomon break; 177b3e3a955b6628acc540ef14854b57abb089e62dfbsalomon } 178b3e3a955b6628acc540ef14854b57abb089e62dfbsalomon } 1797eb8c7b00a5d776bebaf33a8687357df95c1aa43joshualitt this->release(); 1807eb8c7b00a5d776bebaf33a8687357df95c1aa43joshualitt fResource = resource; 181b3e3a955b6628acc540ef14854b57abb089e62dfbsalomon } 182b3e3a955b6628acc540ef14854b57abb089e62dfbsalomon 183b3e3a955b6628acc540ef14854b57abb089e62dfbsalomon ~GrPendingIOResource() { 1847eb8c7b00a5d776bebaf33a8687357df95c1aa43joshualitt this->release(); 1857eb8c7b00a5d776bebaf33a8687357df95c1aa43joshualitt } 1867eb8c7b00a5d776bebaf33a8687357df95c1aa43joshualitt 187b03c4a35bd319d883925a39871b4972ff1b2c0ccbsalomon operator bool() const { return SkToBool(fResource); } 188b03c4a35bd319d883925a39871b4972ff1b2c0ccbsalomon 1897eb8c7b00a5d776bebaf33a8687357df95c1aa43joshualitt T* get() const { return fResource; } 1907eb8c7b00a5d776bebaf33a8687357df95c1aa43joshualitt 1917eb8c7b00a5d776bebaf33a8687357df95c1aa43joshualittprivate: 1927eb8c7b00a5d776bebaf33a8687357df95c1aa43joshualitt void release() { 1937eb8c7b00a5d776bebaf33a8687357df95c1aa43joshualitt if (fResource) { 19445725db1d82615d43408ec488549aec6218f80e4bsalomon switch (IO_TYPE) { 195bcf0a52d4f4221b158e68a06ba0c4cc4db011060bsalomon case kRead_GrIOType: 196b3e3a955b6628acc540ef14854b57abb089e62dfbsalomon fResource->completedRead(); 197b3e3a955b6628acc540ef14854b57abb089e62dfbsalomon break; 198bcf0a52d4f4221b158e68a06ba0c4cc4db011060bsalomon case kWrite_GrIOType: 199b3e3a955b6628acc540ef14854b57abb089e62dfbsalomon fResource->completedWrite(); 200b3e3a955b6628acc540ef14854b57abb089e62dfbsalomon break; 201bcf0a52d4f4221b158e68a06ba0c4cc4db011060bsalomon case kRW_GrIOType: 202b3e3a955b6628acc540ef14854b57abb089e62dfbsalomon fResource->completedRead(); 203b3e3a955b6628acc540ef14854b57abb089e62dfbsalomon fResource->completedWrite(); 204b3e3a955b6628acc540ef14854b57abb089e62dfbsalomon break; 205b3e3a955b6628acc540ef14854b57abb089e62dfbsalomon } 206b3e3a955b6628acc540ef14854b57abb089e62dfbsalomon } 207b3e3a955b6628acc540ef14854b57abb089e62dfbsalomon } 208b3e3a955b6628acc540ef14854b57abb089e62dfbsalomon 209bcf0a52d4f4221b158e68a06ba0c4cc4db011060bsalomon T* fResource; 210b3e3a955b6628acc540ef14854b57abb089e62dfbsalomon}; 21195740981c36266e4595ddde2264aa38e3c7e2d02bsalomon#endif 212