aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Greg Daniel <egdaniel@google.com>2017-09-26 12:49:26 -0400
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2017-09-26 17:11:21 +0000
commitcd871401114f402e72420ccd49edecee2532b0e6 (patch)
treea323510790f271cc2e0a85487ab52cbc7ffc9339
parent98a6216b18b57c2f7a0d58f542c60503686aed69 (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.cpp2
-rw-r--r--src/effects/GrCircleBlurFragmentProcessor.fp2
-rw-r--r--src/effects/SkBlurMaskFilter.cpp4
-rw-r--r--src/gpu/GrBitmapTextureMaker.cpp2
-rw-r--r--src/gpu/GrClipStackClip.cpp4
-rw-r--r--src/gpu/GrResourceCache.cpp40
-rw-r--r--src/gpu/GrResourceCache.h38
-rw-r--r--src/gpu/GrResourceProvider.cpp14
-rw-r--r--src/gpu/GrResourceProvider.h12
-rw-r--r--src/gpu/GrSoftwarePathRenderer.cpp2
-rw-r--r--src/gpu/GrSurfaceProxy.cpp20
-rw-r--r--src/gpu/GrTextureAdjuster.cpp5
-rw-r--r--src/gpu/GrTextureMaker.cpp2
-rw-r--r--src/gpu/GrTextureProxy.cpp7
-rw-r--r--src/gpu/SkGr.cpp3
-rw-r--r--src/gpu/effects/GrTextureStripAtlas.cpp2
-rw-r--r--src/image/SkImage_Lazy.cpp2
-rw-r--r--tests/TextureProxyTest.cpp81
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());