GrGpuResourceRef.cpp revision 952a2435f7a38624ffbd0ac3b44d30f4b887a48b
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
10GrGpuResourceRef::GrGpuResourceRef() {
11    fResource = nullptr;
12    fOwnRef = false;
13    fPendingIO = false;
14}
15
16GrGpuResourceRef::GrGpuResourceRef(GrGpuResource* resource, GrIOType ioType) {
17    fResource = nullptr;
18    fOwnRef = false;
19    fPendingIO = false;
20    this->setResource(resource, ioType);
21}
22
23GrGpuResourceRef::~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
44void 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
54void 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
68void 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
91void 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
116void 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
132GrTextureProxyRef::GrTextureProxyRef() {
133    fProxy = nullptr;
134    fOwnRef = false;
135    fPendingIO = false;
136}
137
138GrTextureProxyRef::GrTextureProxyRef(sk_sp<GrTextureProxy> proxy, GrIOType ioType) {
139    fProxy = nullptr;
140    fOwnRef = false;
141    fPendingIO = false;
142    this->setProxy(proxy, ioType);
143}
144
145GrTextureProxyRef::~GrTextureProxyRef() {
146    if (fOwnRef) {
147        SkASSERT(fProxy);
148        fProxy->unref();
149    }
150    if (fPendingIO) {
151        switch (fIOType) {
152            case kRead_GrIOType:
153                fProxy->completedRead();
154                break;
155            case kWrite_GrIOType:
156                fProxy->completedWrite();
157                break;
158            case kRW_GrIOType:
159                fProxy->completedRead();
160                fProxy->completedWrite();
161                break;
162        }
163    }
164}
165
166void GrTextureProxyRef::reset() {
167    SkASSERT(!fPendingIO);
168    SkASSERT(SkToBool(fProxy) == fOwnRef);
169    if (fOwnRef) {
170        fProxy->unref();
171        fOwnRef = false;
172        fProxy = nullptr;
173    }
174}
175
176void GrTextureProxyRef::setProxy(sk_sp<GrTextureProxy> proxy, GrIOType ioType) {
177    SkASSERT(!fPendingIO);
178    SkASSERT(SkToBool(fProxy) == fOwnRef);
179    SkSafeUnref(fProxy);
180    if (!proxy) {
181        fProxy = nullptr;
182        fOwnRef = false;
183    } else {
184        fProxy = proxy.release();   // due to the semantics of this class we unpack from sk_sp
185        fOwnRef = true;
186        fIOType = ioType;
187    }
188}
189
190void GrTextureProxyRef::markPendingIO() const {
191    // This should only be called when the owning GrProgramElement gets its first
192    // pendingExecution ref.
193    SkASSERT(!fPendingIO);
194    SkASSERT(fProxy);
195    fPendingIO = true;
196    switch (fIOType) {
197        case kRead_GrIOType:
198            fProxy->addPendingRead();
199            break;
200        case kWrite_GrIOType:
201            fProxy->addPendingWrite();
202            break;
203        case kRW_GrIOType:
204            fProxy->addPendingRead();
205            fProxy->addPendingWrite();
206            break;
207    }
208}
209
210void GrTextureProxyRef::pendingIOComplete() const {
211    // This should only be called when the owner's pending executions have ocurred but it is still
212    // reffed.
213    SkASSERT(fOwnRef);
214    SkASSERT(fPendingIO);
215    switch (fIOType) {
216        case kRead_GrIOType:
217            fProxy->completedRead();
218            break;
219        case kWrite_GrIOType:
220            fProxy->completedWrite();
221            break;
222        case kRW_GrIOType:
223            fProxy->completedRead();
224            fProxy->completedWrite();
225            break;
226
227    }
228    fPendingIO = false;
229}
230
231void GrTextureProxyRef::removeRef() const {
232    // This should only be called once, when the owners last ref goes away and
233    // there is a pending execution.
234    SkASSERT(fOwnRef);
235    SkASSERT(fPendingIO);
236    SkASSERT(fProxy);
237    fProxy->unref();
238    fOwnRef = false;
239}
240
241