1 /* 2 * Copyright 2018 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 "GrSurfaceProxyRef.h" 9 #include "GrTextureProxy.h" 10 11 GrSurfaceProxyRef::GrSurfaceProxyRef() { 12 fProxy = nullptr; 13 fOwnRef = false; 14 fPendingIO = false; 15 } 16 17 GrSurfaceProxyRef::GrSurfaceProxyRef(sk_sp<GrSurfaceProxy> proxy, GrIOType ioType) { 18 fProxy = nullptr; 19 fOwnRef = false; 20 fPendingIO = false; 21 this->setProxy(std::move(proxy), ioType); 22 } 23 24 GrSurfaceProxyRef::~GrSurfaceProxyRef() { 25 this->reset(); 26 } 27 28 void GrSurfaceProxyRef::reset() { 29 if (fPendingIO) { 30 SkASSERT(fProxy); 31 switch (fIOType) { 32 case kRead_GrIOType: 33 fProxy->completedRead(); 34 break; 35 case kWrite_GrIOType: 36 fProxy->completedWrite(); 37 break; 38 case kRW_GrIOType: 39 fProxy->completedRead(); 40 fProxy->completedWrite(); 41 break; 42 } 43 fPendingIO = false; 44 } 45 if (fOwnRef) { 46 SkASSERT(fProxy); 47 fProxy->unref(); 48 fOwnRef = false; 49 } 50 51 fProxy = nullptr; 52 } 53 54 void GrSurfaceProxyRef::setProxy(sk_sp<GrSurfaceProxy> proxy, GrIOType ioType) { 55 SkASSERT(!fPendingIO); 56 SkASSERT(SkToBool(fProxy) == fOwnRef); 57 SkSafeUnref(fProxy); 58 if (!proxy) { 59 fProxy = nullptr; 60 fOwnRef = false; 61 } else { 62 fProxy = proxy.release(); // due to the semantics of this class we unpack from sk_sp 63 fOwnRef = true; 64 fIOType = ioType; 65 } 66 } 67 68 void GrSurfaceProxyRef::markPendingIO() const { 69 // This should only be called when the owning GrProgramElement gets its first 70 // pendingExecution ref. 71 SkASSERT(!fPendingIO); 72 SkASSERT(fProxy); 73 fPendingIO = true; 74 switch (fIOType) { 75 case kRead_GrIOType: 76 fProxy->addPendingRead(); 77 break; 78 case kWrite_GrIOType: 79 fProxy->addPendingWrite(); 80 break; 81 case kRW_GrIOType: 82 fProxy->addPendingRead(); 83 fProxy->addPendingWrite(); 84 break; 85 } 86 } 87 88 void GrSurfaceProxyRef::pendingIOComplete() const { 89 // This should only be called when the owner's pending executions have ocurred but it is still 90 // reffed. 91 SkASSERT(fOwnRef); 92 SkASSERT(fPendingIO); 93 switch (fIOType) { 94 case kRead_GrIOType: 95 fProxy->completedRead(); 96 break; 97 case kWrite_GrIOType: 98 fProxy->completedWrite(); 99 break; 100 case kRW_GrIOType: 101 fProxy->completedRead(); 102 fProxy->completedWrite(); 103 break; 104 105 } 106 fPendingIO = false; 107 } 108 109 void GrSurfaceProxyRef::removeRef() const { 110 // This should only be called once, when the owners last ref goes away and 111 // there is a pending execution. 112 SkASSERT(fOwnRef); 113 SkASSERT(fPendingIO); 114 SkASSERT(fProxy); 115 fProxy->unref(); 116 fOwnRef = false; 117 } 118 119