1*c8dee2aaSAndroid Build Coastguard Worker /*
2*c8dee2aaSAndroid Build Coastguard Worker * Copyright 2017 Google Inc.
3*c8dee2aaSAndroid Build Coastguard Worker *
4*c8dee2aaSAndroid Build Coastguard Worker * Use of this source code is governed by a BSD-style license that can be
5*c8dee2aaSAndroid Build Coastguard Worker * found in the LICENSE file.
6*c8dee2aaSAndroid Build Coastguard Worker */
7*c8dee2aaSAndroid Build Coastguard Worker
8*c8dee2aaSAndroid Build Coastguard Worker // This is a GPU-backend specific test.
9*c8dee2aaSAndroid Build Coastguard Worker
10*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkAlphaType.h"
11*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkBitmap.h"
12*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkColorType.h"
13*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkImage.h"
14*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkImageInfo.h"
15*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkRect.h"
16*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkRefCnt.h"
17*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkSize.h"
18*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkTypes.h"
19*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/GpuTypes.h"
20*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/ganesh/GrBackendSurface.h"
21*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/ganesh/GrDirectContext.h"
22*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/ganesh/GrRecordingContext.h"
23*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/ganesh/GrTypes.h"
24*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/ganesh/SkImageGanesh.h"
25*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/gpu/ganesh/GrTypesPriv.h"
26*c8dee2aaSAndroid Build Coastguard Worker #include "src/core/SkMessageBus.h"
27*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ResourceKey.h"
28*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/SkBackingFit.h"
29*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrCaps.h"
30*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrDirectContextPriv.h"
31*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrGpuResourcePriv.h"
32*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrProxyProvider.h"
33*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrRecordingContextPriv.h"
34*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrResourceCache.h"
35*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrSurface.h"
36*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrTexture.h"
37*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrTextureProxy.h"
38*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/SkGr.h"
39*c8dee2aaSAndroid Build Coastguard Worker #include "tests/CtsEnforcement.h"
40*c8dee2aaSAndroid Build Coastguard Worker #include "tests/Test.h"
41*c8dee2aaSAndroid Build Coastguard Worker #include "tools/gpu/ManagedBackendTexture.h"
42*c8dee2aaSAndroid Build Coastguard Worker
43*c8dee2aaSAndroid Build Coastguard Worker #include <cstddef>
44*c8dee2aaSAndroid Build Coastguard Worker #include <cstdint>
45*c8dee2aaSAndroid Build Coastguard Worker #include <initializer_list>
46*c8dee2aaSAndroid Build Coastguard Worker
47*c8dee2aaSAndroid Build Coastguard Worker class GrResourceProvider;
48*c8dee2aaSAndroid Build Coastguard Worker struct GrContextOptions;
49*c8dee2aaSAndroid Build Coastguard Worker
numUniqueKeyProxies_TestOnly() const50*c8dee2aaSAndroid Build Coastguard Worker int GrProxyProvider::numUniqueKeyProxies_TestOnly() const {
51*c8dee2aaSAndroid Build Coastguard Worker return fUniquelyKeyedProxies.count();
52*c8dee2aaSAndroid Build Coastguard Worker }
53*c8dee2aaSAndroid Build Coastguard Worker
54*c8dee2aaSAndroid Build Coastguard Worker static constexpr auto kColorType = GrColorType::kRGBA_8888;
55*c8dee2aaSAndroid Build Coastguard Worker static constexpr auto kSize = SkISize::Make(64, 64);
56*c8dee2aaSAndroid Build Coastguard Worker
57*c8dee2aaSAndroid Build Coastguard Worker ///////////////////////////////////////////////////////////////////////////////////////////////////
58*c8dee2aaSAndroid Build Coastguard Worker // Basic test
59*c8dee2aaSAndroid Build Coastguard Worker
deferred_tex(skiatest::Reporter * reporter,GrRecordingContext * rContext,GrProxyProvider * proxyProvider,SkBackingFit fit)60*c8dee2aaSAndroid Build Coastguard Worker static sk_sp<GrTextureProxy> deferred_tex(skiatest::Reporter* reporter,
61*c8dee2aaSAndroid Build Coastguard Worker GrRecordingContext* rContext,
62*c8dee2aaSAndroid Build Coastguard Worker GrProxyProvider* proxyProvider,
63*c8dee2aaSAndroid Build Coastguard Worker SkBackingFit fit) {
64*c8dee2aaSAndroid Build Coastguard Worker using namespace skgpu;
65*c8dee2aaSAndroid Build Coastguard Worker
66*c8dee2aaSAndroid Build Coastguard Worker const GrCaps* caps = rContext->priv().caps();
67*c8dee2aaSAndroid Build Coastguard Worker
68*c8dee2aaSAndroid Build Coastguard Worker Protected isProtected = Protected(caps->supportsProtectedContent());
69*c8dee2aaSAndroid Build Coastguard Worker
70*c8dee2aaSAndroid Build Coastguard Worker GrBackendFormat format = caps->getDefaultBackendFormat(kColorType, GrRenderable::kNo);
71*c8dee2aaSAndroid Build Coastguard Worker
72*c8dee2aaSAndroid Build Coastguard Worker sk_sp<GrTextureProxy> proxy = proxyProvider->createProxy(format,
73*c8dee2aaSAndroid Build Coastguard Worker kSize,
74*c8dee2aaSAndroid Build Coastguard Worker GrRenderable::kNo,
75*c8dee2aaSAndroid Build Coastguard Worker 1,
76*c8dee2aaSAndroid Build Coastguard Worker Mipmapped::kNo,
77*c8dee2aaSAndroid Build Coastguard Worker fit,
78*c8dee2aaSAndroid Build Coastguard Worker Budgeted::kYes,
79*c8dee2aaSAndroid Build Coastguard Worker isProtected,
80*c8dee2aaSAndroid Build Coastguard Worker /*label=*/{});
81*c8dee2aaSAndroid Build Coastguard Worker // Only budgeted & wrapped external proxies get to carry uniqueKeys
82*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, !proxy->getUniqueKey().isValid());
83*c8dee2aaSAndroid Build Coastguard Worker return proxy;
84*c8dee2aaSAndroid Build Coastguard Worker }
85*c8dee2aaSAndroid Build Coastguard Worker
deferred_texRT(skiatest::Reporter * reporter,GrRecordingContext * rContext,GrProxyProvider * proxyProvider,SkBackingFit fit)86*c8dee2aaSAndroid Build Coastguard Worker static sk_sp<GrTextureProxy> deferred_texRT(skiatest::Reporter* reporter,
87*c8dee2aaSAndroid Build Coastguard Worker GrRecordingContext* rContext,
88*c8dee2aaSAndroid Build Coastguard Worker GrProxyProvider* proxyProvider,
89*c8dee2aaSAndroid Build Coastguard Worker SkBackingFit fit) {
90*c8dee2aaSAndroid Build Coastguard Worker using namespace skgpu;
91*c8dee2aaSAndroid Build Coastguard Worker
92*c8dee2aaSAndroid Build Coastguard Worker const GrCaps* caps = rContext->priv().caps();
93*c8dee2aaSAndroid Build Coastguard Worker
94*c8dee2aaSAndroid Build Coastguard Worker Protected isProtected = Protected(caps->supportsProtectedContent());
95*c8dee2aaSAndroid Build Coastguard Worker
96*c8dee2aaSAndroid Build Coastguard Worker GrBackendFormat format = caps->getDefaultBackendFormat(kColorType, GrRenderable::kYes);
97*c8dee2aaSAndroid Build Coastguard Worker
98*c8dee2aaSAndroid Build Coastguard Worker sk_sp<GrTextureProxy> proxy = proxyProvider->createProxy(format,
99*c8dee2aaSAndroid Build Coastguard Worker kSize,
100*c8dee2aaSAndroid Build Coastguard Worker GrRenderable::kYes,
101*c8dee2aaSAndroid Build Coastguard Worker 1,
102*c8dee2aaSAndroid Build Coastguard Worker Mipmapped::kNo,
103*c8dee2aaSAndroid Build Coastguard Worker fit,
104*c8dee2aaSAndroid Build Coastguard Worker Budgeted::kYes,
105*c8dee2aaSAndroid Build Coastguard Worker isProtected,
106*c8dee2aaSAndroid Build Coastguard Worker /*label=*/{});
107*c8dee2aaSAndroid Build Coastguard Worker // Only budgeted & wrapped external proxies get to carry uniqueKeys
108*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, !proxy->getUniqueKey().isValid());
109*c8dee2aaSAndroid Build Coastguard Worker return proxy;
110*c8dee2aaSAndroid Build Coastguard Worker }
111*c8dee2aaSAndroid Build Coastguard Worker
wrapped(skiatest::Reporter * reporter,GrRecordingContext * rContext,GrProxyProvider * proxyProvider,SkBackingFit fit)112*c8dee2aaSAndroid Build Coastguard Worker static sk_sp<GrTextureProxy> wrapped(skiatest::Reporter* reporter, GrRecordingContext* rContext,
113*c8dee2aaSAndroid Build Coastguard Worker GrProxyProvider* proxyProvider, SkBackingFit fit) {
114*c8dee2aaSAndroid Build Coastguard Worker using namespace skgpu;
115*c8dee2aaSAndroid Build Coastguard Worker
116*c8dee2aaSAndroid Build Coastguard Worker Protected isProtected = Protected(rContext->priv().caps()->supportsProtectedContent());
117*c8dee2aaSAndroid Build Coastguard Worker
118*c8dee2aaSAndroid Build Coastguard Worker sk_sp<GrTextureProxy> proxy = proxyProvider->testingOnly_createInstantiatedProxy(
119*c8dee2aaSAndroid Build Coastguard Worker kSize, kColorType, GrRenderable::kNo, 1, fit, Budgeted::kYes, isProtected);
120*c8dee2aaSAndroid Build Coastguard Worker // Only budgeted & wrapped external proxies get to carry uniqueKeys
121*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, !proxy->getUniqueKey().isValid());
122*c8dee2aaSAndroid Build Coastguard Worker return proxy;
123*c8dee2aaSAndroid Build Coastguard Worker }
124*c8dee2aaSAndroid Build Coastguard Worker
wrapped_with_key(skiatest::Reporter * reporter,GrRecordingContext * rContext,GrProxyProvider * proxyProvider,SkBackingFit fit)125*c8dee2aaSAndroid Build Coastguard Worker static sk_sp<GrTextureProxy> wrapped_with_key(skiatest::Reporter* reporter,
126*c8dee2aaSAndroid Build Coastguard Worker GrRecordingContext* rContext,
127*c8dee2aaSAndroid Build Coastguard Worker GrProxyProvider* proxyProvider,
128*c8dee2aaSAndroid Build Coastguard Worker SkBackingFit fit) {
129*c8dee2aaSAndroid Build Coastguard Worker using namespace skgpu;
130*c8dee2aaSAndroid Build Coastguard Worker
131*c8dee2aaSAndroid Build Coastguard Worker Protected isProtected = Protected(rContext->priv().caps()->supportsProtectedContent());
132*c8dee2aaSAndroid Build Coastguard Worker
133*c8dee2aaSAndroid Build Coastguard Worker static UniqueKey::Domain d = UniqueKey::GenerateDomain();
134*c8dee2aaSAndroid Build Coastguard Worker static int kUniqueKeyData = 0;
135*c8dee2aaSAndroid Build Coastguard Worker
136*c8dee2aaSAndroid Build Coastguard Worker UniqueKey key;
137*c8dee2aaSAndroid Build Coastguard Worker
138*c8dee2aaSAndroid Build Coastguard Worker UniqueKey::Builder builder(&key, d, 1, nullptr);
139*c8dee2aaSAndroid Build Coastguard Worker builder[0] = kUniqueKeyData++;
140*c8dee2aaSAndroid Build Coastguard Worker builder.finish();
141*c8dee2aaSAndroid Build Coastguard Worker
142*c8dee2aaSAndroid Build Coastguard Worker // Only budgeted & wrapped external proxies get to carry uniqueKeys
143*c8dee2aaSAndroid Build Coastguard Worker sk_sp<GrTextureProxy> proxy = proxyProvider->testingOnly_createInstantiatedProxy(
144*c8dee2aaSAndroid Build Coastguard Worker kSize, kColorType, GrRenderable::kNo, 1, fit, Budgeted::kYes, isProtected);
145*c8dee2aaSAndroid Build Coastguard Worker SkAssertResult(proxyProvider->assignUniqueKeyToProxy(key, proxy.get()));
146*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, proxy->getUniqueKey().isValid());
147*c8dee2aaSAndroid Build Coastguard Worker return proxy;
148*c8dee2aaSAndroid Build Coastguard Worker }
149*c8dee2aaSAndroid Build Coastguard Worker
create_wrapped_backend(GrDirectContext * dContext)150*c8dee2aaSAndroid Build Coastguard Worker static sk_sp<GrTextureProxy> create_wrapped_backend(GrDirectContext* dContext) {
151*c8dee2aaSAndroid Build Coastguard Worker using namespace skgpu;
152*c8dee2aaSAndroid Build Coastguard Worker
153*c8dee2aaSAndroid Build Coastguard Worker Protected isProtected = Protected(dContext->priv().caps()->supportsProtectedContent());
154*c8dee2aaSAndroid Build Coastguard Worker
155*c8dee2aaSAndroid Build Coastguard Worker auto mbet = sk_gpu_test::ManagedBackendTexture::MakeWithoutData(
156*c8dee2aaSAndroid Build Coastguard Worker dContext,
157*c8dee2aaSAndroid Build Coastguard Worker kSize.width(),
158*c8dee2aaSAndroid Build Coastguard Worker kSize.height(),
159*c8dee2aaSAndroid Build Coastguard Worker GrColorTypeToSkColorType(kColorType),
160*c8dee2aaSAndroid Build Coastguard Worker Mipmapped::kNo,
161*c8dee2aaSAndroid Build Coastguard Worker GrRenderable::kNo,
162*c8dee2aaSAndroid Build Coastguard Worker isProtected);
163*c8dee2aaSAndroid Build Coastguard Worker if (!mbet) {
164*c8dee2aaSAndroid Build Coastguard Worker return nullptr;
165*c8dee2aaSAndroid Build Coastguard Worker }
166*c8dee2aaSAndroid Build Coastguard Worker GrProxyProvider* proxyProvider = dContext->priv().proxyProvider();
167*c8dee2aaSAndroid Build Coastguard Worker return proxyProvider->wrapBackendTexture(mbet->texture(),
168*c8dee2aaSAndroid Build Coastguard Worker kBorrow_GrWrapOwnership,
169*c8dee2aaSAndroid Build Coastguard Worker GrWrapCacheable::kYes,
170*c8dee2aaSAndroid Build Coastguard Worker kRead_GrIOType,
171*c8dee2aaSAndroid Build Coastguard Worker mbet->refCountedCallback());
172*c8dee2aaSAndroid Build Coastguard Worker }
173*c8dee2aaSAndroid Build Coastguard Worker
174*c8dee2aaSAndroid Build Coastguard Worker // This tests the basic capabilities of the uniquely keyed texture proxies. Does assigning
175*c8dee2aaSAndroid Build Coastguard Worker // and looking them up work, etc.
basic_test(GrDirectContext * dContext,skiatest::Reporter * reporter,sk_sp<GrTextureProxy> proxy,int cacheEntriesPerProxy)176*c8dee2aaSAndroid Build Coastguard Worker static void basic_test(GrDirectContext* dContext,
177*c8dee2aaSAndroid Build Coastguard Worker skiatest::Reporter* reporter,
178*c8dee2aaSAndroid Build Coastguard Worker sk_sp<GrTextureProxy> proxy,
179*c8dee2aaSAndroid Build Coastguard Worker int cacheEntriesPerProxy) {
180*c8dee2aaSAndroid Build Coastguard Worker static int id = 1;
181*c8dee2aaSAndroid Build Coastguard Worker
182*c8dee2aaSAndroid Build Coastguard Worker GrResourceProvider* resourceProvider = dContext->priv().resourceProvider();
183*c8dee2aaSAndroid Build Coastguard Worker GrProxyProvider* proxyProvider = dContext->priv().proxyProvider();
184*c8dee2aaSAndroid Build Coastguard Worker GrResourceCache* cache = dContext->priv().getResourceCache();
185*c8dee2aaSAndroid Build Coastguard Worker
186*c8dee2aaSAndroid Build Coastguard Worker int startCacheCount = cache->getResourceCount();
187*c8dee2aaSAndroid Build Coastguard Worker
188*c8dee2aaSAndroid Build Coastguard Worker skgpu::UniqueKey key;
189*c8dee2aaSAndroid Build Coastguard Worker if (proxy->getUniqueKey().isValid()) {
190*c8dee2aaSAndroid Build Coastguard Worker key = proxy->getUniqueKey();
191*c8dee2aaSAndroid Build Coastguard Worker } else {
192*c8dee2aaSAndroid Build Coastguard Worker GrMakeKeyFromImageID(&key, id, SkIRect::MakeWH(64, 64));
193*c8dee2aaSAndroid Build Coastguard Worker ++id;
194*c8dee2aaSAndroid Build Coastguard Worker
195*c8dee2aaSAndroid Build Coastguard Worker // Assigning the uniqueKey adds the proxy to the hash but doesn't force instantiation
196*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, !proxyProvider->numUniqueKeyProxies_TestOnly());
197*c8dee2aaSAndroid Build Coastguard Worker SkAssertResult(proxyProvider->assignUniqueKeyToProxy(key, proxy.get()));
198*c8dee2aaSAndroid Build Coastguard Worker }
199*c8dee2aaSAndroid Build Coastguard Worker
200*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, 1 == proxyProvider->numUniqueKeyProxies_TestOnly());
201*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, startCacheCount == cache->getResourceCount());
202*c8dee2aaSAndroid Build Coastguard Worker
203*c8dee2aaSAndroid Build Coastguard Worker // setUniqueKey had better stick
204*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, key == proxy->getUniqueKey());
205*c8dee2aaSAndroid Build Coastguard Worker
206*c8dee2aaSAndroid Build Coastguard Worker // We just added it, surely we can find it
207*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, proxyProvider->findOrCreateProxyByUniqueKey(key));
208*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, 1 == proxyProvider->numUniqueKeyProxies_TestOnly());
209*c8dee2aaSAndroid Build Coastguard Worker
210*c8dee2aaSAndroid Build Coastguard Worker int expectedCacheCount = startCacheCount + (proxy->isInstantiated() ? 0 : cacheEntriesPerProxy);
211*c8dee2aaSAndroid Build Coastguard Worker
212*c8dee2aaSAndroid Build Coastguard Worker // Once instantiated, the backing resource should have the same key
213*c8dee2aaSAndroid Build Coastguard Worker SkAssertResult(proxy->instantiate(resourceProvider));
214*c8dee2aaSAndroid Build Coastguard Worker const skgpu::UniqueKey texKey = proxy->peekSurface()->getUniqueKey();
215*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, texKey.isValid());
216*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, key == texKey);
217*c8dee2aaSAndroid Build Coastguard Worker
218*c8dee2aaSAndroid Build Coastguard Worker // An Unbudgeted-cacheable resource will not get purged when a proxy with the same key is
219*c8dee2aaSAndroid Build Coastguard Worker // deleted.
220*c8dee2aaSAndroid Build Coastguard Worker bool expectResourceToOutliveProxy = proxy->peekSurface()->resourcePriv().budgetedType() ==
221*c8dee2aaSAndroid Build Coastguard Worker GrBudgetedType::kUnbudgetedCacheable;
222*c8dee2aaSAndroid Build Coastguard Worker
223*c8dee2aaSAndroid Build Coastguard Worker // An Unbudgeted-uncacheable resource is never kept alive if it's ref cnt reaches zero even if
224*c8dee2aaSAndroid Build Coastguard Worker // it has a key.
225*c8dee2aaSAndroid Build Coastguard Worker bool expectDeletingProxyToDeleteResource =
226*c8dee2aaSAndroid Build Coastguard Worker proxy->peekSurface()->resourcePriv().budgetedType() ==
227*c8dee2aaSAndroid Build Coastguard Worker GrBudgetedType::kUnbudgetedUncacheable;
228*c8dee2aaSAndroid Build Coastguard Worker
229*c8dee2aaSAndroid Build Coastguard Worker // deleting the proxy should delete it from the hash but not the cache
230*c8dee2aaSAndroid Build Coastguard Worker proxy = nullptr;
231*c8dee2aaSAndroid Build Coastguard Worker if (expectDeletingProxyToDeleteResource) {
232*c8dee2aaSAndroid Build Coastguard Worker expectedCacheCount -= cacheEntriesPerProxy;
233*c8dee2aaSAndroid Build Coastguard Worker }
234*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, 0 == proxyProvider->numUniqueKeyProxies_TestOnly());
235*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, expectedCacheCount == cache->getResourceCount());
236*c8dee2aaSAndroid Build Coastguard Worker
237*c8dee2aaSAndroid Build Coastguard Worker // If the proxy was cached refinding it should bring it back to life
238*c8dee2aaSAndroid Build Coastguard Worker proxy = proxyProvider->findOrCreateProxyByUniqueKey(key);
239*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, proxy);
240*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, 1 == proxyProvider->numUniqueKeyProxies_TestOnly());
241*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, expectedCacheCount == cache->getResourceCount());
242*c8dee2aaSAndroid Build Coastguard Worker
243*c8dee2aaSAndroid Build Coastguard Worker // Mega-purging it should remove it from both the hash and the cache
244*c8dee2aaSAndroid Build Coastguard Worker proxy = nullptr;
245*c8dee2aaSAndroid Build Coastguard Worker cache->purgeUnlockedResources(GrPurgeResourceOptions::kAllResources);
246*c8dee2aaSAndroid Build Coastguard Worker if (!expectResourceToOutliveProxy) {
247*c8dee2aaSAndroid Build Coastguard Worker expectedCacheCount -= cacheEntriesPerProxy;
248*c8dee2aaSAndroid Build Coastguard Worker }
249*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, expectedCacheCount == cache->getResourceCount());
250*c8dee2aaSAndroid Build Coastguard Worker
251*c8dee2aaSAndroid Build Coastguard Worker // If the texture was deleted then the proxy should no longer be findable. Otherwise, it should
252*c8dee2aaSAndroid Build Coastguard Worker // be.
253*c8dee2aaSAndroid Build Coastguard Worker proxy = proxyProvider->findOrCreateProxyByUniqueKey(key);
254*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, expectResourceToOutliveProxy ? (bool)proxy : !proxy);
255*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, expectedCacheCount == cache->getResourceCount());
256*c8dee2aaSAndroid Build Coastguard Worker
257*c8dee2aaSAndroid Build Coastguard Worker if (expectResourceToOutliveProxy) {
258*c8dee2aaSAndroid Build Coastguard Worker proxy.reset();
259*c8dee2aaSAndroid Build Coastguard Worker skgpu::UniqueKeyInvalidatedMessage msg(texKey, dContext->priv().contextID());
260*c8dee2aaSAndroid Build Coastguard Worker SkMessageBus<skgpu::UniqueKeyInvalidatedMessage, uint32_t>::Post(msg);
261*c8dee2aaSAndroid Build Coastguard Worker cache->purgeAsNeeded();
262*c8dee2aaSAndroid Build Coastguard Worker expectedCacheCount -= cacheEntriesPerProxy;
263*c8dee2aaSAndroid Build Coastguard Worker proxy = proxyProvider->findOrCreateProxyByUniqueKey(key);
264*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, !proxy);
265*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, expectedCacheCount == cache->getResourceCount());
266*c8dee2aaSAndroid Build Coastguard Worker }
267*c8dee2aaSAndroid Build Coastguard Worker }
268*c8dee2aaSAndroid Build Coastguard Worker
269*c8dee2aaSAndroid Build Coastguard Worker ///////////////////////////////////////////////////////////////////////////////////////////////////
270*c8dee2aaSAndroid Build Coastguard Worker // Invalidation test
271*c8dee2aaSAndroid Build Coastguard Worker
272*c8dee2aaSAndroid Build Coastguard Worker // Test if invalidating unique ids operates as expected for texture proxies.
invalidation_test(GrDirectContext * dContext,skiatest::Reporter * reporter,int cacheEntriesPerProxy)273*c8dee2aaSAndroid Build Coastguard Worker static void invalidation_test(GrDirectContext* dContext,
274*c8dee2aaSAndroid Build Coastguard Worker skiatest::Reporter* reporter,
275*c8dee2aaSAndroid Build Coastguard Worker int cacheEntriesPerProxy) {
276*c8dee2aaSAndroid Build Coastguard Worker
277*c8dee2aaSAndroid Build Coastguard Worker GrProxyProvider* proxyProvider = dContext->priv().proxyProvider();
278*c8dee2aaSAndroid Build Coastguard Worker GrResourceCache* cache = dContext->priv().getResourceCache();
279*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, 0 == cache->getResourceCount());
280*c8dee2aaSAndroid Build Coastguard Worker
281*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkImage> rasterImg;
282*c8dee2aaSAndroid Build Coastguard Worker
283*c8dee2aaSAndroid Build Coastguard Worker {
284*c8dee2aaSAndroid Build Coastguard Worker SkImageInfo ii = SkImageInfo::Make(64, 64, kRGBA_8888_SkColorType, kOpaque_SkAlphaType);
285*c8dee2aaSAndroid Build Coastguard Worker
286*c8dee2aaSAndroid Build Coastguard Worker SkBitmap bm;
287*c8dee2aaSAndroid Build Coastguard Worker bm.allocPixels(ii);
288*c8dee2aaSAndroid Build Coastguard Worker
289*c8dee2aaSAndroid Build Coastguard Worker rasterImg = bm.asImage();
290*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, 0 == proxyProvider->numUniqueKeyProxies_TestOnly());
291*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, 0 == cache->getResourceCount());
292*c8dee2aaSAndroid Build Coastguard Worker }
293*c8dee2aaSAndroid Build Coastguard Worker
294*c8dee2aaSAndroid Build Coastguard Worker // Some of our backends use buffers to do uploads that will live in our resource cache. So we
295*c8dee2aaSAndroid Build Coastguard Worker // need to account for those extra resources here.
296*c8dee2aaSAndroid Build Coastguard Worker int bufferResources = 0;
297*c8dee2aaSAndroid Build Coastguard Worker if (dContext->backend() == GrBackendApi::kVulkan ||
298*c8dee2aaSAndroid Build Coastguard Worker dContext->backend() == GrBackendApi::kDirect3D ||
299*c8dee2aaSAndroid Build Coastguard Worker dContext->backend() == GrBackendApi::kMetal) {
300*c8dee2aaSAndroid Build Coastguard Worker bufferResources = 1;
301*c8dee2aaSAndroid Build Coastguard Worker }
302*c8dee2aaSAndroid Build Coastguard Worker
303*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkImage> textureImg = SkImages::TextureFromImage(dContext, rasterImg);
304*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, 0 == proxyProvider->numUniqueKeyProxies_TestOnly());
305*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, cacheEntriesPerProxy + bufferResources == cache->getResourceCount());
306*c8dee2aaSAndroid Build Coastguard Worker
307*c8dee2aaSAndroid Build Coastguard Worker rasterImg = nullptr; // this invalidates the uniqueKey
308*c8dee2aaSAndroid Build Coastguard Worker
309*c8dee2aaSAndroid Build Coastguard Worker // this forces the cache to respond to the inval msg
310*c8dee2aaSAndroid Build Coastguard Worker size_t maxBytes = dContext->getResourceCacheLimit();
311*c8dee2aaSAndroid Build Coastguard Worker dContext->setResourceCacheLimit(maxBytes-1);
312*c8dee2aaSAndroid Build Coastguard Worker
313*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, 0 == proxyProvider->numUniqueKeyProxies_TestOnly());
314*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, cacheEntriesPerProxy + bufferResources == cache->getResourceCount());
315*c8dee2aaSAndroid Build Coastguard Worker
316*c8dee2aaSAndroid Build Coastguard Worker textureImg = nullptr;
317*c8dee2aaSAndroid Build Coastguard Worker
318*c8dee2aaSAndroid Build Coastguard Worker // For backends that use buffers to upload lets make sure that work has been submit and done
319*c8dee2aaSAndroid Build Coastguard Worker // before we try to purge all resources.
320*c8dee2aaSAndroid Build Coastguard Worker dContext->submit(GrSyncCpu::kYes);
321*c8dee2aaSAndroid Build Coastguard Worker dContext->priv().getResourceCache()->purgeUnlockedResources(
322*c8dee2aaSAndroid Build Coastguard Worker GrPurgeResourceOptions::kAllResources);
323*c8dee2aaSAndroid Build Coastguard Worker
324*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, 0 == proxyProvider->numUniqueKeyProxies_TestOnly());
325*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, 0 == cache->getResourceCount());
326*c8dee2aaSAndroid Build Coastguard Worker }
327*c8dee2aaSAndroid Build Coastguard Worker
328*c8dee2aaSAndroid Build Coastguard Worker // Test if invalidating unique ids prior to instantiating operates as expected
invalidation_and_instantiation_test(GrDirectContext * dContext,skiatest::Reporter * reporter,int cacheEntriesPerProxy)329*c8dee2aaSAndroid Build Coastguard Worker static void invalidation_and_instantiation_test(GrDirectContext* dContext,
330*c8dee2aaSAndroid Build Coastguard Worker skiatest::Reporter* reporter,
331*c8dee2aaSAndroid Build Coastguard Worker int cacheEntriesPerProxy) {
332*c8dee2aaSAndroid Build Coastguard Worker GrProxyProvider* proxyProvider = dContext->priv().proxyProvider();
333*c8dee2aaSAndroid Build Coastguard Worker GrResourceProvider* resourceProvider = dContext->priv().resourceProvider();
334*c8dee2aaSAndroid Build Coastguard Worker GrResourceCache* cache = dContext->priv().getResourceCache();
335*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, 0 == cache->getResourceCount());
336*c8dee2aaSAndroid Build Coastguard Worker
337*c8dee2aaSAndroid Build Coastguard Worker static skgpu::UniqueKey::Domain d = skgpu::UniqueKey::GenerateDomain();
338*c8dee2aaSAndroid Build Coastguard Worker skgpu::UniqueKey key;
339*c8dee2aaSAndroid Build Coastguard Worker skgpu::UniqueKey::Builder builder(&key, d, 1, nullptr);
340*c8dee2aaSAndroid Build Coastguard Worker builder[0] = 0;
341*c8dee2aaSAndroid Build Coastguard Worker builder.finish();
342*c8dee2aaSAndroid Build Coastguard Worker
343*c8dee2aaSAndroid Build Coastguard Worker // Create proxy, assign unique key
344*c8dee2aaSAndroid Build Coastguard Worker sk_sp<GrTextureProxy> proxy = deferred_tex(reporter, dContext, proxyProvider,
345*c8dee2aaSAndroid Build Coastguard Worker SkBackingFit::kExact);
346*c8dee2aaSAndroid Build Coastguard Worker SkAssertResult(proxyProvider->assignUniqueKeyToProxy(key, proxy.get()));
347*c8dee2aaSAndroid Build Coastguard Worker
348*c8dee2aaSAndroid Build Coastguard Worker // Send an invalidation message, which will be sitting in the cache's inbox
349*c8dee2aaSAndroid Build Coastguard Worker SkMessageBus<skgpu::UniqueKeyInvalidatedMessage, uint32_t>::Post(
350*c8dee2aaSAndroid Build Coastguard Worker skgpu::UniqueKeyInvalidatedMessage(key, dContext->priv().contextID()));
351*c8dee2aaSAndroid Build Coastguard Worker
352*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, 1 == proxyProvider->numUniqueKeyProxies_TestOnly());
353*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, 0 == cache->getResourceCount());
354*c8dee2aaSAndroid Build Coastguard Worker
355*c8dee2aaSAndroid Build Coastguard Worker // Instantiate the proxy. This will trigger the message to be processed, so the resulting
356*c8dee2aaSAndroid Build Coastguard Worker // texture should *not* have the unique key on it!
357*c8dee2aaSAndroid Build Coastguard Worker SkAssertResult(proxy->instantiate(resourceProvider));
358*c8dee2aaSAndroid Build Coastguard Worker
359*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, !proxy->getUniqueKey().isValid());
360*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, !proxy->peekTexture()->getUniqueKey().isValid());
361*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, 0 == proxyProvider->numUniqueKeyProxies_TestOnly());
362*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, cacheEntriesPerProxy == cache->getResourceCount());
363*c8dee2aaSAndroid Build Coastguard Worker
364*c8dee2aaSAndroid Build Coastguard Worker proxy = nullptr;
365*c8dee2aaSAndroid Build Coastguard Worker dContext->priv().getResourceCache()->purgeUnlockedResources(
366*c8dee2aaSAndroid Build Coastguard Worker GrPurgeResourceOptions::kAllResources);
367*c8dee2aaSAndroid Build Coastguard Worker
368*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, 0 == proxyProvider->numUniqueKeyProxies_TestOnly());
369*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, 0 == cache->getResourceCount());
370*c8dee2aaSAndroid Build Coastguard Worker }
371*c8dee2aaSAndroid Build Coastguard Worker
DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(TextureProxyTest,reporter,ctxInfo,CtsEnforcement::kApiLevel_T)372*c8dee2aaSAndroid Build Coastguard Worker DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(TextureProxyTest,
373*c8dee2aaSAndroid Build Coastguard Worker reporter,
374*c8dee2aaSAndroid Build Coastguard Worker ctxInfo,
375*c8dee2aaSAndroid Build Coastguard Worker CtsEnforcement::kApiLevel_T) {
376*c8dee2aaSAndroid Build Coastguard Worker auto direct = ctxInfo.directContext();
377*c8dee2aaSAndroid Build Coastguard Worker GrProxyProvider* proxyProvider = direct->priv().proxyProvider();
378*c8dee2aaSAndroid Build Coastguard Worker GrResourceCache* cache = direct->priv().getResourceCache();
379*c8dee2aaSAndroid Build Coastguard Worker
380*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, !proxyProvider->numUniqueKeyProxies_TestOnly());
381*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, 0 == cache->getResourceCount());
382*c8dee2aaSAndroid Build Coastguard Worker
383*c8dee2aaSAndroid Build Coastguard Worker // As we transition to using attachments instead of GrTextures and GrRenderTargets individual
384*c8dee2aaSAndroid Build Coastguard Worker // proxy instansiations may add multiple things to the cache. There would be an entry for the
385*c8dee2aaSAndroid Build Coastguard Worker // GrTexture/GrRenderTarget and entries for one or more attachments.
386*c8dee2aaSAndroid Build Coastguard Worker int cacheEntriesPerProxy = 1;
387*c8dee2aaSAndroid Build Coastguard Worker // We currently only have attachments on the vulkan and metal backends
388*c8dee2aaSAndroid Build Coastguard Worker if (direct->backend() == GrBackend::kVulkan || direct->backend() == GrBackend::kMetal) {
389*c8dee2aaSAndroid Build Coastguard Worker cacheEntriesPerProxy++;
390*c8dee2aaSAndroid Build Coastguard Worker // If we ever have a test with multisamples this would have an additional attachment as
391*c8dee2aaSAndroid Build Coastguard Worker // well.
392*c8dee2aaSAndroid Build Coastguard Worker }
393*c8dee2aaSAndroid Build Coastguard Worker
394*c8dee2aaSAndroid Build Coastguard Worker for (auto fit : { SkBackingFit::kExact, SkBackingFit::kApprox }) {
395*c8dee2aaSAndroid Build Coastguard Worker for (auto create : { deferred_tex, deferred_texRT, wrapped, wrapped_with_key }) {
396*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, 0 == cache->getResourceCount());
397*c8dee2aaSAndroid Build Coastguard Worker basic_test(direct, reporter, create(reporter, direct, proxyProvider, fit),
398*c8dee2aaSAndroid Build Coastguard Worker cacheEntriesPerProxy);
399*c8dee2aaSAndroid Build Coastguard Worker }
400*c8dee2aaSAndroid Build Coastguard Worker
401*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, 0 == cache->getResourceCount());
402*c8dee2aaSAndroid Build Coastguard Worker cache->purgeUnlockedResources(GrPurgeResourceOptions::kAllResources);
403*c8dee2aaSAndroid Build Coastguard Worker }
404*c8dee2aaSAndroid Build Coastguard Worker
405*c8dee2aaSAndroid Build Coastguard Worker basic_test(direct, reporter, create_wrapped_backend(direct), cacheEntriesPerProxy);
406*c8dee2aaSAndroid Build Coastguard Worker
407*c8dee2aaSAndroid Build Coastguard Worker invalidation_test(direct, reporter, cacheEntriesPerProxy);
408*c8dee2aaSAndroid Build Coastguard Worker invalidation_and_instantiation_test(direct, reporter, cacheEntriesPerProxy);
409*c8dee2aaSAndroid Build Coastguard Worker }
410