diff options
author | Greg Daniel <egdaniel@google.com> | 2017-09-26 12:49:26 -0400 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2017-09-26 17:11:21 +0000 |
commit | cd871401114f402e72420ccd49edecee2532b0e6 (patch) | |
tree | a323510790f271cc2e0a85487ab52cbc7ffc9339 | |
parent | 98a6216b18b57c2f7a0d58f542c60503686aed69 (diff) |
Add ability to remove unique key from proxy and underlying surface.
Bug: skia:
Change-Id: I66b891ce9ca35906fdbddb36f565b35b25825112
Reviewed-on: https://skia-review.googlesource.com/51240
Commit-Queue: Greg Daniel <egdaniel@google.com>
Reviewed-by: Robert Phillips <robertphillips@google.com>
-rw-r--r-- | src/effects/GrCircleBlurFragmentProcessor.cpp | 2 | ||||
-rw-r--r-- | src/effects/GrCircleBlurFragmentProcessor.fp | 2 | ||||
-rw-r--r-- | src/effects/SkBlurMaskFilter.cpp | 4 | ||||
-rw-r--r-- | src/gpu/GrBitmapTextureMaker.cpp | 2 | ||||
-rw-r--r-- | src/gpu/GrClipStackClip.cpp | 4 | ||||
-rw-r--r-- | src/gpu/GrResourceCache.cpp | 40 | ||||
-rw-r--r-- | src/gpu/GrResourceCache.h | 38 | ||||
-rw-r--r-- | src/gpu/GrResourceProvider.cpp | 14 | ||||
-rw-r--r-- | src/gpu/GrResourceProvider.h | 12 | ||||
-rw-r--r-- | src/gpu/GrSoftwarePathRenderer.cpp | 2 | ||||
-rw-r--r-- | src/gpu/GrSurfaceProxy.cpp | 20 | ||||
-rw-r--r-- | src/gpu/GrTextureAdjuster.cpp | 5 | ||||
-rw-r--r-- | src/gpu/GrTextureMaker.cpp | 2 | ||||
-rw-r--r-- | src/gpu/GrTextureProxy.cpp | 7 | ||||
-rw-r--r-- | src/gpu/SkGr.cpp | 3 | ||||
-rw-r--r-- | src/gpu/effects/GrTextureStripAtlas.cpp | 2 | ||||
-rw-r--r-- | src/image/SkImage_Lazy.cpp | 2 | ||||
-rw-r--r-- | tests/TextureProxyTest.cpp | 81 |
18 files changed, 199 insertions, 43 deletions
diff --git a/src/effects/GrCircleBlurFragmentProcessor.cpp b/src/effects/GrCircleBlurFragmentProcessor.cpp index 6d63190391..68955f22aa 100644 --- a/src/effects/GrCircleBlurFragmentProcessor.cpp +++ b/src/effects/GrCircleBlurFragmentProcessor.cpp @@ -205,7 +205,7 @@ static sk_sp<GrTextureProxy> create_profile_texture(GrResourceProvider* resource builder.finish(); sk_sp<GrTextureProxy> blurProfile = - resourceProvider->findProxyByUniqueKey(key, kTopLeft_GrSurfaceOrigin); + resourceProvider->findOrCreateProxyByUniqueKey(key, kTopLeft_GrSurfaceOrigin); if (!blurProfile) { static constexpr int kProfileTextureWidth = 512; GrSurfaceDesc texDesc; diff --git a/src/effects/GrCircleBlurFragmentProcessor.fp b/src/effects/GrCircleBlurFragmentProcessor.fp index d91bad8440..a93d2bacf7 100644 --- a/src/effects/GrCircleBlurFragmentProcessor.fp +++ b/src/effects/GrCircleBlurFragmentProcessor.fp @@ -224,7 +224,7 @@ uniform half4 circleData; builder.finish(); sk_sp<GrTextureProxy> blurProfile = - resourceProvider->findProxyByUniqueKey(key, kTopLeft_GrSurfaceOrigin); + resourceProvider->findOrCreateProxyByUniqueKey(key, kTopLeft_GrSurfaceOrigin); if (!blurProfile) { static constexpr int kProfileTextureWidth = 512; GrSurfaceDesc texDesc; diff --git a/src/effects/SkBlurMaskFilter.cpp b/src/effects/SkBlurMaskFilter.cpp index 0dc7ea19a7..4ee1f6bc78 100644 --- a/src/effects/SkBlurMaskFilter.cpp +++ b/src/effects/SkBlurMaskFilter.cpp @@ -947,7 +947,7 @@ sk_sp<GrTextureProxy> GrRectBlurEffect::CreateBlurProfileTexture( builder[0] = profileSize; builder.finish(); - sk_sp<GrTextureProxy> blurProfile(resourceProvider->findProxyByUniqueKey( + sk_sp<GrTextureProxy> blurProfile(resourceProvider->findOrCreateProxyByUniqueKey( key, kTopLeft_GrSurfaceOrigin)); if (!blurProfile) { GrSurfaceDesc texDesc; @@ -1118,7 +1118,7 @@ static sk_sp<GrTextureProxy> find_or_create_rrect_blur_mask(GrContext* context, } builder.finish(); - sk_sp<GrTextureProxy> mask(context->resourceProvider()->findProxyByUniqueKey( + sk_sp<GrTextureProxy> mask(context->resourceProvider()->findOrCreateProxyByUniqueKey( key, kBottomLeft_GrSurfaceOrigin)); if (!mask) { // TODO: this could be approx but the texture coords will need to be updated diff --git a/src/gpu/GrBitmapTextureMaker.cpp b/src/gpu/GrBitmapTextureMaker.cpp index 2bf3afe4e1..6654901e20 100644 --- a/src/gpu/GrBitmapTextureMaker.cpp +++ b/src/gpu/GrBitmapTextureMaker.cpp @@ -37,7 +37,7 @@ sk_sp<GrTextureProxy> GrBitmapTextureMaker::refOriginalTextureProxy(bool willBeM sk_sp<GrTextureProxy> proxy; if (fOriginalKey.isValid()) { - proxy = this->context()->resourceProvider()->findProxyByUniqueKey( + proxy = this->context()->resourceProvider()->findOrCreateProxyByUniqueKey( fOriginalKey, kTopLeft_GrSurfaceOrigin); if (proxy) { return proxy; diff --git a/src/gpu/GrClipStackClip.cpp b/src/gpu/GrClipStackClip.cpp index 1be35a88e3..10880b4891 100644 --- a/src/gpu/GrClipStackClip.cpp +++ b/src/gpu/GrClipStackClip.cpp @@ -393,7 +393,7 @@ sk_sp<GrTextureProxy> GrClipStackClip::createAlphaClipMask(GrContext* context, GrUniqueKey key; create_clip_mask_key(reducedClip.elementsGenID(), reducedClip.ibounds(), &key); - sk_sp<GrTextureProxy> proxy(resourceProvider->findProxyByUniqueKey( + sk_sp<GrTextureProxy> proxy(resourceProvider->findOrCreateProxyByUniqueKey( key, kBottomLeft_GrSurfaceOrigin)); if (proxy) { return proxy; @@ -505,7 +505,7 @@ sk_sp<GrTextureProxy> GrClipStackClip::createSoftwareClipMask( GrUniqueKey key; create_clip_mask_key(reducedClip.elementsGenID(), reducedClip.ibounds(), &key); - sk_sp<GrTextureProxy> proxy(context->resourceProvider()->findProxyByUniqueKey( + sk_sp<GrTextureProxy> proxy(context->resourceProvider()->findOrCreateProxyByUniqueKey( key, kTopLeft_GrSurfaceOrigin)); if (proxy) { return proxy; diff --git a/src/gpu/GrResourceCache.cpp b/src/gpu/GrResourceCache.cpp index c207b44a38..6ff88fc9e7 100644 --- a/src/gpu/GrResourceCache.cpp +++ b/src/gpu/GrResourceCache.cpp @@ -852,6 +852,15 @@ bool GrResourceCache::isInCache(const GrGpuResource* resource) const { #endif +void GrResourceCache::adoptUniqueKeyFromSurface(GrTextureProxy* proxy, const GrSurface* surf) { + SkASSERT(surf->getUniqueKey().isValid()); + proxy->cacheAccess().setUniqueKey(this, surf->getUniqueKey()); + SkASSERT(proxy->getUniqueKey() == surf->getUniqueKey()); + // multiple proxies can't get the same key + SkASSERT(!fUniquelyKeyedProxies.find(surf->getUniqueKey())); + fUniquelyKeyedProxies.add(proxy); +} + void GrResourceCache::assignUniqueKeyToProxy(const GrUniqueKey& key, GrTextureProxy* proxy) { SkASSERT(key.isValid()); SkASSERT(proxy); @@ -884,6 +893,14 @@ sk_sp<GrTextureProxy> GrResourceCache::findProxyByUniqueKey(const GrUniqueKey& k sk_sp<GrTextureProxy> result = sk_ref_sp(fUniquelyKeyedProxies.find(key)); if (result) { SkASSERT(result->origin() == origin); + } + return result; +} + +sk_sp<GrTextureProxy> GrResourceCache::findOrCreateProxyByUniqueKey(const GrUniqueKey& key, + GrSurfaceOrigin origin) { + sk_sp<GrTextureProxy> result = this->findProxyByUniqueKey(key, origin); + if (result) { return result; } @@ -897,7 +914,8 @@ sk_sp<GrTextureProxy> GrResourceCache::findProxyByUniqueKey(const GrUniqueKey& k result = GrSurfaceProxy::MakeWrapped(std::move(texture), origin); SkASSERT(result->getUniqueKey() == key); - fUniquelyKeyedProxies.add(result.get()); + // MakeWrapped should've added this for us + SkASSERT(fUniquelyKeyedProxies.find(key)); return result; } @@ -906,8 +924,24 @@ void GrResourceCache::processInvalidProxyUniqueKey(const GrUniqueKey& key) { // will not be in 'fUniquelyKeyedProxies'. GrTextureProxy* proxy = fUniquelyKeyedProxies.find(key); if (proxy) { - fUniquelyKeyedProxies.remove(key); - proxy->cacheAccess().clearUniqueKey(); + this->processInvalidProxyUniqueKey(key, proxy, false); + } +} + +void GrResourceCache::processInvalidProxyUniqueKey(const GrUniqueKey& key, GrTextureProxy* proxy, + bool invalidateSurface) { + SkASSERT(proxy); + SkASSERT(proxy->getUniqueKey().isValid()); + SkASSERT(proxy->getUniqueKey() == key); + + fUniquelyKeyedProxies.remove(key); + proxy->cacheAccess().clearUniqueKey(); + + if (invalidateSurface && proxy->priv().isInstantiated()) { + GrSurface* surface = proxy->priv().peekSurface(); + if (surface) { + surface->resourcePriv().removeUniqueKey(); + } } } diff --git a/src/gpu/GrResourceCache.h b/src/gpu/GrResourceCache.h index 96323be73c..771196c81c 100644 --- a/src/gpu/GrResourceCache.h +++ b/src/gpu/GrResourceCache.h @@ -160,8 +160,9 @@ public: /////////////////////////////////////////////////////////////////////////// // TextureProxies & GrUniqueKeys // - // The two GrResourceCache methods assignUniqueKeyToProxy and findProxyByUniqueKey drive - // the behavior of uniqueKeys on proxies. + // The four GrResourceCache methods assignUniqueKeyToProxy, adoptUniqueKeyFromSurface, + // findPorxyByUniqueKey, and findOrCreateProxyByUniqueKey drive the behavior of uniqueKeys on + // proxies. // // assignUniqueKeyToProxy does the following: // if the proxy is wrapped, it sets the texture & proxy keys & adds the proxy to the hash @@ -174,8 +175,16 @@ public: // determines that the key will never be used again but, in that case, the proxy should // never receive another key. // + // adoptUniqueKeyFromSurface does the following: + // takes in a GrSurface which must have a valid unique key. It sets the proxy's key to match + // the surface and adds the proxy to the hash. + // // findProxyByUniqueKey does the following: - // first looks in the UniqueKeyProxy hash table to see if there is already a proxy w/ the key + // looks in the UniqueKeyProxy hash table to see if there is already a proxy w/ the key and + // returns the proxy. If it fails it will return null. + // + // findOrCreateProxyByUniqueKey does the following: + // first calls findProxyByUniqueKey to see if a proxy already exists with the key // failing that it looks in the ResourceCache to see there is a texture with that key // if so, it will wrap the texture in a proxy, add the proxy to the hash and return it // failing that it will return null @@ -185,12 +194,26 @@ public: */ void assignUniqueKeyToProxy(const GrUniqueKey&, GrTextureProxy*); + /* + * Sets the unique key of the provided proxy to the unique key of the surface. The surface must + * have a valid unique key. + */ + void adoptUniqueKeyFromSurface(GrTextureProxy* proxy, const GrSurface*); + /** - * Find a texture proxy that is associated with the provided unique key. + * Find a texture proxy that is associated with the provided unique key. It will not look for a + * GrSurface that has the unique key. */ sk_sp<GrTextureProxy> findProxyByUniqueKey(const GrUniqueKey&, GrSurfaceOrigin); /** + * Find a texture proxy that is associated with the provided unique key. If not proxy is found, + * try to find a resources that is associated with the unique key and create a proxy that wraps + * it. + */ + sk_sp<GrTextureProxy> findOrCreateProxyByUniqueKey(const GrUniqueKey&, GrSurfaceOrigin); + + /** * Either the proxy attached to the unique key is being deleted (in which case we * don't want it cluttering up the hash table) or the client has indicated that * it will never refer to the unique key again. In either case, remove the key @@ -200,6 +223,13 @@ public: void processInvalidProxyUniqueKey(const GrUniqueKey&); /** + * Same as above, but you must pass in a GrTextureProxy to save having to search for it. The + * GrUniqueKey of the proxy must be valid and it must match the passed in key. This function + * also gives the option to invalidate the GrUniqueKey on the underlying GrTexture. + */ + void processInvalidProxyUniqueKey(const GrUniqueKey&, GrTextureProxy*, bool invalidateSurface); + + /** * Query whether a unique key exists in the cache. */ bool hasUniqueKey(const GrUniqueKey& key) const { diff --git a/src/gpu/GrResourceProvider.cpp b/src/gpu/GrResourceProvider.cpp index 8c96c2986b..16fe0c359d 100644 --- a/src/gpu/GrResourceProvider.cpp +++ b/src/gpu/GrResourceProvider.cpp @@ -276,6 +276,14 @@ void GrResourceProvider::assignUniqueKeyToResource(const GrUniqueKey& key, resource->resourcePriv().setUniqueKey(key); } +void GrResourceProvider::removeUniqueKeyFromProxy(const GrUniqueKey& key, GrTextureProxy* proxy) { + ASSERT_SINGLE_OWNER + if (this->isAbandoned() || !proxy) { + return; + } + fCache->processInvalidProxyUniqueKey(key, proxy, true); +} + GrGpuResource* GrResourceProvider::findAndRefResourceByUniqueKey(const GrUniqueKey& key) { ASSERT_SINGLE_OWNER return this->isAbandoned() ? nullptr : fCache->findAndRefUniqueResource(key); @@ -313,6 +321,12 @@ sk_sp<GrTextureProxy> GrResourceProvider::findProxyByUniqueKey(const GrUniqueKey return this->isAbandoned() ? nullptr : fCache->findProxyByUniqueKey(key, origin); } +sk_sp<GrTextureProxy> GrResourceProvider::findOrCreateProxyByUniqueKey(const GrUniqueKey& key, + GrSurfaceOrigin origin) { + ASSERT_SINGLE_OWNER + return this->isAbandoned() ? nullptr : fCache->findOrCreateProxyByUniqueKey(key, origin); +} + const GrBuffer* GrResourceProvider::createPatternedIndexBuffer(const uint16_t* pattern, int patternSize, int reps, diff --git a/src/gpu/GrResourceProvider.h b/src/gpu/GrResourceProvider.h index b906013fe8..b3fe32a0b1 100644 --- a/src/gpu/GrResourceProvider.h +++ b/src/gpu/GrResourceProvider.h @@ -52,10 +52,22 @@ public: void assignUniqueKeyToProxy(const GrUniqueKey&, GrTextureProxy*); /* + * Removes a unique key from a proxy. If the proxy has already been instantiated, it will + * also remove the unique key from the target GrSurface. + */ + void removeUniqueKeyFromProxy(const GrUniqueKey&, GrTextureProxy*); + + /* * Finds a proxy by unique key. */ sk_sp<GrTextureProxy> findProxyByUniqueKey(const GrUniqueKey&, GrSurfaceOrigin); + /* + * Finds a proxy by unique key or creates a new one that wraps a resource matching the unique + * key. + */ + sk_sp<GrTextureProxy> findOrCreateProxyByUniqueKey(const GrUniqueKey&, GrSurfaceOrigin); + /////////////////////////////////////////////////////////////////////////// // Textures diff --git a/src/gpu/GrSoftwarePathRenderer.cpp b/src/gpu/GrSoftwarePathRenderer.cpp index c9377e26de..8b509082c8 100644 --- a/src/gpu/GrSoftwarePathRenderer.cpp +++ b/src/gpu/GrSoftwarePathRenderer.cpp @@ -290,7 +290,7 @@ bool GrSoftwarePathRenderer::onDrawPath(const DrawPathArgs& args) { sk_sp<GrTextureProxy> proxy; if (useCache) { - proxy = fResourceProvider->findProxyByUniqueKey(maskKey, kTopLeft_GrSurfaceOrigin); + proxy = fResourceProvider->findOrCreateProxyByUniqueKey(maskKey, kTopLeft_GrSurfaceOrigin); } if (!proxy) { SkBackingFit fit = useCache ? SkBackingFit::kExact : SkBackingFit::kApprox; diff --git a/src/gpu/GrSurfaceProxy.cpp b/src/gpu/GrSurfaceProxy.cpp index 86f9935b7c..bcb9ad4931 100644 --- a/src/gpu/GrSurfaceProxy.cpp +++ b/src/gpu/GrSurfaceProxy.cpp @@ -182,6 +182,16 @@ sk_sp<GrSurfaceProxy> GrSurfaceProxy::MakeWrapped(sk_sp<GrSurface> surf, GrSurfa return nullptr; } + if (surf->getUniqueKey().isValid()) { + // The proxy may already be in the hash. Thus we need to look for it first before creating + // new one. + GrResourceProvider* provider = surf->getContext()->resourceProvider(); + sk_sp<GrSurfaceProxy> proxy = provider->findProxyByUniqueKey(surf->getUniqueKey(), origin); + if (proxy) { + return proxy; + } + } + if (surf->asTexture()) { if (surf->asRenderTarget()) { return sk_sp<GrSurfaceProxy>(new GrTextureRenderTargetProxy(std::move(surf), origin)); @@ -201,6 +211,16 @@ sk_sp<GrTextureProxy> GrSurfaceProxy::MakeWrapped(sk_sp<GrTexture> tex, GrSurfac return nullptr; } + if (tex->getUniqueKey().isValid()) { + // The proxy may already be in the hash. Thus we need to look for it first before creating + // new one. + GrResourceProvider* provider = tex->getContext()->resourceProvider(); + sk_sp<GrTextureProxy> proxy = provider->findProxyByUniqueKey(tex->getUniqueKey(), origin); + if (proxy) { + return proxy; + } + } + if (tex->asRenderTarget()) { return sk_sp<GrTextureProxy>(new GrTextureRenderTargetProxy(std::move(tex), origin)); } else { diff --git a/src/gpu/GrTextureAdjuster.cpp b/src/gpu/GrTextureAdjuster.cpp index 9c34cca569..a06c64f335 100644 --- a/src/gpu/GrTextureAdjuster.cpp +++ b/src/gpu/GrTextureAdjuster.cpp @@ -46,8 +46,9 @@ sk_sp<GrTextureProxy> GrTextureAdjuster::refTextureProxyCopy(const CopyParams& c GrUniqueKey key; this->makeCopyKey(copyParams, &key, nullptr); if (key.isValid()) { - sk_sp<GrTextureProxy> cachedCopy = fContext->resourceProvider()->findProxyByUniqueKey( - key, this->originalProxy()->origin()); + sk_sp<GrTextureProxy> cachedCopy = + fContext->resourceProvider()->findOrCreateProxyByUniqueKey( + key, this->originalProxy()->origin()); if (cachedCopy) { return cachedCopy; } diff --git a/src/gpu/GrTextureMaker.cpp b/src/gpu/GrTextureMaker.cpp index efcf755f7a..db0f421cd0 100644 --- a/src/gpu/GrTextureMaker.cpp +++ b/src/gpu/GrTextureMaker.cpp @@ -50,7 +50,7 @@ sk_sp<GrTextureProxy> GrTextureMaker::refTextureProxyForParams(const GrSamplerSt } else { origOrigin = kTopLeft_GrSurfaceOrigin; } - sk_sp<GrTextureProxy> result(fContext->resourceProvider()->findProxyByUniqueKey( + sk_sp<GrTextureProxy> result(fContext->resourceProvider()->findOrCreateProxyByUniqueKey( copyKey, origOrigin)); if (result) { return result; diff --git a/src/gpu/GrTextureProxy.cpp b/src/gpu/GrTextureProxy.cpp index 3c2fc33741..9aeec8d2aa 100644 --- a/src/gpu/GrTextureProxy.cpp +++ b/src/gpu/GrTextureProxy.cpp @@ -28,8 +28,8 @@ GrTextureProxy::GrTextureProxy(sk_sp<GrSurface> surf, GrSurfaceOrigin origin) , fMipColorMode(fTarget->asTexture()->texturePriv().mipColorMode()) , fCache(nullptr) { if (fTarget->getUniqueKey().isValid()) { - fUniqueKey = fTarget->getUniqueKey(); fCache = fTarget->asTexture()->getContext()->getResourceCache(); + fCache->adoptUniqueKeyFromSurface(this, fTarget); } } @@ -38,7 +38,7 @@ GrTextureProxy::~GrTextureProxy() { // at this point. Zero out the pointer so the cache invalidation code doesn't try to use it. fTarget = nullptr; if (fUniqueKey.isValid()) { - fCache->processInvalidProxyUniqueKey(fUniqueKey); + fCache->processInvalidProxyUniqueKey(fUniqueKey, this, false); } else { SkASSERT(!fCache); } @@ -97,8 +97,7 @@ void GrTextureProxy::setUniqueKey(GrResourceCache* cache, const GrUniqueKey& key SkASSERT(key.isValid()); SkASSERT(!fUniqueKey.isValid()); // proxies can only ever get one uniqueKey - if (fTarget) { - SkASSERT(!fTarget->getUniqueKey().isValid()); + if (fTarget && !fTarget->getUniqueKey().isValid()) { fTarget->resourcePriv().setUniqueKey(key); SkASSERT(fTarget->getUniqueKey() == key); } diff --git a/src/gpu/SkGr.cpp b/src/gpu/SkGr.cpp index b9f75e0821..7f956d67d2 100644 --- a/src/gpu/SkGr.cpp +++ b/src/gpu/SkGr.cpp @@ -256,7 +256,8 @@ sk_sp<GrTextureProxy> GrMakeCachedBitmapProxy(GrResourceProvider* resourceProvid sk_sp<GrTextureProxy> proxy; if (originalKey.isValid()) { - proxy = resourceProvider->findProxyByUniqueKey(originalKey, kTopLeft_GrSurfaceOrigin); + proxy = resourceProvider->findOrCreateProxyByUniqueKey(originalKey, + kTopLeft_GrSurfaceOrigin); } if (!proxy) { // Pass nullptr for |dstColorSpace|. This is lenient - we allow a wider range of diff --git a/src/gpu/effects/GrTextureStripAtlas.cpp b/src/gpu/effects/GrTextureStripAtlas.cpp index 65e3c97cc6..a459b32cd9 100644 --- a/src/gpu/effects/GrTextureStripAtlas.cpp +++ b/src/gpu/effects/GrTextureStripAtlas.cpp @@ -207,7 +207,7 @@ void GrTextureStripAtlas::lockTexture() { builder[0] = static_cast<uint32_t>(fCacheKey); builder.finish(); - sk_sp<GrTextureProxy> proxy = fDesc.fContext->resourceProvider()->findProxyByUniqueKey( + sk_sp<GrTextureProxy> proxy = fDesc.fContext->resourceProvider()->findOrCreateProxyByUniqueKey( key, kTopLeft_GrSurfaceOrigin); if (!proxy) { GrSurfaceDesc texDesc; diff --git a/src/image/SkImage_Lazy.cpp b/src/image/SkImage_Lazy.cpp index 41be5bfd0f..003b28ba98 100644 --- a/src/image/SkImage_Lazy.cpp +++ b/src/image/SkImage_Lazy.cpp @@ -753,7 +753,7 @@ sk_sp<GrTextureProxy> SkImage_Lazy::lockTextureProxy(GrContext* ctx, // 1. Check the cache for a pre-existing one if (key.isValid()) { - if (sk_sp<GrTextureProxy> proxy = ctx->resourceProvider()->findProxyByUniqueKey( + if (sk_sp<GrTextureProxy> proxy = ctx->resourceProvider()->findOrCreateProxyByUniqueKey( key, kTopLeft_GrSurfaceOrigin)) { SK_HISTOGRAM_ENUMERATION("LockTexturePath", kPreExisting_LockTexturePath, kLockTexturePathCount); diff --git a/tests/TextureProxyTest.cpp b/tests/TextureProxyTest.cpp index 58c29fcb85..915539e8b6 100644 --- a/tests/TextureProxyTest.cpp +++ b/tests/TextureProxyTest.cpp @@ -41,21 +41,57 @@ static GrSurfaceDesc make_desc(GrSurfaceFlags flags) { /////////////////////////////////////////////////////////////////////////////////////////////////// // Basic test -static sk_sp<GrTextureProxy> deferred_tex(GrResourceProvider* provider, SkBackingFit fit) { +static sk_sp<GrTextureProxy> deferred_tex(skiatest::Reporter* reporter, + GrResourceProvider* provider, SkBackingFit fit) { GrSurfaceDesc desc = make_desc(kNone_GrSurfaceFlags); // Only budgeted & wrapped external proxies get to carry uniqueKeys - return GrSurfaceProxy::MakeDeferred(provider, desc, fit, SkBudgeted::kYes); + sk_sp<GrTextureProxy> proxy = GrSurfaceProxy::MakeDeferred(provider, desc, fit, + SkBudgeted::kYes); + REPORTER_ASSERT(reporter, !proxy->getUniqueKey().isValid()); + return proxy; } -static sk_sp<GrTextureProxy> deferred_texRT(GrResourceProvider* provider, SkBackingFit fit) { +static sk_sp<GrTextureProxy> deferred_texRT(skiatest::Reporter* reporter, + GrResourceProvider* provider, SkBackingFit fit) { GrSurfaceDesc desc = make_desc(kRenderTarget_GrSurfaceFlag); // Only budgeted & wrapped external proxies get to carry uniqueKeys - return GrSurfaceProxy::MakeDeferred(provider, desc, fit, SkBudgeted::kYes); + sk_sp<GrTextureProxy> proxy = GrSurfaceProxy::MakeDeferred(provider, desc, fit, + SkBudgeted::kYes); + REPORTER_ASSERT(reporter, !proxy->getUniqueKey().isValid()); + return proxy; +} + +static sk_sp<GrTextureProxy> wrapped(skiatest::Reporter* reporter, + GrResourceProvider* provider, SkBackingFit fit) { + GrSurfaceDesc desc = make_desc(kNone_GrSurfaceFlags); + + sk_sp<GrTexture> tex; + if (SkBackingFit::kApprox == fit) { + tex = sk_sp<GrTexture>(provider->createApproxTexture(desc, 0)); + } else { + // Only budgeted & wrapped external proxies get to carry uniqueKeys + tex = provider->createTexture(desc, SkBudgeted::kYes); + } + + sk_sp<GrTextureProxy> proxy = GrSurfaceProxy::MakeWrapped(std::move(tex), + kBottomLeft_GrSurfaceOrigin); + REPORTER_ASSERT(reporter, !proxy->getUniqueKey().isValid()); + return proxy; } -static sk_sp<GrTextureProxy> wrapped(GrResourceProvider* provider, SkBackingFit fit) { +static sk_sp<GrTextureProxy> wrapped_with_key(skiatest::Reporter* reporter, + GrResourceProvider* provider, SkBackingFit fit) { + static GrUniqueKey::Domain d = GrUniqueKey::GenerateDomain(); + static int kUniqueKeyData = 0; + + GrUniqueKey key; + + GrUniqueKey::Builder builder(&key, d, 1, nullptr); + builder[0] = kUniqueKeyData++; + builder.finish(); + GrSurfaceDesc desc = make_desc(kNone_GrSurfaceFlags); sk_sp<GrTexture> tex; @@ -66,7 +102,12 @@ static sk_sp<GrTextureProxy> wrapped(GrResourceProvider* provider, SkBackingFit tex = provider->createTexture(desc, SkBudgeted::kYes); } - return GrSurfaceProxy::MakeWrapped(std::move(tex), kBottomLeft_GrSurfaceOrigin); + tex->resourcePriv().setUniqueKey(key); + + sk_sp<GrTextureProxy> proxy = GrSurfaceProxy::MakeWrapped(std::move(tex), + kBottomLeft_GrSurfaceOrigin); + REPORTER_ASSERT(reporter, proxy->getUniqueKey().isValid()); + return proxy; } static sk_sp<GrTextureProxy> create_wrapped_backend(GrContext* context, SkBackingFit fit, @@ -102,15 +143,18 @@ static void basic_test(GrContext* context, int startCacheCount = cache->getResourceCount(); - REPORTER_ASSERT(reporter, !proxy->getUniqueKey().isValid()); - GrUniqueKey key; - GrMakeKeyFromImageID(&key, id, SkIRect::MakeWH(64, 64)); - ++id; + 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, !cache->numUniqueKeyProxies_TestOnly()); + provider->assignUniqueKeyToProxy(key, proxy.get()); + } - // Assigning the uniqueKey adds the proxy to the hash but doesn't force instantiation - REPORTER_ASSERT(reporter, !cache->numUniqueKeyProxies_TestOnly()); - provider->assignUniqueKeyToProxy(key, proxy.get()); REPORTER_ASSERT(reporter, 1 == cache->numUniqueKeyProxies_TestOnly()); REPORTER_ASSERT(reporter, startCacheCount == cache->getResourceCount()); @@ -118,7 +162,8 @@ static void basic_test(GrContext* context, REPORTER_ASSERT(reporter, key == proxy->getUniqueKey()); // We just added it, surely we can find it - REPORTER_ASSERT(reporter, provider->findProxyByUniqueKey(key, kBottomLeft_GrSurfaceOrigin)); + REPORTER_ASSERT(reporter, provider->findOrCreateProxyByUniqueKey(key, + kBottomLeft_GrSurfaceOrigin)); REPORTER_ASSERT(reporter, 1 == cache->numUniqueKeyProxies_TestOnly()); // Once instantiated, the backing resource should have the same key @@ -136,7 +181,7 @@ static void basic_test(GrContext* context, REPORTER_ASSERT(reporter, 1 == cache->getResourceCount()); // If the proxy was cached refinding it should bring it back to life - proxy = provider->findProxyByUniqueKey(key, kBottomLeft_GrSurfaceOrigin); + proxy = provider->findOrCreateProxyByUniqueKey(key, kBottomLeft_GrSurfaceOrigin); if (proxyIsCached) { REPORTER_ASSERT(reporter, proxy); REPORTER_ASSERT(reporter, 1 == cache->numUniqueKeyProxies_TestOnly()); @@ -156,7 +201,7 @@ static void basic_test(GrContext* context, } // We can bring neither the texture nor proxy back from perma-death - proxy = provider->findProxyByUniqueKey(key, kBottomLeft_GrSurfaceOrigin); + proxy = provider->findOrCreateProxyByUniqueKey(key, kBottomLeft_GrSurfaceOrigin); REPORTER_ASSERT(reporter, !proxy); if (proxyIsCached) { REPORTER_ASSERT(reporter, 0 == cache->getResourceCount()); @@ -218,9 +263,9 @@ DEF_GPUTEST_FOR_RENDERING_CONTEXTS(TextureProxyTest, reporter, ctxInfo) { REPORTER_ASSERT(reporter, 0 == cache->getResourceCount()); for (auto fit : { SkBackingFit::kExact, SkBackingFit::kApprox }) { - for (auto create : { deferred_tex, deferred_texRT, wrapped }) { + for (auto create : { deferred_tex, deferred_texRT, wrapped, wrapped_with_key }) { REPORTER_ASSERT(reporter, 0 == cache->getResourceCount()); - basic_test(context, reporter, create(provider, fit), true); + basic_test(context, reporter, create(reporter, provider, fit), true); } REPORTER_ASSERT(reporter, 0 == cache->getResourceCount()); |