Make lazy proxies have 2 modes for proxy/surface key management.
kSynced: Proxy and GrSurface key kept in sync.
kUnsynced: Proxy and GrSurface keys are unrelated.
This will allow cross-context image generators' lazy instantiation
callbacks to use unique keys to find any pre-existing backing GrTexture
rather than keeping an unref'ed bare pointer to the GrTexture.
Bug: skia:8927
Change-Id: Id15e2a64e8d2e56c4ce70b9399eb1d8bcea6ac9a
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/204723
Commit-Queue: Brian Salomon <bsalomon@google.com>
Reviewed-by: Robert Phillips <robertphillips@google.com>
diff --git a/src/gpu/GrAHardwareBufferImageGenerator.cpp b/src/gpu/GrAHardwareBufferImageGenerator.cpp
index 2055955..51908e1 100644
--- a/src/gpu/GrAHardwareBufferImageGenerator.cpp
+++ b/src/gpu/GrAHardwareBufferImageGenerator.cpp
@@ -150,7 +150,8 @@
sk_sp<GrTextureProxy> texProxy = proxyProvider->createLazyProxy(
[direct, buffer = AutoAHBRelease(hardwareBuffer), width, height, pixelConfig,
- isProtectedContent, backendFormat](GrResourceProvider* resourceProvider) {
+ isProtectedContent, backendFormat](GrResourceProvider* resourceProvider)
+ -> GrSurfaceProxy::LazyInstantiationResult {
GrAHardwareBufferUtils::DeleteImageProc deleteImageProc = nullptr;
GrAHardwareBufferUtils::DeleteImageCtx deleteImageCtx = nullptr;
@@ -163,7 +164,7 @@
backendFormat,
false);
if (!backendTex.isValid()) {
- return sk_sp<GrTexture>();
+ return {};
}
SkASSERT(deleteImageProc && deleteImageCtx);
@@ -175,14 +176,14 @@
backendTex, kBorrow_GrWrapOwnership, GrWrapCacheable::kYes, kRead_GrIOType);
if (!tex) {
deleteImageProc(deleteImageCtx);
- return sk_sp<GrTexture>();
+ return {};
}
if (deleteImageProc) {
tex->setRelease(deleteImageProc, deleteImageCtx);
}
- return tex;
+ return std::move(tex);
},
backendFormat, desc, fSurfaceOrigin, GrMipMapped::kNo,
GrInternalSurfaceFlags::kReadOnly, SkBackingFit::kExact, SkBudgeted::kNo);
diff --git a/src/gpu/GrBackendTextureImageGenerator.cpp b/src/gpu/GrBackendTextureImageGenerator.cpp
index 1bba019..8fdf8cd 100644
--- a/src/gpu/GrBackendTextureImageGenerator.cpp
+++ b/src/gpu/GrBackendTextureImageGenerator.cpp
@@ -136,18 +136,15 @@
desc.fConfig = fConfig;
GrMipMapped mipMapped = fBackendTexture.hasMipMaps() ? GrMipMapped::kYes : GrMipMapped::kNo;
- // Must make copies of member variables to capture in the lambda since this image generator may
- // be deleted before we actuallly execute the lambda.
- sk_sp<GrSemaphore> semaphore = fSemaphore;
- GrBackendTexture backendTexture = fBackendTexture;
- RefHelper* refHelper = fRefHelper;
-
- GrBackendFormat format = backendTexture.getBackendFormat();
+ GrBackendFormat format = fBackendTexture.getBackendFormat();
SkASSERT(format.isValid());
+ // Must make copies of member variables to capture in the lambda since this image generator may
+ // be deleted before we actually execute the lambda.
sk_sp<GrTextureProxy> proxy = proxyProvider->createLazyProxy(
- [refHelper, releaseProcHelper, semaphore,
- backendTexture](GrResourceProvider* resourceProvider) {
+ [refHelper = fRefHelper, releaseProcHelper, semaphore = fSemaphore,
+ backendTexture = fBackendTexture](GrResourceProvider* resourceProvider)
+ -> GrSurfaceProxy::LazyInstantiationResult {
if (semaphore) {
resourceProvider->priv().gpu()->waitSemaphore(semaphore);
}
@@ -172,14 +169,13 @@
backendTexture, kBorrow_GrWrapOwnership, GrWrapCacheable::kNo,
kRead_GrIOType);
if (!tex) {
- return sk_sp<GrTexture>();
+ return {};
}
refHelper->fBorrowedTexture = tex.get();
tex->setRelease(releaseProcHelper);
}
-
- return tex;
+ return std::move(tex);
},
format, desc, fSurfaceOrigin, mipMapped, GrInternalSurfaceFlags::kReadOnly,
SkBackingFit::kExact, SkBudgeted::kNo);
diff --git a/src/gpu/GrProxyProvider.cpp b/src/gpu/GrProxyProvider.cpp
index efa7bf0..526e99c 100644
--- a/src/gpu/GrProxyProvider.cpp
+++ b/src/gpu/GrProxyProvider.cpp
@@ -255,8 +255,8 @@
if (surfaceFlags & GrInternalSurfaceFlags::kNoPendingIO) {
resourceProviderFlags |= GrResourceProvider::Flags::kNoPendingIO;
}
- return resourceProvider->createTexture(desc, budgeted, fit, mipLevel,
- resourceProviderFlags);
+ return LazyInstantiationResult(resourceProvider->createTexture(
+ desc, budgeted, fit, mipLevel, resourceProviderFlags));
},
format, desc, kTopLeft_GrSurfaceOrigin, GrMipMapped::kNo, surfaceFlags, fit, budgeted);
@@ -374,8 +374,8 @@
SkASSERT(texels[i].fPixels);
}
- return resourceProvider->createTexture(desc, SkBudgeted::kYes, texels.get(),
- mipLevelCount);
+ return LazyInstantiationResult(resourceProvider->createTexture(
+ desc, SkBudgeted::kYes, texels.get(), mipLevelCount));
},
format, desc, kTopLeft_GrSurfaceOrigin, GrMipMapped::kYes, SkBackingFit::kExact,
SkBudgeted::kYes);
@@ -446,7 +446,8 @@
GrMipLevel texels;
texels.fPixels = data->data();
texels.fRowBytes = GrBytesPerPixel(desc.fConfig)*desc.fWidth;
- return resourceProvider->createTexture(desc, SkBudgeted::kYes, &texels, 1);
+ return LazyInstantiationResult(
+ resourceProvider->createTexture(desc, SkBudgeted::kYes, &texels, 1));
},
format, desc, kTopLeft_GrSurfaceOrigin, GrMipMapped::kNo, SkBackingFit::kExact,
SkBudgeted::kYes);
diff --git a/src/gpu/GrProxyProvider.h b/src/gpu/GrProxyProvider.h
index 358cf1d..089093c 100644
--- a/src/gpu/GrProxyProvider.h
+++ b/src/gpu/GrProxyProvider.h
@@ -136,7 +136,9 @@
sk_sp<GrRenderTargetProxy> wrapVulkanSecondaryCBAsRenderTarget(const SkImageInfo&,
const GrVkDrawableInfo&);
- using LazyInstantiateCallback = std::function<sk_sp<GrSurface>(GrResourceProvider*)>;
+ using LazyInstantiationKeyMode = GrSurfaceProxy::LazyInstantiationKeyMode;
+ using LazyInstantiationResult = GrSurfaceProxy::LazyInstantiationResult;
+ using LazyInstantiateCallback = GrSurfaceProxy::LazyInstantiateCallback;
enum class Renderable : bool {
kNo = false,
diff --git a/src/gpu/GrSurfaceProxy.cpp b/src/gpu/GrSurfaceProxy.cpp
index b5ddb6e..e9f14cb 100644
--- a/src/gpu/GrSurfaceProxy.cpp
+++ b/src/gpu/GrSurfaceProxy.cpp
@@ -433,8 +433,11 @@
fProxy->asTextureProxy()->getUniqueKey());
}
+ bool syncKey = true;
if (!surface) {
- surface = fProxy->fLazyInstantiateCallback(resourceProvider);
+ auto result = fProxy->fLazyInstantiateCallback(resourceProvider);
+ surface = std::move(result.fSurface);
+ syncKey = result.fKeyMode == GrSurfaceProxy::LazyInstantiationKeyMode::kSynced;
}
if (GrSurfaceProxy::LazyInstantiationType::kSingleUse == fProxy->fLazyInstantiationType) {
fProxy->fLazyInstantiateCallback = nullptr;
@@ -463,14 +466,19 @@
}
if (GrTextureProxy* texProxy = fProxy->asTextureProxy()) {
- const GrUniqueKey& key = texProxy->getUniqueKey();
- if (key.isValid()) {
- if (!surface->asTexture()->getUniqueKey().isValid()) {
- // If 'surface' is newly created, attach the unique key
- resourceProvider->assignUniqueKeyToResource(key, surface.get());
+ texProxy->setTargetKeySync(syncKey);
+ if (syncKey) {
+ const GrUniqueKey& key = texProxy->getUniqueKey();
+ if (key.isValid()) {
+ if (!surface->asTexture()->getUniqueKey().isValid()) {
+ // If 'surface' is newly created, attach the unique key
+ resourceProvider->assignUniqueKeyToResource(key, surface.get());
+ } else {
+ // otherwise we had better have reattached to a cached version
+ SkASSERT(surface->asTexture()->getUniqueKey() == key);
+ }
} else {
- // otherwise we had better have reattached to a cached version
- SkASSERT(surface->asTexture()->getUniqueKey() == key);
+ SkASSERT(!surface->getUniqueKey().isValid());
}
}
}
diff --git a/src/gpu/GrTextureProxy.cpp b/src/gpu/GrTextureProxy.cpp
index 362c469..b319dba 100644
--- a/src/gpu/GrTextureProxy.cpp
+++ b/src/gpu/GrTextureProxy.cpp
@@ -154,7 +154,7 @@
SkASSERT(key.isValid());
SkASSERT(!fUniqueKey.isValid()); // proxies can only ever get one uniqueKey
- if (fTarget) {
+ if (fTarget && fSyncTargetKey) {
if (!fTarget->getUniqueKey().isValid()) {
fTarget->resourcePriv().setUniqueKey(key);
}
diff --git a/src/gpu/ccpr/GrCCAtlas.cpp b/src/gpu/ccpr/GrCCAtlas.cpp
index c297443..82b06f0 100644
--- a/src/gpu/ccpr/GrCCAtlas.cpp
+++ b/src/gpu/ccpr/GrCCAtlas.cpp
@@ -85,9 +85,6 @@
fTextureProxy = GrProxyProvider::MakeFullyLazyProxy(
[this, pixelConfig](GrResourceProvider* resourceProvider) {
- if (!resourceProvider) {
- return sk_sp<GrTexture>();
- }
if (!fBackingTexture) {
GrSurfaceDesc desc;
desc.fFlags = kRenderTarget_GrSurfaceFlag;
@@ -96,7 +93,7 @@
desc.fConfig = pixelConfig;
fBackingTexture = resourceProvider->createTexture(desc, SkBudgeted::kYes);
}
- return fBackingTexture;
+ return GrSurfaceProxy::LazyInstantiationResult(fBackingTexture);
},
format, GrProxyProvider::Renderable::kYes, kTextureOrigin, pixelConfig, caps);
}
diff --git a/src/gpu/ccpr/GrCCClipPath.cpp b/src/gpu/ccpr/GrCCClipPath.cpp
index 8b8d8a6..4c82fb1 100644
--- a/src/gpu/ccpr/GrCCClipPath.cpp
+++ b/src/gpu/ccpr/GrCCClipPath.cpp
@@ -20,10 +20,8 @@
GrSRGBEncoded::kNo);
fAtlasLazyProxy = GrProxyProvider::MakeFullyLazyProxy(
- [this](GrResourceProvider* resourceProvider) {
- if (!resourceProvider) {
- return sk_sp<GrTexture>();
- }
+ [this](GrResourceProvider* resourceProvider)
+ -> GrSurfaceProxy::LazyInstantiationResult {
SkASSERT(fHasAtlas);
SkASSERT(!fHasAtlasTransform);
@@ -31,7 +29,7 @@
if (!textureProxy || !textureProxy->instantiate(resourceProvider)) {
fAtlasScale = fAtlasTranslate = {0, 0};
SkDEBUGCODE(fHasAtlasTransform = true);
- return sk_sp<GrTexture>();
+ return {};
}
SkASSERT(kTopLeft_GrSurfaceOrigin == textureProxy->origin());