blob: 82a726db99dd1d1f9eed63dd21e3b80755f740d9 [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;
37 desc.fSampleCnt = 0;
38
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 Phillips1afd4cd2018-01-08 13:40:32 -050046 GrContext* context, SkBackingFit fit) {
47 GrProxyProvider* proxyProvider = context->contextPriv().proxyProvider();
Robert Phillips0bd24dc2018-01-16 08:06:32 -050048 const GrSurfaceDesc desc = make_desc(kNone_GrSurfaceFlags);
Robert Phillipsae7d3f32017-09-21 08:26:08 -040049
Robert Phillips0bd24dc2018-01-16 08:06:32 -050050 sk_sp<GrTextureProxy> proxy = proxyProvider->createProxy(desc, fit, SkBudgeted::kYes);
Robert Phillipsae7d3f32017-09-21 08:26:08 -040051 // Only budgeted & wrapped external proxies get to carry uniqueKeys
Greg Danielcd871402017-09-26 12:49:26 -040052 REPORTER_ASSERT(reporter, !proxy->getUniqueKey().isValid());
53 return proxy;
Robert Phillipsae7d3f32017-09-21 08:26:08 -040054}
55
Greg Danielcd871402017-09-26 12:49:26 -040056static sk_sp<GrTextureProxy> deferred_texRT(skiatest::Reporter* reporter,
Robert Phillips1afd4cd2018-01-08 13:40:32 -050057 GrContext* context, SkBackingFit fit) {
58 GrProxyProvider* proxyProvider = context->contextPriv().proxyProvider();
Robert Phillips0bd24dc2018-01-16 08:06:32 -050059 const GrSurfaceDesc desc = make_desc(kRenderTarget_GrSurfaceFlag);
Robert Phillipsae7d3f32017-09-21 08:26:08 -040060
Robert Phillips0bd24dc2018-01-16 08:06:32 -050061 sk_sp<GrTextureProxy> proxy = proxyProvider->createProxy(desc, fit, SkBudgeted::kYes);
Robert Phillipsae7d3f32017-09-21 08:26:08 -040062 // Only budgeted & wrapped external proxies get to carry uniqueKeys
Greg Danielcd871402017-09-26 12:49:26 -040063 REPORTER_ASSERT(reporter, !proxy->getUniqueKey().isValid());
64 return proxy;
Robert Phillipsae7d3f32017-09-21 08:26:08 -040065}
66
Greg Danielcd871402017-09-26 12:49:26 -040067static sk_sp<GrTextureProxy> wrapped(skiatest::Reporter* reporter,
Robert Phillips1afd4cd2018-01-08 13:40:32 -050068 GrContext* context, SkBackingFit fit) {
Robert Phillips0bd24dc2018-01-16 08:06:32 -050069 GrProxyProvider* proxyProvider = context->contextPriv().proxyProvider();
70 const GrSurfaceDesc desc = make_desc(kNone_GrSurfaceFlags);
Robert Phillips1afd4cd2018-01-08 13:40:32 -050071
Robert Phillips0bd24dc2018-01-16 08:06:32 -050072 sk_sp<GrTextureProxy> proxy = proxyProvider->createInstantiatedProxy(desc, fit,
73 SkBudgeted::kYes);
74 // Only budgeted & wrapped external proxies get to carry uniqueKeys
Greg Danielcd871402017-09-26 12:49:26 -040075 REPORTER_ASSERT(reporter, !proxy->getUniqueKey().isValid());
76 return proxy;
77}
78
79static sk_sp<GrTextureProxy> wrapped_with_key(skiatest::Reporter* reporter,
Robert Phillips1afd4cd2018-01-08 13:40:32 -050080 GrContext* context, SkBackingFit fit) {
Hal Canarybe46e242018-01-16 18:33:07 +000081 GrResourceProvider* resourceProvider = context->resourceProvider();
Robert Phillips1afd4cd2018-01-08 13:40:32 -050082
Greg Danielcd871402017-09-26 12:49:26 -040083 static GrUniqueKey::Domain d = GrUniqueKey::GenerateDomain();
84 static int kUniqueKeyData = 0;
85
86 GrUniqueKey key;
87
88 GrUniqueKey::Builder builder(&key, d, 1, nullptr);
89 builder[0] = kUniqueKeyData++;
90 builder.finish();
91
Robert Phillips0bd24dc2018-01-16 08:06:32 -050092 const GrSurfaceDesc desc = make_desc(kNone_GrSurfaceFlags);
Greg Danielcd871402017-09-26 12:49:26 -040093
94 sk_sp<GrTexture> tex;
95 if (SkBackingFit::kApprox == fit) {
Robert Phillips1afd4cd2018-01-08 13:40:32 -050096 tex = sk_sp<GrTexture>(resourceProvider->createApproxTexture(desc, 0));
Greg Danielcd871402017-09-26 12:49:26 -040097 } else {
98 // Only budgeted & wrapped external proxies get to carry uniqueKeys
Robert Phillips1afd4cd2018-01-08 13:40:32 -050099 tex = resourceProvider->createTexture(desc, SkBudgeted::kYes);
Greg Danielcd871402017-09-26 12:49:26 -0400100 }
101
102 tex->resourcePriv().setUniqueKey(key);
103
104 sk_sp<GrTextureProxy> proxy = GrSurfaceProxy::MakeWrapped(std::move(tex),
105 kBottomLeft_GrSurfaceOrigin);
106 REPORTER_ASSERT(reporter, proxy->getUniqueKey().isValid());
107 return proxy;
Robert Phillipsae7d3f32017-09-21 08:26:08 -0400108}
109
110static sk_sp<GrTextureProxy> create_wrapped_backend(GrContext* context, SkBackingFit fit,
111 sk_sp<GrTexture>* backingSurface) {
Robert Phillips0bd24dc2018-01-16 08:06:32 -0500112 GrProxyProvider* proxyProvider = context->contextPriv().proxyProvider();
Hal Canarybe46e242018-01-16 18:33:07 +0000113 GrResourceProvider* resourceProvider = context->resourceProvider();
Robert Phillipsae7d3f32017-09-21 08:26:08 -0400114
Robert Phillipsb67821d2017-12-13 15:00:45 -0500115 const GrSurfaceDesc desc = make_desc(kNone_GrSurfaceFlags);
Robert Phillipsae7d3f32017-09-21 08:26:08 -0400116
Robert Phillips0bd24dc2018-01-16 08:06:32 -0500117 *backingSurface = resourceProvider->createTexture(desc, SkBudgeted::kNo);
Robert Phillipsae7d3f32017-09-21 08:26:08 -0400118 if (!(*backingSurface)) {
119 return nullptr;
120 }
121
Robert Phillipsb67821d2017-12-13 15:00:45 -0500122 GrBackendTexture backendTex = (*backingSurface)->getBackendTexture();
Robert Phillipsae7d3f32017-09-21 08:26:08 -0400123
Robert Phillips0bd24dc2018-01-16 08:06:32 -0500124 return proxyProvider->createWrappedTextureProxy(backendTex, kBottomLeft_GrSurfaceOrigin);
Robert Phillipsae7d3f32017-09-21 08:26:08 -0400125}
126
127
128// This tests the basic capabilities of the uniquely keyed texture proxies. Does assigning
129// and looking them up work, etc.
130static void basic_test(GrContext* context,
131 skiatest::Reporter* reporter,
132 sk_sp<GrTextureProxy> proxy, bool proxyIsCached) {
133 static int id = 1;
134
Hal Canarybe46e242018-01-16 18:33:07 +0000135 GrResourceProvider* resourceProvider = context->resourceProvider();
Robert Phillips1afd4cd2018-01-08 13:40:32 -0500136 GrProxyProvider* proxyProvider = context->contextPriv().proxyProvider();
Hal Canarybe46e242018-01-16 18:33:07 +0000137 GrResourceCache* cache = context->getResourceCache();
Robert Phillipsae7d3f32017-09-21 08:26:08 -0400138
139 int startCacheCount = cache->getResourceCount();
140
Robert Phillipsae7d3f32017-09-21 08:26:08 -0400141 GrUniqueKey key;
Greg Danielcd871402017-09-26 12:49:26 -0400142 if (proxy->getUniqueKey().isValid()) {
143 key = proxy->getUniqueKey();
144 } else {
145 GrMakeKeyFromImageID(&key, id, SkIRect::MakeWH(64, 64));
146 ++id;
Robert Phillipsae7d3f32017-09-21 08:26:08 -0400147
Greg Danielcd871402017-09-26 12:49:26 -0400148 // Assigning the uniqueKey adds the proxy to the hash but doesn't force instantiation
Robert Phillips1afd4cd2018-01-08 13:40:32 -0500149 REPORTER_ASSERT(reporter, !proxyProvider->numUniqueKeyProxies_TestOnly());
150 proxyProvider->assignUniqueKeyToProxy(key, proxy.get());
Greg Danielcd871402017-09-26 12:49:26 -0400151 }
152
Robert Phillips1afd4cd2018-01-08 13:40:32 -0500153 REPORTER_ASSERT(reporter, 1 == proxyProvider->numUniqueKeyProxies_TestOnly());
Robert Phillipsae7d3f32017-09-21 08:26:08 -0400154 REPORTER_ASSERT(reporter, startCacheCount == cache->getResourceCount());
155
156 // setUniqueKey had better stick
157 REPORTER_ASSERT(reporter, key == proxy->getUniqueKey());
158
159 // We just added it, surely we can find it
Robert Phillips1afd4cd2018-01-08 13:40:32 -0500160 REPORTER_ASSERT(reporter, proxyProvider->findOrCreateProxyByUniqueKey(
161 key, kBottomLeft_GrSurfaceOrigin));
162 REPORTER_ASSERT(reporter, 1 == proxyProvider->numUniqueKeyProxies_TestOnly());
Robert Phillipsae7d3f32017-09-21 08:26:08 -0400163
164 // Once instantiated, the backing resource should have the same key
Robert Phillips1afd4cd2018-01-08 13:40:32 -0500165 SkAssertResult(proxy->instantiate(resourceProvider));
Robert Phillipsae7d3f32017-09-21 08:26:08 -0400166 const GrUniqueKey& texKey = proxy->priv().peekSurface()->getUniqueKey();
167 REPORTER_ASSERT(reporter, texKey.isValid());
168 REPORTER_ASSERT(reporter, key == texKey);
169 if (proxyIsCached) {
170 REPORTER_ASSERT(reporter, 1 == cache->getResourceCount());
171 }
172
173 // deleting the proxy should delete it from the hash but not the cache
174 proxy = nullptr;
Robert Phillips1afd4cd2018-01-08 13:40:32 -0500175 REPORTER_ASSERT(reporter, 0 == proxyProvider->numUniqueKeyProxies_TestOnly());
Robert Phillipsae7d3f32017-09-21 08:26:08 -0400176 REPORTER_ASSERT(reporter, 1 == cache->getResourceCount());
177
178 // If the proxy was cached refinding it should bring it back to life
Robert Phillips1afd4cd2018-01-08 13:40:32 -0500179 proxy = proxyProvider->findOrCreateProxyByUniqueKey(key, kBottomLeft_GrSurfaceOrigin);
Robert Phillipsae7d3f32017-09-21 08:26:08 -0400180 if (proxyIsCached) {
181 REPORTER_ASSERT(reporter, proxy);
Robert Phillips1afd4cd2018-01-08 13:40:32 -0500182 REPORTER_ASSERT(reporter, 1 == proxyProvider->numUniqueKeyProxies_TestOnly());
Robert Phillipsae7d3f32017-09-21 08:26:08 -0400183 } else {
184 REPORTER_ASSERT(reporter, !proxy);
Robert Phillips1afd4cd2018-01-08 13:40:32 -0500185 REPORTER_ASSERT(reporter, 0 == proxyProvider->numUniqueKeyProxies_TestOnly());
Robert Phillipsae7d3f32017-09-21 08:26:08 -0400186 }
187 REPORTER_ASSERT(reporter, 1 == cache->getResourceCount());
188
189 // Mega-purging it should remove it from both the hash and the cache
190 proxy = nullptr;
191 cache->purgeAllUnlocked();
192 if (proxyIsCached) {
193 REPORTER_ASSERT(reporter, 0 == cache->getResourceCount());
194 } else {
195 REPORTER_ASSERT(reporter, 1 == cache->getResourceCount());
196 }
197
198 // We can bring neither the texture nor proxy back from perma-death
Robert Phillips1afd4cd2018-01-08 13:40:32 -0500199 proxy = proxyProvider->findOrCreateProxyByUniqueKey(key, kBottomLeft_GrSurfaceOrigin);
Robert Phillipsae7d3f32017-09-21 08:26:08 -0400200 REPORTER_ASSERT(reporter, !proxy);
201 if (proxyIsCached) {
202 REPORTER_ASSERT(reporter, 0 == cache->getResourceCount());
203 } else {
204 REPORTER_ASSERT(reporter, 1 == cache->getResourceCount());
205 }
206}
207
208///////////////////////////////////////////////////////////////////////////////////////////////////
209// Invalidation test
210
211// Test if invalidating unique ids operates as expected for texture proxies.
212static void invalidation_test(GrContext* context, skiatest::Reporter* reporter) {
213
Robert Phillips1afd4cd2018-01-08 13:40:32 -0500214 GrProxyProvider* proxyProvider = context->contextPriv().proxyProvider();
Hal Canarybe46e242018-01-16 18:33:07 +0000215 GrResourceCache* cache = context->getResourceCache();
Robert Phillipsae7d3f32017-09-21 08:26:08 -0400216 REPORTER_ASSERT(reporter, 0 == cache->getResourceCount());
217
218 sk_sp<SkImage> rasterImg;
219
220 {
221 SkImageInfo ii = SkImageInfo::Make(64, 64, kRGBA_8888_SkColorType, kOpaque_SkAlphaType);
222
223 SkBitmap bm;
224 bm.allocPixels(ii);
225
226 rasterImg = SkImage::MakeFromBitmap(bm);
Robert Phillips1afd4cd2018-01-08 13:40:32 -0500227 REPORTER_ASSERT(reporter, 0 == proxyProvider->numUniqueKeyProxies_TestOnly());
Robert Phillipsae7d3f32017-09-21 08:26:08 -0400228 REPORTER_ASSERT(reporter, 0 == cache->getResourceCount());
229 }
230
231 sk_sp<SkImage> textureImg = rasterImg->makeTextureImage(context, nullptr);
Robert Phillips1afd4cd2018-01-08 13:40:32 -0500232 REPORTER_ASSERT(reporter, 1 == proxyProvider->numUniqueKeyProxies_TestOnly());
Robert Phillipsae7d3f32017-09-21 08:26:08 -0400233 REPORTER_ASSERT(reporter, 1 == cache->getResourceCount());
234
235 rasterImg = nullptr; // this invalidates the uniqueKey
236
237 // this forces the cache to respond to the inval msg
238 int maxNum;
239 size_t maxBytes;
240 context->getResourceCacheLimits(&maxNum, &maxBytes);
241 context->setResourceCacheLimits(maxNum-1, maxBytes);
242
Robert Phillips1afd4cd2018-01-08 13:40:32 -0500243 REPORTER_ASSERT(reporter, 0 == proxyProvider->numUniqueKeyProxies_TestOnly());
Robert Phillipsae7d3f32017-09-21 08:26:08 -0400244 REPORTER_ASSERT(reporter, 1 == cache->getResourceCount());
245
246 textureImg = nullptr;
247 context->purgeAllUnlockedResources();
248
Robert Phillips1afd4cd2018-01-08 13:40:32 -0500249 REPORTER_ASSERT(reporter, 0 == proxyProvider->numUniqueKeyProxies_TestOnly());
Robert Phillipsae7d3f32017-09-21 08:26:08 -0400250 REPORTER_ASSERT(reporter, 0 == cache->getResourceCount());
251}
252
Robert Phillipsfa8c0802017-10-04 08:42:28 -0400253#ifndef SK_DISABLE_DEFERRED_PROXIES
Brian Osman28c434b2017-09-27 13:11:16 -0400254// Test if invalidating unique ids prior to instantiating operates as expected
255static void invalidation_and_instantiation_test(GrContext* context, skiatest::Reporter* reporter) {
Robert Phillips1afd4cd2018-01-08 13:40:32 -0500256 GrProxyProvider* proxyProvider = context->contextPriv().proxyProvider();
Hal Canarybe46e242018-01-16 18:33:07 +0000257 GrResourceProvider* resourceProvider = context->resourceProvider();
258 GrResourceCache* cache = context->getResourceCache();
Brian Osman28c434b2017-09-27 13:11:16 -0400259 REPORTER_ASSERT(reporter, 0 == cache->getResourceCount());
260
261 static GrUniqueKey::Domain d = GrUniqueKey::GenerateDomain();
262 GrUniqueKey key;
263 GrUniqueKey::Builder builder(&key, d, 1, nullptr);
264 builder[0] = 0;
265 builder.finish();
266
267 // Create proxy, assign unique key
Robert Phillips1afd4cd2018-01-08 13:40:32 -0500268 sk_sp<GrTextureProxy> proxy = deferred_tex(reporter, context, SkBackingFit::kExact);
269 proxyProvider->assignUniqueKeyToProxy(key, proxy.get());
Brian Osman28c434b2017-09-27 13:11:16 -0400270
271 // Send an invalidation message, which will be sitting in the cache's inbox
272 SkMessageBus<GrUniqueKeyInvalidatedMessage>::Post(GrUniqueKeyInvalidatedMessage(key));
273
Robert Phillips1afd4cd2018-01-08 13:40:32 -0500274 REPORTER_ASSERT(reporter, 1 == proxyProvider->numUniqueKeyProxies_TestOnly());
Brian Osman28c434b2017-09-27 13:11:16 -0400275 REPORTER_ASSERT(reporter, 0 == cache->getResourceCount());
276
277 // Instantiate the proxy. This will trigger the message to be processed, so the resulting
278 // texture should *not* have the unique key on it!
Robert Phillips1afd4cd2018-01-08 13:40:32 -0500279 SkAssertResult(proxy->instantiate(resourceProvider));
Brian Osman28c434b2017-09-27 13:11:16 -0400280
281 REPORTER_ASSERT(reporter, !proxy->getUniqueKey().isValid());
282 REPORTER_ASSERT(reporter, !proxy->priv().peekTexture()->getUniqueKey().isValid());
Robert Phillips1afd4cd2018-01-08 13:40:32 -0500283 REPORTER_ASSERT(reporter, 0 == proxyProvider->numUniqueKeyProxies_TestOnly());
Brian Osman28c434b2017-09-27 13:11:16 -0400284 REPORTER_ASSERT(reporter, 1 == cache->getResourceCount());
285
286 proxy = nullptr;
287 context->purgeAllUnlockedResources();
288
Robert Phillips1afd4cd2018-01-08 13:40:32 -0500289 REPORTER_ASSERT(reporter, 0 == proxyProvider->numUniqueKeyProxies_TestOnly());
Brian Osman28c434b2017-09-27 13:11:16 -0400290 REPORTER_ASSERT(reporter, 0 == cache->getResourceCount());
291}
Robert Phillips73f7e1d2017-10-02 14:05:46 -0400292#endif
Brian Osman28c434b2017-09-27 13:11:16 -0400293
Robert Phillipsae7d3f32017-09-21 08:26:08 -0400294DEF_GPUTEST_FOR_RENDERING_CONTEXTS(TextureProxyTest, reporter, ctxInfo) {
295 GrContext* context = ctxInfo.grContext();
Robert Phillips1afd4cd2018-01-08 13:40:32 -0500296 GrProxyProvider* proxyProvider = context->contextPriv().proxyProvider();
Hal Canarybe46e242018-01-16 18:33:07 +0000297 GrResourceCache* cache = context->getResourceCache();
Robert Phillipsae7d3f32017-09-21 08:26:08 -0400298
Robert Phillips1afd4cd2018-01-08 13:40:32 -0500299 REPORTER_ASSERT(reporter, !proxyProvider->numUniqueKeyProxies_TestOnly());
Robert Phillipsae7d3f32017-09-21 08:26:08 -0400300 REPORTER_ASSERT(reporter, 0 == cache->getResourceCount());
301
302 for (auto fit : { SkBackingFit::kExact, SkBackingFit::kApprox }) {
Greg Danielcd871402017-09-26 12:49:26 -0400303 for (auto create : { deferred_tex, deferred_texRT, wrapped, wrapped_with_key }) {
Robert Phillipsae7d3f32017-09-21 08:26:08 -0400304 REPORTER_ASSERT(reporter, 0 == cache->getResourceCount());
Robert Phillips1afd4cd2018-01-08 13:40:32 -0500305 basic_test(context, reporter, create(reporter, context, fit), true);
Robert Phillipsae7d3f32017-09-21 08:26:08 -0400306 }
307
308 REPORTER_ASSERT(reporter, 0 == cache->getResourceCount());
309 sk_sp<GrTexture> backingTex;
310 sk_sp<GrTextureProxy> proxy = create_wrapped_backend(context, fit, &backingTex);
311 basic_test(context, reporter, std::move(proxy), false);
312
313 backingTex = nullptr;
314 cache->purgeAllUnlocked();
315 }
316
317 invalidation_test(context, reporter);
Robert Phillipsfa8c0802017-10-04 08:42:28 -0400318#ifndef SK_DISABLE_DEFERRED_PROXIES
319 invalidation_and_instantiation_test(context, reporter);
320#endif
Robert Phillipsae7d3f32017-09-21 08:26:08 -0400321}
322
323#endif