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>
diff --git a/src/image/SkImage_GpuBase.cpp b/src/image/SkImage_GpuBase.cpp
index 3308082..7c731cf 100644
--- a/src/image/SkImage_GpuBase.cpp
+++ b/src/image/SkImage_GpuBase.cpp
@@ -459,21 +459,31 @@
                 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());