blob: 0225f14cbc2d3b68f162b795e51e427b9d4fc909 [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
Robert Phillipsae7d3f32017-09-21 08:26:08 -040012#include "GrBackendSurface.h"
13#include "GrContextPriv.h"
14#include "GrResourceCache.h"
Robert Phillips1afd4cd2018-01-08 13:40:32 -050015#include "GrProxyProvider.h"
Robert Phillipsae7d3f32017-09-21 08:26:08 -040016#include "GrResourceProvider.h"
17#include "GrTest.h"
18#include "GrTexture.h"
19#include "GrTextureProxy.h"
20
21#include "SkGr.h"
22#include "SkImage.h"
23
Robert Phillips1afd4cd2018-01-08 13:40:32 -050024int GrProxyProvider::numUniqueKeyProxies_TestOnly() const {
Robert Phillipsae7d3f32017-09-21 08:26:08 -040025 return fUniquelyKeyedProxies.count();
26}
27
Robert Phillipsfe0253f2018-03-16 16:47:25 -040028static GrSurfaceDesc make_desc(GrSurfaceDescFlags descFlags) {
Robert Phillipsae7d3f32017-09-21 08:26:08 -040029 GrSurfaceDesc desc;
Robert Phillipsfe0253f2018-03-16 16:47:25 -040030 desc.fFlags = descFlags;
Robert Phillipsae7d3f32017-09-21 08:26:08 -040031 desc.fWidth = 64;
32 desc.fHeight = 64;
33 desc.fConfig = kRGBA_8888_GrPixelConfig;
Brian Salomonbdecacf2018-02-02 20:32:49 -050034 desc.fSampleCnt = 1;
Robert Phillipsae7d3f32017-09-21 08:26:08 -040035
36 return desc;
37}
38
39///////////////////////////////////////////////////////////////////////////////////////////////////
40// Basic test
41
Greg Danielcd871402017-09-26 12:49:26 -040042static sk_sp<GrTextureProxy> deferred_tex(skiatest::Reporter* reporter,
Robert Phillipsadbe1322018-01-17 13:35:46 -050043 GrProxyProvider* proxyProvider, SkBackingFit fit) {
Robert Phillips0bd24dc2018-01-16 08:06:32 -050044 const GrSurfaceDesc desc = make_desc(kNone_GrSurfaceFlags);
Robert Phillipsae7d3f32017-09-21 08:26:08 -040045
Brian Salomon2a4f9832018-03-03 22:43:43 -050046 sk_sp<GrTextureProxy> proxy =
47 proxyProvider->createProxy(desc, kBottomLeft_GrSurfaceOrigin, fit, SkBudgeted::kYes);
Robert Phillipsae7d3f32017-09-21 08:26:08 -040048 // Only budgeted & wrapped external proxies get to carry uniqueKeys
Greg Danielcd871402017-09-26 12:49:26 -040049 REPORTER_ASSERT(reporter, !proxy->getUniqueKey().isValid());
50 return proxy;
Robert Phillipsae7d3f32017-09-21 08:26:08 -040051}
52
Greg Danielcd871402017-09-26 12:49:26 -040053static sk_sp<GrTextureProxy> deferred_texRT(skiatest::Reporter* reporter,
Robert Phillipsadbe1322018-01-17 13:35:46 -050054 GrProxyProvider* proxyProvider, SkBackingFit fit) {
Robert Phillips0bd24dc2018-01-16 08:06:32 -050055 const GrSurfaceDesc desc = make_desc(kRenderTarget_GrSurfaceFlag);
Robert Phillipsae7d3f32017-09-21 08:26:08 -040056
Brian Salomon2a4f9832018-03-03 22:43:43 -050057 sk_sp<GrTextureProxy> proxy =
58 proxyProvider->createProxy(desc, kBottomLeft_GrSurfaceOrigin, fit, SkBudgeted::kYes);
Robert Phillipsae7d3f32017-09-21 08:26:08 -040059 // Only budgeted & wrapped external proxies get to carry uniqueKeys
Greg Danielcd871402017-09-26 12:49:26 -040060 REPORTER_ASSERT(reporter, !proxy->getUniqueKey().isValid());
61 return proxy;
Robert Phillipsae7d3f32017-09-21 08:26:08 -040062}
63
Greg Danielcd871402017-09-26 12:49:26 -040064static sk_sp<GrTextureProxy> wrapped(skiatest::Reporter* reporter,
Robert Phillipsadbe1322018-01-17 13:35:46 -050065 GrProxyProvider* proxyProvider, SkBackingFit fit) {
Robert Phillips0bd24dc2018-01-16 08:06:32 -050066 const GrSurfaceDesc desc = make_desc(kNone_GrSurfaceFlags);
Robert Phillips1afd4cd2018-01-08 13:40:32 -050067
Brian Salomon2a4f9832018-03-03 22:43:43 -050068 sk_sp<GrTextureProxy> proxy = proxyProvider->createInstantiatedProxy(
69 desc, kBottomLeft_GrSurfaceOrigin, fit, SkBudgeted::kYes);
Robert Phillips0bd24dc2018-01-16 08:06:32 -050070 // Only budgeted & wrapped external proxies get to carry uniqueKeys
Greg Danielcd871402017-09-26 12:49:26 -040071 REPORTER_ASSERT(reporter, !proxy->getUniqueKey().isValid());
72 return proxy;
73}
74
75static sk_sp<GrTextureProxy> wrapped_with_key(skiatest::Reporter* reporter,
Robert Phillipsadbe1322018-01-17 13:35:46 -050076 GrProxyProvider* proxyProvider, SkBackingFit fit) {
Greg Danielcd871402017-09-26 12:49:26 -040077 static GrUniqueKey::Domain d = GrUniqueKey::GenerateDomain();
78 static int kUniqueKeyData = 0;
79
80 GrUniqueKey key;
81
82 GrUniqueKey::Builder builder(&key, d, 1, nullptr);
83 builder[0] = kUniqueKeyData++;
84 builder.finish();
85
Robert Phillips0bd24dc2018-01-16 08:06:32 -050086 const GrSurfaceDesc desc = make_desc(kNone_GrSurfaceFlags);
Greg Danielcd871402017-09-26 12:49:26 -040087
Robert Phillipsadbe1322018-01-17 13:35:46 -050088 // Only budgeted & wrapped external proxies get to carry uniqueKeys
Brian Salomon2a4f9832018-03-03 22:43:43 -050089 sk_sp<GrTextureProxy> proxy = proxyProvider->createInstantiatedProxy(
Robert Phillipsfe0253f2018-03-16 16:47:25 -040090 desc, kBottomLeft_GrSurfaceOrigin, fit, SkBudgeted::kYes);
Robert Phillipsadbe1322018-01-17 13:35:46 -050091 SkAssertResult(proxyProvider->assignUniqueKeyToProxy(key, proxy.get()));
Greg Danielcd871402017-09-26 12:49:26 -040092 REPORTER_ASSERT(reporter, proxy->getUniqueKey().isValid());
93 return proxy;
Robert Phillipsae7d3f32017-09-21 08:26:08 -040094}
95
96static sk_sp<GrTextureProxy> create_wrapped_backend(GrContext* context, SkBackingFit fit,
97 sk_sp<GrTexture>* backingSurface) {
Robert Phillips0bd24dc2018-01-16 08:06:32 -050098 GrProxyProvider* proxyProvider = context->contextPriv().proxyProvider();
Robert Phillips6be756b2018-01-16 15:07:54 -050099 GrResourceProvider* resourceProvider = context->contextPriv().resourceProvider();
Robert Phillipsae7d3f32017-09-21 08:26:08 -0400100
Robert Phillipsb67821d2017-12-13 15:00:45 -0500101 const GrSurfaceDesc desc = make_desc(kNone_GrSurfaceFlags);
Robert Phillipsae7d3f32017-09-21 08:26:08 -0400102
Robert Phillips0bd24dc2018-01-16 08:06:32 -0500103 *backingSurface = resourceProvider->createTexture(desc, SkBudgeted::kNo);
Robert Phillipsae7d3f32017-09-21 08:26:08 -0400104 if (!(*backingSurface)) {
105 return nullptr;
106 }
107
Robert Phillipsb67821d2017-12-13 15:00:45 -0500108 GrBackendTexture backendTex = (*backingSurface)->getBackendTexture();
Robert Phillipsae7d3f32017-09-21 08:26:08 -0400109
Brian Salomon7578f3e2018-03-07 14:39:54 -0500110 return proxyProvider->wrapBackendTexture(backendTex, kBottomLeft_GrSurfaceOrigin);
Robert Phillipsae7d3f32017-09-21 08:26:08 -0400111}
112
113
114// This tests the basic capabilities of the uniquely keyed texture proxies. Does assigning
115// and looking them up work, etc.
116static void basic_test(GrContext* context,
117 skiatest::Reporter* reporter,
118 sk_sp<GrTextureProxy> proxy, bool proxyIsCached) {
119 static int id = 1;
120
Robert Phillips6be756b2018-01-16 15:07:54 -0500121 GrResourceProvider* resourceProvider = context->contextPriv().resourceProvider();
Robert Phillips1afd4cd2018-01-08 13:40:32 -0500122 GrProxyProvider* proxyProvider = context->contextPriv().proxyProvider();
Robert Phillips6be756b2018-01-16 15:07:54 -0500123 GrResourceCache* cache = context->contextPriv().getResourceCache();
Robert Phillipsae7d3f32017-09-21 08:26:08 -0400124
125 int startCacheCount = cache->getResourceCount();
126
Robert Phillipsae7d3f32017-09-21 08:26:08 -0400127 GrUniqueKey key;
Greg Danielcd871402017-09-26 12:49:26 -0400128 if (proxy->getUniqueKey().isValid()) {
129 key = proxy->getUniqueKey();
130 } else {
131 GrMakeKeyFromImageID(&key, id, SkIRect::MakeWH(64, 64));
132 ++id;
Robert Phillipsae7d3f32017-09-21 08:26:08 -0400133
Greg Danielcd871402017-09-26 12:49:26 -0400134 // Assigning the uniqueKey adds the proxy to the hash but doesn't force instantiation
Robert Phillips1afd4cd2018-01-08 13:40:32 -0500135 REPORTER_ASSERT(reporter, !proxyProvider->numUniqueKeyProxies_TestOnly());
Robert Phillipsadbe1322018-01-17 13:35:46 -0500136 SkAssertResult(proxyProvider->assignUniqueKeyToProxy(key, proxy.get()));
Greg Danielcd871402017-09-26 12:49:26 -0400137 }
138
Robert Phillips1afd4cd2018-01-08 13:40:32 -0500139 REPORTER_ASSERT(reporter, 1 == proxyProvider->numUniqueKeyProxies_TestOnly());
Robert Phillipsae7d3f32017-09-21 08:26:08 -0400140 REPORTER_ASSERT(reporter, startCacheCount == cache->getResourceCount());
141
142 // setUniqueKey had better stick
143 REPORTER_ASSERT(reporter, key == proxy->getUniqueKey());
144
145 // We just added it, surely we can find it
Robert Phillips1afd4cd2018-01-08 13:40:32 -0500146 REPORTER_ASSERT(reporter, proxyProvider->findOrCreateProxyByUniqueKey(
147 key, kBottomLeft_GrSurfaceOrigin));
148 REPORTER_ASSERT(reporter, 1 == proxyProvider->numUniqueKeyProxies_TestOnly());
Robert Phillipsae7d3f32017-09-21 08:26:08 -0400149
150 // Once instantiated, the backing resource should have the same key
Robert Phillips1afd4cd2018-01-08 13:40:32 -0500151 SkAssertResult(proxy->instantiate(resourceProvider));
Robert Phillipsae7d3f32017-09-21 08:26:08 -0400152 const GrUniqueKey& texKey = proxy->priv().peekSurface()->getUniqueKey();
153 REPORTER_ASSERT(reporter, texKey.isValid());
154 REPORTER_ASSERT(reporter, key == texKey);
155 if (proxyIsCached) {
156 REPORTER_ASSERT(reporter, 1 == cache->getResourceCount());
157 }
158
159 // deleting the proxy should delete it from the hash but not the cache
160 proxy = nullptr;
Robert Phillips1afd4cd2018-01-08 13:40:32 -0500161 REPORTER_ASSERT(reporter, 0 == proxyProvider->numUniqueKeyProxies_TestOnly());
Robert Phillipsae7d3f32017-09-21 08:26:08 -0400162 REPORTER_ASSERT(reporter, 1 == cache->getResourceCount());
163
164 // If the proxy was cached refinding it should bring it back to life
Robert Phillips1afd4cd2018-01-08 13:40:32 -0500165 proxy = proxyProvider->findOrCreateProxyByUniqueKey(key, kBottomLeft_GrSurfaceOrigin);
Robert Phillipsae7d3f32017-09-21 08:26:08 -0400166 if (proxyIsCached) {
167 REPORTER_ASSERT(reporter, proxy);
Robert Phillips1afd4cd2018-01-08 13:40:32 -0500168 REPORTER_ASSERT(reporter, 1 == proxyProvider->numUniqueKeyProxies_TestOnly());
Robert Phillipsae7d3f32017-09-21 08:26:08 -0400169 } else {
170 REPORTER_ASSERT(reporter, !proxy);
Robert Phillips1afd4cd2018-01-08 13:40:32 -0500171 REPORTER_ASSERT(reporter, 0 == proxyProvider->numUniqueKeyProxies_TestOnly());
Robert Phillipsae7d3f32017-09-21 08:26:08 -0400172 }
173 REPORTER_ASSERT(reporter, 1 == cache->getResourceCount());
174
175 // Mega-purging it should remove it from both the hash and the cache
176 proxy = nullptr;
177 cache->purgeAllUnlocked();
178 if (proxyIsCached) {
179 REPORTER_ASSERT(reporter, 0 == cache->getResourceCount());
180 } else {
181 REPORTER_ASSERT(reporter, 1 == cache->getResourceCount());
182 }
183
184 // We can bring neither the texture nor proxy back from perma-death
Robert Phillips1afd4cd2018-01-08 13:40:32 -0500185 proxy = proxyProvider->findOrCreateProxyByUniqueKey(key, kBottomLeft_GrSurfaceOrigin);
Robert Phillipsae7d3f32017-09-21 08:26:08 -0400186 REPORTER_ASSERT(reporter, !proxy);
187 if (proxyIsCached) {
188 REPORTER_ASSERT(reporter, 0 == cache->getResourceCount());
189 } else {
190 REPORTER_ASSERT(reporter, 1 == cache->getResourceCount());
191 }
192}
193
194///////////////////////////////////////////////////////////////////////////////////////////////////
195// Invalidation test
196
197// Test if invalidating unique ids operates as expected for texture proxies.
198static void invalidation_test(GrContext* context, skiatest::Reporter* reporter) {
199
Robert Phillips1afd4cd2018-01-08 13:40:32 -0500200 GrProxyProvider* proxyProvider = context->contextPriv().proxyProvider();
Robert Phillips6be756b2018-01-16 15:07:54 -0500201 GrResourceCache* cache = context->contextPriv().getResourceCache();
Robert Phillipsae7d3f32017-09-21 08:26:08 -0400202 REPORTER_ASSERT(reporter, 0 == cache->getResourceCount());
203
204 sk_sp<SkImage> rasterImg;
205
206 {
207 SkImageInfo ii = SkImageInfo::Make(64, 64, kRGBA_8888_SkColorType, kOpaque_SkAlphaType);
208
209 SkBitmap bm;
210 bm.allocPixels(ii);
211
212 rasterImg = SkImage::MakeFromBitmap(bm);
Robert Phillips1afd4cd2018-01-08 13:40:32 -0500213 REPORTER_ASSERT(reporter, 0 == proxyProvider->numUniqueKeyProxies_TestOnly());
Robert Phillipsae7d3f32017-09-21 08:26:08 -0400214 REPORTER_ASSERT(reporter, 0 == cache->getResourceCount());
215 }
216
217 sk_sp<SkImage> textureImg = rasterImg->makeTextureImage(context, nullptr);
Robert Phillips1afd4cd2018-01-08 13:40:32 -0500218 REPORTER_ASSERT(reporter, 1 == proxyProvider->numUniqueKeyProxies_TestOnly());
Robert Phillipsae7d3f32017-09-21 08:26:08 -0400219 REPORTER_ASSERT(reporter, 1 == cache->getResourceCount());
220
221 rasterImg = nullptr; // this invalidates the uniqueKey
222
223 // this forces the cache to respond to the inval msg
224 int maxNum;
225 size_t maxBytes;
226 context->getResourceCacheLimits(&maxNum, &maxBytes);
227 context->setResourceCacheLimits(maxNum-1, maxBytes);
228
Robert Phillips1afd4cd2018-01-08 13:40:32 -0500229 REPORTER_ASSERT(reporter, 0 == proxyProvider->numUniqueKeyProxies_TestOnly());
Robert Phillipsae7d3f32017-09-21 08:26:08 -0400230 REPORTER_ASSERT(reporter, 1 == cache->getResourceCount());
231
232 textureImg = nullptr;
Robert Phillips0c4b7b12018-03-06 08:20:37 -0500233 context->contextPriv().purgeAllUnlockedResources_ForTesting();
Robert Phillipsae7d3f32017-09-21 08:26:08 -0400234
Robert Phillips1afd4cd2018-01-08 13:40:32 -0500235 REPORTER_ASSERT(reporter, 0 == proxyProvider->numUniqueKeyProxies_TestOnly());
Robert Phillipsae7d3f32017-09-21 08:26:08 -0400236 REPORTER_ASSERT(reporter, 0 == cache->getResourceCount());
237}
238
Brian Osman28c434b2017-09-27 13:11:16 -0400239// Test if invalidating unique ids prior to instantiating operates as expected
240static void invalidation_and_instantiation_test(GrContext* context, skiatest::Reporter* reporter) {
Robert Phillips1afd4cd2018-01-08 13:40:32 -0500241 GrProxyProvider* proxyProvider = context->contextPriv().proxyProvider();
Robert Phillips6be756b2018-01-16 15:07:54 -0500242 GrResourceProvider* resourceProvider = context->contextPriv().resourceProvider();
243 GrResourceCache* cache = context->contextPriv().getResourceCache();
Brian Osman28c434b2017-09-27 13:11:16 -0400244 REPORTER_ASSERT(reporter, 0 == cache->getResourceCount());
245
246 static GrUniqueKey::Domain d = GrUniqueKey::GenerateDomain();
247 GrUniqueKey key;
248 GrUniqueKey::Builder builder(&key, d, 1, nullptr);
249 builder[0] = 0;
250 builder.finish();
251
252 // Create proxy, assign unique key
Robert Phillipsadbe1322018-01-17 13:35:46 -0500253 sk_sp<GrTextureProxy> proxy = deferred_tex(reporter, proxyProvider, SkBackingFit::kExact);
254 SkAssertResult(proxyProvider->assignUniqueKeyToProxy(key, proxy.get()));
Brian Osman28c434b2017-09-27 13:11:16 -0400255
256 // Send an invalidation message, which will be sitting in the cache's inbox
257 SkMessageBus<GrUniqueKeyInvalidatedMessage>::Post(GrUniqueKeyInvalidatedMessage(key));
258
Robert Phillips1afd4cd2018-01-08 13:40:32 -0500259 REPORTER_ASSERT(reporter, 1 == proxyProvider->numUniqueKeyProxies_TestOnly());
Brian Osman28c434b2017-09-27 13:11:16 -0400260 REPORTER_ASSERT(reporter, 0 == cache->getResourceCount());
261
262 // Instantiate the proxy. This will trigger the message to be processed, so the resulting
263 // texture should *not* have the unique key on it!
Robert Phillips1afd4cd2018-01-08 13:40:32 -0500264 SkAssertResult(proxy->instantiate(resourceProvider));
Brian Osman28c434b2017-09-27 13:11:16 -0400265
266 REPORTER_ASSERT(reporter, !proxy->getUniqueKey().isValid());
267 REPORTER_ASSERT(reporter, !proxy->priv().peekTexture()->getUniqueKey().isValid());
Robert Phillips1afd4cd2018-01-08 13:40:32 -0500268 REPORTER_ASSERT(reporter, 0 == proxyProvider->numUniqueKeyProxies_TestOnly());
Brian Osman28c434b2017-09-27 13:11:16 -0400269 REPORTER_ASSERT(reporter, 1 == cache->getResourceCount());
270
271 proxy = nullptr;
Robert Phillips0c4b7b12018-03-06 08:20:37 -0500272 context->contextPriv().purgeAllUnlockedResources_ForTesting();
Brian Osman28c434b2017-09-27 13:11:16 -0400273
Robert Phillips1afd4cd2018-01-08 13:40:32 -0500274 REPORTER_ASSERT(reporter, 0 == proxyProvider->numUniqueKeyProxies_TestOnly());
Brian Osman28c434b2017-09-27 13:11:16 -0400275 REPORTER_ASSERT(reporter, 0 == cache->getResourceCount());
276}
277
Robert Phillipsae7d3f32017-09-21 08:26:08 -0400278DEF_GPUTEST_FOR_RENDERING_CONTEXTS(TextureProxyTest, reporter, ctxInfo) {
279 GrContext* context = ctxInfo.grContext();
Robert Phillips1afd4cd2018-01-08 13:40:32 -0500280 GrProxyProvider* proxyProvider = context->contextPriv().proxyProvider();
Robert Phillips6be756b2018-01-16 15:07:54 -0500281 GrResourceCache* cache = context->contextPriv().getResourceCache();
Robert Phillipsae7d3f32017-09-21 08:26:08 -0400282
Robert Phillips1afd4cd2018-01-08 13:40:32 -0500283 REPORTER_ASSERT(reporter, !proxyProvider->numUniqueKeyProxies_TestOnly());
Robert Phillipsae7d3f32017-09-21 08:26:08 -0400284 REPORTER_ASSERT(reporter, 0 == cache->getResourceCount());
285
286 for (auto fit : { SkBackingFit::kExact, SkBackingFit::kApprox }) {
Greg Danielcd871402017-09-26 12:49:26 -0400287 for (auto create : { deferred_tex, deferred_texRT, wrapped, wrapped_with_key }) {
Robert Phillipsae7d3f32017-09-21 08:26:08 -0400288 REPORTER_ASSERT(reporter, 0 == cache->getResourceCount());
Robert Phillipsadbe1322018-01-17 13:35:46 -0500289 basic_test(context, reporter, create(reporter, proxyProvider, fit), true);
Robert Phillipsae7d3f32017-09-21 08:26:08 -0400290 }
291
292 REPORTER_ASSERT(reporter, 0 == cache->getResourceCount());
293 sk_sp<GrTexture> backingTex;
294 sk_sp<GrTextureProxy> proxy = create_wrapped_backend(context, fit, &backingTex);
295 basic_test(context, reporter, std::move(proxy), false);
296
297 backingTex = nullptr;
298 cache->purgeAllUnlocked();
299 }
300
301 invalidation_test(context, reporter);
Robert Phillipsfa8c0802017-10-04 08:42:28 -0400302 invalidation_and_instantiation_test(context, reporter);
Robert Phillipsae7d3f32017-09-21 08:26:08 -0400303}