GrGpuResourceRef.h revision b3e3a955b6628acc540ef14854b57abb089e62df
1/* 2 * Copyright 2014 Google Inc. 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8#ifndef GrGpuResourceRef_DEFINED 9#define GrGpuResourceRef_DEFINED 10 11#include "SkRefCnt.h" 12 13class GrGpuResource; 14 15/** 16 * This class is intended only for internal use in core Gr code. 17 * 18 * Class that wraps a resource referenced by a GrProgramElement or GrDrawState. It manages 19 * converting refs to pending IO operations. It allows a resource ownership to be in three 20 * states: 21 * 1. Owns a single ref 22 * 2. Owns a single ref and a pending IO operation (read, write, or read-write) 23 * 3. Owns a single pending IO operation. 24 * 25 * It is legal to destroy the GrGpuResourceRef in any of these states. It starts in state 26 * 1. Calling markPendingIO() converts it from state 1 to state 2. Calling removeRef() goes from 27 * state 2 to state 3. Calling pendingIOComplete() moves from state 2 to state 1. There is no 28 * valid way of going from state 3 back to 2 or 1. 29 * 30 * Like SkAutoTUnref, its constructor and setter adopt a ref from their caller. 31 * 32 * TODO: Once GrDODrawState no longer exists and therefore GrDrawState and GrOptDrawState no 33 * longer share an instance of this class, attempt to make the resource owned by GrGpuResourceRef 34 * only settable via the constructor. 35 */ 36class GrGpuResourceRef : SkNoncopyable { 37public: 38 SK_DECLARE_INST_COUNT_ROOT(GrGpuResourceRef); 39 40 enum IOType { 41 kRead_IOType, 42 kWrite_IOType, 43 kRW_IOType, 44 45 kNone_IOType, // For internal use only, don't specify to constructor or setResource(). 46 }; 47 48 ~GrGpuResourceRef(); 49 50 GrGpuResource* getResource() const { return fResource; } 51 52 /** Does this object own a pending read or write on the resource it is wrapping. */ 53 bool ownsPendingIO() const { return fPendingIO; } 54 55 /** Shortcut for calling setResource() with NULL. It cannot be called after markingPendingIO 56 is called. */ 57 void reset(); 58 59protected: 60 GrGpuResourceRef(); 61 62 /** Adopts a ref from the caller. ioType expresses what type of IO operations will be marked as 63 pending on the resource when markPendingIO is called. */ 64 GrGpuResourceRef(GrGpuResource*, IOType); 65 66 /** Adopts a ref from the caller. ioType expresses what type of IO operations will be marked as 67 pending on the resource when markPendingIO is called. */ 68 void setResource(GrGpuResource*, IOType); 69 70private: 71 /** Called by owning GrProgramElement when the program element is first scheduled for 72 execution. It can only be called once. */ 73 void markPendingIO() const; 74 75 /** Called when the program element/draw state is no longer owned by GrDrawTarget-client code. 76 This lets the cache know that the drawing code will no longer schedule additional reads or 77 writes to the resource using the program element or draw state. It can only be called once. 78 */ 79 void removeRef() const; 80 81 /** Called to indicate that the previous pending IO is complete. Useful when the owning object 82 still has refs, so it is not about to destroy this GrGpuResourceRef, but its previously 83 pending executions have been complete. Can only be called if removeRef() was not previously 84 called. */ 85 void pendingIOComplete() const; 86 87 friend class GrRODrawState; 88 friend class GrProgramElement; 89 90 GrGpuResource* fResource; 91 mutable bool fOwnRef; 92 mutable bool fPendingIO; 93 IOType fIOType; 94 95 typedef SkNoncopyable INHERITED; 96}; 97 98/** 99 * Templated version of GrGpuResourceRef to enforce type safety. 100 */ 101template <typename T> class GrTGpuResourceRef : public GrGpuResourceRef { 102public: 103 GrTGpuResourceRef() {} 104 105 /** Adopts a ref from the caller. ioType expresses what type of IO operations will be marked as 106 pending on the resource when markPendingIO is called. */ 107 GrTGpuResourceRef(T* resource, IOType ioType) : INHERITED(resource, ioType) {} 108 109 T* get() const { return static_cast<T*>(this->getResource()); } 110 111 /** Adopts a ref from the caller. ioType expresses what type of IO operations will be marked as 112 pending on the resource when markPendingIO is called. */ 113 void set(T* resource, IOType ioType) { this->setResource(resource, ioType); } 114 115private: 116 typedef GrGpuResourceRef INHERITED; 117}; 118 119/** 120 * This is similar to GrTGpuResourceRef but can only be in the pending IO state. It never owns a 121 * ref. 122 */ 123template <typename T> class GrPendingIOResource : SkNoncopyable { 124public: 125 typedef GrGpuResourceRef::IOType IOType; 126 GrPendingIOResource(T* resource, IOType ioType) : fResource(resource), fIOType(ioType) { 127 if (NULL != fResource) { 128 switch (fIOType) { 129 case GrGpuResourceRef::kNone_IOType: 130 SkFAIL("GrPendingIOResource with neither reads nor writes?"); 131 break; 132 case GrGpuResourceRef::kRead_IOType: 133 fResource->addPendingRead(); 134 break; 135 case GrGpuResourceRef::kWrite_IOType: 136 fResource->addPendingWrite(); 137 break; 138 case GrGpuResourceRef::kRW_IOType: 139 fResource->addPendingRead(); 140 fResource->addPendingWrite(); 141 break; 142 } 143 } 144 } 145 146 ~GrPendingIOResource() { 147 if (NULL != fResource) { 148 switch (fIOType) { 149 case GrGpuResourceRef::kNone_IOType: 150 SkFAIL("GrPendingIOResource with neither reads nor writes?"); 151 break; 152 case GrGpuResourceRef::kRead_IOType: 153 fResource->completedRead(); 154 break; 155 case GrGpuResourceRef::kWrite_IOType: 156 fResource->completedWrite(); 157 break; 158 case GrGpuResourceRef::kRW_IOType: 159 fResource->completedRead(); 160 fResource->completedWrite(); 161 break; 162 } 163 } 164 } 165 166 T* get() const { return fResource; } 167 168private: 169 T* fResource; 170 IOType fIOType; 171}; 172#endif 173