Update GrSurfaceProxy::Copy to return a view.

Additionally this changes updates GrRenderTargetContext drawTexture to take
a view. This was done since there were a bunch of places where the result
of the copy goes straight to the drawTexture call.

Bug: skia:9556
Change-Id: If7094eb51ed343620011d03b86d603e3c6289c17
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/267856
Commit-Queue: Greg Daniel <egdaniel@google.com>
Reviewed-by: Robert Phillips <robertphillips@google.com>
diff --git a/src/gpu/GrAHardwareBufferImageGenerator.cpp b/src/gpu/GrAHardwareBufferImageGenerator.cpp
index ca4c344..33e482a 100644
--- a/src/gpu/GrAHardwareBufferImageGenerator.cpp
+++ b/src/gpu/GrAHardwareBufferImageGenerator.cpp
@@ -80,14 +80,14 @@
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-sk_sp<GrTextureProxy> GrAHardwareBufferImageGenerator::makeProxy(GrRecordingContext* context) {
+GrSurfaceProxyView GrAHardwareBufferImageGenerator::makeView(GrRecordingContext* context) {
     if (context->priv().abandoned()) {
-        return nullptr;
+        return {};
     }
 
     auto direct = context->priv().asDirectContext();
     if (!direct) {
-        return nullptr;
+        return {};
     }
 
     GrBackendFormat backendFormat = GrAHardwareBufferUtils::GetBackendFormat(direct,
@@ -188,14 +188,14 @@
             SkBackingFit::kExact, SkBudgeted::kNo, GrProtected::kNo,
             GrSurfaceProxy::UseAllocator::kYes);
 
-    return texProxy;
+    return GrSurfaceProxyView(std::move(texProxy), fSurfaceOrigin, readSwizzle);
 }
 
 sk_sp<GrTextureProxy> GrAHardwareBufferImageGenerator::onGenerateTexture(
         GrRecordingContext* context, const SkImageInfo& info,
         const SkIPoint& origin, bool willNeedMipMaps) {
-    sk_sp<GrTextureProxy> texProxy = this->makeProxy(context);
-    if (!texProxy) {
+    GrSurfaceProxyView texProxyView = this->makeView(context);
+    if (!texProxyView.proxy()) {
         return nullptr;
     }
 
@@ -203,7 +203,7 @@
         info.width() == this->getInfo().width() && info.height() == this->getInfo().height()) {
         // If the caller wants the full texture we're done. The caller will handle making a copy for
         // mip maps if that is required.
-        return texProxy;
+        return texProxyView.asTextureProxyRef();
     }
     // Otherwise, make a copy for the requested subset.
     SkIRect subset = SkIRect::MakeXYWH(origin.fX, origin.fY, info.width(), info.height());
@@ -211,8 +211,9 @@
     GrMipMapped mipMapped = willNeedMipMaps ? GrMipMapped::kYes : GrMipMapped::kNo;
 
     GrColorType grColorType = SkColorTypeToGrColorType(this->getInfo().colorType());
-    return GrSurfaceProxy::Copy(context, texProxy.get(), grColorType, mipMapped, subset,
-                                SkBackingFit::kExact, SkBudgeted::kYes);
+    return GrSurfaceProxy::Copy(context, texProxyView.proxy(), texProxyView.origin(), grColorType,
+                                mipMapped, subset, SkBackingFit::kExact,
+                                SkBudgeted::kYes).asTextureProxyRef();
 }
 
 bool GrAHardwareBufferImageGenerator::onIsValid(GrContext* context) const {
diff --git a/src/gpu/GrAHardwareBufferImageGenerator.h b/src/gpu/GrAHardwareBufferImageGenerator.h
index f200d39..12ef6a8 100644
--- a/src/gpu/GrAHardwareBufferImageGenerator.h
+++ b/src/gpu/GrAHardwareBufferImageGenerator.h
@@ -12,6 +12,7 @@
 #include "include/private/GrTypesPriv.h"
 
 class GrGpuResource;
+class GrSurfaceProxyView;
 
 extern "C" {
     typedef struct AHardwareBuffer AHardwareBuffer;
@@ -49,7 +50,7 @@
     GrAHardwareBufferImageGenerator(const SkImageInfo&, AHardwareBuffer*, SkAlphaType,
                                     bool isProtectedContent, uint32_t bufferFormat,
                                     GrSurfaceOrigin surfaceOrigin);
-    sk_sp<GrTextureProxy> makeProxy(GrRecordingContext* context);
+    GrSurfaceProxyView makeView(GrRecordingContext* context);
 
     void releaseTextureRef();
 
diff --git a/src/gpu/GrBackendTextureImageGenerator.cpp b/src/gpu/GrBackendTextureImageGenerator.cpp
index 764dfc8..5bc3bdc 100644
--- a/src/gpu/GrBackendTextureImageGenerator.cpp
+++ b/src/gpu/GrBackendTextureImageGenerator.cpp
@@ -216,7 +216,10 @@
         GrMipMapped mipMapped = willNeedMipMaps ? GrMipMapped::kYes : GrMipMapped::kNo;
         SkIRect subset = SkIRect::MakeXYWH(origin.fX, origin.fY, info.width(), info.height());
 
-        return GrSurfaceProxy::Copy(context, proxy.get(), grColorType, mipMapped, subset,
-                                    SkBackingFit::kExact, SkBudgeted::kYes);
+        // TODO: When we update this function to return a view instead of just a proxy then we can
+        // remove the extra ref that happens when we call asTextureProxyRef.
+        return GrSurfaceProxy::Copy(
+                context, proxy.get(), fSurfaceOrigin, grColorType, mipMapped, subset,
+                SkBackingFit::kExact, SkBudgeted::kYes).asTextureProxyRef();
     }
 }
diff --git a/src/gpu/GrBitmapTextureMaker.cpp b/src/gpu/GrBitmapTextureMaker.cpp
index a896ff6..f518714 100644
--- a/src/gpu/GrBitmapTextureMaker.cpp
+++ b/src/gpu/GrBitmapTextureMaker.cpp
@@ -95,8 +95,8 @@
         // proxy into the base layer. We will then let the gpu generate the rest of the mips.
         GrColorType srcColorType = SkColorTypeToGrColorType(fBitmap.colorType());
         if (auto mippedProxy = GrCopyBaseMipMapToTextureProxy(this->context(), proxy.get(),
+                                                              kTopLeft_GrSurfaceOrigin,
                                                               srcColorType)) {
-            SkASSERT(mippedProxy->origin() == kTopLeft_GrSurfaceOrigin);
             if (fOriginalKey.isValid()) {
                 // In this case we are stealing the key from the original proxy which should only
                 // happen when we have just generated mipmaps for an originally unmipped
diff --git a/src/gpu/GrRenderTargetContext.cpp b/src/gpu/GrRenderTargetContext.cpp
index 6ee47ed..665de5e 100644
--- a/src/gpu/GrRenderTargetContext.cpp
+++ b/src/gpu/GrRenderTargetContext.cpp
@@ -1746,14 +1746,15 @@
                 callback(context, nullptr);
                 return;
             }
-            sk_sp<GrTextureProxy> texProxy = this->asTextureProxyRef();
+            GrSurfaceProxyView texProxyView = this->readSurfaceView();
             SkRect srcRectToDraw = SkRect::Make(srcRect);
             // If the src is not texturable first try to make a copy to a texture.
-            if (!texProxy) {
-                texProxy = GrSurfaceProxy::Copy(fContext, this->asSurfaceProxy(),
-                                                this->colorInfo().colorType(), GrMipMapped::kNo,
-                                                srcRect, SkBackingFit::kApprox, SkBudgeted::kNo);
-                if (!texProxy) {
+            if (!texProxyView.asTextureProxy()) {
+                texProxyView = GrSurfaceProxy::Copy(fContext, this->asSurfaceProxy(),
+                                                    this->origin(), this->colorInfo().colorType(),
+                                                    GrMipMapped::kNo, srcRect,
+                                                    SkBackingFit::kApprox, SkBudgeted::kNo);
+                if (!texProxyView.asTextureProxy()) {
                     callback(context, nullptr);
                     return;
                 }
@@ -1767,9 +1768,9 @@
                 callback(context, nullptr);
                 return;
             }
-            tempRTC->drawTexture(GrNoClip(), std::move(texProxy), this->colorInfo().colorType(),
-                                 this->colorInfo().alphaType(), GrSamplerState::Filter::kNearest,
-                                 SkBlendMode::kSrc, SK_PMColor4fWHITE, srcRectToDraw,
+            tempRTC->drawTexture(GrNoClip(), std::move(texProxyView), this->colorInfo().alphaType(),
+                                 GrSamplerState::Filter::kNearest, SkBlendMode::kSrc,
+                                 SK_PMColor4fWHITE, srcRectToDraw,
                                  SkRect::MakeWH(srcRect.width(), srcRect.height()), GrAA::kNo,
                                  GrQuadAAFlags::kNone, SkCanvas::kFast_SrcRectConstraint,
                                  SkMatrix::I(), std::move(xform));
@@ -1947,7 +1948,7 @@
     int x = srcRect.fLeft;
     int y = srcRect.fTop;
     bool needsRescale = srcRect.size() != dstSize;
-    sk_sp<GrTextureProxy> srcProxy;
+    GrSurfaceProxyView srcView;
     if (needsRescale) {
         // We assume the caller wants kPremul. There is no way to indicate a preference.
         auto info = SkImageInfo::Make(dstSize, kRGBA_8888_SkColorType, kPremul_SkAlphaType,
@@ -1961,14 +1962,14 @@
         SkASSERT(SkColorSpace::Equals(tempRTC->colorInfo().colorSpace(), info.colorSpace()));
         SkASSERT(tempRTC->origin() == kTopLeft_GrSurfaceOrigin);
         x = y = 0;
-        srcProxy = tempRTC->asTextureProxyRef();
+        srcView = tempRTC->readSurfaceView();
     } else {
-        srcProxy = this->asTextureProxyRef();
-        if (!srcProxy) {
-            srcProxy = GrSurfaceProxy::Copy(fContext, fReadView.proxy(),
-                                            this->colorInfo().colorType(), GrMipMapped::kNo,
-                                            srcRect, SkBackingFit::kApprox, SkBudgeted::kYes);
-            if (!srcProxy) {
+        srcView = this->readSurfaceView();
+        if (!srcView.asTextureProxy()) {
+            srcView = GrSurfaceProxy::Copy(fContext, fReadView.proxy(), this->origin(),
+                                           this->colorInfo().colorType(), GrMipMapped::kNo,
+                                           srcRect, SkBackingFit::kApprox, SkBudgeted::kYes);
+            if (!srcView.asTextureProxy()) {
                 // If we can't get a texture copy of the contents then give up.
                 callback(context, nullptr);
                 return;
@@ -1988,14 +1989,13 @@
                 callback(context, nullptr);
                 return;
             }
-            tempRTC->drawTexture(GrNoClip(), std::move(srcProxy), this->colorInfo().colorType(),
-                                 this->colorInfo().alphaType(), GrSamplerState::Filter::kNearest,
-                                 SkBlendMode::kSrc, SK_PMColor4fWHITE, srcRectToDraw,
-                                 SkRect::Make(srcRect.size()), GrAA::kNo, GrQuadAAFlags::kNone,
-                                 SkCanvas::kFast_SrcRectConstraint, SkMatrix::I(),
-                                 std::move(xform));
-            srcProxy = tempRTC->asTextureProxyRef();
-            SkASSERT(srcProxy);
+            tempRTC->drawTexture(GrNoClip(), std::move(srcView), this->colorInfo().alphaType(),
+                                 GrSamplerState::Filter::kNearest, SkBlendMode::kSrc,
+                                 SK_PMColor4fWHITE, srcRectToDraw, SkRect::Make(srcRect.size()),
+                                 GrAA::kNo, GrQuadAAFlags::kNone, SkCanvas::kFast_SrcRectConstraint,
+                                 SkMatrix::I(), std::move(xform));
+            srcView = tempRTC->readSurfaceView();
+            SkASSERT(srcView.asTextureProxy());
             x = y = 0;
         }
     }
@@ -2035,7 +2035,7 @@
     std::copy_n(baseM + 0, 5, yM + 15);
     GrPaint yPaint;
     yPaint.addColorFragmentProcessor(
-            GrTextureEffect::Make(srcProxy, this->colorInfo().alphaType(), texMatrix));
+            GrTextureEffect::Make(srcView.proxyRef(), this->colorInfo().alphaType(), texMatrix));
     auto yFP = GrColorMatrixFragmentProcessor::Make(yM, false, true, false);
     yPaint.addColorFragmentProcessor(std::move(yFP));
     yPaint.setPorterDuffXPFactory(SkBlendMode::kSrc);
@@ -2057,7 +2057,8 @@
     std::copy_n(baseM + 5, 5, uM + 15);
     GrPaint uPaint;
     uPaint.addColorFragmentProcessor(GrTextureEffect::Make(
-            srcProxy, this->colorInfo().alphaType(), texMatrix, GrSamplerState::Filter::kBilerp));
+            srcView.proxyRef(), this->colorInfo().alphaType(), texMatrix,
+            GrSamplerState::Filter::kBilerp));
     auto uFP = GrColorMatrixFragmentProcessor::Make(uM, false, true, false);
     uPaint.addColorFragmentProcessor(std::move(uFP));
     uPaint.setPorterDuffXPFactory(SkBlendMode::kSrc);
@@ -2078,7 +2079,8 @@
     std::copy_n(baseM + 10, 5, vM + 15);
     GrPaint vPaint;
     vPaint.addColorFragmentProcessor(GrTextureEffect::Make(
-            srcProxy, this->colorInfo().alphaType(), texMatrix, GrSamplerState::Filter::kBilerp));
+            srcView.detachProxy(), this->colorInfo().alphaType(), texMatrix,
+            GrSamplerState::Filter::kBilerp));
     auto vFP = GrColorMatrixFragmentProcessor::Make(vM, false, true, false);
     vPaint.addColorFragmentProcessor(std::move(vFP));
     vPaint.setPorterDuffXPFactory(SkBlendMode::kSrc);
@@ -2603,12 +2605,13 @@
         dstOffset = {copyRect.fLeft, copyRect.fTop};
         fit = SkBackingFit::kApprox;
     }
-    sk_sp<GrTextureProxy> newProxy =
-            GrSurfaceProxy::Copy(fContext, this->asSurfaceProxy(), colorType, GrMipMapped::kNo,
-                                 copyRect, fit, SkBudgeted::kYes, restrictions.fRectsMustMatch);
-    SkASSERT(newProxy);
+    GrSurfaceProxyView newProxyView =
+            GrSurfaceProxy::Copy(fContext, this->asSurfaceProxy(), this->origin(), colorType,
+                                 GrMipMapped::kNo, copyRect, fit, SkBudgeted::kYes,
+                                 restrictions.fRectsMustMatch);
+    SkASSERT(newProxyView.proxy());
 
-    dstProxyView->setProxyView({std::move(newProxy), this->origin(), this->readSwizzle()});
+    dstProxyView->setProxyView(std::move(newProxyView));
     dstProxyView->setOffset(dstOffset);
     return true;
 }
diff --git a/src/gpu/GrRenderTargetContext.h b/src/gpu/GrRenderTargetContext.h
index eda8654..1799ee9 100644
--- a/src/gpu/GrRenderTargetContext.h
+++ b/src/gpu/GrRenderTargetContext.h
@@ -247,17 +247,14 @@
      * specifies the rectangle to draw in local coords which will be transformed by 'viewMatrix' to
      * device space.
      */
-    void drawTexture(const GrClip& clip, sk_sp<GrTextureProxy> proxy, GrColorType srcColorType,
-                     SkAlphaType srcAlphaType, GrSamplerState::Filter filter, SkBlendMode mode,
-                     const SkPMColor4f& color, const SkRect& srcRect, const SkRect& dstRect,
-                     GrAA aa, GrQuadAAFlags edgeAA, SkCanvas::SrcRectConstraint constraint,
-                     const SkMatrix& viewMatrix, sk_sp<GrColorSpaceXform> texXform) {
+    void drawTexture(const GrClip& clip, GrSurfaceProxyView view, SkAlphaType srcAlphaType,
+                     GrSamplerState::Filter filter, SkBlendMode mode, const SkPMColor4f& color,
+                     const SkRect& srcRect, const SkRect& dstRect, GrAA aa, GrQuadAAFlags edgeAA,
+                     SkCanvas::SrcRectConstraint constraint, const SkMatrix& viewMatrix,
+                     sk_sp<GrColorSpaceXform> texXform) {
         const SkRect* domain = constraint == SkCanvas::kStrict_SrcRectConstraint ?
                 &srcRect : nullptr;
-        GrSurfaceOrigin origin = proxy->origin();
-        const GrSwizzle& swizzle = proxy->textureSwizzle();
-        GrSurfaceProxyView proxyView(std::move(proxy), origin, swizzle);
-        this->drawTexturedQuad(clip, std::move(proxyView), srcAlphaType, std::move(texXform),
+        this->drawTexturedQuad(clip, std::move(view), srcAlphaType, std::move(texXform),
                                filter, color, mode, aa, edgeAA,
                                GrQuad::MakeFromRect(dstRect, viewMatrix), GrQuad(srcRect), domain);
     }
diff --git a/src/gpu/GrSurfaceContext.cpp b/src/gpu/GrSurfaceContext.cpp
index dc4860b..ffca58e 100644
--- a/src/gpu/GrSurfaceContext.cpp
+++ b/src/gpu/GrSurfaceContext.cpp
@@ -534,17 +534,18 @@
     int srcH = srcRect.height();
     int srcX = srcRect.fLeft;
     int srcY = srcRect.fTop;
-    sk_sp<GrTextureProxy> texProxy = sk_ref_sp(this->asTextureProxy());
+    GrSurfaceProxyView texView = this->readSurfaceView();
     SkCanvas::SrcRectConstraint constraint = SkCanvas::kStrict_SrcRectConstraint;
     GrColorType srcColorType = this->colorInfo().colorType();
     SkAlphaType srcAlphaType = this->colorInfo().alphaType();
-    if (!texProxy) {
-        texProxy = GrSurfaceProxy::Copy(fContext, this->asSurfaceProxy(), srcColorType,
-                                        GrMipMapped::kNo, srcRect, SkBackingFit::kApprox,
-                                        SkBudgeted::kNo);
-        if (!texProxy) {
+    if (!texView.asTextureProxy()) {
+        texView = GrSurfaceProxy::Copy(fContext, this->asSurfaceProxy(), this->origin(),
+                                       srcColorType, GrMipMapped::kNo, srcRect,
+                                       SkBackingFit::kApprox, SkBudgeted::kNo);
+        if (!texView.proxy()) {
             return nullptr;
         }
+        SkASSERT(texView.asTextureProxy());
         srcX = 0;
         srcY = 0;
         constraint = SkCanvas::kFast_SrcRectConstraint;
@@ -584,12 +585,13 @@
         if (!linearRTC) {
             return nullptr;
         }
-        linearRTC->drawTexture(GrNoClip(), texProxy, srcColorType, srcAlphaType,
+        linearRTC->drawTexture(GrNoClip(), std::move(texView), srcAlphaType,
                                GrSamplerState::Filter::kNearest, SkBlendMode::kSrc,
                                SK_PMColor4fWHITE, SkRect::Make(srcRect), SkRect::MakeWH(srcW, srcH),
                                GrAA::kNo, GrQuadAAFlags::kNone, constraint, SkMatrix::I(),
                                std::move(xform));
-        texProxy = linearRTC->asTextureProxyRef();
+        texView = linearRTC->readSurfaceView();
+        SkASSERT(texView.asTextureProxy());
         tempA = std::move(linearRTC);
         srcX = 0;
         srcY = 0;
@@ -646,12 +648,13 @@
             } else if (nextH == srcH) {
                 dir = GrBicubicEffect::Direction::kX;
             }
-            if (srcW != texProxy->width() || srcH != texProxy->height()) {
+            if (srcW != texView.proxy()->width() || srcH != texView.proxy()->height()) {
                 auto domain = GrTextureDomain::MakeTexelDomain(
                         SkIRect::MakeXYWH(srcX, srcY, srcW, srcH), GrTextureDomain::kClamp_Mode);
-                fp = GrBicubicEffect::Make(texProxy, matrix, domain, dir, prevAlphaType);
+                fp = GrBicubicEffect::Make(texView.detachProxy(), matrix, domain, dir,
+                                           prevAlphaType);
             } else {
-                fp = GrBicubicEffect::Make(texProxy, matrix, dir, prevAlphaType);
+                fp = GrBicubicEffect::Make(texView.detachProxy(), matrix, dir, prevAlphaType);
             }
             if (xform) {
                 fp = GrColorSpaceXformEffect::Make(std::move(fp), std::move(xform));
@@ -665,11 +668,11 @@
             auto filter = rescaleQuality == kNone_SkFilterQuality ? GrSamplerState::Filter::kNearest
                                                                   : GrSamplerState::Filter::kBilerp;
             auto srcSubset = SkRect::MakeXYWH(srcX, srcY, srcW, srcH);
-            tempB->drawTexture(GrNoClip(), texProxy, srcColorType, srcAlphaType, filter,
+            tempB->drawTexture(GrNoClip(), std::move(texView), srcAlphaType, filter,
                                SkBlendMode::kSrc, SK_PMColor4fWHITE, srcSubset, dstRect, GrAA::kNo,
                                GrQuadAAFlags::kNone, constraint, SkMatrix::I(), std::move(xform));
         }
-        texProxy = tempB->asTextureProxyRef();
+        texView = tempB->readSurfaceView();
         tempA = std::move(tempB);
         srcX = srcY = 0;
         srcW = nextW;
diff --git a/src/gpu/GrSurfaceProxy.cpp b/src/gpu/GrSurfaceProxy.cpp
index 41566bb..b2cee1d 100644
--- a/src/gpu/GrSurfaceProxy.cpp
+++ b/src/gpu/GrSurfaceProxy.cpp
@@ -281,14 +281,15 @@
 }
 #endif
 
-sk_sp<GrTextureProxy> GrSurfaceProxy::Copy(GrRecordingContext* context,
-                                           GrSurfaceProxy* src,
-                                           GrColorType srcColorType,
-                                           GrMipMapped mipMapped,
-                                           SkIRect srcRect,
-                                           SkBackingFit fit,
-                                           SkBudgeted budgeted,
-                                           RectsMustMatch rectsMustMatch) {
+GrSurfaceProxyView GrSurfaceProxy::Copy(GrRecordingContext* context,
+                                        GrSurfaceProxy* src,
+                                        GrSurfaceOrigin origin,
+                                        GrColorType srcColorType,
+                                        GrMipMapped mipMapped,
+                                        SkIRect srcRect,
+                                        SkBackingFit fit,
+                                        SkBudgeted budgeted,
+                                        RectsMustMatch rectsMustMatch) {
     SkASSERT(!src->isFullyLazy());
     int width;
     int height;
@@ -305,19 +306,18 @@
     }
 
     if (!srcRect.intersect(SkIRect::MakeSize(src->dimensions()))) {
-        return nullptr;
+        return {};
     }
     auto format = src->backendFormat().makeTexture2D();
     SkASSERT(format.isValid());
 
-    GrSurfaceOrigin origin = src->origin();
     if (src->backendFormat().textureType() != GrTextureType::kExternal) {
         auto dstContext = GrSurfaceContext::Make(context, {width, height}, format,
                                                  GrRenderable::kNo, 1, mipMapped,
                                                  src->isProtected(), origin, srcColorType,
                                                  kUnknown_SkAlphaType, nullptr, fit, budgeted);
         if (dstContext && dstContext->copy(src, srcRect, dstPoint)) {
-            return dstContext->asTextureProxyRef();
+            return dstContext->readSurfaceView();
         }
     }
     if (src->asTextureProxy()) {
@@ -326,19 +326,20 @@
                                                       mipMapped, src->isProtected(), origin,
                                                       budgeted, nullptr);
         if (dstContext && dstContext->blitTexture(src->asTextureProxy(), srcRect, dstPoint)) {
-            return dstContext->asTextureProxyRef();
+            return dstContext->readSurfaceView();
         }
     }
     // Can't use backend copies or draws.
-    return nullptr;
+    return {};
 }
 
-sk_sp<GrTextureProxy> GrSurfaceProxy::Copy(GrRecordingContext* context, GrSurfaceProxy* src,
-                                           GrColorType srcColorType, GrMipMapped mipMapped,
-                                           SkBackingFit fit, SkBudgeted budgeted) {
+GrSurfaceProxyView GrSurfaceProxy::Copy(GrRecordingContext* context, GrSurfaceProxy* src,
+                                        GrSurfaceOrigin origin, GrColorType srcColorType,
+                                        GrMipMapped mipMapped, SkBackingFit fit,
+                                        SkBudgeted budgeted) {
     SkASSERT(!src->isFullyLazy());
-    return Copy(context, src, srcColorType, mipMapped, SkIRect::MakeSize(src->dimensions()), fit,
-                budgeted);
+    return Copy(context, src, origin, srcColorType, mipMapped, SkIRect::MakeSize(src->dimensions()),
+                fit, budgeted);
 }
 
 #if GR_TEST_UTILS
diff --git a/src/gpu/GrSurfaceProxy.h b/src/gpu/GrSurfaceProxy.h
index f9f2197..46af8d7 100644
--- a/src/gpu/GrSurfaceProxy.h
+++ b/src/gpu/GrSurfaceProxy.h
@@ -26,6 +26,7 @@
 class GrResourceProvider;
 class GrSurfaceContext;
 class GrSurfaceProxyPriv;
+class GrSurfaceProxyView;
 class GrTextureProxy;
 
 class GrSurfaceProxy : public SkNVRefCnt<GrSurfaceProxy> {
@@ -290,15 +291,25 @@
 
     // Helper function that creates a temporary SurfaceContext to perform the copy
     // The copy is is not a render target and not multisampled.
-    static sk_sp<GrTextureProxy> Copy(GrRecordingContext*, GrSurfaceProxy* src,
-                                      GrColorType srcColorType, GrMipMapped,
-                                      SkIRect srcRect, SkBackingFit, SkBudgeted,
-                                      RectsMustMatch = RectsMustMatch::kNo);
+    //
+    // The intended use of this copy call is simply to copy exact pixel values from one proxy to a
+    // new one. Thus there isn't a need for a swizzle when doing the copy. Also, there shouldn't be
+    // an assumed "view" of the copy. However, even though not really needed for the swizzle, we
+    // still pass in a srcColorType since it is required for making a GrSurface/RenderTargetContext.
+    // Additionally, almost all callers of this will immediately put the resulting proxy into a view
+    // which is compatible with the srcColorType and origin passed in here. Thus for now we just
+    // return the GrSurfaceProxyView that is already stored on the internal GrSurfaceContext. If we
+    // later decide to not pass in a srcColorType (and assume some default color type based on the
+    // backend format) then we should go back to returning a proxy here and have the callers decide
+    // what view they want of the proxy.
+    static GrSurfaceProxyView Copy(GrRecordingContext*, GrSurfaceProxy* src,
+                                   GrSurfaceOrigin, GrColorType srcColorType, GrMipMapped,
+                                   SkIRect srcRect, SkBackingFit, SkBudgeted,
+                                   RectsMustMatch = RectsMustMatch::kNo);
 
-    // Copy the entire 'src'
-    static sk_sp<GrTextureProxy> Copy(GrRecordingContext*, GrSurfaceProxy* src,
-                                      GrColorType srcColorType, GrMipMapped, SkBackingFit,
-                                      SkBudgeted);
+    // Same as above Copy but copies the entire 'src'
+    static GrSurfaceProxyView Copy(GrRecordingContext*, GrSurfaceProxy* src, GrSurfaceOrigin,
+                                   GrColorType srcColorType, GrMipMapped, SkBackingFit, SkBudgeted);
 
 #if GR_TEST_UTILS
     int32_t testingOnly_getBackingRefCnt() const;
diff --git a/src/gpu/GrTextureAdjuster.cpp b/src/gpu/GrTextureAdjuster.cpp
index 66f6266..d15a5ea 100644
--- a/src/gpu/GrTextureAdjuster.cpp
+++ b/src/gpu/GrTextureAdjuster.cpp
@@ -53,7 +53,8 @@
 
     sk_sp<GrTextureProxy> copy;
     if (copyForMipsOnly) {
-        copy = GrCopyBaseMipMapToTextureProxy(this->context(), proxy.get(), this->colorType());
+        copy = GrCopyBaseMipMapToTextureProxy(this->context(), proxy.get(),
+                                              this->originalProxy()->origin(), this->colorType());
     } else {
         copy = CopyOnGpu(this->context(), std::move(proxy), this->colorType(),
                          copyParams, willBeMipped);
diff --git a/src/gpu/GrTextureProducer.cpp b/src/gpu/GrTextureProducer.cpp
index 243582d..4ec6ec1 100644
--- a/src/gpu/GrTextureProducer.cpp
+++ b/src/gpu/GrTextureProducer.cpp
@@ -41,6 +41,7 @@
     if (copyParams.fFilter == GrSamplerState::Filter::kNearest && !resizing &&
         dstWillRequireMipMaps) {
         sk_sp<GrTextureProxy> proxy = GrCopyBaseMipMapToTextureProxy(context, inputProxy.get(),
+                                                                     inputProxy->origin(),
                                                                      colorType);
         if (proxy) {
             return proxy;
diff --git a/src/gpu/SkGpuDevice.cpp b/src/gpu/SkGpuDevice.cpp
index 64f1c70..35dd2de 100644
--- a/src/gpu/SkGpuDevice.cpp
+++ b/src/gpu/SkGpuDevice.cpp
@@ -1248,17 +1248,17 @@
     if (forceCopy || !view.asTextureProxy()) {
         // When the device doesn't have a texture, or a copy is requested, we create a temporary
         // texture that matches the device contents
-        auto proxy = GrSurfaceProxy::Copy(fContext.get(),
-                                          rtc->asSurfaceProxy(),
-                                          rtc->colorInfo().colorType(),
-                                          GrMipMapped::kNo,      // Don't auto generate mips
-                                          subset,
-                                          SkBackingFit::kApprox,
-                                          SkBudgeted::kYes);     // Always budgeted
-        if (!proxy) {
+        view = GrSurfaceProxy::Copy(fContext.get(),
+                                    rtc->asSurfaceProxy(),
+                                    view.origin(),
+                                    rtc->colorInfo().colorType(),
+                                    GrMipMapped::kNo,      // Don't auto generate mips
+                                    subset,
+                                    SkBackingFit::kApprox,
+                                    SkBudgeted::kYes);     // Always budgeted
+        if (!view.proxy()) {
             return nullptr;
         }
-        view = GrSurfaceProxyView(std::move(proxy), view.origin(), view.swizzle());
 
         // Since this copied only the requested subset, the special image wrapping the proxy no
         // longer needs the original subset.
diff --git a/src/gpu/SkGpuDevice_drawTexture.cpp b/src/gpu/SkGpuDevice_drawTexture.cpp
index 26c988a..fa9b07c 100644
--- a/src/gpu/SkGpuDevice_drawTexture.cpp
+++ b/src/gpu/SkGpuDevice_drawTexture.cpp
@@ -225,9 +225,12 @@
                              constraint == SkCanvas::kStrict_SrcRectConstraint ? &srcRect : nullptr,
                              ctm, std::move(textureXform));
     } else {
-        rtc->drawTexture(clip, std::move(proxy), srcColorInfo.colorType(), srcColorInfo.alphaType(),
-                         filter, paint.getBlendMode(), color, srcRect, dstRect, aa, aaFlags,
-                         constraint, ctm, std::move(textureXform));
+        GrSurfaceOrigin origin = proxy->origin();
+        GrSwizzle swizzle = proxy->textureSwizzle();
+        GrSurfaceProxyView view(std::move(proxy), origin, swizzle);
+        rtc->drawTexture(clip, std::move(view), srcColorInfo.alphaType(), filter,
+                         paint.getBlendMode(), color, srcRect, dstRect, aa, aaFlags, constraint,
+                         ctm, std::move(textureXform));
     }
 }
 
diff --git a/src/gpu/SkGr.cpp b/src/gpu/SkGr.cpp
index 0c5c40a..d2ec15a 100644
--- a/src/gpu/SkGr.cpp
+++ b/src/gpu/SkGr.cpp
@@ -126,14 +126,17 @@
 
 sk_sp<GrTextureProxy> GrCopyBaseMipMapToTextureProxy(GrRecordingContext* ctx,
                                                      GrSurfaceProxy* baseProxy,
+                                                     GrSurfaceOrigin origin,
                                                      GrColorType srcColorType) {
     SkASSERT(baseProxy);
 
     if (!ctx->priv().caps()->isFormatCopyable(baseProxy->backendFormat())) {
         return nullptr;
     }
-    return GrSurfaceProxy::Copy(ctx, baseProxy, srcColorType, GrMipMapped::kYes,
-                                SkBackingFit::kExact, SkBudgeted::kYes);
+    GrSurfaceProxyView view = GrSurfaceProxy::Copy(ctx, baseProxy, origin, srcColorType,
+                                                   GrMipMapped::kYes, SkBackingFit::kExact,
+                                                   SkBudgeted::kYes);
+    return view.asTextureProxyRef();
 }
 
 sk_sp<GrTextureProxy> GrRefCachedBitmapTextureProxy(GrRecordingContext* ctx,
diff --git a/src/gpu/SkGr.h b/src/gpu/SkGr.h
index 4ca7c8a..49109cf 100644
--- a/src/gpu/SkGr.h
+++ b/src/gpu/SkGr.h
@@ -182,6 +182,7 @@
  */
 sk_sp<GrTextureProxy> GrCopyBaseMipMapToTextureProxy(GrRecordingContext*,
                                                      GrSurfaceProxy* baseProxy,
+                                                     GrSurfaceOrigin origin,
                                                      GrColorType srcColorType);
 
 /*