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