1 /*
2 * Copyright 2016 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 // This is a GPU-backend specific test.
9
10 #include "Test.h"
11
12 #include "GrContextPriv.h"
13 #include "GrPendingIOResource.h"
14 #include "GrProxyProvider.h"
15 #include "GrRenderTargetProxy.h"
16 #include "GrResourceProvider.h"
17 #include "GrSurfaceProxy.h"
18 #include "GrTexture.h"
19 #include "GrTextureProxy.h"
20
getBackingRefCnt_TestOnly() const21 int32_t GrIORefProxy::getBackingRefCnt_TestOnly() const {
22 if (fTarget) {
23 return fTarget->fRefCnt;
24 }
25
26 return -1; // no backing GrSurface
27 }
28
getPendingReadCnt_TestOnly() const29 int32_t GrIORefProxy::getPendingReadCnt_TestOnly() const {
30 if (fTarget) {
31 return fTarget->fPendingReads;
32 }
33
34 return fPendingReads;
35 }
36
getPendingWriteCnt_TestOnly() const37 int32_t GrIORefProxy::getPendingWriteCnt_TestOnly() const {
38 if (fTarget) {
39 return fTarget->fPendingWrites;
40 }
41
42 return fPendingWrites;
43 }
44
45 static const int kWidthHeight = 128;
46
check_refs(skiatest::Reporter * reporter,GrTextureProxy * proxy,int32_t expectedProxyRefs,int32_t expectedBackingRefs,int32_t expectedNumReads,int32_t expectedNumWrites)47 static void check_refs(skiatest::Reporter* reporter,
48 GrTextureProxy* proxy,
49 int32_t expectedProxyRefs,
50 int32_t expectedBackingRefs,
51 int32_t expectedNumReads,
52 int32_t expectedNumWrites) {
53 REPORTER_ASSERT(reporter, proxy->priv().getProxyRefCnt() == expectedProxyRefs);
54 REPORTER_ASSERT(reporter, proxy->getBackingRefCnt_TestOnly() == expectedBackingRefs);
55 REPORTER_ASSERT(reporter, proxy->getPendingReadCnt_TestOnly() == expectedNumReads);
56 REPORTER_ASSERT(reporter, proxy->getPendingWriteCnt_TestOnly() == expectedNumWrites);
57
58 SkASSERT(proxy->priv().getProxyRefCnt() == expectedProxyRefs);
59 SkASSERT(proxy->getBackingRefCnt_TestOnly() == expectedBackingRefs);
60 SkASSERT(proxy->getPendingReadCnt_TestOnly() == expectedNumReads);
61 SkASSERT(proxy->getPendingWriteCnt_TestOnly() == expectedNumWrites);
62 }
63
make_deferred(GrProxyProvider * proxyProvider,const GrCaps * caps)64 static sk_sp<GrTextureProxy> make_deferred(GrProxyProvider* proxyProvider, const GrCaps* caps) {
65 GrSurfaceDesc desc;
66 desc.fFlags = kRenderTarget_GrSurfaceFlag;
67 desc.fWidth = kWidthHeight;
68 desc.fHeight = kWidthHeight;
69 desc.fConfig = kRGBA_8888_GrPixelConfig;
70
71 const GrBackendFormat format = caps->getBackendFormatFromColorType(kRGBA_8888_SkColorType);
72 return proxyProvider->createProxy(format, desc, kBottomLeft_GrSurfaceOrigin,
73 SkBackingFit::kApprox, SkBudgeted::kYes,
74 GrInternalSurfaceFlags::kNoPendingIO);
75 }
76
make_wrapped(GrProxyProvider * proxyProvider,const GrCaps * caps)77 static sk_sp<GrTextureProxy> make_wrapped(GrProxyProvider* proxyProvider, const GrCaps* caps) {
78 GrSurfaceDesc desc;
79 desc.fFlags = kRenderTarget_GrSurfaceFlag;
80 desc.fWidth = kWidthHeight;
81 desc.fHeight = kWidthHeight;
82 desc.fConfig = kRGBA_8888_GrPixelConfig;
83
84 return proxyProvider->testingOnly_createInstantiatedProxy(
85 desc, kBottomLeft_GrSurfaceOrigin, SkBackingFit::kExact, SkBudgeted::kNo);
86 }
87
DEF_GPUTEST_FOR_RENDERING_CONTEXTS(ProxyRefTest,reporter,ctxInfo)88 DEF_GPUTEST_FOR_RENDERING_CONTEXTS(ProxyRefTest, reporter, ctxInfo) {
89 GrProxyProvider* proxyProvider = ctxInfo.grContext()->contextPriv().proxyProvider();
90 GrResourceProvider* resourceProvider = ctxInfo.grContext()->contextPriv().resourceProvider();
91 const GrCaps* caps = ctxInfo.grContext()->contextPriv().caps();
92
93 for (auto make : { make_deferred, make_wrapped }) {
94 // A single write
95 {
96 sk_sp<GrTextureProxy> proxy((*make)(proxyProvider, caps));
97 if (proxy.get()) {
98 GrPendingIOResource<GrSurfaceProxy, kWrite_GrIOType> fWrite(proxy.get());
99
100 static const int kExpectedReads = 0;
101 static const int kExpectedWrites = 1;
102
103 int backingRefs = proxy->isWrapped_ForTesting() ? 1 : -1;
104
105 check_refs(reporter, proxy.get(), 1, backingRefs, kExpectedReads, kExpectedWrites);
106
107 proxy->instantiate(resourceProvider);
108
109 // In the deferred case, this checks that the refs transfered to the GrSurface
110 check_refs(reporter, proxy.get(), 1, 1, kExpectedReads, kExpectedWrites);
111 }
112 }
113
114 // A single read
115 {
116 sk_sp<GrTextureProxy> proxy((*make)(proxyProvider, caps));
117 if (proxy.get()) {
118 GrPendingIOResource<GrSurfaceProxy, kRead_GrIOType> fRead(proxy.get());
119
120 static const int kExpectedReads = 1;
121 static const int kExpectedWrites = 0;
122
123 int backingRefs = proxy->isWrapped_ForTesting() ? 1 : -1;
124
125 check_refs(reporter, proxy.get(), 1, backingRefs, kExpectedReads, kExpectedWrites);
126
127 proxy->instantiate(resourceProvider);
128
129 // In the deferred case, this checks that the refs transfered to the GrSurface
130 check_refs(reporter, proxy.get(), 1, 1, kExpectedReads, kExpectedWrites);
131 }
132 }
133
134 // A single read/write pair
135 {
136 sk_sp<GrTextureProxy> proxy((*make)(proxyProvider, caps));
137 if (proxy.get()) {
138 GrPendingIOResource<GrSurfaceProxy, kRW_GrIOType> fRW(proxy.get());
139
140 static const int kExpectedReads = 1;
141 static const int kExpectedWrites = 1;
142
143 int backingRefs = proxy->isWrapped_ForTesting() ? 1 : -1;
144
145 check_refs(reporter, proxy.get(), 1, backingRefs, kExpectedReads, kExpectedWrites);
146
147 proxy->instantiate(resourceProvider);
148
149 // In the deferred case, this checks that the refs transferred to the GrSurface
150 check_refs(reporter, proxy.get(), 1, 1, kExpectedReads, kExpectedWrites);
151 }
152 }
153
154 // Multiple normal refs
155 {
156 sk_sp<GrTextureProxy> proxy((*make)(proxyProvider, caps));
157 if (proxy.get()) {
158 proxy->ref();
159 proxy->ref();
160
161 static const int kExpectedReads = 0;
162 static const int kExpectedWrites = 0;
163
164 int backingRefs = proxy->isWrapped_ForTesting() ? 3 : -1;
165
166 check_refs(reporter, proxy.get(), 3, backingRefs, kExpectedReads, kExpectedWrites);
167
168 proxy->instantiate(resourceProvider);
169
170 // In the deferred case, this checks that the refs transferred to the GrSurface
171 check_refs(reporter, proxy.get(), 3, 3, kExpectedReads, kExpectedWrites);
172
173 proxy->unref();
174 proxy->unref();
175 }
176 }
177
178 // Continue using (reffing) proxy after instantiation
179 {
180 sk_sp<GrTextureProxy> proxy((*make)(proxyProvider, caps));
181 if (proxy.get()) {
182 proxy->ref();
183
184 GrPendingIOResource<GrSurfaceProxy, kWrite_GrIOType> fWrite(proxy.get());
185
186 static const int kExpectedWrites = 1;
187
188 int backingRefs = proxy->isWrapped_ForTesting() ? 2 : -1;
189
190 check_refs(reporter, proxy.get(), 2, backingRefs, 0, kExpectedWrites);
191
192 proxy->instantiate(resourceProvider);
193
194 // In the deferred case, this checks that the refs transfered to the GrSurface
195 check_refs(reporter, proxy.get(), 2, 2, 0, kExpectedWrites);
196
197 proxy->unref();
198 check_refs(reporter, proxy.get(), 1, 1, 0, kExpectedWrites);
199
200 GrPendingIOResource<GrSurfaceProxy, kRead_GrIOType> fRead(proxy.get());
201 check_refs(reporter, proxy.get(), 1, 1, 1, kExpectedWrites);
202 }
203 }
204 }
205 }
206