blob: 5745e4ebd4d4794c26905cdccb44683e1cb2b13b [file] [log] [blame]
Robert Phillipsae7d3f32017-09-21 08:26:08 -04001/*
2 * Copyright 2017 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#if SK_SUPPORT_GPU
13
14#include "GrBackendSurface.h"
15#include "GrContextPriv.h"
16#include "GrResourceCache.h"
Robert Phillips1afd4cd2018-01-08 13:40:32 -050017#include "GrProxyProvider.h"
Robert Phillipsae7d3f32017-09-21 08:26:08 -040018#include "GrResourceProvider.h"
19#include "GrTest.h"
20#include "GrTexture.h"
21#include "GrTextureProxy.h"
22
23#include "SkGr.h"
24#include "SkImage.h"
25
Robert Phillips1afd4cd2018-01-08 13:40:32 -050026int GrProxyProvider::numUniqueKeyProxies_TestOnly() const {
Robert Phillipsae7d3f32017-09-21 08:26:08 -040027 return fUniquelyKeyedProxies.count();
28}
29
30static GrSurfaceDesc make_desc(GrSurfaceFlags flags) {
31 GrSurfaceDesc desc;
32 desc.fFlags = flags;
Robert Phillipsae7d3f32017-09-21 08:26:08 -040033 desc.fWidth = 64;
34 desc.fHeight = 64;
35 desc.fConfig = kRGBA_8888_GrPixelConfig;
Brian Salomonbdecacf2018-02-02 20:32:49 -050036 desc.fSampleCnt = 1;
Robert Phillipsae7d3f32017-09-21 08:26:08 -040037
38 return desc;
39}
40
41///////////////////////////////////////////////////////////////////////////////////////////////////
42// Basic test
43
Greg Danielcd871402017-09-26 12:49:26 -040044static sk_sp<GrTextureProxy> deferred_tex(skiatest::Reporter* reporter,
Robert Phillipsadbe1322018-01-17 13:35:46 -050045 GrProxyProvider* proxyProvider, SkBackingFit fit) {
Robert Phillips0bd24dc2018-01-16 08:06:32 -050046 const GrSurfaceDesc desc = make_desc(kNone_GrSurfaceFlags);
Robert Phillipsae7d3f32017-09-21 08:26:08 -040047
Brian Salomon2a4f9832018-03-03 22:43:43 -050048 sk_sp<GrTextureProxy> proxy =
49 proxyProvider->createProxy(desc, kBottomLeft_GrSurfaceOrigin, fit, SkBudgeted::kYes);
Robert Phillipsae7d3f32017-09-21 08:26:08 -040050 // Only budgeted & wrapped external proxies get to carry uniqueKeys
Greg Danielcd871402017-09-26 12:49:26 -040051 REPORTER_ASSERT(reporter, !proxy->getUniqueKey().isValid());
52 return proxy;
Robert Phillipsae7d3f32017-09-21 08:26:08 -040053}
54
Greg Danielcd871402017-09-26 12:49:26 -040055static sk_sp<GrTextureProxy> deferred_texRT(skiatest::Reporter* reporter,
Robert Phillipsadbe1322018-01-17 13:35:46 -050056 GrProxyProvider* proxyProvider, SkBackingFit fit) {
Robert Phillips0bd24dc2018-01-16 08:06:32 -050057 const GrSurfaceDesc desc = make_desc(kRenderTarget_GrSurfaceFlag);
Robert Phillipsae7d3f32017-09-21 08:26:08 -040058
Brian Salomon2a4f9832018-03-03 22:43:43 -050059 sk_sp<GrTextureProxy> proxy =
60 proxyProvider->createProxy(desc, kBottomLeft_GrSurfaceOrigin, fit, SkBudgeted::kYes);
Robert Phillipsae7d3f32017-09-21 08:26:08 -040061 // Only budgeted & wrapped external proxies get to carry uniqueKeys
Greg Danielcd871402017-09-26 12:49:26 -040062 REPORTER_ASSERT(reporter, !proxy->getUniqueKey().isValid());
63 return proxy;
Robert Phillipsae7d3f32017-09-21 08:26:08 -040064}
65
Greg Danielcd871402017-09-26 12:49:26 -040066static sk_sp<GrTextureProxy> wrapped(skiatest::Reporter* reporter,
Robert Phillipsadbe1322018-01-17 13:35:46 -050067 GrProxyProvider* proxyProvider, SkBackingFit fit) {
Robert Phillips0bd24dc2018-01-16 08:06:32 -050068 const GrSurfaceDesc desc = make_desc(kNone_GrSurfaceFlags);
Robert Phillips1afd4cd2018-01-08 13:40:32 -050069
Brian Salomon2a4f9832018-03-03 22:43:43 -050070 sk_sp<GrTextureProxy> proxy = proxyProvider->createInstantiatedProxy(
71 desc, kBottomLeft_GrSurfaceOrigin, fit, SkBudgeted::kYes);
Robert Phillips0bd24dc2018-01-16 08:06:32 -050072 // Only budgeted & wrapped external proxies get to carry uniqueKeys
Greg Danielcd871402017-09-26 12:49:26 -040073 REPORTER_ASSERT(reporter, !proxy->getUniqueKey().isValid());
74 return proxy;
75}
76
77static sk_sp<GrTextureProxy> wrapped_with_key(skiatest::Reporter* reporter,
Robert Phillipsadbe1322018-01-17 13:35:46 -050078 GrProxyProvider* proxyProvider, SkBackingFit fit) {
Greg Danielcd871402017-09-26 12:49:26 -040079 static GrUniqueKey::Domain d = GrUniqueKey::GenerateDomain();
80 static int kUniqueKeyData = 0;
81
82 GrUniqueKey key;
83
84 GrUniqueKey::Builder builder(&key, d, 1, nullptr);
85 builder[0] = kUniqueKeyData++;
86 builder.finish();
87
Robert Phillips0bd24dc2018-01-16 08:06:32 -050088 const GrSurfaceDesc desc = make_desc(kNone_GrSurfaceFlags);
Greg Danielcd871402017-09-26 12:49:26 -040089
Robert Phillipsadbe1322018-01-17 13:35:46 -050090 // Only budgeted & wrapped external proxies get to carry uniqueKeys
Brian Salomon2a4f9832018-03-03 22:43:43 -050091 sk_sp<GrTextureProxy> proxy = proxyProvider->createInstantiatedProxy(
92 desc, kBottomLeft_GrSurfaceOrigin, fit, SkBudgeted::kYes, 0);
Robert Phillipsadbe1322018-01-17 13:35:46 -050093 SkAssertResult(proxyProvider->assignUniqueKeyToProxy(key, proxy.get()));
Greg Danielcd871402017-09-26 12:49:26 -040094 REPORTER_ASSERT(reporter, proxy->getUniqueKey().isValid());
95 return proxy;
Robert Phillipsae7d3f32017-09-21 08:26:08 -040096}
97
98static sk_sp<GrTextureProxy> create_wrapped_backend(GrContext* context, SkBackingFit fit,
99 sk_sp<GrTexture>* backingSurface) {
Robert Phillips0bd24dc2018-01-16 08:06:32 -0500100 GrProxyProvider* proxyProvider = context->contextPriv().proxyProvider();
Robert Phillips6be756b2018-01-16 15:07:54 -0500101 GrResourceProvider* resourceProvider = context->contextPriv().resourceProvider();
Robert Phillipsae7d3f32017-09-21 08:26:08 -0400102
Robert Phillipsb67821d2017-12-13 15:00:45 -0500103 const GrSurfaceDesc desc = make_desc(kNone_GrSurfaceFlags);
Robert Phillipsae7d3f32017-09-21 08:26:08 -0400104
Robert Phillips0bd24dc2018-01-16 08:06:32 -0500105 *backingSurface = resourceProvider->createTexture(desc, SkBudgeted::kNo);
Robert Phillipsae7d3f32017-09-21 08:26:08 -0400106 if (!(*backingSurface)) {
107 return nullptr;
108 }
109
Robert Phillipsb67821d2017-12-13 15:00:45 -0500110 GrBackendTexture backendTex = (*backingSurface)->getBackendTexture();
Robert Phillipsae7d3f32017-09-21 08:26:08 -0400111
Brian Salomon7578f3e2018-03-07 14:39:54 -0500112 return proxyProvider->wrapBackendTexture(backendTex, kBottomLeft_GrSurfaceOrigin);
Robert Phillipsae7d3f32017-09-21 08:26:08 -0400113}
114
115
116// This tests the basic capabilities of the uniquely keyed texture proxies. Does assigning
117// and looking them up work, etc.
118static void basic_test(GrContext* context,
119 skiatest::Reporter* reporter,
120 sk_sp<GrTextureProxy> proxy, bool proxyIsCached) {
121 static int id = 1;
122
Robert Phillips6be756b2018-01-16 15:07:54 -0500123 GrResourceProvider* resourceProvider = context->contextPriv().resourceProvider();
Robert Phillips1afd4cd2018-01-08 13:40:32 -0500124 GrProxyProvider* proxyProvider = context->contextPriv().proxyProvider();
Robert Phillips6be756b2018-01-16 15:07:54 -0500125 GrResourceCache* cache = context->contextPriv().getResourceCache();
Robert Phillipsae7d3f32017-09-21 08:26:08 -0400126
127 int startCacheCount = cache->getResourceCount();
128
Robert Phillipsae7d3f32017-09-21 08:26:08 -0400129 GrUniqueKey key;
Greg Danielcd871402017-09-26 12:49:26 -0400130 if (proxy->getUniqueKey().isValid()) {
131 key = proxy->getUniqueKey();
132 } else {
133 GrMakeKeyFromImageID(&key, id, SkIRect::MakeWH(64, 64));
134 ++id;
Robert Phillipsae7d3f32017-09-21 08:26:08 -0400135
Greg Danielcd871402017-09-26 12:49:26 -0400136 // Assigning the uniqueKey adds the proxy to the hash but doesn't force instantiation
Robert Phillips1afd4cd2018-01-08 13:40:32 -0500137 REPORTER_ASSERT(reporter, !proxyProvider->numUniqueKeyProxies_TestOnly());
Robert Phillipsadbe1322018-01-17 13:35:46 -0500138 SkAssertResult(proxyProvider->assignUniqueKeyToProxy(key, proxy.get()));
Greg Danielcd871402017-09-26 12:49:26 -0400139 }
140
Robert Phillips1afd4cd2018-01-08 13:40:32 -0500141 REPORTER_ASSERT(reporter, 1 == proxyProvider->numUniqueKeyProxies_TestOnly());
Robert Phillipsae7d3f32017-09-21 08:26:08 -0400142 REPORTER_ASSERT(reporter, startCacheCount == cache->getResourceCount());
143
144 // setUniqueKey had better stick
145 REPORTER_ASSERT(reporter, key == proxy->getUniqueKey());
146
147 // We just added it, surely we can find it
Robert Phillips1afd4cd2018-01-08 13:40:32 -0500148 REPORTER_ASSERT(reporter, proxyProvider->findOrCreateProxyByUniqueKey(
149 key, kBottomLeft_GrSurfaceOrigin));
150 REPORTER_ASSERT(reporter, 1 == proxyProvider->numUniqueKeyProxies_TestOnly());
Robert Phillipsae7d3f32017-09-21 08:26:08 -0400151
152 // Once instantiated, the backing resource should have the same key
Robert Phillips1afd4cd2018-01-08 13:40:32 -0500153 SkAssertResult(proxy->instantiate(resourceProvider));
Robert Phillipsae7d3f32017-09-21 08:26:08 -0400154 const GrUniqueKey& texKey = proxy->priv().peekSurface()->getUniqueKey();
155 REPORTER_ASSERT(reporter, texKey.isValid());
156 REPORTER_ASSERT(reporter, key == texKey);
157 if (proxyIsCached) {
158 REPORTER_ASSERT(reporter, 1 == cache->getResourceCount());
159 }
160
161 // deleting the proxy should delete it from the hash but not the cache
162 proxy = nullptr;
Robert Phillips1afd4cd2018-01-08 13:40:32 -0500163 REPORTER_ASSERT(reporter, 0 == proxyProvider->numUniqueKeyProxies_TestOnly());
Robert Phillipsae7d3f32017-09-21 08:26:08 -0400164 REPORTER_ASSERT(reporter, 1 == cache->getResourceCount());
165
166 // If the proxy was cached refinding it should bring it back to life
Robert Phillips1afd4cd2018-01-08 13:40:32 -0500167 proxy = proxyProvider->findOrCreateProxyByUniqueKey(key, kBottomLeft_GrSurfaceOrigin);
Robert Phillipsae7d3f32017-09-21 08:26:08 -0400168 if (proxyIsCached) {
169 REPORTER_ASSERT(reporter, proxy);
Robert Phillips1afd4cd2018-01-08 13:40:32 -0500170 REPORTER_ASSERT(reporter, 1 == proxyProvider->numUniqueKeyProxies_TestOnly());
Robert Phillipsae7d3f32017-09-21 08:26:08 -0400171 } else {
172 REPORTER_ASSERT(reporter, !proxy);
Robert Phillips1afd4cd2018-01-08 13:40:32 -0500173 REPORTER_ASSERT(reporter, 0 == proxyProvider->numUniqueKeyProxies_TestOnly());
Robert Phillipsae7d3f32017-09-21 08:26:08 -0400174 }
175 REPORTER_ASSERT(reporter, 1 == cache->getResourceCount());
176
177 // Mega-purging it should remove it from both the hash and the cache
178 proxy = nullptr;
179 cache->purgeAllUnlocked();
180 if (proxyIsCached) {
181 REPORTER_ASSERT(reporter, 0 == cache->getResourceCount());
182 } else {
183 REPORTER_ASSERT(reporter, 1 == cache->getResourceCount());
184 }
185
186 // We can bring neither the texture nor proxy back from perma-death
Robert Phillips1afd4cd2018-01-08 13:40:32 -0500187 proxy = proxyProvider->findOrCreateProxyByUniqueKey(key, kBottomLeft_GrSurfaceOrigin);
Robert Phillipsae7d3f32017-09-21 08:26:08 -0400188 REPORTER_ASSERT(reporter, !proxy);
189 if (proxyIsCached) {
190 REPORTER_ASSERT(reporter, 0 == cache->getResourceCount());
191 } else {
192 REPORTER_ASSERT(reporter, 1 == cache->getResourceCount());
193 }
194}
195
196///////////////////////////////////////////////////////////////////////////////////////////////////
197// Invalidation test
198
199// Test if invalidating unique ids operates as expected for texture proxies.
200static void invalidation_test(GrContext* context, skiatest::Reporter* reporter) {
201
Robert Phillips1afd4cd2018-01-08 13:40:32 -0500202 GrProxyProvider* proxyProvider = context->contextPriv().proxyProvider();
Robert Phillips6be756b2018-01-16 15:07:54 -0500203 GrResourceCache* cache = context->contextPriv().getResourceCache();
Robert Phillipsae7d3f32017-09-21 08:26:08 -0400204 REPORTER_ASSERT(reporter, 0 == cache->getResourceCount());
205
206 sk_sp<SkImage> rasterImg;
207
208 {
209 SkImageInfo ii = SkImageInfo::Make(64, 64, kRGBA_8888_SkColorType, kOpaque_SkAlphaType);
210
211 SkBitmap bm;
212 bm.allocPixels(ii);
213
214 rasterImg = SkImage::MakeFromBitmap(bm);
Robert Phillips1afd4cd2018-01-08 13:40:32 -0500215 REPORTER_ASSERT(reporter, 0 == proxyProvider->numUniqueKeyProxies_TestOnly());
Robert Phillipsae7d3f32017-09-21 08:26:08 -0400216 REPORTER_ASSERT(reporter, 0 == cache->getResourceCount());
217 }
218
219 sk_sp<SkImage> textureImg = rasterImg->makeTextureImage(context, nullptr);
Robert Phillips1afd4cd2018-01-08 13:40:32 -0500220 REPORTER_ASSERT(reporter, 1 == proxyProvider->numUniqueKeyProxies_TestOnly());
Robert Phillipsae7d3f32017-09-21 08:26:08 -0400221 REPORTER_ASSERT(reporter, 1 == cache->getResourceCount());
222
223 rasterImg = nullptr; // this invalidates the uniqueKey
224
225 // this forces the cache to respond to the inval msg
226 int maxNum;
227 size_t maxBytes;
228 context->getResourceCacheLimits(&maxNum, &maxBytes);
229 context->setResourceCacheLimits(maxNum-1, maxBytes);
230
Robert Phillips1afd4cd2018-01-08 13:40:32 -0500231 REPORTER_ASSERT(reporter, 0 == proxyProvider->numUniqueKeyProxies_TestOnly());
Robert Phillipsae7d3f32017-09-21 08:26:08 -0400232 REPORTER_ASSERT(reporter, 1 == cache->getResourceCount());
233
234 textureImg = nullptr;
Robert Phillips0c4b7b12018-03-06 08:20:37 -0500235 context->contextPriv().purgeAllUnlockedResources_ForTesting();
Robert Phillipsae7d3f32017-09-21 08:26:08 -0400236
Robert Phillips1afd4cd2018-01-08 13:40:32 -0500237 REPORTER_ASSERT(reporter, 0 == proxyProvider->numUniqueKeyProxies_TestOnly());
Robert Phillipsae7d3f32017-09-21 08:26:08 -0400238 REPORTER_ASSERT(reporter, 0 == cache->getResourceCount());
239}
240
Brian Osman28c434b2017-09-27 13:11:16 -0400241// Test if invalidating unique ids prior to instantiating operates as expected
242static void invalidation_and_instantiation_test(GrContext* context, skiatest::Reporter* reporter) {
Robert Phillips1afd4cd2018-01-08 13:40:32 -0500243 GrProxyProvider* proxyProvider = context->contextPriv().proxyProvider();
Robert Phillips6be756b2018-01-16 15:07:54 -0500244 GrResourceProvider* resourceProvider = context->contextPriv().resourceProvider();
245 GrResourceCache* cache = context->contextPriv().getResourceCache();
Brian Osman28c434b2017-09-27 13:11:16 -0400246 REPORTER_ASSERT(reporter, 0 == cache->getResourceCount());
247
248 static GrUniqueKey::Domain d = GrUniqueKey::GenerateDomain();
249 GrUniqueKey key;
250 GrUniqueKey::Builder builder(&key, d, 1, nullptr);
251 builder[0] = 0;
252 builder.finish();
253
254 // Create proxy, assign unique key
Robert Phillipsadbe1322018-01-17 13:35:46 -0500255 sk_sp<GrTextureProxy> proxy = deferred_tex(reporter, proxyProvider, SkBackingFit::kExact);
256 SkAssertResult(proxyProvider->assignUniqueKeyToProxy(key, proxy.get()));
Brian Osman28c434b2017-09-27 13:11:16 -0400257
258 // Send an invalidation message, which will be sitting in the cache's inbox
259 SkMessageBus<GrUniqueKeyInvalidatedMessage>::Post(GrUniqueKeyInvalidatedMessage(key));
260
Robert Phillips1afd4cd2018-01-08 13:40:32 -0500261 REPORTER_ASSERT(reporter, 1 == proxyProvider->numUniqueKeyProxies_TestOnly());
Brian Osman28c434b2017-09-27 13:11:16 -0400262 REPORTER_ASSERT(reporter, 0 == cache->getResourceCount());
263
264 // Instantiate the proxy. This will trigger the message to be processed, so the resulting
265 // texture should *not* have the unique key on it!
Robert Phillips1afd4cd2018-01-08 13:40:32 -0500266 SkAssertResult(proxy->instantiate(resourceProvider));
Brian Osman28c434b2017-09-27 13:11:16 -0400267
268 REPORTER_ASSERT(reporter, !proxy->getUniqueKey().isValid());
269 REPORTER_ASSERT(reporter, !proxy->priv().peekTexture()->getUniqueKey().isValid());
Robert Phillips1afd4cd2018-01-08 13:40:32 -0500270 REPORTER_ASSERT(reporter, 0 == proxyProvider->numUniqueKeyProxies_TestOnly());
Brian Osman28c434b2017-09-27 13:11:16 -0400271 REPORTER_ASSERT(reporter, 1 == cache->getResourceCount());
272
273 proxy = nullptr;
Robert Phillips0c4b7b12018-03-06 08:20:37 -0500274 context->contextPriv().purgeAllUnlockedResources_ForTesting();
Brian Osman28c434b2017-09-27 13:11:16 -0400275
Robert Phillips1afd4cd2018-01-08 13:40:32 -0500276 REPORTER_ASSERT(reporter, 0 == proxyProvider->numUniqueKeyProxies_TestOnly());
Brian Osman28c434b2017-09-27 13:11:16 -0400277 REPORTER_ASSERT(reporter, 0 == cache->getResourceCount());
278}
279
Robert Phillipsae7d3f32017-09-21 08:26:08 -0400280DEF_GPUTEST_FOR_RENDERING_CONTEXTS(TextureProxyTest, reporter, ctxInfo) {
281 GrContext* context = ctxInfo.grContext();
Robert Phillips1afd4cd2018-01-08 13:40:32 -0500282 GrProxyProvider* proxyProvider = context->contextPriv().proxyProvider();
Robert Phillips6be756b2018-01-16 15:07:54 -0500283 GrResourceCache* cache = context->contextPriv().getResourceCache();
Robert Phillipsae7d3f32017-09-21 08:26:08 -0400284
Robert Phillips1afd4cd2018-01-08 13:40:32 -0500285 REPORTER_ASSERT(reporter, !proxyProvider->numUniqueKeyProxies_TestOnly());
Robert Phillipsae7d3f32017-09-21 08:26:08 -0400286 REPORTER_ASSERT(reporter, 0 == cache->getResourceCount());
287
288 for (auto fit : { SkBackingFit::kExact, SkBackingFit::kApprox }) {
Greg Danielcd871402017-09-26 12:49:26 -0400289 for (auto create : { deferred_tex, deferred_texRT, wrapped, wrapped_with_key }) {
Robert Phillipsae7d3f32017-09-21 08:26:08 -0400290 REPORTER_ASSERT(reporter, 0 == cache->getResourceCount());
Robert Phillipsadbe1322018-01-17 13:35:46 -0500291 basic_test(context, reporter, create(reporter, proxyProvider, fit), true);
Robert Phillipsae7d3f32017-09-21 08:26:08 -0400292 }
293
294 REPORTER_ASSERT(reporter, 0 == cache->getResourceCount());
295 sk_sp<GrTexture> backingTex;
296 sk_sp<GrTextureProxy> proxy = create_wrapped_backend(context, fit, &backingTex);
297 basic_test(context, reporter, std::move(proxy), false);
298
299 backingTex = nullptr;
300 cache->purgeAllUnlocked();
301 }
302
303 invalidation_test(context, reporter);
Robert Phillipsfa8c0802017-10-04 08:42:28 -0400304 invalidation_and_instantiation_test(context, reporter);
Robert Phillipsae7d3f32017-09-21 08:26:08 -0400305}
306
307#endif