• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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