Add native caching of uniquely keyed GrTextureProxies (take 2)
TBR=bsalomon@google.com
Change-Id: I590dcdc85fb60706c7eb06277694791dc04c9141
Reviewed-on: https://skia-review.googlesource.com/49543
Reviewed-by: Brian Salomon <bsalomon@google.com>
Commit-Queue: Robert Phillips <robertphillips@google.com>
diff --git a/src/gpu/GrResourceCache.cpp b/src/gpu/GrResourceCache.cpp
index f6170c0..c207b44 100644
--- a/src/gpu/GrResourceCache.cpp
+++ b/src/gpu/GrResourceCache.cpp
@@ -10,6 +10,8 @@
#include "GrCaps.h"
#include "GrGpuResourceCacheAccess.h"
+#include "GrTexture.h"
+#include "GrTextureProxyCacheAccess.h"
#include "GrTracing.h"
#include "SkGr.h"
#include "SkMessageBus.h"
@@ -578,6 +580,8 @@
void GrResourceCache::processInvalidUniqueKeys(
const SkTArray<GrUniqueKeyInvalidatedMessage>& msgs) {
for (int i = 0; i < msgs.count(); ++i) {
+ this->processInvalidProxyUniqueKey(msgs[i].key());
+
GrGpuResource* resource = this->findAndRefUniqueResource(msgs[i].key());
if (resource) {
resource->resourcePriv().removeUniqueKey();
@@ -847,3 +851,63 @@
}
#endif
+
+void GrResourceCache::assignUniqueKeyToProxy(const GrUniqueKey& key, GrTextureProxy* proxy) {
+ SkASSERT(key.isValid());
+ SkASSERT(proxy);
+
+ // If there is already a GrResource with this key then the caller has violated the normal
+ // usage pattern of uniquely keyed resources (e.g., they have created one w/o first seeing
+ // if it already existed in the cache).
+ SkASSERT(!this->findAndRefUniqueResource(key));
+
+ // 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 == proxy->isBudgeted() &&
+ (!proxy->priv().isInstantiated() ||
+ !proxy->priv().peekSurface()->resourcePriv().refsWrappedObjects())) {
+ return;
+ }
+
+ SkASSERT(!fUniquelyKeyedProxies.find(key)); // multiple proxies can't get the same key
+
+ proxy->cacheAccess().setUniqueKey(this, key);
+ SkASSERT(proxy->getUniqueKey() == key);
+ fUniquelyKeyedProxies.add(proxy);
+}
+
+sk_sp<GrTextureProxy> GrResourceCache::findProxyByUniqueKey(const GrUniqueKey& key,
+ GrSurfaceOrigin origin) {
+
+ sk_sp<GrTextureProxy> result = sk_ref_sp(fUniquelyKeyedProxies.find(key));
+ if (result) {
+ SkASSERT(result->origin() == origin);
+ return result;
+ }
+
+ GrGpuResource* resource = findAndRefUniqueResource(key);
+ if (!resource) {
+ return nullptr;
+ }
+
+ sk_sp<GrTexture> texture(static_cast<GrSurface*>(resource)->asTexture());
+ SkASSERT(texture);
+
+ result = GrSurfaceProxy::MakeWrapped(std::move(texture), origin);
+ SkASSERT(result->getUniqueKey() == key);
+ fUniquelyKeyedProxies.add(result.get());
+ return result;
+}
+
+void GrResourceCache::processInvalidProxyUniqueKey(const GrUniqueKey& key) {
+ // Note: this method is called for the whole variety of GrGpuResources so often 'key'
+ // will not be in 'fUniquelyKeyedProxies'.
+ GrTextureProxy* proxy = fUniquelyKeyedProxies.find(key);
+ if (proxy) {
+ fUniquelyKeyedProxies.remove(key);
+ proxy->cacheAccess().clearUniqueKey();
+ }
+}
+