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