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 #include "GrGpuResourceRef.h" 9 10 GrGpuResourceRef::GrGpuResourceRef() { 11 fResource = nullptr; 12 fOwnRef = false; 13 fPendingIO = false; 14 } 15 16 GrGpuResourceRef::GrGpuResourceRef(GrGpuResource* resource, GrIOType ioType) { 17 fResource = nullptr; 18 fOwnRef = false; 19 fPendingIO = false; 20 this->setResource(resource, ioType); 21 } 22 23 GrGpuResourceRef::~GrGpuResourceRef() { 24 if (fOwnRef) { 25 SkASSERT(fResource); 26 fResource->unref(); 27 } 28 if (fPendingIO) { 29 switch (fIOType) { 30 case kRead_GrIOType: 31 fResource->completedRead(); 32 break; 33 case kWrite_GrIOType: 34 fResource->completedWrite(); 35 break; 36 case kRW_GrIOType: 37 fResource->completedRead(); 38 fResource->completedWrite(); 39 break; 40 } 41 } 42 } 43 44 void GrGpuResourceRef::reset() { 45 SkASSERT(!fPendingIO); 46 SkASSERT(SkToBool(fResource) == fOwnRef); 47 if (fOwnRef) { 48 fResource->unref(); 49 fOwnRef = false; 50 fResource = nullptr; 51 } 52 } 53 54 void GrGpuResourceRef::setResource(GrGpuResource* resource, GrIOType ioType) { 55 SkASSERT(!fPendingIO); 56 SkASSERT(SkToBool(fResource) == fOwnRef); 57 SkSafeUnref(fResource); 58 if (nullptr == resource) { 59 fResource = nullptr; 60 fOwnRef = false; 61 } else { 62 fResource = resource; 63 fOwnRef = true; 64 fIOType = ioType; 65 } 66 } 67 68 void GrGpuResourceRef::markPendingIO() const { 69 if (!fResource) { 70 return; 71 } 72 73 // This should only be called when the owning GrProgramElement gets its first 74 // pendingExecution ref. 75 SkASSERT(!fPendingIO); 76 fPendingIO = true; 77 switch (fIOType) { 78 case kRead_GrIOType: 79 fResource->addPendingRead(); 80 break; 81 case kWrite_GrIOType: 82 fResource->addPendingWrite(); 83 break; 84 case kRW_GrIOType: 85 fResource->addPendingRead(); 86 fResource->addPendingWrite(); 87 break; 88 } 89 } 90 91 void GrGpuResourceRef::pendingIOComplete() const { 92 if (!fResource) { 93 return; 94 } 95 96 // This should only be called when the owner's pending executions have ocurred but it is still 97 // reffed. 98 SkASSERT(fOwnRef); 99 SkASSERT(fPendingIO); 100 switch (fIOType) { 101 case kRead_GrIOType: 102 fResource->completedRead(); 103 break; 104 case kWrite_GrIOType: 105 fResource->completedWrite(); 106 break; 107 case kRW_GrIOType: 108 fResource->completedRead(); 109 fResource->completedWrite(); 110 break; 111 112 } 113 fPendingIO = false; 114 } 115 116 void GrGpuResourceRef::removeRef() const { 117 if (!fResource) { 118 return; 119 } 120 121 // This should only be called once, when the owners last ref goes away and 122 // there is a pending execution. 123 SkASSERT(fOwnRef); 124 SkASSERT(fPendingIO); 125 fResource->unref(); 126 fOwnRef = false; 127 } 128 129 /////////////////////////////////////////////////////////////////////////////// 130 #include "GrTextureProxy.h" 131 132 GrSurfaceProxyRef::GrSurfaceProxyRef() { 133 fProxy = nullptr; 134 fOwnRef = false; 135 fPendingIO = false; 136 } 137 138 GrSurfaceProxyRef::GrSurfaceProxyRef(sk_sp<GrSurfaceProxy> proxy, GrIOType ioType) { 139 fProxy = nullptr; 140 fOwnRef = false; 141 fPendingIO = false; 142 this->setProxy(std::move(proxy), ioType); 143 } 144 145 GrSurfaceProxyRef::~GrSurfaceProxyRef() { 146 this->reset(); 147 } 148 149 void GrSurfaceProxyRef::reset() { 150 if (fPendingIO) { 151 SkASSERT(fProxy); 152 switch (fIOType) { 153 case kRead_GrIOType: 154 fProxy->completedRead(); 155 break; 156 case kWrite_GrIOType: 157 fProxy->completedWrite(); 158 break; 159 case kRW_GrIOType: 160 fProxy->completedRead(); 161 fProxy->completedWrite(); 162 break; 163 } 164 fPendingIO = false; 165 } 166 if (fOwnRef) { 167 SkASSERT(fProxy); 168 fProxy->unref(); 169 fOwnRef = false; 170 } 171 172 fProxy = nullptr; 173 } 174 175 void GrSurfaceProxyRef::setProxy(sk_sp<GrSurfaceProxy> proxy, GrIOType ioType) { 176 SkASSERT(!fPendingIO); 177 SkASSERT(SkToBool(fProxy) == fOwnRef); 178 SkSafeUnref(fProxy); 179 if (!proxy) { 180 fProxy = nullptr; 181 fOwnRef = false; 182 } else { 183 fProxy = proxy.release(); // due to the semantics of this class we unpack from sk_sp 184 fOwnRef = true; 185 fIOType = ioType; 186 } 187 } 188 189 void GrSurfaceProxyRef::markPendingIO() const { 190 // This should only be called when the owning GrProgramElement gets its first 191 // pendingExecution ref. 192 SkASSERT(!fPendingIO); 193 SkASSERT(fProxy); 194 fPendingIO = true; 195 switch (fIOType) { 196 case kRead_GrIOType: 197 fProxy->addPendingRead(); 198 break; 199 case kWrite_GrIOType: 200 fProxy->addPendingWrite(); 201 break; 202 case kRW_GrIOType: 203 fProxy->addPendingRead(); 204 fProxy->addPendingWrite(); 205 break; 206 } 207 } 208 209 void GrSurfaceProxyRef::pendingIOComplete() const { 210 // This should only be called when the owner's pending executions have ocurred but it is still 211 // reffed. 212 SkASSERT(fOwnRef); 213 SkASSERT(fPendingIO); 214 switch (fIOType) { 215 case kRead_GrIOType: 216 fProxy->completedRead(); 217 break; 218 case kWrite_GrIOType: 219 fProxy->completedWrite(); 220 break; 221 case kRW_GrIOType: 222 fProxy->completedRead(); 223 fProxy->completedWrite(); 224 break; 225 226 } 227 fPendingIO = false; 228 } 229 230 void GrSurfaceProxyRef::removeRef() const { 231 // This should only be called once, when the owners last ref goes away and 232 // there is a pending execution. 233 SkASSERT(fOwnRef); 234 SkASSERT(fPendingIO); 235 SkASSERT(fProxy); 236 fProxy->unref(); 237 fOwnRef = false; 238 } 239 240