From 0562eb9c6c98f07732ca96a1dd4e986f1ca089b8 Mon Sep 17 00:00:00 2001 From: Brian Osman Date: Mon, 8 May 2017 11:16:39 -0400 Subject: [PATCH] Allow wrapped resources to have unique keys Previously, wrapped resources were never budgeted. Now we explicitly allow wrapped, unbudgeted resources with unique keys. This allows code that wraps (and re-wraps) external resources with a deterministic key to find the same wrapped resource - saving time and ensuring a single wrapped copy, to preserve state on the resource (like texture sampler state). Bug: skia: Change-Id: I1dd7642f1ed8bb6c620029d46203cf5cb6b3c160 Reviewed-on: https://skia-review.googlesource.com/15241 Commit-Queue: Brian Osman Reviewed-by: Robert Phillips Reviewed-by: Brian Salomon --- src/gpu/GrGpuResource.cpp | 7 +++++-- src/gpu/GrGpuResourcePriv.h | 2 +- src/gpu/GrResourceCache.cpp | 4 ++-- tests/ResourceCacheTest.cpp | 8 ++++++-- 4 files changed, 14 insertions(+), 7 deletions(-) diff --git a/src/gpu/GrGpuResource.cpp b/src/gpu/GrGpuResource.cpp index dcc4e62..c7df663 100644 --- a/src/gpu/GrGpuResource.cpp +++ b/src/gpu/GrGpuResource.cpp @@ -134,8 +134,11 @@ void GrGpuResource::setUniqueKey(const GrUniqueKey& key) { SkASSERT(this->internalHasRef()); SkASSERT(key.isValid()); - // Wrapped and uncached resources can never have a unique key. - if (SkBudgeted::kNo == this->resourcePriv().isBudgeted()) { + // Uncached resources can never have a unique key, unless they're wrapped resources. Wrapped + // resources are a special case: the unique keys give us a weak ref so that we can reuse the + // same resource (rather than re-wrapping). When a wrapped resource is no longer referenced, + // it will always be released - it is never converted to a scratch resource. + if (SkBudgeted::kNo == this->resourcePriv().isBudgeted() && !this->fRefsWrappedObjects) { return; } diff --git a/src/gpu/GrGpuResourcePriv.h b/src/gpu/GrGpuResourcePriv.h index 82bf072..a1e207d 100644 --- a/src/gpu/GrGpuResourcePriv.h +++ b/src/gpu/GrGpuResourcePriv.h @@ -45,7 +45,7 @@ public: */ SkBudgeted isBudgeted() const { bool ret = SkBudgeted::kYes == fResource->fBudgeted; - SkASSERT(ret || !fResource->getUniqueKey().isValid()); + SkASSERT(ret || !fResource->getUniqueKey().isValid() || fResource->fRefsWrappedObjects); return SkBudgeted(ret); } diff --git a/src/gpu/GrResourceCache.cpp b/src/gpu/GrResourceCache.cpp index 596af6d..e3373b2 100644 --- a/src/gpu/GrResourceCache.cpp +++ b/src/gpu/GrResourceCache.cpp @@ -697,8 +697,8 @@ void GrResourceCache::validate() const { if (uniqueKey.isValid()) { ++fContent; SkASSERT(fUniqueHash->find(uniqueKey) == resource); - SkASSERT(!resource->resourcePriv().refsWrappedObjects()); - SkASSERT(SkBudgeted::kYes == resource->resourcePriv().isBudgeted()); + SkASSERT(SkBudgeted::kYes == resource->resourcePriv().isBudgeted() || + resource->resourcePriv().refsWrappedObjects()); if (scratchKey.isValid()) { SkASSERT(!fScratchMap->has(resource, scratchKey)); diff --git a/tests/ResourceCacheTest.cpp b/tests/ResourceCacheTest.cpp index 17e02ba..5590c86 100644 --- a/tests/ResourceCacheTest.cpp +++ b/tests/ResourceCacheTest.cpp @@ -471,11 +471,15 @@ static void test_budgeting(skiatest::Reporter* reporter) { new TestResource(context->getGpu(), SkBudgeted::kNo); unbudgeted->setSize(13); - // Make sure we can't add a unique key to the wrapped resource + // Make sure we can add a unique key to the wrapped resource GrUniqueKey uniqueKey2; make_unique_key<0>(&uniqueKey2, 1); wrapped->resourcePriv().setUniqueKey(uniqueKey2); - REPORTER_ASSERT(reporter, nullptr == cache->findAndRefUniqueResource(uniqueKey2)); + GrGpuResource* wrappedViaKey = cache->findAndRefUniqueResource(uniqueKey2); + REPORTER_ASSERT(reporter, wrappedViaKey != nullptr); + + // Remove the extra ref we just added. + wrappedViaKey->unref(); // Make sure sizes are as we expect REPORTER_ASSERT(reporter, 4 == cache->getResourceCount()); -- 2.7.4