blob: f81df8e99eead067bf615d66273c8427e0d90a4c [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;
33 desc.fOrigin = kBottomLeft_GrSurfaceOrigin;
34 desc.fWidth = 64;
35 desc.fHeight = 64;
36 desc.fConfig = kRGBA_8888_GrPixelConfig;
Brian Salomonbdecacf2018-02-02 20:32:49 -050037 desc.fSampleCnt = 1;
Robert Phillipsae7d3f32017-09-21 08:26:08 -040038
39 return desc;
40}
41
42///////////////////////////////////////////////////////////////////////////////////////////////////
43// Basic test
44
Greg Danielcd871402017-09-26 12:49:26 -040045static sk_sp<GrTextureProxy> deferred_tex(skiatest::Reporter* reporter,
Robert Phillipsadbe1322018-01-17 13:35:46 -050046 GrProxyProvider* proxyProvider, SkBackingFit fit) {
Robert Phillips0bd24dc2018-01-16 08:06:32 -050047 const GrSurfaceDesc desc = make_desc(kNone_GrSurfaceFlags);
Robert Phillipsae7d3f32017-09-21 08:26:08 -040048
Robert Phillips0bd24dc2018-01-16 08:06:32 -050049 sk_sp<GrTextureProxy> proxy = proxyProvider->createProxy(desc, 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
Robert Phillips0bd24dc2018-01-16 08:06:32 -050059 sk_sp<GrTextureProxy> proxy = proxyProvider->createProxy(desc, fit, SkBudgeted::kYes);
Robert Phillipsae7d3f32017-09-21 08:26:08 -040060 // Only budgeted & wrapped external proxies get to carry uniqueKeys
Greg Danielcd871402017-09-26 12:49:26 -040061 REPORTER_ASSERT(reporter, !proxy->getUniqueKey().isValid());
62 return proxy;
Robert Phillipsae7d3f32017-09-21 08:26:08 -040063}
64
Greg Danielcd871402017-09-26 12:49:26 -040065static sk_sp<GrTextureProxy> wrapped(skiatest::Reporter* reporter,
Robert Phillipsadbe1322018-01-17 13:35:46 -050066 GrProxyProvider* proxyProvider, SkBackingFit fit) {
Robert Phillips0bd24dc2018-01-16 08:06:32 -050067 const GrSurfaceDesc desc = make_desc(kNone_GrSurfaceFlags);
Robert Phillips1afd4cd2018-01-08 13:40:32 -050068
Robert Phillips0bd24dc2018-01-16 08:06:32 -050069 sk_sp<GrTextureProxy> proxy = proxyProvider->createInstantiatedProxy(desc, fit,
70 SkBudgeted::kYes);
71 // Only budgeted & wrapped external proxies get to carry uniqueKeys
Greg Danielcd871402017-09-26 12:49:26 -040072 REPORTER_ASSERT(reporter, !proxy->getUniqueKey().isValid());
73 return proxy;
74}
75
76static sk_sp<GrTextureProxy> wrapped_with_key(skiatest::Reporter* reporter,
Robert Phillipsadbe1322018-01-17 13:35:46 -050077 GrProxyProvider* proxyProvider, SkBackingFit fit) {
Greg Danielcd871402017-09-26 12:49:26 -040078 static GrUniqueKey::Domain d = GrUniqueKey::GenerateDomain();
79 static int kUniqueKeyData = 0;
80
81 GrUniqueKey key;
82
83 GrUniqueKey::Builder builder(&key, d, 1, nullptr);
84 builder[0] = kUniqueKeyData++;
85 builder.finish();
86
Robert Phillips0bd24dc2018-01-16 08:06:32 -050087 const GrSurfaceDesc desc = make_desc(kNone_GrSurfaceFlags);
Greg Danielcd871402017-09-26 12:49:26 -040088
Robert Phillipsadbe1322018-01-17 13:35:46 -050089 // Only budgeted & wrapped external proxies get to carry uniqueKeys
90 sk_sp<GrTextureProxy> proxy = proxyProvider->createInstantiatedProxy(desc, fit,
91 SkBudgeted::kYes, 0);
92 SkAssertResult(proxyProvider->assignUniqueKeyToProxy(key, proxy.get()));
Greg Danielcd871402017-09-26 12:49:26 -040093 REPORTER_ASSERT(reporter, proxy->getUniqueKey().isValid());
94 return proxy;
Robert Phillipsae7d3f32017-09-21 08:26:08 -040095}
96
97static sk_sp<GrTextureProxy> create_wrapped_backend(GrContext* context, SkBackingFit fit,
98 sk_sp<GrTexture>* backingSurface) {
Robert Phillips0bd24dc2018-01-16 08:06:32 -050099 GrProxyProvider* proxyProvider = context->contextPriv().proxyProvider();
Robert Phillips6be756b2018-01-16 15:07:54 -0500100 GrResourceProvider* resourceProvider = context->contextPriv().resourceProvider();
Robert Phillipsae7d3f32017-09-21 08:26:08 -0400101
Robert Phillipsb67821d2017-12-13 15:00:45 -0500102 const GrSurfaceDesc desc = make_desc(kNone_GrSurfaceFlags);
Robert Phillipsae7d3f32017-09-21 08:26:08 -0400103
Robert Phillips0bd24dc2018-01-16 08:06:32 -0500104 *backingSurface = resourceProvider->createTexture(desc, SkBudgeted::kNo);
Robert Phillipsae7d3f32017-09-21 08:26:08 -0400105 if (!(*backingSurface)) {
106 return nullptr;
107 }
108
Robert Phillipsb67821d2017-12-13 15:00:45 -0500109 GrBackendTexture backendTex = (*backingSurface)->getBackendTexture();
Robert Phillipsae7d3f32017-09-21 08:26:08 -0400110
Robert Phillips0bd24dc2018-01-16 08:06:32 -0500111 return proxyProvider->createWrappedTextureProxy(backendTex, kBottomLeft_GrSurfaceOrigin);
Robert Phillipsae7d3f32017-09-21 08:26:08 -0400112}
113
114
115// This tests the basic capabilities of the uniquely keyed texture proxies. Does assigning
116// and looking them up work, etc.
117static void basic_test(GrContext* context,
118 skiatest::Reporter* reporter,
119 sk_sp<GrTextureProxy> proxy, bool proxyIsCached) {
120 static int id = 1;
121
Robert Phillips6be756b2018-01-16 15:07:54 -0500122 GrResourceProvider* resourceProvider = context->contextPriv().resourceProvider();
Robert Phillips1afd4cd2018-01-08 13:40:32 -0500123 GrProxyProvider* proxyProvider = context->contextPriv().proxyProvider();
Robert Phillips6be756b2018-01-16 15:07:54 -0500124 GrResourceCache* cache = context->contextPriv().getResourceCache();
Robert Phillipsae7d3f32017-09-21 08:26:08 -0400125
126 int startCacheCount = cache->getResourceCount();
127
Robert Phillipsae7d3f32017-09-21 08:26:08 -0400128 GrUniqueKey key;
Greg Danielcd871402017-09-26 12:49:26 -0400129 if (proxy->getUniqueKey().isValid()) {
130 key = proxy->getUniqueKey();
131 } else {
132 GrMakeKeyFromImageID(&key, id, SkIRect::MakeWH(64, 64));
133 ++id;
Robert Phillipsae7d3f32017-09-21 08:26:08 -0400134
Greg Danielcd871402017-09-26 12:49:26 -0400135 // Assigning the uniqueKey adds the proxy to the hash but doesn't force instantiation
Robert Phillips1afd4cd2018-01-08 13:40:32 -0500136 REPORTER_ASSERT(reporter, !proxyProvider->numUniqueKeyProxies_TestOnly());
Robert Phillipsadbe1322018-01-17 13:35:46 -0500137 SkAssertResult(proxyProvider->assignUniqueKeyToProxy(key, proxy.get()));
Greg Danielcd871402017-09-26 12:49:26 -0400138 }
139
Robert Phillips1afd4cd2018-01-08 13:40:32 -0500140 REPORTER_ASSERT(reporter, 1 == proxyProvider->numUniqueKeyProxies_TestOnly());
Robert Phillipsae7d3f32017-09-21 08:26:08 -0400141 REPORTER_ASSERT(reporter, startCacheCount == cache->getResourceCount());
142
143 // setUniqueKey had better stick
144 REPORTER_ASSERT(reporter, key == proxy->getUniqueKey());
145
146 // We just added it, surely we can find it
Robert Phillips1afd4cd2018-01-08 13:40:32 -0500147 REPORTER_ASSERT(reporter, proxyProvider->findOrCreateProxyByUniqueKey(
148 key, kBottomLeft_GrSurfaceOrigin));
149 REPORTER_ASSERT(reporter, 1 == proxyProvider->numUniqueKeyProxies_TestOnly());
Robert Phillipsae7d3f32017-09-21 08:26:08 -0400150
151 // Once instantiated, the backing resource should have the same key
Robert Phillips1afd4cd2018-01-08 13:40:32 -0500152 SkAssertResult(proxy->instantiate(resourceProvider));
Robert Phillipsae7d3f32017-09-21 08:26:08 -0400153 const GrUniqueKey& texKey = proxy->priv().peekSurface()->getUniqueKey();
154 REPORTER_ASSERT(reporter, texKey.isValid());
155 REPORTER_ASSERT(reporter, key == texKey);
156 if (proxyIsCached) {
157 REPORTER_ASSERT(reporter, 1 == cache->getResourceCount());
158 }
159
160 // deleting the proxy should delete it from the hash but not the cache
161 proxy = nullptr;
Robert Phillips1afd4cd2018-01-08 13:40:32 -0500162 REPORTER_ASSERT(reporter, 0 == proxyProvider->numUniqueKeyProxies_TestOnly());
Robert Phillipsae7d3f32017-09-21 08:26:08 -0400163 REPORTER_ASSERT(reporter, 1 == cache->getResourceCount());
164
165 // If the proxy was cached refinding it should bring it back to life
Robert Phillips1afd4cd2018-01-08 13:40:32 -0500166 proxy = proxyProvider->findOrCreateProxyByUniqueKey(key, kBottomLeft_GrSurfaceOrigin);
Robert Phillipsae7d3f32017-09-21 08:26:08 -0400167 if (proxyIsCached) {
168 REPORTER_ASSERT(reporter, proxy);
Robert Phillips1afd4cd2018-01-08 13:40:32 -0500169 REPORTER_ASSERT(reporter, 1 == proxyProvider->numUniqueKeyProxies_TestOnly());
Robert Phillipsae7d3f32017-09-21 08:26:08 -0400170 } else {
171 REPORTER_ASSERT(reporter, !proxy);
Robert Phillips1afd4cd2018-01-08 13:40:32 -0500172 REPORTER_ASSERT(reporter, 0 == proxyProvider->numUniqueKeyProxies_TestOnly());
Robert Phillipsae7d3f32017-09-21 08:26:08 -0400173 }
174 REPORTER_ASSERT(reporter, 1 == cache->getResourceCount());
175
176 // Mega-purging it should remove it from both the hash and the cache
177 proxy = nullptr;
178 cache->purgeAllUnlocked();
179 if (proxyIsCached) {
180 REPORTER_ASSERT(reporter, 0 == cache->getResourceCount());
181 } else {
182 REPORTER_ASSERT(reporter, 1 == cache->getResourceCount());
183 }
184
185 // We can bring neither the texture nor proxy back from perma-death
Robert Phillips1afd4cd2018-01-08 13:40:32 -0500186 proxy = proxyProvider->findOrCreateProxyByUniqueKey(key, kBottomLeft_GrSurfaceOrigin);
Robert Phillipsae7d3f32017-09-21 08:26:08 -0400187 REPORTER_ASSERT(reporter, !proxy);
188 if (proxyIsCached) {
189 REPORTER_ASSERT(reporter, 0 == cache->getResourceCount());
190 } else {
191 REPORTER_ASSERT(reporter, 1 == cache->getResourceCount());
192 }
193}
194
195///////////////////////////////////////////////////////////////////////////////////////////////////
196// Invalidation test
197
198// Test if invalidating unique ids operates as expected for texture proxies.
199static void invalidation_test(GrContext* context, skiatest::Reporter* reporter) {
200
Robert Phillips1afd4cd2018-01-08 13:40:32 -0500201 GrProxyProvider* proxyProvider = context->contextPriv().proxyProvider();
Robert Phillips6be756b2018-01-16 15:07:54 -0500202 GrResourceCache* cache = context->contextPriv().getResourceCache();
Robert Phillipsae7d3f32017-09-21 08:26:08 -0400203 REPORTER_ASSERT(reporter, 0 == cache->getResourceCount());
204
205 sk_sp<SkImage> rasterImg;
206
207 {
208 SkImageInfo ii = SkImageInfo::Make(64, 64, kRGBA_8888_SkColorType, kOpaque_SkAlphaType);
209
210 SkBitmap bm;
211 bm.allocPixels(ii);
212
213 rasterImg = SkImage::MakeFromBitmap(bm);
Robert Phillips1afd4cd2018-01-08 13:40:32 -0500214 REPORTER_ASSERT(reporter, 0 == proxyProvider->numUniqueKeyProxies_TestOnly());
Robert Phillipsae7d3f32017-09-21 08:26:08 -0400215 REPORTER_ASSERT(reporter, 0 == cache->getResourceCount());
216 }
217
218 sk_sp<SkImage> textureImg = rasterImg->makeTextureImage(context, nullptr);
Robert Phillips1afd4cd2018-01-08 13:40:32 -0500219 REPORTER_ASSERT(reporter, 1 == proxyProvider->numUniqueKeyProxies_TestOnly());
Robert Phillipsae7d3f32017-09-21 08:26:08 -0400220 REPORTER_ASSERT(reporter, 1 == cache->getResourceCount());
221
222 rasterImg = nullptr; // this invalidates the uniqueKey
223
224 // this forces the cache to respond to the inval msg
225 int maxNum;
226 size_t maxBytes;
227 context->getResourceCacheLimits(&maxNum, &maxBytes);
228 context->setResourceCacheLimits(maxNum-1, maxBytes);
229
Robert Phillips1afd4cd2018-01-08 13:40:32 -0500230 REPORTER_ASSERT(reporter, 0 == proxyProvider->numUniqueKeyProxies_TestOnly());
Robert Phillipsae7d3f32017-09-21 08:26:08 -0400231 REPORTER_ASSERT(reporter, 1 == cache->getResourceCount());
232
233 textureImg = nullptr;
234 context->purgeAllUnlockedResources();
235
Robert Phillips1afd4cd2018-01-08 13:40:32 -0500236 REPORTER_ASSERT(reporter, 0 == proxyProvider->numUniqueKeyProxies_TestOnly());
Robert Phillipsae7d3f32017-09-21 08:26:08 -0400237 REPORTER_ASSERT(reporter, 0 == cache->getResourceCount());
238}
239
Brian Osman28c434b2017-09-27 13:11:16 -0400240// Test if invalidating unique ids prior to instantiating operates as expected
241static void invalidation_and_instantiation_test(GrContext* context, skiatest::Reporter* reporter) {
Robert Phillips1afd4cd2018-01-08 13:40:32 -0500242 GrProxyProvider* proxyProvider = context->contextPriv().proxyProvider();
Robert Phillips6be756b2018-01-16 15:07:54 -0500243 GrResourceProvider* resourceProvider = context->contextPriv().resourceProvider();
244 GrResourceCache* cache = context->contextPriv().getResourceCache();
Brian Osman28c434b2017-09-27 13:11:16 -0400245 REPORTER_ASSERT(reporter, 0 == cache->getResourceCount());
246
247 static GrUniqueKey::Domain d = GrUniqueKey::GenerateDomain();
248 GrUniqueKey key;
249 GrUniqueKey::Builder builder(&key, d, 1, nullptr);
250 builder[0] = 0;
251 builder.finish();
252
253 // Create proxy, assign unique key
Robert Phillipsadbe1322018-01-17 13:35:46 -0500254 sk_sp<GrTextureProxy> proxy = deferred_tex(reporter, proxyProvider, SkBackingFit::kExact);
255 SkAssertResult(proxyProvider->assignUniqueKeyToProxy(key, proxy.get()));
Brian Osman28c434b2017-09-27 13:11:16 -0400256
257 // Send an invalidation message, which will be sitting in the cache's inbox
258 SkMessageBus<GrUniqueKeyInvalidatedMessage>::Post(GrUniqueKeyInvalidatedMessage(key));
259
Robert Phillips1afd4cd2018-01-08 13:40:32 -0500260 REPORTER_ASSERT(reporter, 1 == proxyProvider->numUniqueKeyProxies_TestOnly());
Brian Osman28c434b2017-09-27 13:11:16 -0400261 REPORTER_ASSERT(reporter, 0 == cache->getResourceCount());
262
263 // Instantiate the proxy. This will trigger the message to be processed, so the resulting
264 // texture should *not* have the unique key on it!
Robert Phillips1afd4cd2018-01-08 13:40:32 -0500265 SkAssertResult(proxy->instantiate(resourceProvider));
Brian Osman28c434b2017-09-27 13:11:16 -0400266
267 REPORTER_ASSERT(reporter, !proxy->getUniqueKey().isValid());
268 REPORTER_ASSERT(reporter, !proxy->priv().peekTexture()->getUniqueKey().isValid());
Robert Phillips1afd4cd2018-01-08 13:40:32 -0500269 REPORTER_ASSERT(reporter, 0 == proxyProvider->numUniqueKeyProxies_TestOnly());
Brian Osman28c434b2017-09-27 13:11:16 -0400270 REPORTER_ASSERT(reporter, 1 == cache->getResourceCount());
271
272 proxy = nullptr;
273 context->purgeAllUnlockedResources();
274
Robert Phillips1afd4cd2018-01-08 13:40:32 -0500275 REPORTER_ASSERT(reporter, 0 == proxyProvider->numUniqueKeyProxies_TestOnly());
Brian Osman28c434b2017-09-27 13:11:16 -0400276 REPORTER_ASSERT(reporter, 0 == cache->getResourceCount());
277}
278
Robert Phillipsae7d3f32017-09-21 08:26:08 -0400279DEF_GPUTEST_FOR_RENDERING_CONTEXTS(TextureProxyTest, reporter, ctxInfo) {
280 GrContext* context = ctxInfo.grContext();
Robert Phillips1afd4cd2018-01-08 13:40:32 -0500281 GrProxyProvider* proxyProvider = context->contextPriv().proxyProvider();
Robert Phillips6be756b2018-01-16 15:07:54 -0500282 GrResourceCache* cache = context->contextPriv().getResourceCache();
Robert Phillipsae7d3f32017-09-21 08:26:08 -0400283
Robert Phillips1afd4cd2018-01-08 13:40:32 -0500284 REPORTER_ASSERT(reporter, !proxyProvider->numUniqueKeyProxies_TestOnly());
Robert Phillipsae7d3f32017-09-21 08:26:08 -0400285 REPORTER_ASSERT(reporter, 0 == cache->getResourceCount());
286
287 for (auto fit : { SkBackingFit::kExact, SkBackingFit::kApprox }) {
Greg Danielcd871402017-09-26 12:49:26 -0400288 for (auto create : { deferred_tex, deferred_texRT, wrapped, wrapped_with_key }) {
Robert Phillipsae7d3f32017-09-21 08:26:08 -0400289 REPORTER_ASSERT(reporter, 0 == cache->getResourceCount());
Robert Phillipsadbe1322018-01-17 13:35:46 -0500290 basic_test(context, reporter, create(reporter, proxyProvider, fit), true);
Robert Phillipsae7d3f32017-09-21 08:26:08 -0400291 }
292
293 REPORTER_ASSERT(reporter, 0 == cache->getResourceCount());
294 sk_sp<GrTexture> backingTex;
295 sk_sp<GrTextureProxy> proxy = create_wrapped_backend(context, fit, &backingTex);
296 basic_test(context, reporter, std::move(proxy), false);
297
298 backingTex = nullptr;
299 cache->purgeAllUnlocked();
300 }
301
302 invalidation_test(context, reporter);
Robert Phillipsfa8c0802017-10-04 08:42:28 -0400303 invalidation_and_instantiation_test(context, reporter);
Robert Phillipsae7d3f32017-09-21 08:26:08 -0400304}
305
306#endif