sk_sp<GrTextureProxy> GrTextureAdjuster::refTextureProxyCopy(const CopyParams& copyParams, bool willBeMipped) { GrProxyProvider* proxyProvider = fContext->contextPriv().proxyProvider(); GrUniqueKey key; this->makeCopyKey(copyParams, &key, nullptr); if (key.isValid()) { sk_sp<GrTextureProxy> cachedCopy = proxyProvider->findOrCreateProxyByUniqueKey(key, this->originalProxy()->origin()); if (cachedCopy) { return cachedCopy; } } sk_sp<GrTextureProxy> proxy = this->originalProxyRef(); sk_sp<GrTextureProxy> copy = CopyOnGpu(fContext, std::move(proxy), copyParams, willBeMipped); if (copy) { if (key.isValid()) { SkASSERT(copy->origin() == this->originalProxy()->origin()); proxyProvider->assignUniqueKeyToProxy(key, copy.get()); this->didCacheCopy(key); } } return copy; }
// Test if invalidating unique ids prior to instantiating operates as expected static void invalidation_and_instantiation_test(GrContext* context, skiatest::Reporter* reporter) { GrProxyProvider* proxyProvider = context->priv().proxyProvider(); GrResourceProvider* resourceProvider = context->priv().resourceProvider(); GrResourceCache* cache = context->priv().getResourceCache(); REPORTER_ASSERT(reporter, 0 == cache->getResourceCount()); static GrUniqueKey::Domain d = GrUniqueKey::GenerateDomain(); GrUniqueKey key; GrUniqueKey::Builder builder(&key, d, 1, nullptr); builder[0] = 0; builder.finish(); // Create proxy, assign unique key sk_sp<GrTextureProxy> proxy = deferred_tex(reporter, context, proxyProvider, SkBackingFit::kExact); SkAssertResult(proxyProvider->assignUniqueKeyToProxy(key, proxy.get())); // Send an invalidation message, which will be sitting in the cache's inbox SkMessageBus<GrUniqueKeyInvalidatedMessage>::Post( GrUniqueKeyInvalidatedMessage(key, context->priv().contextID())); REPORTER_ASSERT(reporter, 1 == proxyProvider->numUniqueKeyProxies_TestOnly()); REPORTER_ASSERT(reporter, 0 == cache->getResourceCount()); // Instantiate the proxy. This will trigger the message to be processed, so the resulting // texture should *not* have the unique key on it! SkAssertResult(proxy->instantiate(resourceProvider)); REPORTER_ASSERT(reporter, !proxy->getUniqueKey().isValid()); REPORTER_ASSERT(reporter, !proxy->peekTexture()->getUniqueKey().isValid()); REPORTER_ASSERT(reporter, 0 == proxyProvider->numUniqueKeyProxies_TestOnly()); REPORTER_ASSERT(reporter, 1 == cache->getResourceCount()); proxy = nullptr; context->priv().testingOnly_purgeAllUnlockedResources(); REPORTER_ASSERT(reporter, 0 == proxyProvider->numUniqueKeyProxies_TestOnly()); REPORTER_ASSERT(reporter, 0 == cache->getResourceCount()); }
// This tests the basic capabilities of the uniquely keyed texture proxies. Does assigning // and looking them up work, etc. static void basic_test(GrContext* context, skiatest::Reporter* reporter, sk_sp<GrTextureProxy> proxy) { static int id = 1; GrResourceProvider* resourceProvider = context->priv().resourceProvider(); GrProxyProvider* proxyProvider = context->priv().proxyProvider(); GrResourceCache* cache = context->priv().getResourceCache(); int startCacheCount = cache->getResourceCount(); GrUniqueKey key; if (proxy->getUniqueKey().isValid()) { key = proxy->getUniqueKey(); } else { GrMakeKeyFromImageID(&key, id, SkIRect::MakeWH(64, 64)); ++id; // Assigning the uniqueKey adds the proxy to the hash but doesn't force instantiation REPORTER_ASSERT(reporter, !proxyProvider->numUniqueKeyProxies_TestOnly()); SkAssertResult(proxyProvider->assignUniqueKeyToProxy(key, proxy.get())); } REPORTER_ASSERT(reporter, 1 == proxyProvider->numUniqueKeyProxies_TestOnly()); REPORTER_ASSERT(reporter, startCacheCount == cache->getResourceCount()); // setUniqueKey had better stick REPORTER_ASSERT(reporter, key == proxy->getUniqueKey()); // We just added it, surely we can find it REPORTER_ASSERT(reporter, proxyProvider->findOrCreateProxyByUniqueKey( key, kBottomLeft_GrSurfaceOrigin)); REPORTER_ASSERT(reporter, 1 == proxyProvider->numUniqueKeyProxies_TestOnly()); int expectedCacheCount = startCacheCount + (proxy->isInstantiated() ? 0 : 1); // Once instantiated, the backing resource should have the same key SkAssertResult(proxy->instantiate(resourceProvider)); const GrUniqueKey texKey = proxy->peekSurface()->getUniqueKey(); REPORTER_ASSERT(reporter, texKey.isValid()); REPORTER_ASSERT(reporter, key == texKey); // An Unbudgeted-cacheable resource will not get purged when a proxy with the same key is // deleted. bool expectResourceToOutliveProxy = proxy->peekSurface()->resourcePriv().budgetedType() == GrBudgetedType::kUnbudgetedCacheable; // An Unbudgeted-uncacheable resource is never kept alive if it's ref cnt reaches zero even if // it has a key. bool expectDeletingProxyToDeleteResource = proxy->peekSurface()->resourcePriv().budgetedType() == GrBudgetedType::kUnbudgetedUncacheable; // deleting the proxy should delete it from the hash but not the cache proxy = nullptr; if (expectDeletingProxyToDeleteResource) { expectedCacheCount -= 1; } REPORTER_ASSERT(reporter, 0 == proxyProvider->numUniqueKeyProxies_TestOnly()); REPORTER_ASSERT(reporter, expectedCacheCount == cache->getResourceCount()); // If the proxy was cached refinding it should bring it back to life proxy = proxyProvider->findOrCreateProxyByUniqueKey(key, kBottomLeft_GrSurfaceOrigin); REPORTER_ASSERT(reporter, proxy); REPORTER_ASSERT(reporter, 1 == proxyProvider->numUniqueKeyProxies_TestOnly()); REPORTER_ASSERT(reporter, expectedCacheCount == cache->getResourceCount()); // Mega-purging it should remove it from both the hash and the cache proxy = nullptr; cache->purgeAllUnlocked(); if (!expectResourceToOutliveProxy) { expectedCacheCount--; } REPORTER_ASSERT(reporter, expectedCacheCount == cache->getResourceCount()); // If the texture was deleted then the proxy should no longer be findable. Otherwise, it should // be. proxy = proxyProvider->findOrCreateProxyByUniqueKey(key, kBottomLeft_GrSurfaceOrigin); REPORTER_ASSERT(reporter, expectResourceToOutliveProxy ? (bool)proxy : !proxy); REPORTER_ASSERT(reporter, expectedCacheCount == cache->getResourceCount()); if (expectResourceToOutliveProxy) { proxy.reset(); GrUniqueKeyInvalidatedMessage msg(texKey, context->priv().contextID()); SkMessageBus<GrUniqueKeyInvalidatedMessage>::Post(msg); cache->purgeAsNeeded(); expectedCacheCount--; proxy = proxyProvider->findOrCreateProxyByUniqueKey(key, kBottomLeft_GrSurfaceOrigin); REPORTER_ASSERT(reporter, !proxy); REPORTER_ASSERT(reporter, expectedCacheCount == cache->getResourceCount()); } }