Actually reuse GrTexture if SkPromiseImageTexture used with multiple
images. Change-Id: Id68d2f2a4c0012b2219a505f1259a9c9bd014c65 Reviewed-on: https://skia-review.googlesource.com/c/186700 Reviewed-by: Robert Phillips <robertphillips@google.com> Commit-Queue: Brian Salomon <bsalomon@google.com>
This commit is contained in:
parent
aae638807c
commit
0d60676556
@ -64,14 +64,13 @@ public:
|
||||
SkASSERT(0 == fPendingReads);
|
||||
SkASSERT(0 == fPendingWrites);
|
||||
|
||||
SkASSERT(fRefCnt == fTarget->fRefCnt);
|
||||
SkASSERT(!fTarget->internalHasPendingIO());
|
||||
// In the current hybrid world, the proxy and backing surface are ref/unreffed in
|
||||
// synchrony. In this instance we're deInstantiating the proxy so, regardless of the
|
||||
// number of refs on the backing surface, we're going to remove it. If/when the proxy
|
||||
// is re-instantiated all the refs on the proxy (presumably due to multiple uses in ops)
|
||||
// will be transfered to the new surface.
|
||||
for (int refs = fTarget->fRefCnt; refs; --refs) {
|
||||
// synchrony. Each ref we've added or removed to the proxy was mirrored to the backing
|
||||
// surface. Though, that backing surface could be owned by other proxies as well. Remove
|
||||
// a ref from the backing surface for each ref the proxy has since we are about to remove
|
||||
// our pointer to the surface. If this proxy is reinstantiated then all the proxy's refs
|
||||
// get transferred to the (possibly new) backing surface.
|
||||
for (int refs = fRefCnt; refs; --refs) {
|
||||
fTarget->unref();
|
||||
}
|
||||
fTarget = nullptr;
|
||||
|
@ -459,21 +459,31 @@ sk_sp<GrTextureProxy> SkImage_GpuBase::MakePromiseImageLazyProxy(
|
||||
return sk_sp<GrTexture>();
|
||||
}
|
||||
|
||||
auto tex = resourceProvider->wrapBackendTexture(backendTexture, kBorrow_GrWrapOwnership,
|
||||
GrWrapCacheable::kYes, kRead_GrIOType);
|
||||
if (!tex) {
|
||||
// Even though we failed to wrap the backend texture, we must call the release
|
||||
// proc to keep our contract of always calling Fulfill and Release in pairs.
|
||||
fReleaseContext->release();
|
||||
return sk_sp<GrTexture>();
|
||||
}
|
||||
// The texture gets a ref, which is balanced when the idle callback is called.
|
||||
this->addToIdleContext(tex.get());
|
||||
static const GrUniqueKey::Domain kDomain = GrUniqueKey::GenerateDomain();
|
||||
GrUniqueKey::Builder builder(&fLastFulfilledKey, kDomain, 2, "promise");
|
||||
builder[0] = promiseTexture->uniqueID();
|
||||
builder[1] = fConfig;
|
||||
builder.finish();
|
||||
// A texture with this key may already exist from a different instance of this lazy
|
||||
// callback. This could happen if the client fulfills a promise image with a texture
|
||||
// that was previously used to fulfill a different promise image.
|
||||
sk_sp<GrTexture> tex;
|
||||
if (auto surf = resourceProvider->findByUniqueKey<GrSurface>(fLastFulfilledKey)) {
|
||||
tex = sk_ref_sp(surf->asTexture());
|
||||
SkASSERT(tex);
|
||||
} else {
|
||||
if ((tex = resourceProvider->wrapBackendTexture(
|
||||
backendTexture, kBorrow_GrWrapOwnership, GrWrapCacheable::kYes,
|
||||
kRead_GrIOType))) {
|
||||
tex->resourcePriv().setUniqueKey(fLastFulfilledKey);
|
||||
} else {
|
||||
// Even though we failed to wrap the backend texture, we must call the release
|
||||
// proc to keep our contract of always calling Fulfill and Release in pairs.
|
||||
fReleaseContext->release();
|
||||
return sk_sp<GrTexture>();
|
||||
}
|
||||
}
|
||||
this->addToIdleContext(tex.get());
|
||||
tex->resourcePriv().setUniqueKey(fLastFulfilledKey);
|
||||
SkASSERT(fContextID == SK_InvalidUniqueID ||
|
||||
fContextID == tex->getContext()->uniqueID());
|
||||
|
Loading…
Reference in New Issue
Block a user