Reland "Remove support for copyAsDraw in gpu copySurface."

This reverts commit c5167c053bd58e6afbad83fe493c0231df3f9704.

Reason for revert: fixed

Original change's description:
> Revert "Remove support for copyAsDraw in gpu copySurface."
>
> This reverts commit 6565506463db042d3d543a1707f473cdf1ef4e9e.
>
> Reason for revert: seems to break things?
>
> Original change's description:
> > Remove support for copyAsDraw in gpu copySurface.
> >
> > The major changes on a higher lever are:
> > 1) The majority of all copies now go through GrSurfaceProxy::Copy which
> > takes in a proxy and returns a new one with the data copied to it. This
> > is the most common use case within Ganesh.
> >
> > 2) The backend copy calls no longer do draws, require origins to be the
> > same, and won't do any swizzling or adjustment of subrects. They are
> > all implemented to be dumb copy this data to this other spot.
> >
> > 3) The GrSurfaceContext copy call has now been moved to priv and renamed
> > copyNoDraw, and a new priv copyAsDraw was added to GrRenderTargetContext.
> >
> > 4) WritePixels and ReplaceRenderTarget both need to specifiy the destination
> > of copies. They are the only users (besides the GrSurfaceProxy::Copy) which
> > call the priv methods on GrSurfaceContext.
> >
> > Change-Id: Iaf1eb3a73ccaf39a75af77e281dae594f809186f
> > Reviewed-on: https://skia-review.googlesource.com/c/skia/+/217459
> > Reviewed-by: Brian Salomon <bsalomon@google.com>
> > Commit-Queue: Greg Daniel <egdaniel@google.com>
>
> TBR=egdaniel@google.com,bsalomon@google.com,robertphillips@google.com
>
> Change-Id: Id43aa8aa1451e794342e930441d9975b90e6b59f
> No-Presubmit: true
> No-Tree-Checks: true
> No-Try: true
> Reviewed-on: https://skia-review.googlesource.com/c/skia/+/218549
> Reviewed-by: Greg Daniel <egdaniel@google.com>
> Commit-Queue: Greg Daniel <egdaniel@google.com>

TBR=egdaniel@google.com,bsalomon@google.com,robertphillips@google.com

Change-Id: I1a96f85ae2ff7622a6b57406755d478e7fbcf56e
No-Presubmit: true
No-Tree-Checks: true
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/218797
Reviewed-by: Brian Salomon <bsalomon@google.com>
Commit-Queue: Greg Daniel <egdaniel@google.com>
diff --git a/src/gpu/GrRenderTargetContext.cpp b/src/gpu/GrRenderTargetContext.cpp
index 6b77d30..56e38c5 100644
--- a/src/gpu/GrRenderTargetContext.cpp
+++ b/src/gpu/GrRenderTargetContext.cpp
@@ -1785,27 +1785,17 @@
     int srcH = srcRect.height();
     int srcX = srcRect.fLeft;
     int srcY = srcRect.fTop;
-    sk_sp<GrSurfaceContext> srcContext = sk_ref_sp(this);
+    sk_sp<GrTextureProxy> texProxy = sk_ref_sp(fRenderTargetProxy->asTextureProxy());
     SkCanvas::SrcRectConstraint constraint = SkCanvas::kStrict_SrcRectConstraint;
-    if (!this->asTextureProxy()) {
-        GrSurfaceDesc desc;
-        desc.fWidth = srcW;
-        desc.fHeight = srcH;
-        desc.fConfig = fRenderTargetProxy->config();
-        auto sContext = direct->priv().makeDeferredSurfaceContext(
-                fRenderTargetProxy->backendFormat().makeTexture2D(), desc, this->origin(),
-                GrMipMapped::kNo, SkBackingFit::kApprox, SkBudgeted::kNo,
-                this->colorSpaceInfo().refColorSpace());
-        if (!sContext) {
-            return nullptr;
-        }
-        if (!sContext->copy(fRenderTargetProxy.get(), srcRect, {0, 0})) {
+    if (!texProxy) {
+        texProxy = GrSurfaceProxy::Copy(fContext, fRenderTargetProxy.get(), GrMipMapped::kNo,
+                                        srcRect, SkBackingFit::kApprox, SkBudgeted::kNo);
+        if (!texProxy) {
             return nullptr;
         }
         srcX = 0;
         srcY = 0;
         constraint = SkCanvas::kFast_SrcRectConstraint;
-        srcContext = std::move(sContext);
     }
 
     float sx = (float)info.width() / srcW;
@@ -1824,33 +1814,35 @@
         stepsY = sy != 1.f;
     }
     SkASSERT(stepsX || stepsY);
+    auto currentColorSpace = this->colorSpaceInfo().refColorSpace();
     // Assume we should ignore the rescale linear request if the surface has no color space since
     // it's unclear how we'd linearize from an unknown color space.
     if (rescaleGamma == SkSurface::RescaleGamma::kLinear &&
-        srcContext->colorSpaceInfo().colorSpace() &&
-        !srcContext->colorSpaceInfo().colorSpace()->gammaIsLinear()) {
-        auto cs = srcContext->colorSpaceInfo().colorSpace()->makeLinearGamma();
+        currentColorSpace.get() && !currentColorSpace->gammaIsLinear()) {
+        auto cs = currentColorSpace->makeLinearGamma();
         auto backendFormat = this->caps()->getBackendFormatFromGrColorType(GrColorType::kRGBA_F16,
                                                                            GrSRGBEncoded::kNo);
-        auto xform = GrColorSpaceXform::Make(srcContext->colorSpaceInfo().colorSpace(),
-                                             kPremul_SkAlphaType, cs.get(), kPremul_SkAlphaType);
+        auto xform = GrColorSpaceXform::Make(currentColorSpace.get(), kPremul_SkAlphaType, cs.get(),
+                                             kPremul_SkAlphaType);
         // We'll fall back to kRGBA_8888 if half float not supported.
         auto linearRTC = fContext->priv().makeDeferredRenderTargetContextWithFallback(
-                backendFormat, SkBackingFit::kExact, srcW, srcH, kRGBA_half_GrPixelConfig,
-                std::move(cs), 1, GrMipMapped::kNo, kTopLeft_GrSurfaceOrigin);
+                backendFormat, SkBackingFit::kExact, srcW, srcH, kRGBA_half_GrPixelConfig, cs, 1,
+                GrMipMapped::kNo, kTopLeft_GrSurfaceOrigin);
         if (!linearRTC) {
             return nullptr;
         }
-        linearRTC->drawTexture(GrNoClip(), srcContext->asTextureProxyRef(),
+        linearRTC->drawTexture(GrNoClip(), texProxy,
                                GrSamplerState::Filter::kNearest, SkBlendMode::kSrc,
                                SK_PMColor4fWHITE, SkRect::Make(srcRect), SkRect::MakeWH(srcW, srcH),
                                GrAA::kNo, GrQuadAAFlags::kNone, constraint, SkMatrix::I(),
                                std::move(xform));
-        srcContext = std::move(linearRTC);
+        texProxy = linearRTC->asTextureProxyRef();
+        currentColorSpace = std::move(cs);
         srcX = 0;
         srcY = 0;
         constraint = SkCanvas::kFast_SrcRectConstraint;
     }
+    sk_sp<GrRenderTargetContext> currRTC;
     while (stepsX || stepsY) {
         int nextW = info.width();
         int nextH = info.height();
@@ -1872,23 +1864,22 @@
             }
             --stepsY;
         }
-        GrBackendFormat backendFormat =
-                srcContext->asSurfaceProxy()->backendFormat().makeTexture2D();
-        GrPixelConfig config = srcContext->asSurfaceProxy()->config();
-        auto cs = srcContext->colorSpaceInfo().refColorSpace();
+        GrBackendFormat backendFormat = texProxy->backendFormat().makeTexture2D();
+        GrPixelConfig config = texProxy->config();
+        auto cs = currentColorSpace;
         sk_sp<GrColorSpaceXform> xform;
         if (!stepsX && !stepsY) {
             // Might as well fold conversion to final info in the last step.
             backendFormat = this->caps()->getBackendFormatFromColorType(info.colorType());
             config = this->caps()->getConfigFromBackendFormat(backendFormat, info.colorType());
             cs = info.refColorSpace();
-            xform = GrColorSpaceXform::Make(srcContext->colorSpaceInfo().colorSpace(),
+            xform = GrColorSpaceXform::Make(this->colorSpaceInfo().colorSpace(),
                                             kPremul_SkAlphaType, cs.get(), info.alphaType());
         }
-        auto nextRTC = fContext->priv().makeDeferredRenderTargetContextWithFallback(
+        currRTC = fContext->priv().makeDeferredRenderTargetContextWithFallback(
                 backendFormat, SkBackingFit::kExact, nextW, nextH, config, std::move(cs), 1,
                 GrMipMapped::kNo, kTopLeft_GrSurfaceOrigin);
-        if (!nextRTC) {
+        if (!currRTC) {
             return nullptr;
         }
         auto dstRect = SkRect::MakeWH(nextW, nextH);
@@ -1902,14 +1893,12 @@
             } else if (nextH == srcH) {
                 dir = GrBicubicEffect::Direction::kX;
             }
-            if (srcW != srcContext->width() || srcH != srcContext->height()) {
+            if (srcW != texProxy->width() || srcH != texProxy->height()) {
                 auto domain = GrTextureDomain::MakeTexelDomain(
                         SkIRect::MakeXYWH(srcX, srcY, srcW, srcH), GrTextureDomain::kClamp_Mode);
-                fp = GrBicubicEffect::Make(srcContext->asTextureProxyRef(), matrix, domain, dir,
-                                           kPremul_SkAlphaType);
+                fp = GrBicubicEffect::Make(texProxy, matrix, domain, dir, kPremul_SkAlphaType);
             } else {
-                fp = GrBicubicEffect::Make(srcContext->asTextureProxyRef(), matrix, dir,
-                                           kPremul_SkAlphaType);
+                fp = GrBicubicEffect::Make(texProxy, matrix, dir, kPremul_SkAlphaType);
             }
             if (xform) {
                 fp = GrColorSpaceXformEffect::Make(std::move(fp), std::move(xform));
@@ -1917,26 +1906,24 @@
             GrPaint paint;
             paint.addColorFragmentProcessor(std::move(fp));
             paint.setPorterDuffXPFactory(SkBlendMode::kSrc);
-            nextRTC->drawFilledRect(GrNoClip(), std::move(paint), GrAA::kNo, SkMatrix::I(),
+            currRTC->drawFilledRect(GrNoClip(), std::move(paint), GrAA::kNo, SkMatrix::I(),
                                     dstRect);
         } else {
             auto filter = rescaleQuality == kNone_SkFilterQuality ? GrSamplerState::Filter::kNearest
                                                                   : GrSamplerState::Filter::kBilerp;
             auto srcSubset = SkRect::MakeXYWH(srcX, srcY, srcW, srcH);
-            nextRTC->drawTexture(GrNoClip(), srcContext->asTextureProxyRef(), filter,
-                                 SkBlendMode::kSrc, SK_PMColor4fWHITE, srcSubset, dstRect,
-                                 GrAA::kNo, GrQuadAAFlags::kNone, constraint, SkMatrix::I(),
-                                 std::move(xform));
+            currRTC->drawTexture(GrNoClip(), texProxy, filter, SkBlendMode::kSrc, SK_PMColor4fWHITE,
+                                 srcSubset, dstRect, GrAA::kNo, GrQuadAAFlags::kNone, constraint,
+                                 SkMatrix::I(), std::move(xform));
         }
-        srcContext = std::move(nextRTC);
+        texProxy = currRTC->asTextureProxyRef();
         srcX = srcY = 0;
         srcW = nextW;
         srcH = nextH;
         constraint = SkCanvas::kFast_SrcRectConstraint;
     }
-    auto result = sk_ref_sp(srcContext->asRenderTargetContext());
-    SkASSERT(result);
-    return result;
+    SkASSERT(currRTC);
+    return currRTC;
 }
 
 void GrRenderTargetContext::asyncRescaleAndReadPixels(
@@ -2001,24 +1988,13 @@
             SkRect srcRectToDraw = SkRect::Make(srcRect);
             // If the src is not texturable first try to make a copy to a texture.
             if (!texProxy) {
-                GrSurfaceDesc desc;
-                desc.fWidth = srcRect.width();
-                desc.fHeight = srcRect.height();
-                desc.fConfig = fRenderTargetProxy->config();
-                auto sContext = direct->priv().makeDeferredSurfaceContext(
-                        backendFormat, desc, this->origin(), GrMipMapped::kNo,
-                        SkBackingFit::kApprox, SkBudgeted::kNo,
-                        this->colorSpaceInfo().refColorSpace());
-                if (!sContext) {
+                texProxy = GrSurfaceProxy::Copy(fContext, fRenderTargetProxy.get(),
+                                                GrMipMapped::kNo, srcRect, SkBackingFit::kApprox,
+                                                SkBudgeted::kNo);
+                if (!texProxy) {
                     callback(context, nullptr, 0);
                     return;
                 }
-                if (!sContext->copy(fRenderTargetProxy.get(), srcRect, {0, 0})) {
-                    callback(context, nullptr, 0);
-                    return;
-                }
-                texProxy = sk_ref_sp(sContext->asTextureProxy());
-                SkASSERT(texProxy);
                 srcRectToDraw = SkRect::MakeWH(srcRect.width(), srcRect.height());
             }
             rtc = direct->priv().makeDeferredRenderTargetContext(
@@ -2568,12 +2544,10 @@
     GrSurfaceDesc desc;
     bool rectsMustMatch = false;
     bool disallowSubrect = false;
-    GrSurfaceOrigin origin;
-    if (!this->caps()->initDescForDstCopy(rtProxy, &desc, &origin, &rectsMustMatch,
+    if (!this->caps()->initDescForDstCopy(rtProxy, &desc, &rectsMustMatch,
                                           &disallowSubrect)) {
         desc.fFlags = kRenderTarget_GrSurfaceFlag;
         desc.fConfig = rtProxy->config();
-        origin = rtProxy->origin();
     }
 
     if (!disallowSubrect) {
@@ -2582,36 +2556,56 @@
 
     SkIPoint dstPoint, dstOffset;
     SkBackingFit fit;
+    GrSurfaceProxy::RectsMustMatch matchRects;
     if (rectsMustMatch) {
         desc.fWidth = rtProxy->width();
         desc.fHeight = rtProxy->height();
         dstPoint = {copyRect.fLeft, copyRect.fTop};
         dstOffset = {0, 0};
         fit = SkBackingFit::kExact;
+        matchRects = GrSurfaceProxy::RectsMustMatch::kYes;
     } else {
         desc.fWidth = copyRect.width();
         desc.fHeight = copyRect.height();
         dstPoint = {0, 0};
         dstOffset = {copyRect.fLeft, copyRect.fTop};
         fit = SkBackingFit::kApprox;
+        matchRects = GrSurfaceProxy::RectsMustMatch::kNo;
     }
 
-    SkASSERT(rtProxy->backendFormat().textureType() == GrTextureType::k2D);
-    const GrBackendFormat& format = rtProxy->backendFormat();
-    sk_sp<GrSurfaceContext> sContext = fContext->priv().makeDeferredSurfaceContext(
-            format, desc, origin, GrMipMapped::kNo, fit, SkBudgeted::kYes,
-            sk_ref_sp(this->colorSpaceInfo().colorSpace()));
-    if (!sContext) {
-        SkDebugf("setupDstTexture: surfaceContext creation failed.\n");
-        return false;
-    }
+    sk_sp<GrTextureProxy> newProxy = GrSurfaceProxy::Copy(fContext, rtProxy, GrMipMapped::kNo,
+                                                          copyRect, fit, SkBudgeted::kYes,
+                                                          matchRects);
+    SkASSERT(newProxy);
 
-    if (!sContext->copy(rtProxy, copyRect, dstPoint)) {
-        SkDebugf("setupDstTexture: copy failed.\n");
-        return false;
-    }
-
-    dstProxy->setProxy(sContext->asTextureProxyRef());
+    dstProxy->setProxy(std::move(newProxy));
     dstProxy->setOffset(dstOffset);
     return true;
 }
+
+bool GrRenderTargetContext::blitTexture(GrTextureProxy* src, const SkIRect& srcRect,
+                                        const SkIPoint& dstPoint) {
+    SkIRect clippedSrcRect;
+    SkIPoint clippedDstPoint;
+    if (!GrClipSrcRectAndDstPoint(this->asSurfaceProxy()->isize(), src->isize(), srcRect, dstPoint,
+                                  &clippedSrcRect, &clippedDstPoint)) {
+        return false;
+    }
+
+    GrPaint paint;
+    paint.setPorterDuffXPFactory(SkBlendMode::kSrc);
+    auto fp = GrSimpleTextureEffect::Make(sk_ref_sp(src->asTextureProxy()),
+                                          SkMatrix::I());
+    if (!fp) {
+        return false;
+    }
+    paint.addColorFragmentProcessor(std::move(fp));
+
+    this->fillRectToRect(
+            GrNoClip(), std::move(paint), GrAA::kNo, SkMatrix::I(),
+            SkRect::MakeXYWH(clippedDstPoint.fX, clippedDstPoint.fY, clippedSrcRect.width(),
+                             clippedSrcRect.height()),
+            SkRect::Make(clippedSrcRect));
+    return true;
+}
+