Copy on write for wrapped backend texture surfaces.

Makes SkImage_Gpu backed by two proxies, an original and a copy. The
image uses the original until a new render task is bound to it at which
point further uses of the image will use the copy. If the image is ever
used off a GrDirectContext we fall over to the copy. If the copy is
never used and never can be used by the next flush then the render
task that populates it is marked "skipped" and we don't perform the
copy.

Bug: skia:11208

Change-Id: Id255f4a733acc608c8a53c1a5633207aeafc404b
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/366282
Commit-Queue: Brian Salomon <bsalomon@google.com>
Reviewed-by: Robert Phillips <robertphillips@google.com>
diff --git a/src/gpu/GrSurfaceContext.h b/src/gpu/GrSurfaceContext.h
index 80e3fb1..b51d1af 100644
--- a/src/gpu/GrSurfaceContext.h
+++ b/src/gpu/GrSurfaceContext.h
@@ -18,6 +18,7 @@
 #include "src/gpu/GrDataUtils.h"
 #include "src/gpu/GrImageInfo.h"
 #include "src/gpu/GrPixmap.h"
+#include "src/gpu/GrRenderTask.h"
 #include "src/gpu/GrSurfaceProxy.h"
 #include "src/gpu/GrSurfaceProxyView.h"
 
@@ -181,12 +182,12 @@
 
 #if GR_TEST_UTILS
     bool testCopy(sk_sp<GrSurfaceProxy> src, const SkIRect& srcRect, const SkIPoint& dstPoint) {
-        return this->copy(std::move(src), srcRect, dstPoint);
+        return this->copy(std::move(src), srcRect, dstPoint) != nullptr;
     }
 
     bool testCopy(sk_sp<GrSurfaceProxy> src) {
         auto rect = SkIRect::MakeSize(src->dimensions());
-        return this->copy(std::move(src), rect, {0, 0});
+        return this->copy(std::move(src), rect, {0, 0}) != nullptr;
     }
 #endif
 
@@ -234,7 +235,8 @@
      * should go through GrSurfaceProxy::Copy.
      * @param src       src of pixels
      * @param dstPoint  the origin of the 'srcRect' in the destination coordinate space
-     * @return          true if the copy succeeded; false otherwise
+     * @return          a task (that may be skippable by calling canSkip) if successful and
+     *                  null otherwise.
      *
      * Note: Notionally, 'srcRect' is clipped to 'src's extent with 'dstPoint' being adjusted.
      *       Then the 'srcRect' offset by 'dstPoint' is clipped against the dst's extent.
@@ -242,7 +244,7 @@
      *       regions will not be shifted. The 'src' must have the same origin as the backing proxy
      *       of fSurfaceContext.
      */
-    bool copy(sk_sp<GrSurfaceProxy> src, SkIRect srcRect, SkIPoint dstPoint);
+    sk_sp<GrRenderTask> copy(sk_sp<GrSurfaceProxy> src, SkIRect srcRect, SkIPoint dstPoint);
 
     class AsyncReadResult;