Remove GrSurfaceOrigin from GrSurfaceDesc.

This field has no interpretation at the GrTexture/GrGpu as the orientation is
handled at the GrSurfaceProxy level.

This change requires GrGpu to accept a GrSurfaceOrigin when creating a texture with initial data. The origin refers to the texel data to be uploaded. Longer term the plan is to remove this and require the data to be kTopLeft. Additionally, kBottomLeft will only be allowed for wrapped texture/RTs as this evolves.

Change-Id: I7d25b0199aafd9bf3b74c39b2cae451acadcd772
Reviewed-on: https://skia-review.googlesource.com/111806
Reviewed-by: Robert Phillips <robertphillips@google.com>
Commit-Queue: Brian Salomon <bsalomon@google.com>
diff --git a/gm/flippity.cpp b/gm/flippity.cpp
index bd9930c..554b4d1 100644
--- a/gm/flippity.cpp
+++ b/gm/flippity.cpp
@@ -111,15 +111,11 @@
     }
 
     GrSurfaceDesc desc;
-    desc.fOrigin = kTopLeft_GrSurfaceOrigin;
     desc.fWidth = kImageSize;
     desc.fHeight = kImageSize;
     desc.fConfig = kRGBA_8888_GrPixelConfig;
 
-    if (bottomLeftOrigin) {
-        // Note that Ganesh will flip the data when it is uploaded
-        desc.fOrigin = kBottomLeft_GrSurfaceOrigin;
-    }
+    auto origin = bottomLeftOrigin ? kBottomLeft_GrSurfaceOrigin : kTopLeft_GrSurfaceOrigin;
 
     if (kN32_SkColorType == kBGRA_8888_SkColorType) {
         // We're playing a game here and uploading N32 data into an RGB dest. We might have
@@ -132,7 +128,7 @@
         }
     }
 
-    sk_sp<GrTextureProxy> proxy = proxyProvider->createTextureProxy(desc, SkBudgeted::kYes,
+    sk_sp<GrTextureProxy> proxy = proxyProvider->createTextureProxy(desc, origin, SkBudgeted::kYes,
                                                                     bm.getPixels(), bm.rowBytes());
     if (!proxy) {
         return nullptr;
diff --git a/gm/image_pict.cpp b/gm/image_pict.cpp
index bf1c651..f244fe8 100644
--- a/gm/image_pict.cpp
+++ b/gm/image_pict.cpp
@@ -181,7 +181,6 @@
 
         // need to copy the subset into a new texture
         GrSurfaceDesc desc;
-        desc.fOrigin = fProxy->origin();
         desc.fWidth = info.width();
         desc.fHeight = info.height();
         desc.fConfig = fProxy->config();
@@ -189,10 +188,7 @@
         GrMipMapped mipMapped = willBeMipped ? GrMipMapped::kYes : GrMipMapped::kNo;
 
         sk_sp<GrSurfaceContext> dstContext(fCtx->contextPriv().makeDeferredSurfaceContext(
-                                                                            desc,
-                                                                            mipMapped,
-                                                                            SkBackingFit::kExact,
-                                                                            SkBudgeted::kYes));
+                desc, fProxy->origin(), mipMapped, SkBackingFit::kExact, SkBudgeted::kYes));
         if (!dstContext) {
             return nullptr;
         }
diff --git a/gm/texdata.cpp b/gm/texdata.cpp
deleted file mode 100644
index b00daf5..0000000
--- a/gm/texdata.cpp
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
- * Copyright 2011 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-// This test only works with the GPU backend.
-
-#include "gm.h"
-
-#if SK_SUPPORT_GPU
-#include "GrContext.h"
-#include "GrContextPriv.h"
-#include "GrProxyProvider.h"
-#include "GrRenderTargetContext.h"
-#include "GrTextureContext.h"
-#include "GrFixedClip.h"
-#include "SkColorPriv.h"
-#include "SkGr.h"
-#include "effects/GrPorterDuffXferProcessor.h"
-#include "effects/GrSimpleTextureEffect.h"
-
-constexpr int S = 200;
-constexpr int kStride = 2 * S;
-
-// Fill in the pixels:
-//   gray  | white
-//   -------------
-//   black | gray
-static void fill_in_pixels(SkPMColor* pixels) {
-    const SkPMColor gray  = SkPackARGB32(0x40, 0x40, 0x40, 0x40);
-    const SkPMColor white = SkPackARGB32(0xff, 0xff, 0xff, 0xff);
-    const SkPMColor black = SkPackARGB32(0x00, 0x00, 0x00, 0x00);
-
-    int offset = 0;
-
-    // fill upper-left
-    for (int y = 0; y < S; ++y) {
-        for (int x = 0; x < S; ++x) {
-            pixels[offset + y * kStride + x] = gray;
-        }
-    }
-    // fill upper-right
-    offset = S;
-    for (int y = 0; y < S; ++y) {
-        for (int x = 0; x < S; ++x) {
-            pixels[offset + y * kStride + x] = white;
-        }
-    }
-    // fill lower left
-    offset = S * kStride;
-    for (int y = 0; y < S; ++y) {
-        for (int x = 0; x < S; ++x) {
-            pixels[offset + y * kStride + x] = black;
-        }
-    }
-    // fill lower right
-    offset = S * kStride + S;
-    for (int y = 0; y < S; ++y) {
-        for (int x = 0; x < S; ++x) {
-            pixels[offset + y * kStride + x] = gray;
-        }
-    }
-}
-
-DEF_SIMPLE_GM_BG(texdata, canvas, 2 * S, 2 * S, SK_ColorBLACK) {
-    GrRenderTargetContext* renderTargetContext =
-        canvas->internal_private_accessTopLayerRenderTargetContext();
-    if (!renderTargetContext) {
-        skiagm::GM::DrawGpuOnlyMessage(canvas);
-        return;
-    }
-
-    GrContext* context = canvas->getGrContext();
-    if (!context) {
-        return;
-    }
-
-    GrProxyProvider* proxyProvider = context->contextPriv().proxyProvider();
-    const SkImageInfo ii = SkImageInfo::Make(S, S, kBGRA_8888_SkColorType, kPremul_SkAlphaType);
-
-    SkAutoTArray<SkPMColor> gTextureData((2 * S) * (2 * S));
-    const SkPMColor red   = SkPackARGB32(0x80, 0x80, 0x00, 0x00);
-    const SkPMColor blue  = SkPackARGB32(0x80, 0x00, 0x00, 0x80);
-    const SkPMColor green = SkPackARGB32(0x80, 0x00, 0x80, 0x00);
-    for (int i = 0; i < 2; ++i) {
-        fill_in_pixels(gTextureData.get());
-
-        GrSurfaceDesc desc;
-        desc.fOrigin    = i ? kBottomLeft_GrSurfaceOrigin : kTopLeft_GrSurfaceOrigin;
-        desc.fWidth     = 2 * S;
-        desc.fHeight    = 2 * S;
-        desc.fConfig    = SkImageInfo2GrPixelConfig(ii, *context->caps());
-        SkASSERT(kUnknown_GrPixelConfig != desc.fConfig);
-
-        sk_sp<GrTextureProxy> proxy = proxyProvider->createTextureProxy(desc, SkBudgeted::kNo,
-                                                                        gTextureData.get(), 0);
-        if (!proxy) {
-            return;
-        }
-
-        sk_sp<GrSurfaceContext> tContext = context->contextPriv().makeWrappedSurfaceContext(
-                                                                                  std::move(proxy));
-
-        if (!tContext) {
-            return;
-        }
-
-        // setup new clip
-        GrFixedClip clip(SkIRect::MakeWH(2*S, 2*S));
-
-        GrPaint paint;
-        paint.setPorterDuffXPFactory(SkBlendMode::kSrcOver);
-
-        SkMatrix vm;
-        if (i) {
-            vm.setRotate(90 * SK_Scalar1, S * SK_Scalar1, S * SK_Scalar1);
-        } else {
-            vm.reset();
-        }
-        paint.addColorTextureProcessor(tContext->asTextureProxyRef(), vm);
-
-        renderTargetContext->drawRect(clip, GrPaint::Clone(paint), GrAA::kNo, vm,
-                                      SkRect::MakeWH(2 * S, 2 * S));
-
-        // now update the lower right of the texture in first pass
-        // or upper right in second pass
-        for (int y = 0; y < S; ++y) {
-            for (int x = 0; x < S; ++x) {
-                gTextureData[y * kStride + x] = ((x + y) % 2) ? (i ? green : red) : blue;
-            }
-        }
-
-        if (!tContext->writePixels(ii, gTextureData.get(), 4 * kStride, S, i ? 0 : S)) {
-            continue;
-        }
-
-        renderTargetContext->drawRect(clip, std::move(paint), GrAA::kNo, vm,
-                                      SkRect::MakeWH(2 * S, 2 * S));
-    }
-}
-#endif
-
diff --git a/gm/texturedomaineffect.cpp b/gm/texturedomaineffect.cpp
index 7f7f4c4..716bbc3 100644
--- a/gm/texturedomaineffect.cpp
+++ b/gm/texturedomaineffect.cpp
@@ -89,15 +89,14 @@
 
         GrProxyProvider* proxyProvider = context->contextPriv().proxyProvider();
         GrSurfaceDesc desc;
-        desc.fOrigin = kTopLeft_GrSurfaceOrigin;
         desc.fWidth = fBmp.width();
         desc.fHeight = fBmp.height();
         desc.fConfig = SkImageInfo2GrPixelConfig(fBmp.info(), *context->caps());
         SkASSERT(kUnknown_GrPixelConfig != desc.fConfig);
 
-        sk_sp<GrTextureProxy> proxy = proxyProvider->createTextureProxy(desc, SkBudgeted::kYes,
-                                                                        fBmp.getPixels(),
-                                                                        fBmp.rowBytes());
+        sk_sp<GrTextureProxy> proxy =
+                proxyProvider->createTextureProxy(desc, kTopLeft_GrSurfaceOrigin, SkBudgeted::kYes,
+                                                  fBmp.getPixels(), fBmp.rowBytes());
         if (!proxy) {
             return;
         }
diff --git a/gm/yuvtorgbeffect.cpp b/gm/yuvtorgbeffect.cpp
index 841f574..ee710ee 100644
--- a/gm/yuvtorgbeffect.cpp
+++ b/gm/yuvtorgbeffect.cpp
@@ -86,22 +86,18 @@
         GrProxyProvider* proxyProvider = context->contextPriv().proxyProvider();
         sk_sp<GrTextureProxy> proxy[3];
 
-        {
+        for (int i = 0; i < 3; ++i) {
             GrSurfaceDesc desc;
-            desc.fOrigin = kTopLeft_GrSurfaceOrigin;
+            desc.fWidth = fBmp[i].width();
+            desc.fHeight = fBmp[i].height();
+            desc.fConfig = SkImageInfo2GrPixelConfig(fBmp[i].info(), *context->caps());
+            SkASSERT(kUnknown_GrPixelConfig != desc.fConfig);
 
-            for (int i = 0; i < 3; ++i) {
-                desc.fWidth = fBmp[i].width();
-                desc.fHeight = fBmp[i].height();
-                desc.fConfig = SkImageInfo2GrPixelConfig(fBmp[i].info(), *context->caps());
-                SkASSERT(kUnknown_GrPixelConfig != desc.fConfig);
-
-                proxy[i] = proxyProvider->createTextureProxy(desc, SkBudgeted::kYes,
-                                                             fBmp[i].getPixels(),
-                                                             fBmp[i].rowBytes());
-                if (!proxy[i]) {
-                    return;
-                }
+            proxy[i] = proxyProvider->createTextureProxy(desc, kTopLeft_GrSurfaceOrigin,
+                                                         SkBudgeted::kYes, fBmp[i].getPixels(),
+                                                         fBmp[i].rowBytes());
+            if (!proxy[i]) {
+                return;
             }
         }
 
@@ -216,24 +212,19 @@
         GrProxyProvider* proxyProvider = context->contextPriv().proxyProvider();
         sk_sp<GrTextureProxy> proxy[3];
 
-        {
+        for (int i = 0; i < 3; ++i) {
+            int index = (0 == i) ? 0 : 1;
             GrSurfaceDesc desc;
-            desc.fOrigin = kTopLeft_GrSurfaceOrigin;
+            desc.fWidth = fBmp[index].width();
+            desc.fHeight = fBmp[index].height();
+            desc.fConfig = SkImageInfo2GrPixelConfig(fBmp[index].info(), *context->caps());
+            SkASSERT(kUnknown_GrPixelConfig != desc.fConfig);
 
-            for (int i = 0; i < 3; ++i) {
-                int index = (0 == i) ? 0 : 1;
-
-                desc.fWidth = fBmp[index].width();
-                desc.fHeight = fBmp[index].height();
-                desc.fConfig = SkImageInfo2GrPixelConfig(fBmp[index].info(), *context->caps());
-                SkASSERT(kUnknown_GrPixelConfig != desc.fConfig);
-
-                proxy[i] = proxyProvider->createTextureProxy(desc, SkBudgeted::kYes,
-                                                             fBmp[index].getPixels(),
-                                                             fBmp[index].rowBytes());
-                if (!proxy[i]) {
-                    return;
-                }
+            proxy[i] = proxyProvider->createTextureProxy(desc, kTopLeft_GrSurfaceOrigin,
+                                                         SkBudgeted::kYes, fBmp[index].getPixels(),
+                                                         fBmp[index].rowBytes());
+            if (!proxy[i]) {
+                return;
             }
         }
 
diff --git a/gn/gm.gni b/gn/gm.gni
index bd55939..649a36e 100644
--- a/gn/gm.gni
+++ b/gn/gm.gni
@@ -300,7 +300,6 @@
   "$_gm/tablecolorfilter.cpp",
   "$_gm/tallstretchedbitmaps.cpp",
   "$_gm/testgradient.cpp",
-  "$_gm/texdata.cpp",
   "$_gm/textblob.cpp",
   "$_gm/textblobblockreordering.cpp",
   "$_gm/textblobcolortrans.cpp",
diff --git a/include/gpu/GrCaps.h b/include/gpu/GrCaps.h
index 2e01cd9..7f1a45e 100644
--- a/include/gpu/GrCaps.h
+++ b/include/gpu/GrCaps.h
@@ -223,13 +223,14 @@
     /**
      * This is can be called before allocating a texture to be a dst for copySurface. This is only
      * used for doing dst copies needed in blends, thus the src is always a GrRenderTargetProxy. It
-     * will populate the origin, config, and flags fields of the desc such that copySurface can
-     * efficiently succeed. rectsMustMatch will be set to true if the copy operation must ensure
-     * that the src and dest rects are identical. disallowSubrect will be set to true if copy rect
-     * must equal src's bounds.
+     * will populate config and flags fields of the desc such that copySurface can efficiently
+     * succeed as well as the proxy origin. rectsMustMatch will be set to true if the copy operation
+     * must ensure that the src and dest rects are identical. disallowSubrect will be set to true if
+     * copy rect must equal src's bounds.
      */
     virtual bool initDescForDstCopy(const GrRenderTargetProxy* src, GrSurfaceDesc* desc,
-                                    bool* rectsMustMatch, bool* disallowSubrect) const = 0;
+                                    GrSurfaceOrigin* origin, bool* rectsMustMatch,
+                                    bool* disallowSubrect) const = 0;
 
     bool validateSurfaceDesc(const GrSurfaceDesc&, GrMipMapped) const;
 
diff --git a/include/gpu/GrTypes.h b/include/gpu/GrTypes.h
index ef7426c..97d6210 100644
--- a/include/gpu/GrTypes.h
+++ b/include/gpu/GrTypes.h
@@ -404,14 +404,12 @@
 struct GrSurfaceDesc {
     GrSurfaceDesc()
             : fFlags(kNone_GrSurfaceFlags)
-            , fOrigin(kTopLeft_GrSurfaceOrigin)
             , fWidth(0)
             , fHeight(0)
             , fConfig(kUnknown_GrPixelConfig)
             , fSampleCnt(1) {}
 
     GrSurfaceFlags         fFlags;  //!< bitfield of TextureFlags
-    GrSurfaceOrigin        fOrigin; //!< origin of the texture
     int                    fWidth;  //!< Width of the texture
     int                    fHeight; //!< Height of the texture
 
diff --git a/include/private/GrRenderTargetProxy.h b/include/private/GrRenderTargetProxy.h
index 783f54e..2468df3 100644
--- a/include/private/GrRenderTargetProxy.h
+++ b/include/private/GrRenderTargetProxy.h
@@ -64,8 +64,8 @@
     friend class GrProxyProvider;  // for ctors
 
     // Deferred version
-    GrRenderTargetProxy(const GrCaps&, const GrSurfaceDesc&,
-                        SkBackingFit, SkBudgeted, uint32_t flags);
+    GrRenderTargetProxy(const GrCaps&, const GrSurfaceDesc&, GrSurfaceOrigin, SkBackingFit,
+                        SkBudgeted, uint32_t flags);
 
     // Lazy-callback version
     // There are two main use cases for lazily-instantiated proxies:
@@ -78,8 +78,8 @@
     // The minimal knowledge version is used for CCPR where we are generating an atlas but we do not
     // know the final size until flush time.
     GrRenderTargetProxy(LazyInstantiateCallback&&, LazyInstantiationType lazyType,
-                        const GrSurfaceDesc&, SkBackingFit, SkBudgeted, uint32_t flags,
-                        GrRenderTargetFlags renderTargetFlags);
+                        const GrSurfaceDesc&, GrSurfaceOrigin, SkBackingFit, SkBudgeted,
+                        uint32_t flags, GrRenderTargetFlags renderTargetFlags);
 
     // Wrapped version
     GrRenderTargetProxy(sk_sp<GrSurface>, GrSurfaceOrigin);
diff --git a/include/private/GrSurfaceProxy.h b/include/private/GrSurfaceProxy.h
index 6beb11e..470ab7d 100644
--- a/include/private/GrSurfaceProxy.h
+++ b/include/private/GrSurfaceProxy.h
@@ -355,7 +355,7 @@
 
     // Test-only entry point - should decrease in use as proxies propagate
     static sk_sp<GrSurfaceContext> TestCopy(GrContext* context, const GrSurfaceDesc& dstDesc,
-                                            GrSurfaceProxy* srcProxy);
+                                            GrSurfaceOrigin, GrSurfaceProxy* srcProxy);
 
     bool isWrapped_ForTesting() const;
 
@@ -367,9 +367,10 @@
 
 protected:
     // Deferred version
-    GrSurfaceProxy(const GrSurfaceDesc& desc, SkBackingFit fit, SkBudgeted budgeted, uint32_t flags)
-            : GrSurfaceProxy(nullptr, LazyInstantiationType::kSingleUse,
-                             desc, fit, budgeted, flags) {
+    GrSurfaceProxy(const GrSurfaceDesc& desc, GrSurfaceOrigin origin, SkBackingFit fit,
+                   SkBudgeted budgeted, uint32_t flags)
+            : GrSurfaceProxy(nullptr, LazyInstantiationType::kSingleUse, desc, origin, fit,
+                             budgeted, flags) {
         // Note: this ctor pulls a new uniqueID from the same pool at the GrGpuResources
     }
 
@@ -377,8 +378,8 @@
 
     // Lazy-callback version
     GrSurfaceProxy(LazyInstantiateCallback&& callback, LazyInstantiationType lazyType,
-                   const GrSurfaceDesc& desc, SkBackingFit fit, SkBudgeted budgeted,
-                   uint32_t flags);
+                   const GrSurfaceDesc& desc, GrSurfaceOrigin origin, SkBackingFit fit,
+                   SkBudgeted budgeted, uint32_t flags);
 
     // Wrapped version
     GrSurfaceProxy(sk_sp<GrSurface> surface, GrSurfaceOrigin origin, SkBackingFit fit);
diff --git a/include/private/GrTextureProxy.h b/include/private/GrTextureProxy.h
index 508b512..950a78a 100644
--- a/include/private/GrTextureProxy.h
+++ b/include/private/GrTextureProxy.h
@@ -72,8 +72,8 @@
     friend class GrTextureProxyPriv;
 
     // Deferred version
-    GrTextureProxy(const GrSurfaceDesc& srcDesc, GrMipMapped, SkBackingFit, SkBudgeted,
-                   const void* srcData, size_t srcRowBytes, uint32_t flags);
+    GrTextureProxy(const GrSurfaceDesc& srcDesc, GrSurfaceOrigin, GrMipMapped, SkBackingFit,
+                   SkBudgeted, const void* srcData, size_t srcRowBytes, uint32_t flags);
 
     // Lazy-callback version
     // There are two main use cases for lazily-instantiated proxies:
@@ -86,7 +86,8 @@
     // The minimal knowledge version is used for CCPR where we are generating an atlas but we do not
     // know the final size until flush time.
     GrTextureProxy(LazyInstantiateCallback&&, LazyInstantiationType, const GrSurfaceDesc& desc,
-                   GrMipMapped, SkBackingFit fit, SkBudgeted budgeted, uint32_t flags);
+                   GrSurfaceOrigin, GrMipMapped, SkBackingFit fit, SkBudgeted budgeted,
+                   uint32_t flags);
 
     // Wrapped version
     GrTextureProxy(sk_sp<GrSurface>, GrSurfaceOrigin);
diff --git a/src/effects/GrCircleBlurFragmentProcessor.cpp b/src/effects/GrCircleBlurFragmentProcessor.cpp
index 31311e2..c774540 100644
--- a/src/effects/GrCircleBlurFragmentProcessor.cpp
+++ b/src/effects/GrCircleBlurFragmentProcessor.cpp
@@ -212,7 +212,6 @@
     if (!blurProfile) {
         static constexpr int kProfileTextureWidth = 512;
         GrSurfaceDesc texDesc;
-        texDesc.fOrigin = kTopLeft_GrSurfaceOrigin;
         texDesc.fWidth = kProfileTextureWidth;
         texDesc.fHeight = 1;
         texDesc.fConfig = kAlpha_8_GrPixelConfig;
@@ -227,8 +226,8 @@
                     create_circle_profile(sigma * scale, circleR * scale, kProfileTextureWidth));
         }
 
-        blurProfile =
-                proxyProvider->createTextureProxy(texDesc, SkBudgeted::kYes, profile.get(), 0);
+        blurProfile = proxyProvider->createTextureProxy(texDesc, kTopLeft_GrSurfaceOrigin,
+                                                        SkBudgeted::kYes, profile.get(), 0);
         if (!blurProfile) {
             return nullptr;
         }
diff --git a/src/effects/GrCircleBlurFragmentProcessor.fp b/src/effects/GrCircleBlurFragmentProcessor.fp
index 21c8007..2294e0f 100644
--- a/src/effects/GrCircleBlurFragmentProcessor.fp
+++ b/src/effects/GrCircleBlurFragmentProcessor.fp
@@ -234,7 +234,6 @@
         if (!blurProfile) {
             static constexpr int kProfileTextureWidth = 512;
             GrSurfaceDesc texDesc;
-            texDesc.fOrigin = kTopLeft_GrSurfaceOrigin;
             texDesc.fWidth = kProfileTextureWidth;
             texDesc.fHeight = 1;
             texDesc.fConfig = kAlpha_8_GrPixelConfig;
@@ -249,8 +248,8 @@
                                                     kProfileTextureWidth));
             }
 
-            blurProfile = proxyProvider->createTextureProxy(texDesc, SkBudgeted::kYes,
-                                                            profile.get(), 0);
+            blurProfile = proxyProvider->createTextureProxy(
+                    texDesc, kTopLeft_GrSurfaceOrigin, SkBudgeted::kYes, profile.get(), 0);
             if (!blurProfile) {
                 return nullptr;
             }
diff --git a/src/gpu/GrBackendTextureImageGenerator.cpp b/src/gpu/GrBackendTextureImageGenerator.cpp
index 90f006a..aafa3a2 100644
--- a/src/gpu/GrBackendTextureImageGenerator.cpp
+++ b/src/gpu/GrBackendTextureImageGenerator.cpp
@@ -122,7 +122,6 @@
     SkASSERT(fRefHelper->fBorrowingContextID == context->uniqueID());
 
     GrSurfaceDesc desc;
-    desc.fOrigin = fSurfaceOrigin;
     desc.fWidth = fBackendTexture.width();
     desc.fHeight = fBackendTexture.height();
     desc.fConfig = fConfig;
@@ -135,8 +134,8 @@
     RefHelper* refHelper = fRefHelper;
 
     sk_sp<GrTextureProxy> proxy = proxyProvider->createLazyProxy(
-            [refHelper, releaseProcHelper, semaphore, backendTexture]
-            (GrResourceProvider* resourceProvider) {
+            [refHelper, releaseProcHelper, semaphore,
+             backendTexture](GrResourceProvider* resourceProvider) {
                 if (!resourceProvider) {
                     return sk_sp<GrTexture>();
                 }
@@ -172,7 +171,8 @@
 
                 return tex;
 
-            }, desc, mipMapped, SkBackingFit::kExact, SkBudgeted::kNo);
+            },
+            desc, fSurfaceOrigin, mipMapped, SkBackingFit::kExact, SkBudgeted::kNo);
 
     if (0 == origin.fX && 0 == origin.fY &&
         info.width() == fBackendTexture.width() && info.height() == fBackendTexture.height() &&
diff --git a/src/gpu/GrBlurUtils.cpp b/src/gpu/GrBlurUtils.cpp
index b6e3092..fb8977e 100644
--- a/src/gpu/GrBlurUtils.cpp
+++ b/src/gpu/GrBlurUtils.cpp
@@ -78,16 +78,13 @@
     // we now have a device-aligned 8bit mask in dstM, ready to be drawn using
     // the current clip (and identity matrix) and GrPaint settings
     GrSurfaceDesc desc;
-    desc.fOrigin = kTopLeft_GrSurfaceOrigin;
     desc.fWidth = dstM.fBounds.width();
     desc.fHeight = dstM.fBounds.height();
     desc.fConfig = kAlpha_8_GrPixelConfig;
 
     sk_sp<GrSurfaceContext> sContext = context->contextPriv().makeDeferredSurfaceContext(
-                                                        desc,
-                                                        GrMipMapped::kNo,
-                                                        SkBackingFit::kApprox,
-                                                        SkBudgeted::kYes);
+            desc, kTopLeft_GrSurfaceOrigin, GrMipMapped::kNo, SkBackingFit::kApprox,
+            SkBudgeted::kYes);
     if (!sContext) {
         return false;
     }
diff --git a/src/gpu/GrClipStackClip.cpp b/src/gpu/GrClipStackClip.cpp
index 24c813e..179573e 100644
--- a/src/gpu/GrClipStackClip.cpp
+++ b/src/gpu/GrClipStackClip.cpp
@@ -460,14 +460,13 @@
     if (taskGroup && renderTargetContext) {
         // Create our texture proxy
         GrSurfaceDesc desc;
-        desc.fOrigin = kTopLeft_GrSurfaceOrigin;
         desc.fWidth = maskSpaceIBounds.width();
         desc.fHeight = maskSpaceIBounds.height();
         desc.fConfig = kAlpha_8_GrPixelConfig;
         // MDB TODO: We're going to fill this proxy with an ASAP upload (which is out of order wrt
         // to ops), so it can't have any pending IO.
-        proxy = proxyProvider->createProxy(desc, SkBackingFit::kApprox, SkBudgeted::kYes,
-                                           GrResourceProvider::kNoPendingIO_Flag);
+        proxy = proxyProvider->createProxy(desc, kTopLeft_GrSurfaceOrigin, SkBackingFit::kApprox,
+                                           SkBudgeted::kYes, GrResourceProvider::kNoPendingIO_Flag);
 
         auto uploader = skstd::make_unique<GrTDeferredProxyUploader<ClipMaskData>>(reducedClip);
         GrTDeferredProxyUploader<ClipMaskData>* uploaderRaw = uploader.get();
diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp
index 45c4f87..627f20a 100644
--- a/src/gpu/GrContext.cpp
+++ b/src/gpu/GrContext.cpp
@@ -805,8 +805,8 @@
     sk_sp<GrTextureProxy> tempProxy;
     if (GrGpu::kNoDraw_DrawPreference != drawPreference) {
         tempProxy = this->proxyProvider()->createProxy(tempDrawInfo.fTempSurfaceDesc,
-                                                       SkBackingFit::kApprox,
-                                                       SkBudgeted::kYes);
+                                                       kTopLeft_GrSurfaceOrigin,
+                                                       SkBackingFit::kApprox, SkBudgeted::kYes);
         if (!tempProxy && GrGpu::kRequireDraw_DrawPreference == drawPreference) {
             return false;
         }
@@ -968,7 +968,7 @@
                                                           std::move(colorSpace),
                                                           tempDrawInfo.fTempSurfaceDesc.fSampleCnt,
                                                           GrMipMapped::kNo,
-                                                          tempDrawInfo.fTempSurfaceDesc.fOrigin);
+                                                          kTopLeft_GrSurfaceOrigin);
         if (tempRTC) {
             // Adding discard to appease vulkan validation warning about loading uninitialized data
             // on draw
@@ -1073,9 +1073,8 @@
         desc.fWidth = width;
         desc.fHeight = height;
         desc.fSampleCnt = 1;
-        desc.fOrigin = kTopLeft_GrSurfaceOrigin;
-        auto tempProxy =
-                this->proxyProvider()->createProxy(desc, SkBackingFit::kApprox, SkBudgeted::kYes);
+        auto tempProxy = this->proxyProvider()->createProxy(
+                desc, kTopLeft_GrSurfaceOrigin, SkBackingFit::kApprox, SkBudgeted::kYes);
         if (!tempProxy) {
             return false;
         }
@@ -1216,6 +1215,7 @@
 }
 
 sk_sp<GrSurfaceContext> GrContextPriv::makeDeferredSurfaceContext(const GrSurfaceDesc& dstDesc,
+                                                                  GrSurfaceOrigin origin,
                                                                   GrMipMapped mipMapped,
                                                                   SkBackingFit fit,
                                                                   SkBudgeted isDstBudgeted,
@@ -1223,10 +1223,10 @@
                                                                   const SkSurfaceProps* props) {
     sk_sp<GrTextureProxy> proxy;
     if (GrMipMapped::kNo == mipMapped) {
-        proxy = this->proxyProvider()->createProxy(dstDesc, fit, isDstBudgeted);
+        proxy = this->proxyProvider()->createProxy(dstDesc, origin, fit, isDstBudgeted);
     } else {
         SkASSERT(SkBackingFit::kExact == fit);
-        proxy = this->proxyProvider()->createMipMapProxy(dstDesc, isDstBudgeted);
+        proxy = this->proxyProvider()->createMipMapProxy(dstDesc, origin, isDstBudgeted);
     }
     if (!proxy) {
         return nullptr;
@@ -1371,7 +1371,6 @@
 
     GrSurfaceDesc desc;
     desc.fFlags = kRenderTarget_GrSurfaceFlag;
-    desc.fOrigin = origin;
     desc.fWidth = width;
     desc.fHeight = height;
     desc.fConfig = config;
@@ -1379,9 +1378,9 @@
 
     sk_sp<GrTextureProxy> rtp;
     if (GrMipMapped::kNo == mipMapped) {
-        rtp = fProxyProvider->createProxy(desc, fit, budgeted);
+        rtp = fProxyProvider->createProxy(desc, origin, fit, budgeted);
     } else {
-        rtp = fProxyProvider->createMipMapProxy(desc, budgeted);
+        rtp = fProxyProvider->createMipMapProxy(desc, origin, budgeted);
     }
     if (!rtp) {
         return nullptr;
diff --git a/src/gpu/GrContextPriv.h b/src/gpu/GrContextPriv.h
index d8baef8..0db572c 100644
--- a/src/gpu/GrContextPriv.h
+++ b/src/gpu/GrContextPriv.h
@@ -37,6 +37,7 @@
                                                       const SkSurfaceProps* = nullptr);
 
     sk_sp<GrSurfaceContext> makeDeferredSurfaceContext(const GrSurfaceDesc&,
+                                                       GrSurfaceOrigin,
                                                        GrMipMapped,
                                                        SkBackingFit,
                                                        SkBudgeted,
diff --git a/src/gpu/GrDrawOpAtlas.cpp b/src/gpu/GrDrawOpAtlas.cpp
index 56dfcef..bbb87f7 100644
--- a/src/gpu/GrDrawOpAtlas.cpp
+++ b/src/gpu/GrDrawOpAtlas.cpp
@@ -500,7 +500,6 @@
 
     GrSurfaceDesc desc;
     desc.fFlags = kNone_GrSurfaceFlags;
-    desc.fOrigin = kTopLeft_GrSurfaceOrigin;
     desc.fWidth = fTextureWidth;
     desc.fHeight = fTextureHeight;
     desc.fConfig = fPixelConfig;
@@ -509,8 +508,8 @@
     int numPlotsY = fTextureHeight/fPlotHeight;
 
     for (uint32_t i = 0; i < this->maxPages(); ++i) {
-        fProxies[i] = proxyProvider->createProxy(desc, SkBackingFit::kExact, SkBudgeted::kYes,
-                                                 GrResourceProvider::kNoPendingIO_Flag);
+        fProxies[i] = proxyProvider->createProxy(desc, kTopLeft_GrSurfaceOrigin,
+                SkBackingFit::kExact, SkBudgeted::kYes, GrResourceProvider::kNoPendingIO_Flag);
         if (!fProxies[i]) {
             return false;
         }
diff --git a/src/gpu/GrGpu.cpp b/src/gpu/GrGpu.cpp
index a53dc8a..5e15472 100644
--- a/src/gpu/GrGpu.cpp
+++ b/src/gpu/GrGpu.cpp
@@ -72,7 +72,8 @@
 }
 
 sk_sp<GrTexture> GrGpu::createTexture(const GrSurfaceDesc& origDesc, SkBudgeted budgeted,
-                                      const GrMipLevel texels[], int mipLevelCount) {
+                                      GrSurfaceOrigin texelsOrigin, const GrMipLevel texels[],
+                                      int mipLevelCount) {
     GR_CREATE_TRACE_MARKER_CONTEXT("GrGpu", "createTexture", fContext);
     GrSurfaceDesc desc = origDesc;
 
@@ -93,7 +94,8 @@
     }
 
     this->handleDirtyContext();
-    sk_sp<GrTexture> tex = this->onCreateTexture(desc, budgeted, texels, mipLevelCount);
+    sk_sp<GrTexture> tex =
+            this->onCreateTexture(desc, budgeted, texelsOrigin, texels, mipLevelCount);
     if (tex) {
         if (!this->caps()->reuseScratchTextures() && !isRT) {
             tex->resourcePriv().removeScratchKey();
@@ -109,7 +111,7 @@
 }
 
 sk_sp<GrTexture> GrGpu::createTexture(const GrSurfaceDesc& desc, SkBudgeted budgeted) {
-    return this->createTexture(desc, budgeted, nullptr, 0);
+    return this->createTexture(desc, budgeted, kTopLeft_GrSurfaceOrigin, nullptr, 0);
 }
 
 sk_sp<GrTexture> GrGpu::wrapBackendTexture(const GrBackendTexture& backendTex,
@@ -253,7 +255,6 @@
     tempDrawInfo->fTempSurfaceDesc.fWidth = width;
     tempDrawInfo->fTempSurfaceDesc.fHeight = height;
     tempDrawInfo->fTempSurfaceDesc.fSampleCnt = 1;
-    tempDrawInfo->fTempSurfaceDesc.fOrigin = kTopLeft_GrSurfaceOrigin;  // no CPU y-flip for TL.
     tempDrawInfo->fTempSurfaceDesc.fConfig = tempSurfaceConfig;
     tempDrawInfo->fTempSurfaceFit = SkBackingFit::kApprox;
     tempDrawInfo->fSwizzle = GrSwizzle::RGBA();
@@ -334,7 +335,6 @@
     tempDrawInfo->fTempSurfaceDesc.fWidth = width;
     tempDrawInfo->fTempSurfaceDesc.fHeight = height;
     tempDrawInfo->fTempSurfaceDesc.fSampleCnt = 1;
-    tempDrawInfo->fTempSurfaceDesc.fOrigin = kTopLeft_GrSurfaceOrigin;  // no CPU y-flip for TL.
     tempDrawInfo->fSwizzle = GrSwizzle::RGBA();
     tempDrawInfo->fWriteColorType = srcColorType;
 
diff --git a/src/gpu/GrGpu.h b/src/gpu/GrGpu.h
index 7c3b796..dc518cd 100644
--- a/src/gpu/GrGpu.h
+++ b/src/gpu/GrGpu.h
@@ -93,17 +93,19 @@
      * pixel configs can be used as render targets. Support for configs as textures
      * or render targets can be checked using GrCaps.
      *
-     * @param desc        describes the texture to be created.
-     * @param budgeted    does this texture count against the resource cache budget?
-     * @param texels      array of mipmap levels containing texel data to load.
-     *                    Each level begins with full-size palette data for paletted textures.
-     *                    It contains width*height texels. If there is only one
-     *                    element and it contains nullptr fPixels, texture data is
-     *                    uninitialized.
+     * @param desc         describes the texture to be created.
+     * @param budgeted     does this texture count against the resource cache budget?
+     * @param texelsOrigin origin of the texel data to be uploaded. Ignored if there is
+     *                     no initial texel data.
+     * @param texels       array of mipmap levels containing texel data to load.
+     *                     Each level begins with full-size palette data for paletted textures.
+     *                     It contains width*height texels. If there is only one
+     *                     element and it contains nullptr fPixels, texture data is
+     *                     uninitialized.
      * @param mipLevelCount the number of levels in 'texels'
      * @return    The texture object if successful, otherwise nullptr.
      */
-    sk_sp<GrTexture> createTexture(const GrSurfaceDesc&, SkBudgeted,
+    sk_sp<GrTexture> createTexture(const GrSurfaceDesc&, SkBudgeted, GrSurfaceOrigin texelsOrigin,
                                    const GrMipLevel texels[], int mipLevelCount);
 
     /**
@@ -544,8 +546,8 @@
     // Texture size and sample size will have already been validated in base class before
     // onCreateTexture is called.
     virtual sk_sp<GrTexture> onCreateTexture(const GrSurfaceDesc&, SkBudgeted,
-                                             const GrMipLevel texels[],
-                                             int mipLevelCount) = 0;
+                                             GrSurfaceOrigin texelsOrigin,
+                                             const GrMipLevel texels[], int mipLevelCount) = 0;
 
     virtual sk_sp<GrTexture> onWrapBackendTexture(const GrBackendTexture&, GrWrapOwnership) = 0;
     virtual sk_sp<GrTexture> onWrapRenderableBackendTexture(const GrBackendTexture&,
diff --git a/src/gpu/GrOnFlushResourceProvider.cpp b/src/gpu/GrOnFlushResourceProvider.cpp
index 32fb3a9..9abd3f6 100644
--- a/src/gpu/GrOnFlushResourceProvider.cpp
+++ b/src/gpu/GrOnFlushResourceProvider.cpp
@@ -13,9 +13,10 @@
 #include "GrSurfaceProxy.h"
 
 sk_sp<GrRenderTargetContext> GrOnFlushResourceProvider::makeRenderTargetContext(
-                                                        const GrSurfaceDesc& desc,
-                                                        sk_sp<SkColorSpace> colorSpace,
-                                                        const SkSurfaceProps* props) {
+        const GrSurfaceDesc& desc,
+        GrSurfaceOrigin origin,
+        sk_sp<SkColorSpace> colorSpace,
+        const SkSurfaceProps* props) {
     GrSurfaceDesc tmpDesc = desc;
     tmpDesc.fFlags |= kRenderTarget_GrSurfaceFlag;
 
@@ -25,9 +26,9 @@
     // Because this is being allocated at the start of a flush we must ensure the proxy
     // will, when instantiated, have no pending IO.
     // TODO: fold the kNoPendingIO_Flag into GrSurfaceFlags?
-    sk_sp<GrSurfaceProxy> proxy = proxyProvider->createProxy(tmpDesc, SkBackingFit::kExact,
-                                                             SkBudgeted::kYes,
-                                                             GrResourceProvider::kNoPendingIO_Flag);
+    sk_sp<GrSurfaceProxy> proxy =
+            proxyProvider->createProxy(tmpDesc, origin, SkBackingFit::kExact, SkBudgeted::kYes,
+                                       GrResourceProvider::kNoPendingIO_Flag);
     if (!proxy->asRenderTargetProxy()) {
         return nullptr;
     }
diff --git a/src/gpu/GrOnFlushResourceProvider.h b/src/gpu/GrOnFlushResourceProvider.h
index 75b9b0c..3bfc87d 100644
--- a/src/gpu/GrOnFlushResourceProvider.h
+++ b/src/gpu/GrOnFlushResourceProvider.h
@@ -69,6 +69,7 @@
     explicit GrOnFlushResourceProvider(GrDrawingManager* drawingMgr) : fDrawingMgr(drawingMgr) {}
 
     sk_sp<GrRenderTargetContext> makeRenderTargetContext(const GrSurfaceDesc&,
+                                                         GrSurfaceOrigin,
                                                          sk_sp<SkColorSpace>,
                                                          const SkSurfaceProps*);
 
diff --git a/src/gpu/GrOpFlushState.cpp b/src/gpu/GrOpFlushState.cpp
index 53986c5..5309be8 100644
--- a/src/gpu/GrOpFlushState.cpp
+++ b/src/gpu/GrOpFlushState.cpp
@@ -99,7 +99,6 @@
         // TODO: Shouldn't we be bailing here if a draw is really required instead of a copy?
         // e.g. if (tempInfo.fSwizzle != "RGBA") fail.
         GrSurfaceDesc desc;
-        desc.fOrigin = dstProxy->origin();
         desc.fWidth = width;
         desc.fHeight = height;
         desc.fConfig = dstProxy->config();
diff --git a/src/gpu/GrProxyProvider.cpp b/src/gpu/GrProxyProvider.cpp
index 0027f2a..5b91dd1 100644
--- a/src/gpu/GrProxyProvider.cpp
+++ b/src/gpu/GrProxyProvider.cpp
@@ -157,6 +157,7 @@
 }
 
 sk_sp<GrTextureProxy> GrProxyProvider::createInstantiatedProxy(const GrSurfaceDesc& desc,
+                                                               GrSurfaceOrigin origin,
                                                                SkBackingFit fit,
                                                                SkBudgeted budgeted,
                                                                uint32_t flags) {
@@ -171,12 +172,13 @@
         return nullptr;
     }
 
-    return this->createWrapped(std::move(tex), desc.fOrigin);
+    return this->createWrapped(std::move(tex), origin);
 }
 
 sk_sp<GrTextureProxy> GrProxyProvider::createTextureProxy(const GrSurfaceDesc& desc,
-                                                          SkBudgeted budgeted,
-                                                          const void* srcData, size_t rowBytes) {
+                                                          GrSurfaceOrigin origin,
+                                                          SkBudgeted budgeted, const void* srcData,
+                                                          size_t rowBytes) {
     ASSERT_SINGLE_OWNER
 
     if (this->isAbandoned()) {
@@ -186,16 +188,16 @@
     if (srcData) {
         GrMipLevel mipLevel = { srcData, rowBytes };
 
-        sk_sp<GrTexture> tex = fResourceProvider->createTexture(desc, budgeted,
-                                                                SkBackingFit::kExact, mipLevel);
+        sk_sp<GrTexture> tex = fResourceProvider->createTexture(
+                desc, budgeted, SkBackingFit::kExact, origin, mipLevel);
         if (!tex) {
             return nullptr;
         }
 
-        return this->createWrapped(std::move(tex), desc.fOrigin);
+        return this->createWrapped(std::move(tex), origin);
     }
 
-    return this->createProxy(desc, SkBackingFit::kExact, budgeted);
+    return this->createProxy(desc, origin, SkBackingFit::kExact, budgeted);
 }
 
 sk_sp<GrTextureProxy> GrProxyProvider::createTextureProxy(sk_sp<SkImage> srcImage,
@@ -239,13 +241,11 @@
     desc.fWidth = srcImage->width();
     desc.fHeight = srcImage->height();
     desc.fFlags = flags;
-    desc.fOrigin = origin;
     desc.fSampleCnt = sampleCnt;
     desc.fConfig = config;
 
     sk_sp<GrTextureProxy> proxy = this->createLazyProxy(
-            [desc, budgeted, srcImage, fit]
-            (GrResourceProvider* resourceProvider) {
+            [desc, origin, budgeted, srcImage, fit](GrResourceProvider* resourceProvider) {
                 if (!resourceProvider) {
                     // Nothing to clean up here. Once the proxy (and thus lambda) is deleted the ref
                     // on srcImage will be released.
@@ -255,8 +255,9 @@
                 SkAssertResult(srcImage->peekPixels(&pixMap));
                 GrMipLevel mipLevel = { pixMap.addr(), pixMap.rowBytes() };
 
-                return resourceProvider->createTexture(desc, budgeted, fit, mipLevel);
-            }, desc, GrMipMapped::kNo, renderTargetFlags, fit, budgeted);
+                return resourceProvider->createTexture(desc, budgeted, fit, origin, mipLevel);
+            },
+            desc, origin, GrMipMapped::kNo, renderTargetFlags, fit, budgeted);
 
     if (fResourceProvider) {
         // In order to reuse code we always create a lazy proxy. When we aren't in DDL mode however
@@ -269,6 +270,7 @@
 }
 
 sk_sp<GrTextureProxy> GrProxyProvider::createMipMapProxy(const GrSurfaceDesc& desc,
+                                                         GrSurfaceOrigin origin,
                                                          SkBudgeted budgeted) {
     ASSERT_SINGLE_OWNER
 
@@ -276,7 +278,7 @@
         return nullptr;
     }
 
-    return this->createProxy(desc, GrMipMapped::kYes, SkBackingFit::kExact, budgeted, 0);
+    return this->createProxy(desc, origin, GrMipMapped::kYes, SkBackingFit::kExact, budgeted, 0);
 }
 
 sk_sp<GrTextureProxy> GrProxyProvider::createMipMapProxyFromBitmap(const SkBitmap& bitmap,
@@ -324,8 +326,7 @@
     }
 
     sk_sp<GrTextureProxy> proxy = this->createLazyProxy(
-            [desc, baseLevel, mipmaps, mipColorMode]
-            (GrResourceProvider* resourceProvider) {
+            [desc, baseLevel, mipmaps, mipColorMode](GrResourceProvider* resourceProvider) {
                 if (!resourceProvider) {
                     return sk_sp<GrTexture>();
                 }
@@ -349,9 +350,12 @@
                     SkASSERT(texels[i].fPixels);
                 }
 
-                return resourceProvider->createTexture(desc, SkBudgeted::kYes, texels.get(),
+                return resourceProvider->createTexture(desc, SkBudgeted::kYes,
+                                                       kTopLeft_GrSurfaceOrigin, texels.get(),
                                                        mipLevelCount, mipColorMode);
-            }, desc, GrMipMapped::kYes, SkBackingFit::kExact, SkBudgeted::kYes);
+            },
+            desc, kTopLeft_GrSurfaceOrigin, GrMipMapped::kYes, SkBackingFit::kExact,
+            SkBudgeted::kYes);
 
     if (fResourceProvider) {
         // In order to reuse code we always create a lazy proxy. When we aren't in DDL mode however
@@ -364,6 +368,7 @@
 }
 
 sk_sp<GrTextureProxy> GrProxyProvider::createProxy(const GrSurfaceDesc& desc,
+                                                   GrSurfaceOrigin origin,
                                                    GrMipMapped mipMapped,
                                                    SkBackingFit fit,
                                                    SkBudgeted budgeted,
@@ -390,13 +395,12 @@
     if (copyDesc.fFlags & kRenderTarget_GrSurfaceFlag) {
         // We know anything we instantiate later from this deferred path will be
         // both texturable and renderable
-        return sk_sp<GrTextureProxy>(
-                new GrTextureRenderTargetProxy(*this->caps(), copyDesc, mipMapped, fit, budgeted,
-                                               flags));
+        return sk_sp<GrTextureProxy>(new GrTextureRenderTargetProxy(
+                *this->caps(), copyDesc, origin, mipMapped, fit, budgeted, flags));
     }
 
-    return sk_sp<GrTextureProxy>(new GrTextureProxy(copyDesc, mipMapped, fit, budgeted, nullptr, 0,
-                                                    flags));
+    return sk_sp<GrTextureProxy>(
+            new GrTextureProxy(copyDesc, origin, mipMapped, fit, budgeted, nullptr, 0, flags));
 }
 
 sk_sp<GrTextureProxy> GrProxyProvider::createWrappedTextureProxy(
@@ -410,7 +414,6 @@
     }
 
     GrSurfaceDesc desc;
-    desc.fOrigin = origin;
     desc.fWidth = backendTex.width();
     desc.fHeight = backendTex.height();
     desc.fConfig = backendTex.config();
@@ -422,8 +425,7 @@
     }
 
     sk_sp<GrTextureProxy> proxy = this->createLazyProxy(
-            [backendTex, ownership, releaseHelper]
-            (GrResourceProvider* resourceProvider) {
+            [backendTex, ownership, releaseHelper](GrResourceProvider* resourceProvider) {
                 if (!resourceProvider) {
                     // If this had a releaseHelper it will get unrefed when we delete this lambda
                     // and will call the release proc so that the client knows they can free the
@@ -445,7 +447,8 @@
                 SkASSERT(SkBudgeted::kNo == tex->resourcePriv().isBudgeted());
 
                 return tex;
-            }, desc, mipMapped, SkBackingFit::kExact, SkBudgeted::kNo);
+            },
+            desc, origin, mipMapped, SkBackingFit::kExact, SkBudgeted::kNo);
 
     if (fResourceProvider) {
         // In order to reuse code we always create a lazy proxy. When we aren't in DDL mode however,
@@ -470,7 +473,6 @@
     }
 
     GrSurfaceDesc desc;
-    desc.fOrigin = origin;
     desc.fWidth = backendTex.width();
     desc.fHeight = backendTex.height();
     desc.fConfig = backendTex.config();
@@ -487,7 +489,7 @@
     }
 
     sk_sp<GrTextureProxy> proxy = this->createLazyProxy(
-            [backendTex, sampleCnt] (GrResourceProvider* resourceProvider) {
+            [backendTex, sampleCnt](GrResourceProvider* resourceProvider) {
                 if (!resourceProvider) {
                     return sk_sp<GrTexture>();
                 }
@@ -502,7 +504,8 @@
                 SkASSERT(SkBudgeted::kNo == tex->resourcePriv().isBudgeted());
 
                 return tex;
-            }, desc, mipMapped, renderTargetFlags, SkBackingFit::kExact, SkBudgeted::kNo);
+            },
+            desc, origin, mipMapped, renderTargetFlags, SkBackingFit::kExact, SkBudgeted::kNo);
 
     if (fResourceProvider) {
         // In order to reuse code we always create a lazy proxy. When we aren't in DDL mode however,
@@ -522,7 +525,6 @@
     }
 
     GrSurfaceDesc desc;
-    desc.fOrigin = origin;
     desc.fWidth = backendRT.width();
     desc.fHeight = backendRT.height();
     desc.fConfig = backendRT.config();
@@ -538,7 +540,7 @@
     }
 
     sk_sp<GrRenderTargetProxy> proxy = this->createLazyRenderTargetProxy(
-            [backendRT] (GrResourceProvider* resourceProvider) {
+            [backendRT](GrResourceProvider* resourceProvider) {
                 if (!resourceProvider) {
                     return sk_sp<GrRenderTarget>();
                 }
@@ -553,8 +555,9 @@
                 SkASSERT(SkBudgeted::kNo == rt->resourcePriv().isBudgeted());
 
                 return rt;
-            }, desc, renderTargetFlags, Textureable::kNo, GrMipMapped::kNo, SkBackingFit::kExact,
-               SkBudgeted::kNo);
+            },
+            desc, origin, renderTargetFlags, Textureable::kNo, GrMipMapped::kNo,
+            SkBackingFit::kExact, SkBudgeted::kNo);
 
     if (fResourceProvider) {
         // In order to reuse code we always create a lazy proxy. When we aren't in DDL mode however,
@@ -580,7 +583,6 @@
     }
 
     GrSurfaceDesc desc;
-    desc.fOrigin = origin;
     desc.fWidth = backendTex.width();
     desc.fHeight = backendTex.height();
     desc.fConfig = backendTex.config();
@@ -596,7 +598,7 @@
     }
 
     sk_sp<GrRenderTargetProxy> proxy = this->createLazyRenderTargetProxy(
-            [backendTex, sampleCnt] (GrResourceProvider* resourceProvider) {
+            [backendTex, sampleCnt](GrResourceProvider* resourceProvider) {
                 if (!resourceProvider) {
                     return sk_sp<GrRenderTarget>();
                 }
@@ -612,8 +614,9 @@
                 SkASSERT(SkBudgeted::kNo == rt->resourcePriv().isBudgeted());
 
                 return rt;
-            }, desc, renderTargetFlags, Textureable::kNo, GrMipMapped::kNo, SkBackingFit::kExact,
-               SkBudgeted::kNo);
+            },
+            desc, origin, renderTargetFlags, Textureable::kNo, GrMipMapped::kNo,
+            SkBackingFit::kExact, SkBudgeted::kNo);
 
     if (fResourceProvider) {
         // In order to reuse code we always create a lazy proxy. When we aren't in DDL mode however,
@@ -627,14 +630,16 @@
 
 sk_sp<GrTextureProxy> GrProxyProvider::createLazyProxy(LazyInstantiateCallback&& callback,
                                                        const GrSurfaceDesc& desc,
-                                                       GrMipMapped mipMapped,
-                                                       SkBackingFit fit, SkBudgeted budgeted) {
-    return this->createLazyProxy(std::move(callback), desc, mipMapped, GrRenderTargetFlags::kNone,
-                                 fit, budgeted);
+                                                       GrSurfaceOrigin origin,
+                                                       GrMipMapped mipMapped, SkBackingFit fit,
+                                                       SkBudgeted budgeted) {
+    return this->createLazyProxy(std::move(callback), desc, origin, mipMapped,
+                                 GrRenderTargetFlags::kNone, fit, budgeted);
 }
 
 sk_sp<GrTextureProxy> GrProxyProvider::createLazyProxy(LazyInstantiateCallback&& callback,
                                                        const GrSurfaceDesc& desc,
+                                                       GrSurfaceOrigin origin,
                                                        GrMipMapped mipMapped,
                                                        GrRenderTargetFlags renderTargetFlags,
                                                        SkBackingFit fit, SkBudgeted budgeted) {
@@ -658,21 +663,19 @@
     LazyInstantiationType lazyType = fResourceProvider ? LazyInstantiationType::kSingleUse
                                                        : LazyInstantiationType::kMultipleUse;
 
-    return sk_sp<GrTextureProxy>(SkToBool(kRenderTarget_GrSurfaceFlag & desc.fFlags) ?
-                                 new GrTextureRenderTargetProxy(std::move(callback), lazyType, desc,
-                                                                mipMapped, fit, budgeted, flags,
-                                                                renderTargetFlags) :
-                                 new GrTextureProxy(std::move(callback), lazyType, desc, mipMapped,
-                                                    fit, budgeted, flags));
+    return sk_sp<GrTextureProxy>(
+            SkToBool(kRenderTarget_GrSurfaceFlag & desc.fFlags)
+                    ? new GrTextureRenderTargetProxy(std::move(callback), lazyType, desc, origin,
+                                                     mipMapped, fit, budgeted, flags,
+                                                     renderTargetFlags)
+                    : new GrTextureProxy(std::move(callback), lazyType, desc, origin, mipMapped,
+                                         fit, budgeted, flags));
 }
 
 sk_sp<GrRenderTargetProxy> GrProxyProvider::createLazyRenderTargetProxy(
-                                                LazyInstantiateCallback&& callback,
-                                                const GrSurfaceDesc& desc,
-                                                GrRenderTargetFlags renderTargetFlags,
-                                                Textureable textureable,
-                                                GrMipMapped mipMapped,
-                                                SkBackingFit fit, SkBudgeted budgeted) {
+        LazyInstantiateCallback&& callback, const GrSurfaceDesc& desc, GrSurfaceOrigin origin,
+        GrRenderTargetFlags renderTargetFlags, Textureable textureable, GrMipMapped mipMapped,
+        SkBackingFit fit, SkBudgeted budgeted) {
     SkASSERT((desc.fWidth <= 0 && desc.fHeight <= 0) ||
              (desc.fWidth > 0 && desc.fHeight > 0));
     SkASSERT(SkToBool(kRenderTarget_GrSurfaceFlag & desc.fFlags));
@@ -693,15 +696,13 @@
                                                        : LazyInstantiationType::kMultipleUse;
 
     if (Textureable::kYes == textureable) {
-        return sk_sp<GrRenderTargetProxy>(new GrTextureRenderTargetProxy(std::move(callback),
-                                                                         lazyType, desc, mipMapped,
-                                                                         fit, budgeted, flags,
-                                                                         renderTargetFlags));
+        return sk_sp<GrRenderTargetProxy>(
+                new GrTextureRenderTargetProxy(std::move(callback), lazyType, desc, origin,
+                                               mipMapped, fit, budgeted, flags, renderTargetFlags));
     }
 
-    return sk_sp<GrRenderTargetProxy>(new GrRenderTargetProxy(std::move(callback), lazyType, desc,
-                                                              fit, budgeted, flags,
-                                                              renderTargetFlags));
+    return sk_sp<GrRenderTargetProxy>(new GrRenderTargetProxy(
+            std::move(callback), lazyType, desc, origin, fit, budgeted, flags, renderTargetFlags));
 }
 
 sk_sp<GrTextureProxy> GrProxyProvider::createFullyLazyProxy(LazyInstantiateCallback&& callback,
@@ -716,15 +717,13 @@
             renderTargetFlags |= GrRenderTargetFlags::kWindowRectsSupport;
         }
     }
-    desc.fOrigin = origin;
     desc.fWidth = -1;
     desc.fHeight = -1;
     desc.fConfig = config;
     desc.fSampleCnt = 1;
 
-    return this->createLazyProxy(std::move(callback), desc, GrMipMapped::kNo, renderTargetFlags,
-                                 SkBackingFit::kApprox, SkBudgeted::kYes);
-
+    return this->createLazyProxy(std::move(callback), desc, origin, GrMipMapped::kNo,
+                                 renderTargetFlags, SkBackingFit::kApprox, SkBudgeted::kYes);
 }
 
 bool GrProxyProvider::IsFunctionallyExact(GrSurfaceProxy* proxy) {
diff --git a/src/gpu/GrProxyProvider.h b/src/gpu/GrProxyProvider.h
index 254686a..20d546f 100644
--- a/src/gpu/GrProxyProvider.h
+++ b/src/gpu/GrProxyProvider.h
@@ -65,15 +65,15 @@
      * DDL TODO: remove the remaining Skia-internal use of this method and make it truly
      * testing-only.
      */
-    sk_sp<GrTextureProxy> createInstantiatedProxy(const GrSurfaceDesc&, SkBackingFit, SkBudgeted,
-                                                  uint32_t flags = 0);
+    sk_sp<GrTextureProxy> createInstantiatedProxy(const GrSurfaceDesc&, GrSurfaceOrigin,
+                                                  SkBackingFit, SkBudgeted, uint32_t flags = 0);
 
     /*
      * Create an un-mipmapped texture proxy with data.
      * DDL TODO: need to refine ownership semantics of 'srcData' if we're in completely
      * deferred mode
      */
-    sk_sp<GrTextureProxy> createTextureProxy(const GrSurfaceDesc&, SkBudgeted,
+    sk_sp<GrTextureProxy> createTextureProxy(const GrSurfaceDesc&, GrSurfaceOrigin, SkBudgeted,
                                              const void* srcData, size_t rowBytes);
 
     /*
@@ -95,7 +95,7 @@
      * simply has space allocated for the mips. We will allocated the full amount of mip levels
      * based on the width and height in the GrSurfaceDesc.
      */
-    sk_sp<GrTextureProxy> createMipMapProxy(const GrSurfaceDesc&, SkBudgeted);
+    sk_sp<GrTextureProxy> createMipMapProxy(const GrSurfaceDesc&, GrSurfaceOrigin, SkBudgeted);
 
     /*
      * Creates a new mipmapped texture proxy for the bitmap with mip levels generated by the cpu.
@@ -106,12 +106,12 @@
     /*
      * Create a GrSurfaceProxy without any data.
      */
-    sk_sp<GrTextureProxy> createProxy(const GrSurfaceDesc&, GrMipMapped, SkBackingFit, SkBudgeted,
-                                      uint32_t flags);
+    sk_sp<GrTextureProxy> createProxy(const GrSurfaceDesc&, GrSurfaceOrigin, GrMipMapped,
+                                      SkBackingFit, SkBudgeted, uint32_t flags);
 
-    sk_sp<GrTextureProxy> createProxy(const GrSurfaceDesc& desc, SkBackingFit fit,
-                                      SkBudgeted budgeted, uint32_t flags = 0) {
-        return this->createProxy(desc, GrMipMapped::kNo, fit, budgeted, flags);
+    sk_sp<GrTextureProxy> createProxy(const GrSurfaceDesc& desc, GrSurfaceOrigin origin,
+                                      SkBackingFit fit, SkBudgeted budgeted, uint32_t flags = 0) {
+        return this->createProxy(desc, origin, GrMipMapped::kNo, fit, budgeted, flags);
     }
 
     // These match the definitions in SkImage & GrTexture.h, for whence they came
@@ -168,11 +168,11 @@
      * callback should cleanup any resources it captured and return an empty sk_sp<GrTextureProxy>.
      */
     sk_sp<GrTextureProxy> createLazyProxy(LazyInstantiateCallback&&, const GrSurfaceDesc&,
-                                          GrMipMapped, GrRenderTargetFlags, SkBackingFit,
-                                          SkBudgeted);
+                                          GrSurfaceOrigin, GrMipMapped, GrRenderTargetFlags,
+                                          SkBackingFit, SkBudgeted);
 
     sk_sp<GrTextureProxy> createLazyProxy(LazyInstantiateCallback&&, const GrSurfaceDesc&,
-                                          GrMipMapped, SkBackingFit, SkBudgeted);
+                                          GrSurfaceOrigin, GrMipMapped, SkBackingFit, SkBudgeted);
 
     /**
      * Fully lazy proxies have unspecified width and height. Methods that rely on those values
@@ -183,6 +183,7 @@
 
     sk_sp<GrRenderTargetProxy> createLazyRenderTargetProxy(LazyInstantiateCallback&&,
                                                            const GrSurfaceDesc&,
+                                                           GrSurfaceOrigin origin,
                                                            GrRenderTargetFlags, Textureable,
                                                            GrMipMapped, SkBackingFit, SkBudgeted);
 
diff --git a/src/gpu/GrRenderTargetContext.cpp b/src/gpu/GrRenderTargetContext.cpp
index 1de4ab8..f6da289 100644
--- a/src/gpu/GrRenderTargetContext.cpp
+++ b/src/gpu/GrRenderTargetContext.cpp
@@ -1790,9 +1790,10 @@
     GrSurfaceDesc desc;
     bool rectsMustMatch = false;
     bool disallowSubrect = false;
-    if (!this->caps()->initDescForDstCopy(rtProxy, &desc, &rectsMustMatch, &disallowSubrect)) {
+    GrSurfaceOrigin origin;
+    if (!this->caps()->initDescForDstCopy(rtProxy, &desc, &origin, &rectsMustMatch,
+                                          &disallowSubrect)) {
         desc.fFlags = kRenderTarget_GrSurfaceFlag;
-        desc.fOrigin = kBottomLeft_GrSurfaceOrigin;
         desc.fConfig = rtProxy->config();
     }
 
@@ -1803,7 +1804,6 @@
     SkIPoint dstPoint, dstOffset;
     SkBackingFit fit;
     if (rectsMustMatch) {
-        SkASSERT(desc.fOrigin == rtProxy->origin());
         desc.fWidth = rtProxy->width();
         desc.fHeight = rtProxy->height();
         dstPoint = {copyRect.fLeft, copyRect.fTop};
@@ -1818,7 +1818,7 @@
     }
 
     sk_sp<GrSurfaceContext> sContext = fContext->contextPriv().makeDeferredSurfaceContext(
-            desc, GrMipMapped::kNo, fit, SkBudgeted::kYes,
+            desc, origin, GrMipMapped::kNo, fit, SkBudgeted::kYes,
             sk_ref_sp(this->colorSpaceInfo().colorSpace()));
     if (!sContext) {
         SkDebugf("setupDstTexture: surfaceContext creation failed.\n");
diff --git a/src/gpu/GrRenderTargetProxy.cpp b/src/gpu/GrRenderTargetProxy.cpp
index e0dbe8f..e97900c 100644
--- a/src/gpu/GrRenderTargetProxy.cpp
+++ b/src/gpu/GrRenderTargetProxy.cpp
@@ -19,8 +19,9 @@
 // TODO: we can probably munge the 'desc' in both the wrapped and deferred
 // cases to make the sampleConfig/numSamples stuff more rational.
 GrRenderTargetProxy::GrRenderTargetProxy(const GrCaps& caps, const GrSurfaceDesc& desc,
-                                         SkBackingFit fit, SkBudgeted budgeted, uint32_t flags)
-        : INHERITED(desc, fit, budgeted, flags)
+                                         GrSurfaceOrigin origin, SkBackingFit fit,
+                                         SkBudgeted budgeted, uint32_t flags)
+        : INHERITED(desc, origin, fit, budgeted, flags)
         , fSampleCnt(desc.fSampleCnt)
         , fNeedsStencil(false)
         , fRenderTargetFlags(GrRenderTargetFlags::kNone) {
@@ -36,12 +37,11 @@
 
 // Lazy-callback version
 GrRenderTargetProxy::GrRenderTargetProxy(LazyInstantiateCallback&& callback,
-                                         LazyInstantiationType lazyType,
-                                         const GrSurfaceDesc& desc,
-                                         SkBackingFit fit, SkBudgeted budgeted,
-                                         uint32_t flags,
+                                         LazyInstantiationType lazyType, const GrSurfaceDesc& desc,
+                                         GrSurfaceOrigin origin, SkBackingFit fit,
+                                         SkBudgeted budgeted, uint32_t flags,
                                          GrRenderTargetFlags renderTargetFlags)
-        : INHERITED(std::move(callback), lazyType, desc, fit, budgeted, flags)
+        : INHERITED(std::move(callback), lazyType, desc, origin, fit, budgeted, flags)
         , fSampleCnt(desc.fSampleCnt)
         , fNeedsStencil(false)
         , fRenderTargetFlags(renderTargetFlags) {
diff --git a/src/gpu/GrResourceProvider.cpp b/src/gpu/GrResourceProvider.cpp
index df09e27..62a17a4 100644
--- a/src/gpu/GrResourceProvider.cpp
+++ b/src/gpu/GrResourceProvider.cpp
@@ -62,6 +62,7 @@
 }
 
 sk_sp<GrTexture> GrResourceProvider::createTexture(const GrSurfaceDesc& desc, SkBudgeted budgeted,
+                                                   GrSurfaceOrigin texelsOrigin,
                                                    const GrMipLevel texels[], int mipLevelCount,
                                                    SkDestinationSurfaceColorMode mipColorMode) {
     ASSERT_SINGLE_OWNER
@@ -77,7 +78,7 @@
         return nullptr;
     }
 
-    sk_sp<GrTexture> tex(fGpu->createTexture(desc, budgeted, texels, mipLevelCount));
+    sk_sp<GrTexture> tex(fGpu->createTexture(desc, budgeted, texelsOrigin, texels, mipLevelCount));
     if (tex) {
         tex->texturePriv().setMipColorMode(mipColorMode);
     }
@@ -108,6 +109,7 @@
 sk_sp<GrTexture> GrResourceProvider::createTexture(const GrSurfaceDesc& desc,
                                                    SkBudgeted budgeted,
                                                    SkBackingFit fit,
+                                                   GrSurfaceOrigin mipLevelOrigin,
                                                    const GrMipLevel& mipLevel) {
     ASSERT_SINGLE_OWNER
 
@@ -131,9 +133,8 @@
     if (make_info(desc.fWidth, desc.fHeight, desc.fConfig, &srcInfo)) {
         // DDL TODO: remove this use of createInstantiatedProxy and convert it to a testing-only
         // method.
-        sk_sp<GrTextureProxy> proxy = proxyProvider->createInstantiatedProxy(desc,
-                                                                             fit,
-                                                                             budgeted);
+        sk_sp<GrTextureProxy> proxy =
+                proxyProvider->createInstantiatedProxy(desc, mipLevelOrigin, fit, budgeted);
         if (proxy) {
             // We use an ephemeral surface context to do the write pixels. Here it isn't clear what
             // color space to tag it with. That's ok because GrSurfaceContext::writePixels doesn't
@@ -154,7 +155,7 @@
         }
     }
 
-    return fGpu->createTexture(desc, budgeted, &mipLevel, 1);
+    return fGpu->createTexture(desc, budgeted, mipLevelOrigin, &mipLevel, 1);
 }
 
 sk_sp<GrTexture> GrResourceProvider::createTexture(const GrSurfaceDesc& desc, SkBudgeted budgeted,
diff --git a/src/gpu/GrResourceProvider.h b/src/gpu/GrResourceProvider.h
index dcabb0c..2ad1202 100644
--- a/src/gpu/GrResourceProvider.h
+++ b/src/gpu/GrResourceProvider.h
@@ -68,13 +68,13 @@
      */
     sk_sp<GrTexture> createTexture(const GrSurfaceDesc&, SkBudgeted, uint32_t flags = 0);
 
-    sk_sp<GrTexture> createTexture(const GrSurfaceDesc&, SkBudgeted,
+    sk_sp<GrTexture> createTexture(const GrSurfaceDesc&, SkBudgeted, GrSurfaceOrigin texelsOrigin,
                                    const GrMipLevel texels[], int mipLevelCount,
                                    SkDestinationSurfaceColorMode mipColorMode);
 
     // Create a potentially loose fit texture with the provided data
     sk_sp<GrTexture> createTexture(const GrSurfaceDesc&, SkBudgeted, SkBackingFit,
-                                   const GrMipLevel&);
+                                   GrSurfaceOrigin mipLevelOrigin, const GrMipLevel&);
 
     ///////////////////////////////////////////////////////////////////////////
     // Wrapped Backend Surfaces
diff --git a/src/gpu/GrSWMaskHelper.cpp b/src/gpu/GrSWMaskHelper.cpp
index 1005758..bae0f43 100644
--- a/src/gpu/GrSWMaskHelper.cpp
+++ b/src/gpu/GrSWMaskHelper.cpp
@@ -93,16 +93,12 @@
 
 sk_sp<GrTextureProxy> GrSWMaskHelper::toTextureProxy(GrContext* context, SkBackingFit fit) {
     GrSurfaceDesc desc;
-    desc.fOrigin = kTopLeft_GrSurfaceOrigin;
     desc.fWidth = fPixels->width();
     desc.fHeight = fPixels->height();
     desc.fConfig = kAlpha_8_GrPixelConfig;
 
     sk_sp<GrSurfaceContext> sContext = context->contextPriv().makeDeferredSurfaceContext(
-                                                                                desc,
-                                                                                GrMipMapped::kNo,
-                                                                                fit,
-                                                                                SkBudgeted::kYes);
+            desc, kTopLeft_GrSurfaceOrigin, GrMipMapped::kNo, fit, SkBudgeted::kYes);
     if (!sContext || !sContext->asTextureProxy()) {
         return nullptr;
     }
diff --git a/src/gpu/GrSoftwarePathRenderer.cpp b/src/gpu/GrSoftwarePathRenderer.cpp
index ff6a20f..2ac4b5e 100644
--- a/src/gpu/GrSoftwarePathRenderer.cpp
+++ b/src/gpu/GrSoftwarePathRenderer.cpp
@@ -172,14 +172,13 @@
     GrProxyProvider* proxyProvider = context->contextPriv().proxyProvider();
 
     GrSurfaceDesc desc;
-    desc.fOrigin = kTopLeft_GrSurfaceOrigin;
     desc.fWidth = width;
     desc.fHeight = height;
     desc.fConfig = kAlpha_8_GrPixelConfig;
 
     // MDB TODO: We're going to fill this proxy with an ASAP upload (which is out of order wrt to
     // ops), so it can't have any pending IO.
-    return proxyProvider->createProxy(desc, fit, SkBudgeted::kYes,
+    return proxyProvider->createProxy(desc, kTopLeft_GrSurfaceOrigin, fit, SkBudgeted::kYes,
                                       GrResourceProvider::kNoPendingIO_Flag);
 }
 
diff --git a/src/gpu/GrSurfaceProxy.cpp b/src/gpu/GrSurfaceProxy.cpp
index 7acc03b..b8132e8 100644
--- a/src/gpu/GrSurfaceProxy.cpp
+++ b/src/gpu/GrSurfaceProxy.cpp
@@ -45,12 +45,12 @@
 
 // Lazy-callback version
 GrSurfaceProxy::GrSurfaceProxy(LazyInstantiateCallback&& callback, LazyInstantiationType lazyType,
-                               const GrSurfaceDesc& desc, SkBackingFit fit, SkBudgeted budgeted,
-                               uint32_t flags)
+                               const GrSurfaceDesc& desc, GrSurfaceOrigin origin, SkBackingFit fit,
+                               SkBudgeted budgeted, uint32_t flags)
         : fConfig(desc.fConfig)
         , fWidth(desc.fWidth)
         , fHeight(desc.fHeight)
-        , fOrigin(desc.fOrigin)
+        , fOrigin(origin)
         , fFit(fit)
         , fBudgeted(budgeted)
         , fFlags(flags)
@@ -122,7 +122,6 @@
     if (fNeedsClear) {
         desc.fFlags |= kPerformInitialClear_GrSurfaceFlag;
     }
-    desc.fOrigin = fOrigin;
     desc.fWidth = fWidth;
     desc.fHeight = fHeight;
     desc.fConfig = fConfig;
@@ -145,7 +144,7 @@
             texels[i].fRowBytes = 0;
         }
 
-        surface = resourceProvider->createTexture(desc, fBudgeted, texels.get(), mipCount,
+        surface = resourceProvider->createTexture(desc, fBudgeted, fOrigin, texels.get(), mipCount,
                                                   SkDestinationSurfaceColorMode::kLegacy);
         if (surface) {
             SkASSERT(surface->asTexture());
@@ -300,7 +299,6 @@
     }
 
     GrSurfaceDesc dstDesc;
-    dstDesc.fOrigin = src->origin();
     dstDesc.fWidth = srcRect.width();
     dstDesc.fHeight = srcRect.height();
     dstDesc.fConfig = src->config();
@@ -315,7 +313,8 @@
         colorSpace = SkColorSpace::MakeSRGB();
     }
     sk_sp<GrSurfaceContext> dstContext(context->contextPriv().makeDeferredSurfaceContext(
-            dstDesc, mipMapped, SkBackingFit::kExact, budgeted, std::move(colorSpace)));
+            dstDesc, src->origin(), mipMapped, SkBackingFit::kExact, budgeted,
+            std::move(colorSpace)));
     if (!dstContext) {
         return nullptr;
     }
@@ -334,13 +333,10 @@
 }
 
 sk_sp<GrSurfaceContext> GrSurfaceProxy::TestCopy(GrContext* context, const GrSurfaceDesc& dstDesc,
-                                                 GrSurfaceProxy* srcProxy) {
+                                                 GrSurfaceOrigin origin, GrSurfaceProxy* srcProxy) {
     SkASSERT(LazyState::kFully != srcProxy->lazyInstantiationState());
     sk_sp<GrSurfaceContext> dstContext(context->contextPriv().makeDeferredSurfaceContext(
-                                                                            dstDesc,
-                                                                            GrMipMapped::kNo,
-                                                                            SkBackingFit::kExact,
-                                                                            SkBudgeted::kYes));
+            dstDesc, origin, GrMipMapped::kNo, SkBackingFit::kExact, SkBudgeted::kYes));
     if (!dstContext) {
         return nullptr;
     }
diff --git a/src/gpu/GrTextureProxy.cpp b/src/gpu/GrTextureProxy.cpp
index d6ce9fe..cfeb34c 100644
--- a/src/gpu/GrTextureProxy.cpp
+++ b/src/gpu/GrTextureProxy.cpp
@@ -15,10 +15,10 @@
 #include "GrTexturePriv.h"
 
 // Deferred version
-GrTextureProxy::GrTextureProxy(const GrSurfaceDesc& srcDesc, GrMipMapped mipMapped,
-                               SkBackingFit fit, SkBudgeted budgeted, const void* srcData,
-                               size_t /*rowBytes*/, uint32_t flags)
-        : INHERITED(srcDesc, fit, budgeted, flags)
+GrTextureProxy::GrTextureProxy(const GrSurfaceDesc& srcDesc, GrSurfaceOrigin origin,
+                               GrMipMapped mipMapped, SkBackingFit fit, SkBudgeted budgeted,
+                               const void* srcData, size_t /*rowBytes*/, uint32_t flags)
+        : INHERITED(srcDesc, origin, fit, budgeted, flags)
         , fMipMapped(mipMapped)
         , fProxyProvider(nullptr)
         , fDeferredUploader(nullptr) {
@@ -27,13 +27,13 @@
 
 // Lazy-callback version
 GrTextureProxy::GrTextureProxy(LazyInstantiateCallback&& callback, LazyInstantiationType lazyType,
-                               const GrSurfaceDesc& desc, GrMipMapped mipMapped, SkBackingFit fit,
-                               SkBudgeted budgeted, uint32_t flags)
-        : INHERITED(std::move(callback), lazyType, desc, fit, budgeted, flags)
+                               const GrSurfaceDesc& desc, GrSurfaceOrigin origin,
+                               GrMipMapped mipMapped, SkBackingFit fit, SkBudgeted budgeted,
+                               uint32_t flags)
+        : INHERITED(std::move(callback), lazyType, desc, origin, fit, budgeted, flags)
         , fMipMapped(mipMapped)
         , fProxyProvider(nullptr)
-        , fDeferredUploader(nullptr) {
-}
+        , fDeferredUploader(nullptr) {}
 
 // Wrapped version
 GrTextureProxy::GrTextureProxy(sk_sp<GrSurface> surf, GrSurfaceOrigin origin)
diff --git a/src/gpu/GrTextureRenderTargetProxy.cpp b/src/gpu/GrTextureRenderTargetProxy.cpp
index 213359b..c36867d 100644
--- a/src/gpu/GrTextureRenderTargetProxy.cpp
+++ b/src/gpu/GrTextureRenderTargetProxy.cpp
@@ -19,32 +19,33 @@
 // GrRenderTargetProxy) so its constructor must be explicitly called.
 GrTextureRenderTargetProxy::GrTextureRenderTargetProxy(const GrCaps& caps,
                                                        const GrSurfaceDesc& desc,
+                                                       GrSurfaceOrigin origin,
                                                        GrMipMapped mipMapped,
                                                        SkBackingFit fit,
                                                        SkBudgeted budgeted,
                                                        uint32_t flags)
-        : GrSurfaceProxy(desc, fit, budgeted, flags)
+        : GrSurfaceProxy(desc, origin, fit, budgeted, flags)
         // for now textures w/ data are always wrapped
-        , GrTextureProxy(desc, mipMapped, fit, budgeted, nullptr, 0, flags)
-        , GrRenderTargetProxy(caps, desc, fit, budgeted, flags) {
-}
+        , GrTextureProxy(desc, origin, mipMapped, fit, budgeted, nullptr, 0, flags)
+        , GrRenderTargetProxy(caps, desc, origin, fit, budgeted, flags) {}
 
 // Lazy-callback version
 GrTextureRenderTargetProxy::GrTextureRenderTargetProxy(LazyInstantiateCallback&& callback,
                                                        LazyInstantiationType lazyType,
                                                        const GrSurfaceDesc& desc,
+                                                       GrSurfaceOrigin origin,
                                                        GrMipMapped mipMapped,
                                                        SkBackingFit fit,
                                                        SkBudgeted budgeted,
                                                        uint32_t flags,
                                                        GrRenderTargetFlags renderTargetFlags)
-        : GrSurfaceProxy(std::move(callback), lazyType, desc, fit, budgeted, flags)
+        : GrSurfaceProxy(std::move(callback), lazyType, desc, origin, fit, budgeted, flags)
         // Since we have virtual inheritance, we initialize GrSurfaceProxy directly. Send null
         // callbacks to the texture and RT proxies simply to route to the appropriate constructors.
-        , GrTextureProxy(LazyInstantiateCallback(), lazyType, desc, mipMapped, fit, budgeted, flags)
-        , GrRenderTargetProxy(LazyInstantiateCallback(), lazyType, desc, fit, budgeted, flags,
-                              renderTargetFlags) {
-}
+        , GrTextureProxy(LazyInstantiateCallback(), lazyType, desc, origin, mipMapped, fit,
+                         budgeted, flags)
+        , GrRenderTargetProxy(LazyInstantiateCallback(), lazyType, desc, origin, fit, budgeted,
+                              flags, renderTargetFlags) {}
 
 // Wrapped version
 // This class is virtually derived from GrSurfaceProxy (via both GrTextureProxy and
diff --git a/src/gpu/GrTextureRenderTargetProxy.h b/src/gpu/GrTextureRenderTargetProxy.h
index a236189..9dd0400 100644
--- a/src/gpu/GrTextureRenderTargetProxy.h
+++ b/src/gpu/GrTextureRenderTargetProxy.h
@@ -28,13 +28,13 @@
     friend class GrProxyProvider; // for ctors
 
     // Deferred version
-    GrTextureRenderTargetProxy(const GrCaps&, const GrSurfaceDesc&, GrMipMapped,
+    GrTextureRenderTargetProxy(const GrCaps&, const GrSurfaceDesc&, GrSurfaceOrigin, GrMipMapped,
                                SkBackingFit, SkBudgeted, uint32_t flags);
 
     // Lazy-callback version
     GrTextureRenderTargetProxy(LazyInstantiateCallback&&, LazyInstantiationType,
-                               const GrSurfaceDesc& desc, GrMipMapped, SkBackingFit, SkBudgeted,
-                               uint32_t flags, GrRenderTargetFlags);
+                               const GrSurfaceDesc& desc, GrSurfaceOrigin, GrMipMapped,
+                               SkBackingFit, SkBudgeted, uint32_t flags, GrRenderTargetFlags);
 
     // Wrapped version
     GrTextureRenderTargetProxy(sk_sp<GrSurface>, GrSurfaceOrigin);
diff --git a/src/gpu/SkGr.cpp b/src/gpu/SkGr.cpp
index 095a867..58df7c5 100644
--- a/src/gpu/SkGr.cpp
+++ b/src/gpu/SkGr.cpp
@@ -45,7 +45,6 @@
 GrSurfaceDesc GrImageInfoToSurfaceDesc(const SkImageInfo& info, const GrCaps& caps) {
     GrSurfaceDesc desc;
     desc.fFlags = kNone_GrSurfaceFlags;
-    desc.fOrigin = kTopLeft_GrSurfaceOrigin;
     desc.fWidth = info.width();
     desc.fHeight = info.height();
     desc.fConfig = SkImageInfo2GrPixelConfig(info, caps);
@@ -119,13 +118,13 @@
     GrProxyProvider* proxyProvider = ctx->contextPriv().proxyProvider();
     GrSurfaceDesc desc;
     desc.fFlags = kNone_GrSurfaceFlags;
-    desc.fOrigin = baseProxy->origin();
     desc.fWidth = baseProxy->width();
     desc.fHeight = baseProxy->height();
     desc.fConfig = baseProxy->config();
     desc.fSampleCnt = 1;
 
-    sk_sp<GrTextureProxy> proxy = proxyProvider->createMipMapProxy(desc, SkBudgeted::kYes);
+    sk_sp<GrTextureProxy> proxy =
+            proxyProvider->createMipMapProxy(desc, baseProxy->origin(), SkBudgeted::kYes);
     if (!proxy) {
         return nullptr;
     }
diff --git a/src/gpu/ccpr/GrCCAtlas.cpp b/src/gpu/ccpr/GrCCAtlas.cpp
index ce5cddb..da4138f 100644
--- a/src/gpu/ccpr/GrCCAtlas.cpp
+++ b/src/gpu/ccpr/GrCCAtlas.cpp
@@ -146,11 +146,11 @@
 
     GrSurfaceDesc desc;
     desc.fFlags = kRenderTarget_GrSurfaceFlag;
-    desc.fOrigin = kTopLeft_GrSurfaceOrigin;
     desc.fWidth = fWidth;
     desc.fHeight = fHeight;
     desc.fConfig = kAlpha_half_GrPixelConfig;
-    sk_sp<GrRenderTargetContext> rtc = onFlushRP->makeRenderTargetContext(desc, nullptr, nullptr);
+    sk_sp<GrRenderTargetContext> rtc =
+            onFlushRP->makeRenderTargetContext(desc, kTopLeft_GrSurfaceOrigin, nullptr, nullptr);
     if (!rtc) {
         SkDebugf("WARNING: failed to allocate a %ix%i atlas. Some paths will not be drawn.\n",
                  fWidth, fHeight);
diff --git a/src/gpu/effects/GrConfigConversionEffect.fp b/src/gpu/effects/GrConfigConversionEffect.fp
index 5690111..63dc358 100644
--- a/src/gpu/effects/GrConfigConversionEffect.fp
+++ b/src/gpu/effects/GrConfigConversionEffect.fp
@@ -54,15 +54,14 @@
         readRTC->discard();
 
         GrSurfaceDesc desc;
-        desc.fOrigin = kTopLeft_GrSurfaceOrigin;
         desc.fWidth = kSize;
         desc.fHeight = kSize;
         desc.fConfig = kConfig;
 
         GrProxyProvider* proxyProvider = context->contextPriv().proxyProvider();
 
-        sk_sp<GrTextureProxy> dataProxy = proxyProvider->createTextureProxy(desc, SkBudgeted::kYes,
-                                                                            data, 0);
+        sk_sp<GrTextureProxy> dataProxy = proxyProvider->createTextureProxy(
+                desc, kTopLeft_GrSurfaceOrigin, SkBudgeted::kYes, data, 0);
         if (!dataProxy) {
             return false;
         }
diff --git a/src/gpu/effects/GrConfigConversionEffect.h b/src/gpu/effects/GrConfigConversionEffect.h
index ec5c2b3..40bbc97 100644
--- a/src/gpu/effects/GrConfigConversionEffect.h
+++ b/src/gpu/effects/GrConfigConversionEffect.h
@@ -58,15 +58,14 @@
         readRTC->discard();
 
         GrSurfaceDesc desc;
-        desc.fOrigin = kTopLeft_GrSurfaceOrigin;
         desc.fWidth = kSize;
         desc.fHeight = kSize;
         desc.fConfig = kConfig;
 
         GrProxyProvider* proxyProvider = context->contextPriv().proxyProvider();
 
-        sk_sp<GrTextureProxy> dataProxy =
-                proxyProvider->createTextureProxy(desc, SkBudgeted::kYes, data, 0);
+        sk_sp<GrTextureProxy> dataProxy = proxyProvider->createTextureProxy(
+                desc, kTopLeft_GrSurfaceOrigin, SkBudgeted::kYes, data, 0);
         if (!dataProxy) {
             return false;
         }
diff --git a/src/gpu/effects/GrTextureStripAtlas.cpp b/src/gpu/effects/GrTextureStripAtlas.cpp
index a3d4fc0..0025af0 100644
--- a/src/gpu/effects/GrTextureStripAtlas.cpp
+++ b/src/gpu/effects/GrTextureStripAtlas.cpp
@@ -222,13 +222,12 @@
                                                                 key, kTopLeft_GrSurfaceOrigin);
     if (!proxy) {
         GrSurfaceDesc texDesc;
-        texDesc.fOrigin = kTopLeft_GrSurfaceOrigin;
         texDesc.fWidth  = fDesc.fWidth;
         texDesc.fHeight = fDesc.fHeight;
         texDesc.fConfig = fDesc.fConfig;
 
-        proxy = proxyProvider->createProxy(texDesc, SkBackingFit::kExact, SkBudgeted::kYes,
-                                           GrResourceProvider::kNoPendingIO_Flag);
+        proxy = proxyProvider->createProxy(texDesc, kTopLeft_GrSurfaceOrigin, SkBackingFit::kExact,
+                                           SkBudgeted::kYes, GrResourceProvider::kNoPendingIO_Flag);
         if (!proxy) {
             return;
         }
diff --git a/src/gpu/gl/GrGLCaps.cpp b/src/gpu/gl/GrGLCaps.cpp
index ad3cfea..8e5806f 100644
--- a/src/gpu/gl/GrGLCaps.cpp
+++ b/src/gpu/gl/GrGLCaps.cpp
@@ -2006,7 +2006,8 @@
 }
 
 bool GrGLCaps::initDescForDstCopy(const GrRenderTargetProxy* src, GrSurfaceDesc* desc,
-                                  bool* rectsMustMatch, bool* disallowSubrect) const {
+                                  GrSurfaceOrigin* origin, bool* rectsMustMatch,
+                                  bool* disallowSubrect) const {
     // By default, we don't require rects to match.
     *rectsMustMatch = false;
 
@@ -2016,7 +2017,7 @@
     // If the src is a texture, we can implement the blit as a draw assuming the config is
     // renderable.
     if (src->asTextureProxy() && !this->isConfigRenderable(src->config())) {
-        desc->fOrigin = kBottomLeft_GrSurfaceOrigin;
+        *origin = kBottomLeft_GrSurfaceOrigin;
         desc->fFlags = kRenderTarget_GrSurfaceFlag;
         desc->fConfig = src->config();
         return true;
@@ -2060,7 +2061,7 @@
         // glCopyTexSubImage2D doesn't work with this config. If the bgra can be used with fbo blit
         // then we set up for that, otherwise fail.
         if (this->canConfigBeFBOColorAttachment(kBGRA_8888_GrPixelConfig)) {
-            desc->fOrigin = originForBlitFramebuffer;
+            *origin = originForBlitFramebuffer;
             desc->fConfig = kBGRA_8888_GrPixelConfig;
             *rectsMustMatch = rectsMustMatchForBlitFramebuffer;
             *disallowSubrect = disallowSubrectForBlitFramebuffer;
@@ -2076,7 +2077,7 @@
             // It's illegal to call CopyTexSubImage2D on a MSAA renderbuffer. Set up for FBO
             // blit or fail.
             if (this->canConfigBeFBOColorAttachment(src->config())) {
-                desc->fOrigin = originForBlitFramebuffer;
+                *origin = originForBlitFramebuffer;
                 desc->fConfig = src->config();
                 *rectsMustMatch = rectsMustMatchForBlitFramebuffer;
                 *disallowSubrect = disallowSubrectForBlitFramebuffer;
@@ -2087,8 +2088,8 @@
     }
 
     // We'll do a CopyTexSubImage. Make the dst a plain old texture.
+    *origin = src->origin();
     desc->fConfig = src->config();
-    desc->fOrigin = src->origin();
     desc->fFlags = kNone_GrSurfaceFlags;
     return true;
 }
diff --git a/src/gpu/gl/GrGLCaps.h b/src/gpu/gl/GrGLCaps.h
index c4a10b3..dbcccd5 100644
--- a/src/gpu/gl/GrGLCaps.h
+++ b/src/gpu/gl/GrGLCaps.h
@@ -399,7 +399,7 @@
                                                          : pendingInstanceCount;
     }
 
-    bool initDescForDstCopy(const GrRenderTargetProxy* src, GrSurfaceDesc* desc,
+    bool initDescForDstCopy(const GrRenderTargetProxy* src, GrSurfaceDesc* desc, GrSurfaceOrigin*,
                             bool* rectsMustMatch, bool* disallowSubrect) const override;
 
     bool programBinarySupport() const {
diff --git a/src/gpu/gl/GrGLGpu.cpp b/src/gpu/gl/GrGLGpu.cpp
index a571f5a..97aa4ac 100644
--- a/src/gpu/gl/GrGLGpu.cpp
+++ b/src/gpu/gl/GrGLGpu.cpp
@@ -541,7 +541,6 @@
 
     GrSurfaceDesc surfDesc;
     surfDesc.fFlags = kNone_GrSurfaceFlags;
-    surfDesc.fOrigin = kTopLeft_GrSurfaceOrigin; // This isn't used in the following
     surfDesc.fWidth = backendTex.width();
     surfDesc.fHeight = backendTex.height();
     surfDesc.fConfig = backendTex.config();
@@ -577,7 +576,6 @@
 
     GrSurfaceDesc surfDesc;
     surfDesc.fFlags = kRenderTarget_GrSurfaceFlag;
-    surfDesc.fOrigin = kBottomLeft_GrSurfaceOrigin; // This isn't actually used in the following
     surfDesc.fWidth = backendTex.width();
     surfDesc.fHeight = backendTex.height();
     surfDesc.fConfig = backendTex.config();
@@ -615,7 +613,6 @@
 
     GrSurfaceDesc desc;
     desc.fFlags = kRenderTarget_GrSurfaceFlag;
-    desc.fOrigin = kBottomLeft_GrSurfaceOrigin; // This isn't actually used in the following
     desc.fWidth = backendRT.width();
     desc.fHeight = backendRT.height();
     desc.fConfig = backendRT.config();
@@ -645,7 +642,6 @@
 
     GrSurfaceDesc surfDesc;
     surfDesc.fFlags = kRenderTarget_GrSurfaceFlag;
-    surfDesc.fOrigin = kBottomLeft_GrSurfaceOrigin; // This isn't actually used in the following
     surfDesc.fWidth = tex.width();
     surfDesc.fHeight = tex.height();
     surfDesc.fConfig = tex.config();
@@ -1417,6 +1413,7 @@
 
 sk_sp<GrTexture> GrGLGpu::onCreateTexture(const GrSurfaceDesc& desc,
                                           SkBudgeted budgeted,
+                                          GrSurfaceOrigin texelsOrigin,
                                           const GrMipLevel texels[],
                                           int mipLevelCount) {
     // We fail if the MSAA was requested and is not available.
@@ -1449,7 +1446,7 @@
     GrMipMapsStatus mipMapsStatus;
     GrGLTexture::TexParams initialTexParams;
     if (!this->createTextureImpl(desc, &idDesc.fInfo, isRenderTarget, &initialTexParams,
-                                 texels, mipLevelCount, &mipMapsStatus)) {
+                                 texelsOrigin, texels, mipLevelCount, &mipMapsStatus)) {
         return return_null_texture();
     }
 
@@ -1634,10 +1631,10 @@
     return this->glCaps().getStencilFormatIndexForConfig(config);
 }
 
-bool GrGLGpu::createTextureImpl(const GrSurfaceDesc& desc, GrGLTextureInfo* info,
-                                bool renderTarget, GrGLTexture::TexParams* initialTexParams,
-                                const GrMipLevel texels[], int mipLevelCount,
-                                GrMipMapsStatus* mipMapsStatus) {
+bool GrGLGpu::createTextureImpl(const GrSurfaceDesc& desc, GrGLTextureInfo* info, bool renderTarget,
+                                GrGLTexture::TexParams* initialTexParams,
+                                GrSurfaceOrigin texelsOrigin, const GrMipLevel texels[],
+                                int mipLevelCount, GrMipMapsStatus* mipMapsStatus) {
     info->fID = 0;
     info->fTarget = GR_GL_TEXTURE_2D;
     GL_CALL(GenTextures(1, &(info->fID)));
@@ -1659,7 +1656,8 @@
     if (info) {
         set_initial_texture_params(this->glInterface(), *info, initialTexParams);
     }
-    if (!this->uploadTexData(desc.fConfig, desc.fWidth, desc.fHeight, desc.fOrigin, info->fTarget,
+
+    if (!this->uploadTexData(desc.fConfig, desc.fWidth, desc.fHeight, texelsOrigin, info->fTarget,
                              kNewTexture_UploadType, 0, 0, desc.fWidth, desc.fHeight, desc.fConfig,
                              texels, mipLevelCount, mipMapsStatus)) {
         GL_CALL(DeleteTextures(1, &(info->fID)));
@@ -2138,7 +2136,6 @@
         desc.fWidth = desc.fHeight = 16;
         if (this->glCaps().isConfigRenderable(rtConfig)) {
             desc.fFlags = kRenderTarget_GrSurfaceFlag;
-            desc.fOrigin = kBottomLeft_GrSurfaceOrigin;
             temp = this->createTexture(desc, SkBudgeted::kNo);
             if (!temp) {
                 return false;
@@ -2147,7 +2144,6 @@
             this->flushRenderTargetNoColorWrites(glrt);
             return true;
         } else if (this->glCaps().canConfigBeFBOColorAttachment(rtConfig)) {
-            desc.fOrigin = kTopLeft_GrSurfaceOrigin;
             temp = this->createTexture(desc, SkBudgeted::kNo);
             if (!temp) {
                 return false;
diff --git a/src/gpu/gl/GrGLGpu.h b/src/gpu/gl/GrGLGpu.h
index 677028a..a62c715 100644
--- a/src/gpu/gl/GrGLGpu.h
+++ b/src/gpu/gl/GrGLGpu.h
@@ -184,7 +184,7 @@
     void xferBarrier(GrRenderTarget*, GrXferBarrierType) override;
 
     sk_sp<GrTexture> onCreateTexture(const GrSurfaceDesc& desc, SkBudgeted budgeted,
-                                     const GrMipLevel texels[],
+                                     GrSurfaceOrigin texelsOrigin, const GrMipLevel texels[],
                                      int mipLevelCount) override;
 
     GrBuffer* onCreateBuffer(size_t size, GrBufferType intendedType, GrAccessPattern,
@@ -207,8 +207,8 @@
     // result is stored in |info|.
     // The texture is populated with |texels|, if it exists.
     // The texture parameters are cached in |initialTexParams|.
-    bool createTextureImpl(const GrSurfaceDesc& desc, GrGLTextureInfo* info,
-                           bool renderTarget, GrGLTexture::TexParams* initialTexParams,
+    bool createTextureImpl(const GrSurfaceDesc& desc, GrGLTextureInfo* info, bool renderTarget,
+                           GrGLTexture::TexParams* initialTexParams, GrSurfaceOrigin texelsOrigin,
                            const GrMipLevel texels[], int mipLevelCount,
                            GrMipMapsStatus* mipMapsStatus);
 
diff --git a/src/gpu/mock/GrMockCaps.h b/src/gpu/mock/GrMockCaps.h
index d8a2aad..4bcd459 100644
--- a/src/gpu/mock/GrMockCaps.h
+++ b/src/gpu/mock/GrMockCaps.h
@@ -69,7 +69,7 @@
 
     bool surfaceSupportsWritePixels(const GrSurface* surface) const override { return true; }
 
-    bool initDescForDstCopy(const GrRenderTargetProxy* src, GrSurfaceDesc* desc,
+    bool initDescForDstCopy(const GrRenderTargetProxy* src, GrSurfaceDesc* desc, GrSurfaceOrigin*,
                             bool* rectsMustMatch, bool* disallowSubrect) const override {
         return false;
     }
diff --git a/src/gpu/mock/GrMockGpu.cpp b/src/gpu/mock/GrMockGpu.cpp
index 9d1661b..3a6b661 100644
--- a/src/gpu/mock/GrMockGpu.cpp
+++ b/src/gpu/mock/GrMockGpu.cpp
@@ -65,7 +65,8 @@
 }
 
 sk_sp<GrTexture> GrMockGpu::onCreateTexture(const GrSurfaceDesc& desc, SkBudgeted budgeted,
-                                            const GrMipLevel texels[], int mipLevelCount) {
+                                            GrSurfaceOrigin texelsOrigin, const GrMipLevel texels[],
+                                            int mipLevelCount) {
     GrMipMapsStatus mipMapsStatus = mipLevelCount > 1 ? GrMipMapsStatus::kValid
                                                       : GrMipMapsStatus::kNotAllocated;
     GrMockTextureInfo info;
diff --git a/src/gpu/mock/GrMockGpu.h b/src/gpu/mock/GrMockGpu.h
index 74c9264..b5398e5 100644
--- a/src/gpu/mock/GrMockGpu.h
+++ b/src/gpu/mock/GrMockGpu.h
@@ -55,7 +55,7 @@
 
     void xferBarrier(GrRenderTarget*, GrXferBarrierType) override {}
 
-    sk_sp<GrTexture> onCreateTexture(const GrSurfaceDesc&, SkBudgeted,
+    sk_sp<GrTexture> onCreateTexture(const GrSurfaceDesc&, SkBudgeted, GrSurfaceOrigin texelsOrigin,
                                      const GrMipLevel texels[], int mipLevelCount) override;
 
     sk_sp<GrTexture> onWrapBackendTexture(const GrBackendTexture&, GrWrapOwnership) override {
diff --git a/src/gpu/mtl/GrMtlCaps.h b/src/gpu/mtl/GrMtlCaps.h
index 1252fd8..130af67 100644
--- a/src/gpu/mtl/GrMtlCaps.h
+++ b/src/gpu/mtl/GrMtlCaps.h
@@ -45,7 +45,7 @@
         return fPreferedStencilFormat;
     }
 #endif
-    bool initDescForDstCopy(const GrRenderTargetProxy* src, GrSurfaceDesc* desc,
+    bool initDescForDstCopy(const GrRenderTargetProxy* src, GrSurfaceDesc* desc, GrSurfaceOrigin*,
                             bool* rectsMustMatch, bool* disallowSubrect) const override {
         return false;
     }
diff --git a/src/gpu/mtl/GrMtlGpu.h b/src/gpu/mtl/GrMtlGpu.h
index 9482d95..a48618b 100644
--- a/src/gpu/mtl/GrMtlGpu.h
+++ b/src/gpu/mtl/GrMtlGpu.h
@@ -82,7 +82,8 @@
     void xferBarrier(GrRenderTarget*, GrXferBarrierType) override {}
 
     sk_sp<GrTexture> onCreateTexture(const GrSurfaceDesc& desc, SkBudgeted budgeted,
-                                     const GrMipLevel texels[], int mipLevelCount) override;
+                                     GrSurfaceOrigin texelsOrigin, const GrMipLevel texels[],
+                                     int mipLevelCount) override;
 
     sk_sp<GrTexture> onWrapBackendTexture(const GrBackendTexture&, GrWrapOwnership) override {
         return nullptr;
diff --git a/src/gpu/mtl/GrMtlGpu.mm b/src/gpu/mtl/GrMtlGpu.mm
index 149e562..c8952e0 100644
--- a/src/gpu/mtl/GrMtlGpu.mm
+++ b/src/gpu/mtl/GrMtlGpu.mm
@@ -107,7 +107,8 @@
 }
 
 sk_sp<GrTexture> GrMtlGpu::onCreateTexture(const GrSurfaceDesc& desc, SkBudgeted budgeted,
-                                           const GrMipLevel texels[], int mipLevelCount) {
+                                           GrSurfaceOrigin texelsOrigin, const GrMipLevel texels[],
+                                           int mipLevelCount) {
     int mipLevels = !mipLevelCount ? 1 : mipLevelCount;
 
     if (!fMtlCaps->isConfigTexturable(desc.fConfig)) {
diff --git a/src/gpu/ops/GrTextureOp.cpp b/src/gpu/ops/GrTextureOp.cpp
index 2aeb49b..926bd54 100644
--- a/src/gpu/ops/GrTextureOp.cpp
+++ b/src/gpu/ops/GrTextureOp.cpp
@@ -836,11 +836,11 @@
     desc.fConfig = kRGBA_8888_GrPixelConfig;
     desc.fHeight = random->nextULessThan(90) + 10;
     desc.fWidth = random->nextULessThan(90) + 10;
-    desc.fOrigin = random->nextBool() ? kTopLeft_GrSurfaceOrigin : kBottomLeft_GrSurfaceOrigin;
+    auto origin = random->nextBool() ? kTopLeft_GrSurfaceOrigin : kBottomLeft_GrSurfaceOrigin;
     SkBackingFit fit = random->nextBool() ? SkBackingFit::kApprox : SkBackingFit::kExact;
 
     GrProxyProvider* proxyProvider = context->contextPriv().proxyProvider();
-    sk_sp<GrTextureProxy> proxy = proxyProvider->createProxy(desc, fit, SkBudgeted::kNo);
+    sk_sp<GrTextureProxy> proxy = proxyProvider->createProxy(desc, origin, fit, SkBudgeted::kNo);
 
     SkRect rect = GrTest::TestRect(random);
     SkRect srcRect;
diff --git a/src/gpu/vk/GrVkCaps.cpp b/src/gpu/vk/GrVkCaps.cpp
index 73ba2e7..7e22135 100644
--- a/src/gpu/vk/GrVkCaps.cpp
+++ b/src/gpu/vk/GrVkCaps.cpp
@@ -54,7 +54,8 @@
 }
 
 bool GrVkCaps::initDescForDstCopy(const GrRenderTargetProxy* src, GrSurfaceDesc* desc,
-                                  bool* rectsMustMatch, bool* disallowSubrect) const {
+                                  GrSurfaceOrigin* origin, bool* rectsMustMatch,
+                                  bool* disallowSubrect) const {
     // Vk doesn't use rectsMustMatch or disallowSubrect. Always return false.
     *rectsMustMatch = false;
     *disallowSubrect = false;
@@ -62,7 +63,7 @@
     // We can always succeed here with either a CopyImage (none msaa src) or ResolveImage (msaa).
     // For CopyImage we can make a simple texture, for ResolveImage we require the dst to be a
     // render target as well.
-    desc->fOrigin = src->origin();
+    *origin = src->origin();
     desc->fConfig = src->config();
     if (src->numColorSamples() > 1 || (src->asTextureProxy() && this->supportsCopiesAsDraws())) {
         desc->fFlags = kRenderTarget_GrSurfaceFlag;
diff --git a/src/gpu/vk/GrVkCaps.h b/src/gpu/vk/GrVkCaps.h
index 809cbf5..d8d1d2e 100644
--- a/src/gpu/vk/GrVkCaps.h
+++ b/src/gpu/vk/GrVkCaps.h
@@ -114,7 +114,7 @@
         return fPreferedStencilFormat;
     }
 
-    bool initDescForDstCopy(const GrRenderTargetProxy* src, GrSurfaceDesc* desc,
+    bool initDescForDstCopy(const GrRenderTargetProxy* src, GrSurfaceDesc* desc, GrSurfaceOrigin*,
                             bool* rectsMustMatch, bool* disallowSubrect) const override;
 
     bool validateBackendTexture(const GrBackendTexture&, SkColorType,
diff --git a/src/gpu/vk/GrVkGpu.cpp b/src/gpu/vk/GrVkGpu.cpp
index bfd5593..01d1846 100644
--- a/src/gpu/vk/GrVkGpu.cpp
+++ b/src/gpu/vk/GrVkGpu.cpp
@@ -763,7 +763,8 @@
 
 ////////////////////////////////////////////////////////////////////////////////
 sk_sp<GrTexture> GrVkGpu::onCreateTexture(const GrSurfaceDesc& desc, SkBudgeted budgeted,
-                                          const GrMipLevel texels[], int mipLevelCount) {
+                                          GrSurfaceOrigin texelsOrigin, const GrMipLevel texels[],
+                                          int mipLevelCount) {
     bool renderTarget = SkToBool(desc.fFlags & kRenderTarget_GrSurfaceFlag);
 
     VkFormat pixelFormat;
@@ -824,7 +825,7 @@
 
     auto colorType = GrPixelConfigToColorType(desc.fConfig);
     if (mipLevelCount) {
-        if (!this->uploadTexDataOptimal(tex.get(), desc.fOrigin, 0, 0, desc.fWidth, desc.fHeight,
+        if (!this->uploadTexDataOptimal(tex.get(), texelsOrigin, 0, 0, desc.fWidth, desc.fHeight,
                                         colorType, texels, mipLevelCount)) {
             tex->unref();
             return nullptr;
@@ -891,7 +892,6 @@
 
     GrSurfaceDesc surfDesc;
     surfDesc.fFlags = kNone_GrSurfaceFlags;
-    surfDesc.fOrigin = kTopLeft_GrSurfaceOrigin; // Not actually used in the following
     surfDesc.fWidth = backendTex.width();
     surfDesc.fHeight = backendTex.height();
     surfDesc.fConfig = backendTex.config();
@@ -909,7 +909,6 @@
 
     GrSurfaceDesc surfDesc;
     surfDesc.fFlags = kRenderTarget_GrSurfaceFlag;
-    surfDesc.fOrigin = kBottomLeft_GrSurfaceOrigin; // Not actually used in the following
     surfDesc.fWidth = backendTex.width();
     surfDesc.fHeight = backendTex.height();
     surfDesc.fConfig = backendTex.config();
@@ -938,7 +937,6 @@
 
     GrSurfaceDesc desc;
     desc.fFlags = kRenderTarget_GrSurfaceFlag;
-    desc.fOrigin = kBottomLeft_GrSurfaceOrigin; // Not actually used in the following
     desc.fWidth = backendRT.width();
     desc.fHeight = backendRT.height();
     desc.fConfig = backendRT.config();
@@ -966,7 +964,6 @@
 
     GrSurfaceDesc desc;
     desc.fFlags = kRenderTarget_GrSurfaceFlag;
-    desc.fOrigin = kBottomLeft_GrSurfaceOrigin; // Not actually used in the following
     desc.fWidth = tex.width();
     desc.fHeight = tex.height();
     desc.fConfig = tex.config();
diff --git a/src/gpu/vk/GrVkGpu.h b/src/gpu/vk/GrVkGpu.h
index 0b52147..3655527 100644
--- a/src/gpu/vk/GrVkGpu.h
+++ b/src/gpu/vk/GrVkGpu.h
@@ -165,7 +165,8 @@
     void destroyResources();
 
     sk_sp<GrTexture> onCreateTexture(const GrSurfaceDesc& desc, SkBudgeted budgeted,
-                                     const GrMipLevel texels[], int mipLevelCount) override;
+                                     GrSurfaceOrigin texelsOrigin, const GrMipLevel texels[],
+                                     int mipLevelCount) override;
 
     sk_sp<GrTexture> onWrapBackendTexture(const GrBackendTexture&, GrWrapOwnership) override;
     sk_sp<GrTexture> onWrapRenderableBackendTexture(const GrBackendTexture&,
diff --git a/src/image/SkImage_Gpu.cpp b/src/image/SkImage_Gpu.cpp
index ad89e92..1ce53c6 100644
--- a/src/image/SkImage_Gpu.cpp
+++ b/src/image/SkImage_Gpu.cpp
@@ -271,16 +271,12 @@
 
 sk_sp<SkImage> SkImage_Gpu::onMakeSubset(const SkIRect& subset) const {
     GrSurfaceDesc desc;
-    desc.fOrigin = fProxy->origin();
     desc.fWidth = subset.width();
     desc.fHeight = subset.height();
     desc.fConfig = fProxy->config();
 
     sk_sp<GrSurfaceContext> sContext(fContext->contextPriv().makeDeferredSurfaceContext(
-                                                                        desc,
-                                                                        GrMipMapped::kNo,
-                                                                        SkBackingFit::kExact,
-                                                                        fBudgeted));
+            desc, fProxy->origin(), GrMipMapped::kNo, SkBackingFit::kExact, fBudgeted));
     if (!sContext) {
         return nullptr;
     }
@@ -651,7 +647,8 @@
         if (SkImageInfoIsValid(pixmap.info(), colorMode)) {
             ATRACE_ANDROID_FRAMEWORK("Upload Texture [%ux%u]", pixmap.width(), pixmap.height());
             GrSurfaceDesc desc = GrImageInfoToSurfaceDesc(pixmap.info(), *proxyProvider->caps());
-            proxy = proxyProvider->createTextureProxy(desc, SkBudgeted::kYes, pixmap.addr(),
+            proxy = proxyProvider->createTextureProxy(desc, kTopLeft_GrSurfaceOrigin,
+                                                      SkBudgeted::kYes, pixmap.addr(),
                                                       pixmap.rowBytes());
         }
     }
diff --git a/tests/BlendTest.cpp b/tests/BlendTest.cpp
index 3ac7e3c..5332b10 100644
--- a/tests/BlendTest.cpp
+++ b/tests/BlendTest.cpp
@@ -89,7 +89,6 @@
         sk_sp<GrTexture>* backingSurface) {
     GrSurfaceDesc backingDesc;
     backingDesc.fFlags = kRenderTarget_GrSurfaceFlag;
-    backingDesc.fOrigin = origin;
     backingDesc.fWidth = width;
     backingDesc.fHeight = height;
     backingDesc.fConfig = config;
diff --git a/tests/CopySurfaceTest.cpp b/tests/CopySurfaceTest.cpp
index b8ccb1f..b373258 100644
--- a/tests/CopySurfaceTest.cpp
+++ b/tests/CopySurfaceTest.cpp
@@ -1,3 +1,4 @@
+
 /*
  * Copyright 2016 Google Inc.
  *
@@ -69,16 +70,14 @@
                     for (auto srcRect : kSrcRects) {
                         for (auto dstPoint : kDstPoints) {
                             GrSurfaceDesc srcDesc = baseDesc;
-                            srcDesc.fOrigin = sOrigin;
                             srcDesc.fFlags = sFlags;
                             GrSurfaceDesc dstDesc = baseDesc;
-                            dstDesc.fOrigin = dOrigin;
                             dstDesc.fFlags = dFlags;
 
                             sk_sp<GrTextureProxy> src = proxyProvider->createTextureProxy(
-                                             srcDesc, SkBudgeted::kNo, srcPixels.get(), kRowBytes);
+                                    srcDesc, sOrigin, SkBudgeted::kNo, srcPixels.get(), kRowBytes);
                             sk_sp<GrTextureProxy> dst = proxyProvider->createTextureProxy(
-                                             dstDesc, SkBudgeted::kNo, dstPixels.get(), kRowBytes);
+                                    dstDesc, dOrigin, SkBudgeted::kNo, dstPixels.get(), kRowBytes);
                             if (!src || !dst) {
                                 ERRORF(reporter,
                                        "Could not create surfaces for copy surface test.");
diff --git a/tests/DetermineDomainModeTest.cpp b/tests/DetermineDomainModeTest.cpp
index 7833da4..9c9e198 100644
--- a/tests/DetermineDomainModeTest.cpp
+++ b/tests/DetermineDomainModeTest.cpp
@@ -119,7 +119,6 @@
     SkBackingFit fit = isExact ? SkBackingFit::kExact : SkBackingFit::kApprox;
 
     GrSurfaceDesc desc;
-    desc.fOrigin = kTopLeft_GrSurfaceOrigin;
     desc.fWidth = size;
     desc.fHeight = size;
     desc.fConfig = kRGBA_8888_GrPixelConfig;
@@ -134,7 +133,7 @@
               (isPowerOfTwo || isExact) ? RectInfo::kHard : RectInfo::kBad,
               name);
 
-    return proxyProvider->createProxy(desc, fit, SkBudgeted::kYes);
+    return proxyProvider->createProxy(desc, kTopLeft_GrSurfaceOrigin, fit, SkBudgeted::kYes);
 }
 
 static RectInfo::EdgeType compute_inset_edgetype(RectInfo::EdgeType previous,
diff --git a/tests/FloatingPointTextureTest.cpp b/tests/FloatingPointTextureTest.cpp
index 9a06d2d..6d2beb3 100644
--- a/tests/FloatingPointTextureTest.cpp
+++ b/tests/FloatingPointTextureTest.cpp
@@ -45,16 +45,15 @@
         controlPixelData[i + 3] = maxInt;
     }
 
-    for (int origin = 0; origin < 2; ++origin) {
+    for (auto origin : {kTopLeft_GrSurfaceOrigin, kBottomLeft_GrSurfaceOrigin}) {
         GrSurfaceDesc desc;
         desc.fFlags = kRenderTarget_GrSurfaceFlag;
-        desc.fOrigin = 0 == origin ? kTopLeft_GrSurfaceOrigin : kBottomLeft_GrSurfaceOrigin;
         desc.fWidth = DEV_W;
         desc.fHeight = DEV_H;
         desc.fConfig = GrColorTypeToPixelConfig(colorType, GrSRGBEncoded::kNo);
 
         sk_sp<GrTextureProxy> fpProxy = proxyProvider->createTextureProxy(
-                                           desc, SkBudgeted::kNo, controlPixelData.begin(), 0);
+                desc, origin, SkBudgeted::kNo, controlPixelData.begin(), 0);
         // Floating point textures are NOT supported everywhere
         if (!fpProxy) {
             continue;
diff --git a/tests/GLProgramsTest.cpp b/tests/GLProgramsTest.cpp
index f625a77..1384e38 100644
--- a/tests/GLProgramsTest.cpp
+++ b/tests/GLProgramsTest.cpp
@@ -272,20 +272,20 @@
     {
         GrSurfaceDesc dummyDesc;
         dummyDesc.fFlags = kRenderTarget_GrSurfaceFlag;
-        dummyDesc.fOrigin = kBottomLeft_GrSurfaceOrigin;
         dummyDesc.fWidth = 34;
         dummyDesc.fHeight = 18;
         dummyDesc.fConfig = kRGBA_8888_GrPixelConfig;
-        proxies[0] = proxyProvider->createProxy(dummyDesc, SkBackingFit::kExact, SkBudgeted::kNo);
+        proxies[0] = proxyProvider->createProxy(dummyDesc, kBottomLeft_GrSurfaceOrigin,
+                                                SkBackingFit::kExact, SkBudgeted::kNo);
     }
     {
         GrSurfaceDesc dummyDesc;
         dummyDesc.fFlags = kNone_GrSurfaceFlags;
-        dummyDesc.fOrigin = kTopLeft_GrSurfaceOrigin;
         dummyDesc.fWidth = 16;
         dummyDesc.fHeight = 22;
         dummyDesc.fConfig = kAlpha_8_GrPixelConfig;
-        proxies[1] = proxyProvider->createProxy(dummyDesc, SkBackingFit::kExact, SkBudgeted::kNo);
+        proxies[1] = proxyProvider->createProxy(dummyDesc, kTopLeft_GrSurfaceOrigin,
+                                                SkBackingFit::kExact, SkBudgeted::kNo);
     }
 
     if (!proxies[0] || !proxies[1]) {
diff --git a/tests/GrSurfaceTest.cpp b/tests/GrSurfaceTest.cpp
index a645f99..daef511 100644
--- a/tests/GrSurfaceTest.cpp
+++ b/tests/GrSurfaceTest.cpp
@@ -29,7 +29,6 @@
 
     GrSurfaceDesc desc;
     desc.fFlags = kRenderTarget_GrSurfaceFlag;
-    desc.fOrigin = kBottomLeft_GrSurfaceOrigin;
     desc.fWidth = 256;
     desc.fHeight = 256;
     desc.fConfig = kRGBA_8888_GrPixelConfig;
@@ -46,7 +45,6 @@
                     static_cast<GrSurface*>(texRT1->asTexture()));
 
     desc.fFlags = kNone_GrSurfaceFlags;
-    desc.fOrigin = kTopLeft_GrSurfaceOrigin;
     sk_sp<GrTexture> tex1 = resourceProvider->createTexture(desc, SkBudgeted::kNo);
     REPORTER_ASSERT(reporter, nullptr == tex1->asRenderTarget());
     REPORTER_ASSERT(reporter, tex1.get() == tex1->asTexture());
@@ -108,7 +106,6 @@
     for (GrPixelConfig config : configs) {
         for (GrSurfaceOrigin origin : { kTopLeft_GrSurfaceOrigin, kBottomLeft_GrSurfaceOrigin }) {
             desc.fFlags = kNone_GrSurfaceFlags;
-            desc.fOrigin = origin;
             desc.fConfig = config;
             desc.fSampleCnt = 1;
 
@@ -117,8 +114,8 @@
             REPORTER_ASSERT(reporter, SkToBool(tex) == ict,
                             "config:%d, tex:%d, isConfigTexturable:%d", config, SkToBool(tex), ict);
 
-            sk_sp<GrTextureProxy> proxy = proxyProvider->createMipMapProxy(
-                                                            desc, SkBudgeted::kNo);
+            sk_sp<GrTextureProxy> proxy =
+                    proxyProvider->createMipMapProxy(desc, origin, SkBudgeted::kNo);
             REPORTER_ASSERT(reporter, SkToBool(proxy.get()) ==
                             (caps->isConfigTexturable(desc.fConfig) &&
                              caps->mipMapSupport()));
@@ -170,13 +167,12 @@
             desc.fFlags |= rt ? kRenderTarget_GrSurfaceFlag : kNone_GrSurfaceFlags;
             for (GrSurfaceOrigin origin :
                  {kTopLeft_GrSurfaceOrigin, kBottomLeft_GrSurfaceOrigin}) {
-                desc.fOrigin = origin;
                 for (auto fit : { SkBackingFit::kApprox, SkBackingFit::kExact }) {
                     // Try directly creating the texture.
                     // Do this twice in an attempt to hit the cache on the second time through.
                     for (int i = 0; i < 2; ++i) {
                         sk_sp<GrTextureProxy> proxy = proxyProvider->createInstantiatedProxy(
-                                                                    desc, fit, SkBudgeted::kYes);
+                                desc, origin, fit, SkBudgeted::kYes);
                         if (!proxy) {
                             continue;
                         }
@@ -206,7 +202,7 @@
                     // Try creating the texture as a deferred proxy.
                     for (int i = 0; i < 2; ++i) {
                         auto surfCtx = context->contextPriv().makeDeferredSurfaceContext(
-                                desc, GrMipMapped::kNo, fit, SkBudgeted::kYes, colorSpace);
+                                desc, origin, GrMipMapped::kNo, fit, SkBudgeted::kYes, colorSpace);
                         if (!surfCtx) {
                             continue;
                         }
diff --git a/tests/ImageFilterCacheTest.cpp b/tests/ImageFilterCacheTest.cpp
index 3105e9b..a2409dc 100644
--- a/tests/ImageFilterCacheTest.cpp
+++ b/tests/ImageFilterCacheTest.cpp
@@ -192,12 +192,11 @@
 
     GrSurfaceDesc desc;
     desc.fFlags  = kNone_GrSurfaceFlags;
-    desc.fOrigin = kTopLeft_GrSurfaceOrigin;
     desc.fWidth  = kFullSize;
     desc.fHeight = kFullSize;
     desc.fConfig = kRGBA_8888_GrPixelConfig;
 
-    return proxyProvider->createTextureProxy(desc, SkBudgeted::kYes,
+    return proxyProvider->createTextureProxy(desc, kTopLeft_GrSurfaceOrigin, SkBudgeted::kYes,
                                              srcBM.getPixels(), srcBM.rowBytes());
 }
 
diff --git a/tests/LazyProxyTest.cpp b/tests/LazyProxyTest.cpp
index aca9b56..da83dcb 100644
--- a/tests/LazyProxyTest.cpp
+++ b/tests/LazyProxyTest.cpp
@@ -70,7 +70,6 @@
                     GrSurfaceDesc desc;
                     desc.fWidth = 1234;
                     desc.fHeight = 567;
-                    desc.fOrigin = kTopLeft_GrSurfaceOrigin;
                     desc.fConfig = kRGB_565_GrPixelConfig;
                     sk_sp<GrTexture> texture = rp->createTexture(desc, SkBudgeted::kYes);
                     REPORTER_ASSERT(fTest->fReporter, texture);
@@ -228,7 +227,9 @@
                         }
                         *testCountPtr = 1;
                         return sk_sp<GrTexture>();
-                    }, desc, GrMipMapped::kNo, SkBackingFit::kExact, SkBudgeted::kNo);
+                    },
+                    desc, kTopLeft_GrSurfaceOrigin, GrMipMapped::kNo, SkBackingFit::kExact,
+                    SkBudgeted::kNo);
 
             proxy->priv().testingOnly_setLazyInstantiationType(lazyType);
 
@@ -267,7 +268,7 @@
         desc.fConfig = kRGBA_8888_GrPixelConfig;
 
         fLazyProxy = proxyProvider->createLazyProxy(
-                [testExecuteValue, shouldFailInstantiation, desc] (GrResourceProvider* rp) {
+                [testExecuteValue, shouldFailInstantiation, desc](GrResourceProvider* rp) {
                     if (!rp) {
                         return sk_sp<GrTexture>();
                     }
@@ -276,7 +277,9 @@
                         return sk_sp<GrTexture>();
                     }
                     return rp->createTexture(desc, SkBudgeted::kNo);
-                }, desc, GrMipMapped::kNo, SkBackingFit::kExact, SkBudgeted::kNo);
+                },
+                desc, kTopLeft_GrSurfaceOrigin, GrMipMapped::kNo, SkBackingFit::kExact,
+                SkBudgeted::kNo);
 
         this->setBounds(SkRect::MakeIWH(kSize, kSize),
                         HasAABloat::kNo, IsZeroArea::kNo);
diff --git a/tests/OnFlushCallbackTest.cpp b/tests/OnFlushCallbackTest.cpp
index 62f6c0f..5cd3bcd 100644
--- a/tests/OnFlushCallbackTest.cpp
+++ b/tests/OnFlushCallbackTest.cpp
@@ -302,7 +302,6 @@
 
                     GrSurfaceDesc desc;
                     desc.fFlags = kRenderTarget_GrSurfaceFlag;
-                    desc.fOrigin = kBottomLeft_GrSurfaceOrigin;
                     // TODO: until partial flushes in MDB lands we're stuck having
                     // all 9 atlas draws occur
                     desc.fWidth = 9 /*this->numOps()*/ * kAtlasTileSize;
diff --git a/tests/PackedConfigsTextureTest.cpp b/tests/PackedConfigsTextureTest.cpp
index 0555fc4..0ac322d 100644
--- a/tests/PackedConfigsTextureTest.cpp
+++ b/tests/PackedConfigsTextureTest.cpp
@@ -118,10 +118,9 @@
         desc.fWidth = DEV_W;
         desc.fHeight = DEV_H;
         desc.fConfig = config;
-        desc.fOrigin = origin;
 
         sk_sp<GrTextureProxy> proxy = proxyProvider->createTextureProxy(
-                                                desc, SkBudgeted::kNo, controlPixelData.begin(), 0);
+                desc, origin, SkBudgeted::kNo, controlPixelData.begin(), 0);
         SkASSERT(proxy);
 
         sk_sp<GrSurfaceContext> sContext = context->contextPriv().makeWrappedSurfaceContext(
diff --git a/tests/ProcessorTest.cpp b/tests/ProcessorTest.cpp
index 2325a9a..aea5208 100644
--- a/tests/ProcessorTest.cpp
+++ b/tests/ProcessorTest.cpp
@@ -161,7 +161,6 @@
     GrResourceProvider* resourceProvider = context->contextPriv().resourceProvider();
 
     GrSurfaceDesc desc;
-    desc.fOrigin = kTopLeft_GrSurfaceOrigin;
     desc.fWidth = 10;
     desc.fHeight = 10;
     desc.fConfig = kRGBA_8888_GrPixelConfig;
@@ -169,18 +168,18 @@
     for (bool makeClone : {false, true}) {
         for (int parentCnt = 0; parentCnt < 2; parentCnt++) {
             sk_sp<GrRenderTargetContext> renderTargetContext(
-                    context->makeDeferredRenderTargetContext( SkBackingFit::kApprox, 1, 1,
-                                                              kRGBA_8888_GrPixelConfig, nullptr));
+                    context->makeDeferredRenderTargetContext(SkBackingFit::kApprox, 1, 1,
+                                                             kRGBA_8888_GrPixelConfig, nullptr));
             {
                 bool texelBufferSupport = context->caps()->shaderCaps()->texelBufferSupport();
-                sk_sp<GrTextureProxy> proxy1 =
-                        proxyProvider->createProxy(desc, SkBackingFit::kExact, SkBudgeted::kYes);
-                sk_sp<GrTextureProxy> proxy2 =
-                        proxyProvider->createProxy(desc, SkBackingFit::kExact, SkBudgeted::kYes);
-                sk_sp<GrTextureProxy> proxy3 =
-                        proxyProvider->createProxy(desc, SkBackingFit::kExact, SkBudgeted::kYes);
-                sk_sp<GrTextureProxy> proxy4 =
-                        proxyProvider->createProxy(desc, SkBackingFit::kExact, SkBudgeted::kYes);
+                sk_sp<GrTextureProxy> proxy1 = proxyProvider->createProxy(
+                        desc, kTopLeft_GrSurfaceOrigin, SkBackingFit::kExact, SkBudgeted::kYes);
+                sk_sp<GrTextureProxy> proxy2 = proxyProvider->createProxy(
+                        desc, kTopLeft_GrSurfaceOrigin, SkBackingFit::kExact, SkBudgeted::kYes);
+                sk_sp<GrTextureProxy> proxy3 = proxyProvider->createProxy(
+                        desc, kTopLeft_GrSurfaceOrigin, SkBackingFit::kExact, SkBudgeted::kYes);
+                sk_sp<GrTextureProxy> proxy4 = proxyProvider->createProxy(
+                        desc, kTopLeft_GrSurfaceOrigin, SkBackingFit::kExact, SkBudgeted::kYes);
                 sk_sp<GrBuffer> buffer(texelBufferSupport
                         ? resourceProvider->createBuffer(
                                   1024, GrBufferType::kTexel_GrBufferType,
@@ -294,7 +293,6 @@
                         sk_sp<GrTextureProxy> proxies[2]) {
     static const int kTestTextureSize = 256;
     GrSurfaceDesc desc;
-    desc.fOrigin = kBottomLeft_GrSurfaceOrigin;
     desc.fWidth = kTestTextureSize;
     desc.fHeight = kTestTextureSize;
     desc.fConfig = kRGBA_8888_GrPixelConfig;
@@ -309,8 +307,8 @@
             }
         }
 
-        proxies[0] = proxyProvider->createTextureProxy(desc, SkBudgeted::kYes,
-                                                       rgbaData.get(),
+        proxies[0] = proxyProvider->createTextureProxy(desc, kBottomLeft_GrSurfaceOrigin,
+                                                       SkBudgeted::kYes, rgbaData.get(),
                                                        kTestTextureSize * sizeof(GrColor));
     }
 
@@ -324,8 +322,9 @@
             }
         }
 
-        proxies[1] = proxyProvider->createTextureProxy(desc, SkBudgeted::kYes,
-                                                       alphaData.get(), kTestTextureSize);
+        proxies[1] = proxyProvider->createTextureProxy(desc, kBottomLeft_GrSurfaceOrigin,
+                                                       SkBudgeted::kYes, alphaData.get(),
+                                                       kTestTextureSize);
     }
 
     return proxies[0] && proxies[1];
@@ -341,12 +340,11 @@
         }
     }
     GrSurfaceDesc desc;
-    desc.fOrigin = kBottomLeft_GrSurfaceOrigin;
     desc.fWidth = width;
     desc.fHeight = height;
     desc.fConfig = kRGBA_8888_GrPixelConfig;
 
-    return proxyProvider->createTextureProxy(desc, SkBudgeted::kYes,
+    return proxyProvider->createTextureProxy(desc, kBottomLeft_GrSurfaceOrigin, SkBudgeted::kYes,
                                              data.get(), width * sizeof(GrColor));
 }
 
diff --git a/tests/ProxyConversionTest.cpp b/tests/ProxyConversionTest.cpp
index c8b6905..a4c4a60 100644
--- a/tests/ProxyConversionTest.cpp
+++ b/tests/ProxyConversionTest.cpp
@@ -21,25 +21,28 @@
 
 static sk_sp<GrSurfaceProxy> make_wrapped_FBO0(GrProxyProvider* provider,
                                                skiatest::Reporter* reporter,
-                                               const GrSurfaceDesc& desc) {
+                                               const GrSurfaceDesc& desc,
+                                               GrSurfaceOrigin origin) {
     GrGLFramebufferInfo fboInfo;
     fboInfo.fFBOID = 0;
     GrBackendRenderTarget backendRT(desc.fWidth, desc.fHeight, desc.fSampleCnt, 8,
                                     desc.fConfig, fboInfo);
 
-    return provider->createWrappedRenderTargetProxy(backendRT, desc.fOrigin);
+    return provider->createWrappedRenderTargetProxy(backendRT, origin);
 }
 
 static sk_sp<GrSurfaceProxy> make_wrapped_offscreen_rt(GrProxyProvider* provider,
-                                                       const GrSurfaceDesc& desc) {
+                                                       const GrSurfaceDesc& desc,
+                                                       GrSurfaceOrigin origin) {
     SkASSERT(kRenderTarget_GrSurfaceFlag == desc.fFlags);
 
-    return provider->createInstantiatedProxy(desc, SkBackingFit::kExact, SkBudgeted::kYes);
+    return provider->createInstantiatedProxy(desc, origin, SkBackingFit::kExact, SkBudgeted::kYes);
 }
 
 static sk_sp<GrSurfaceProxy> make_wrapped_texture(GrProxyProvider* provider,
-                                                  const GrSurfaceDesc& desc) {
-    return provider->createInstantiatedProxy(desc, SkBackingFit::kExact, SkBudgeted::kYes);
+                                                  const GrSurfaceDesc& desc,
+                                                  GrSurfaceOrigin origin) {
+    return provider->createInstantiatedProxy(desc, origin, SkBackingFit::kExact, SkBudgeted::kYes);
 }
 
 // Test converting between RenderTargetProxies and TextureProxies for wrapped
@@ -52,11 +55,11 @@
     desc.fWidth = 64;
     desc.fHeight = 64;
     desc.fConfig = kRGBA_8888_GrPixelConfig;
-    desc.fOrigin = kBottomLeft_GrSurfaceOrigin;
 
     if (kOpenGL_GrBackend == ctxInfo.backend()) {
         // External on-screen render target.
-        sk_sp<GrSurfaceProxy> sProxy(make_wrapped_FBO0(proxyProvider, reporter, desc));
+        sk_sp<GrSurfaceProxy> sProxy(
+                make_wrapped_FBO0(proxyProvider, reporter, desc, kBottomLeft_GrSurfaceOrigin));
         if (sProxy) {
             // RenderTarget-only
             GrRenderTargetProxy* rtProxy = sProxy->asRenderTargetProxy();
@@ -68,7 +71,8 @@
 
     {
         // Internal offscreen render target.
-        sk_sp<GrSurfaceProxy> sProxy(make_wrapped_offscreen_rt(proxyProvider, desc));
+        sk_sp<GrSurfaceProxy> sProxy(
+                make_wrapped_offscreen_rt(proxyProvider, desc, kBottomLeft_GrSurfaceOrigin));
         if (sProxy) {
             // Both RenderTarget and Texture
             GrRenderTargetProxy* rtProxy = sProxy->asRenderTargetProxy();
@@ -82,7 +86,8 @@
 
     {
         // Internal offscreen render target - but through GrTextureProxy
-        sk_sp<GrSurfaceProxy> sProxy(make_wrapped_texture(proxyProvider, desc));
+        sk_sp<GrSurfaceProxy> sProxy(
+                make_wrapped_texture(proxyProvider, desc, kBottomLeft_GrSurfaceOrigin));
         if (sProxy) {
             // Both RenderTarget and Texture
             GrTextureProxy* tProxy = sProxy->asTextureProxy();
@@ -97,7 +102,8 @@
     {
         desc.fFlags = kNone_GrSurfaceFlags; // force no-RT
 
-        sk_sp<GrSurfaceProxy> sProxy(make_wrapped_texture(proxyProvider, desc));
+        sk_sp<GrSurfaceProxy> sProxy(
+                make_wrapped_texture(proxyProvider, desc, kBottomLeft_GrSurfaceOrigin));
         if (sProxy) {
             // Texture-only
             GrTextureProxy* tProxy = sProxy->asTextureProxy();
@@ -115,14 +121,13 @@
 
     GrSurfaceDesc desc;
     desc.fFlags = kRenderTarget_GrSurfaceFlag;
-    desc.fOrigin = kBottomLeft_GrSurfaceOrigin;
     desc.fWidth = 64;
     desc.fHeight = 64;
     desc.fConfig = kRGBA_8888_GrPixelConfig;
 
     {
-        sk_sp<GrTextureProxy> proxy = proxyProvider->createProxy(desc, SkBackingFit::kApprox,
-                                                                 SkBudgeted::kYes);
+        sk_sp<GrTextureProxy> proxy = proxyProvider->createProxy(
+                desc, kBottomLeft_GrSurfaceOrigin, SkBackingFit::kApprox, SkBudgeted::kYes);
 
         // Both RenderTarget and Texture
         GrRenderTargetProxy* rtProxy = proxy->asRenderTargetProxy();
@@ -134,8 +139,8 @@
     }
 
     {
-        sk_sp<GrTextureProxy> proxy = proxyProvider->createProxy(desc, SkBackingFit::kApprox,
-                                                                 SkBudgeted::kYes);
+        sk_sp<GrTextureProxy> proxy = proxyProvider->createProxy(
+                desc, kBottomLeft_GrSurfaceOrigin, SkBackingFit::kApprox, SkBudgeted::kYes);
 
         // Both RenderTarget and Texture - but via GrTextureProxy
         GrTextureProxy* tProxy = proxy->asTextureProxy();
@@ -148,10 +153,9 @@
 
     {
         desc.fFlags = kNone_GrSurfaceFlags; // force no-RT
-        desc.fOrigin = kTopLeft_GrSurfaceOrigin;
 
-        sk_sp<GrTextureProxy> proxy = proxyProvider->createProxy(desc, SkBackingFit::kApprox,
-                                                                 SkBudgeted::kYes);
+        sk_sp<GrTextureProxy> proxy = proxyProvider->createProxy(
+                desc, kTopLeft_GrSurfaceOrigin, SkBackingFit::kApprox, SkBudgeted::kYes);
         // Texture-only
         GrTextureProxy* tProxy = proxy->asTextureProxy();
         REPORTER_ASSERT(reporter, tProxy);
diff --git a/tests/ProxyRefTest.cpp b/tests/ProxyRefTest.cpp
index e84e6e7..e564397c 100644
--- a/tests/ProxyRefTest.cpp
+++ b/tests/ProxyRefTest.cpp
@@ -69,24 +69,23 @@
 static sk_sp<GrTextureProxy> make_deferred(GrProxyProvider* proxyProvider) {
     GrSurfaceDesc desc;
     desc.fFlags = kRenderTarget_GrSurfaceFlag;
-    desc.fOrigin = kBottomLeft_GrSurfaceOrigin;
     desc.fWidth = kWidthHeight;
     desc.fHeight = kWidthHeight;
     desc.fConfig = kRGBA_8888_GrPixelConfig;
 
-    return proxyProvider->createProxy(desc, SkBackingFit::kApprox, SkBudgeted::kYes,
-                                      GrResourceProvider::kNoPendingIO_Flag);
+    return proxyProvider->createProxy(desc, kBottomLeft_GrSurfaceOrigin, SkBackingFit::kApprox,
+                                      SkBudgeted::kYes, GrResourceProvider::kNoPendingIO_Flag);
 }
 
 static sk_sp<GrTextureProxy> make_wrapped(GrProxyProvider* proxyProvider) {
     GrSurfaceDesc desc;
     desc.fFlags = kRenderTarget_GrSurfaceFlag;
-    desc.fOrigin = kBottomLeft_GrSurfaceOrigin;
     desc.fWidth = kWidthHeight;
     desc.fHeight = kWidthHeight;
     desc.fConfig = kRGBA_8888_GrPixelConfig;
 
-    return proxyProvider->createInstantiatedProxy(desc, SkBackingFit::kExact, SkBudgeted::kNo);
+    return proxyProvider->createInstantiatedProxy(desc, kBottomLeft_GrSurfaceOrigin,
+                                                  SkBackingFit::kExact, SkBudgeted::kNo);
 }
 
 DEF_GPUTEST_FOR_RENDERING_CONTEXTS(ProxyRefTest, reporter, ctxInfo) {
diff --git a/tests/ProxyTest.cpp b/tests/ProxyTest.cpp
index 6ad8199..f346f87 100644
--- a/tests/ProxyTest.cpp
+++ b/tests/ProxyTest.cpp
@@ -110,7 +110,6 @@
                         for (auto numSamples : {1, 4, 16, 128}) {
                             GrSurfaceDesc desc;
                             desc.fFlags = kRenderTarget_GrSurfaceFlag;
-                            desc.fOrigin = origin;
                             desc.fWidth = widthHeight;
                             desc.fHeight = widthHeight;
                             desc.fConfig = config;
@@ -124,8 +123,8 @@
                                     tex = resourceProvider->createTexture(desc, budgeted);
                                 }
 
-                                sk_sp<GrTextureProxy> proxy = proxyProvider->createProxy(
-                                                                            desc, fit, budgeted);
+                                sk_sp<GrTextureProxy> proxy =
+                                        proxyProvider->createProxy(desc, origin, fit, budgeted);
                                 REPORTER_ASSERT(reporter, SkToBool(tex) == SkToBool(proxy));
                                 if (proxy) {
                                     REPORTER_ASSERT(reporter, proxy->asRenderTargetProxy());
@@ -157,8 +156,8 @@
                                     tex = resourceProvider->createTexture(desc, budgeted);
                                 }
 
-                                sk_sp<GrTextureProxy> proxy(proxyProvider->createProxy(
-                                                                            desc, fit, budgeted));
+                                sk_sp<GrTextureProxy> proxy(
+                                        proxyProvider->createProxy(desc, origin, fit, budgeted));
                                 REPORTER_ASSERT(reporter, SkToBool(tex) == SkToBool(proxy));
                                 if (proxy) {
                                     // This forces the proxy to compute and cache its
@@ -319,13 +318,13 @@
 
                     GrSurfaceDesc desc;
                     desc.fFlags = flags;
-                    desc.fOrigin = kBottomLeft_GrSurfaceOrigin;
                     desc.fWidth = width;
                     desc.fHeight = height;
                     desc.fConfig = kRGBA_8888_GrPixelConfig;
                     desc.fSampleCnt = 1;
 
-                    sk_sp<GrTextureProxy> proxy = provider->createProxy(desc, fit, SkBudgeted::kNo);
+                    sk_sp<GrTextureProxy> proxy = provider->createProxy(
+                            desc, kBottomLeft_GrSurfaceOrigin, fit, SkBudgeted::kNo);
                     REPORTER_ASSERT(reporter, !proxy);
                 }
             }
diff --git a/tests/ReadPixelsTest.cpp b/tests/ReadPixelsTest.cpp
index 2198e67..34cf5bc 100644
--- a/tests/ReadPixelsTest.cpp
+++ b/tests/ReadPixelsTest.cpp
@@ -461,11 +461,9 @@
             desc.fWidth = DEV_W;
             desc.fHeight = DEV_H;
             desc.fConfig = kSkia8888_GrPixelConfig;
-            desc.fOrigin = origin;
 
-            sk_sp<GrTextureProxy> proxy = proxyProvider->createTextureProxy(desc, SkBudgeted::kNo,
-                                                                            bmp.getPixels(),
-                                                                            bmp.rowBytes());
+            sk_sp<GrTextureProxy> proxy = proxyProvider->createTextureProxy(
+                    desc, origin, SkBudgeted::kNo, bmp.getPixels(), bmp.rowBytes());
 
             sk_sp<GrSurfaceContext> sContext = context->contextPriv().makeWrappedSurfaceContext(
                                                                                 std::move(proxy));
diff --git a/tests/ReadWriteAlphaTest.cpp b/tests/ReadWriteAlphaTest.cpp
index de9422d..f495fc2 100644
--- a/tests/ReadWriteAlphaTest.cpp
+++ b/tests/ReadWriteAlphaTest.cpp
@@ -59,7 +59,6 @@
     {
         GrSurfaceDesc desc;
         desc.fFlags     = kNone_GrSurfaceFlags;
-        desc.fOrigin    = kTopLeft_GrSurfaceOrigin;
         desc.fConfig    = kAlpha_8_GrPixelConfig;    // it is a single channel texture
         desc.fWidth     = X_SIZE;
         desc.fHeight    = Y_SIZE;
@@ -67,8 +66,8 @@
         // We are initializing the texture with zeros here
         memset(alphaData, 0, X_SIZE * Y_SIZE);
 
-        sk_sp<GrTextureProxy> proxy = proxyProvider->createTextureProxy(desc, SkBudgeted::kNo,
-                                                                        alphaData, 0);
+        sk_sp<GrTextureProxy> proxy = proxyProvider->createTextureProxy(
+                desc, kTopLeft_GrSurfaceOrigin, SkBudgeted::kNo, alphaData, 0);
         if (!proxy) {
             ERRORF(reporter, "Could not create alpha texture.");
             return;
@@ -170,7 +169,6 @@
         for (int rt = 0; rt < 2; ++rt) {
             GrSurfaceDesc desc;
             desc.fFlags     = rt ? kRenderTarget_GrSurfaceFlag : kNone_GrSurfaceFlags;
-            desc.fOrigin    = rt ? kBottomLeft_GrSurfaceOrigin : kTopLeft_GrSurfaceOrigin;
             desc.fConfig    = config;
             desc.fWidth     = X_SIZE;
             desc.fHeight    = Y_SIZE;
@@ -183,8 +181,9 @@
                 }
             }
 
-            sk_sp<GrTextureProxy> proxy = proxyProvider->createTextureProxy(desc, SkBudgeted::kNo,
-                                                                            rgbaData, 0);
+            auto origin = rt ? kBottomLeft_GrSurfaceOrigin : kTopLeft_GrSurfaceOrigin;
+            sk_sp<GrTextureProxy> proxy =
+                    proxyProvider->createTextureProxy(desc, origin, SkBudgeted::kNo, rgbaData, 0);
             if (!proxy) {
                 // We always expect to be able to create a RGBA texture
                 if (!rt  && kRGBA_8888_GrPixelConfig == desc.fConfig) {
diff --git a/tests/ResourceAllocatorTest.cpp b/tests/ResourceAllocatorTest.cpp
index 29ad5b3..f424463 100644
--- a/tests/ResourceAllocatorTest.cpp
+++ b/tests/ResourceAllocatorTest.cpp
@@ -34,13 +34,12 @@
 static sk_sp<GrSurfaceProxy> make_deferred(GrProxyProvider* proxyProvider, const ProxyParams& p) {
     GrSurfaceDesc desc;
     desc.fFlags = p.fIsRT ? kRenderTarget_GrSurfaceFlag : kNone_GrSurfaceFlags;
-    desc.fOrigin = p.fOrigin;
     desc.fWidth  = p.fSize;
     desc.fHeight = p.fSize;
     desc.fConfig = p.fConfig;
     desc.fSampleCnt = p.fSampleCnt;
 
-    return proxyProvider->createProxy(desc, p.fFit, SkBudgeted::kNo);
+    return proxyProvider->createProxy(desc, p.fOrigin, p.fFit, SkBudgeted::kNo);
 }
 
 static sk_sp<GrSurfaceProxy> make_backend(GrContext* context, const ProxyParams& p,
diff --git a/tests/ResourceCacheTest.cpp b/tests/ResourceCacheTest.cpp
index f6ff218..55f4f85 100644
--- a/tests/ResourceCacheTest.cpp
+++ b/tests/ResourceCacheTest.cpp
@@ -100,7 +100,6 @@
                                                int size, int sampleCount, SkBudgeted budgeted) {
     GrSurfaceDesc desc;
     desc.fFlags = kRenderTarget_GrSurfaceFlag;
-    desc.fOrigin = kBottomLeft_GrSurfaceOrigin;
     desc.fWidth = size;
     desc.fHeight = size;
     desc.fConfig = kRGBA_8888_GrPixelConfig;
@@ -1646,7 +1645,6 @@
                                             int sampleCnt) {
     GrSurfaceDesc desc;
     desc.fFlags = flags;
-    desc.fOrigin = kTopLeft_GrSurfaceOrigin;
     desc.fWidth = width;
     desc.fHeight = height;
     desc.fConfig = kRGBA_8888_GrPixelConfig;
@@ -1661,14 +1659,15 @@
                                                int sampleCnt) {
     GrSurfaceDesc desc;
     desc.fFlags = flags;
-    desc.fOrigin = (flags & kRenderTarget_GrSurfaceFlag) ? kBottomLeft_GrSurfaceOrigin
-                                                         : kTopLeft_GrSurfaceOrigin;
     desc.fWidth = width;
     desc.fHeight = height;
     desc.fConfig = kRGBA_8888_GrPixelConfig;
     desc.fSampleCnt = sampleCnt;
 
-    return proxyProvider->createMipMapProxy(desc, SkBudgeted::kYes);
+    auto origin = (flags & kRenderTarget_GrSurfaceFlag) ? kBottomLeft_GrSurfaceOrigin
+                                                        : kTopLeft_GrSurfaceOrigin;
+
+    return proxyProvider->createMipMapProxy(desc, origin, SkBudgeted::kYes);
 }
 
 // Exercise GrSurface::gpuMemorySize for different combos of MSAA, RT-only,
diff --git a/tests/SRGBMipMapTest.cpp b/tests/SRGBMipMapTest.cpp
index b24b7f7..466aad2 100644
--- a/tests/SRGBMipMapTest.cpp
+++ b/tests/SRGBMipMapTest.cpp
@@ -126,14 +126,13 @@
     // Create our test texture
     GrSurfaceDesc desc;
     desc.fFlags = kNone_GrSurfaceFlags;
-    desc.fOrigin = kTopLeft_GrSurfaceOrigin;
     desc.fWidth = texS;
     desc.fHeight = texS;
     desc.fConfig = kSRGBA_8888_GrPixelConfig;
 
     GrProxyProvider* proxyProvider = context->contextPriv().proxyProvider();
-    sk_sp<GrTextureProxy> proxy = proxyProvider->createTextureProxy(
-                                                                desc, SkBudgeted::kNo, texData, 0);
+    sk_sp<GrTextureProxy> proxy = proxyProvider->createTextureProxy(desc, kTopLeft_GrSurfaceOrigin,
+                                                                    SkBudgeted::kNo, texData, 0);
 
     // Create two render target contexts (L32 and S32)
     sk_sp<SkColorSpace> srgbColorSpace = SkColorSpace::MakeSRGB();
diff --git a/tests/SRGBReadWritePixelsTest.cpp b/tests/SRGBReadWritePixelsTest.cpp
index 8b7dd07..18ed738 100644
--- a/tests/SRGBReadWritePixelsTest.cpp
+++ b/tests/SRGBReadWritePixelsTest.cpp
@@ -199,14 +199,13 @@
                                                     skiatest::Reporter* reporter) {
     GrSurfaceDesc desc;
     desc.fFlags = kRenderTarget_GrSurfaceFlag;
-    desc.fOrigin = kBottomLeft_GrSurfaceOrigin;
     desc.fWidth = kW;
     desc.fHeight = kH;
     desc.fConfig = encoding_as_pixel_config(contextEncoding);
 
     auto surfaceContext = context->contextPriv().makeDeferredSurfaceContext(
-            desc, GrMipMapped::kNo, SkBackingFit::kExact, SkBudgeted::kNo,
-            encoding_as_color_space(contextEncoding));
+            desc, kBottomLeft_GrSurfaceOrigin, GrMipMapped::kNo, SkBackingFit::kExact,
+            SkBudgeted::kNo, encoding_as_color_space(contextEncoding));
     if (!surfaceContext) {
         ERRORF(reporter, "Could not create %s surface context.", encoding_as_str(contextEncoding));
     }
diff --git a/tests/SpecialImageTest.cpp b/tests/SpecialImageTest.cpp
index 4b86697..f201fb0 100644
--- a/tests/SpecialImageTest.cpp
+++ b/tests/SpecialImageTest.cpp
@@ -238,7 +238,7 @@
         const GrSurfaceDesc desc = GrImageInfoToSurfaceDesc(bm.info(), *context->caps());
 
         sk_sp<GrTextureProxy> proxy = proxyProvider->createTextureProxy(
-                                            desc, SkBudgeted::kNo, bm.getPixels(), bm.rowBytes());
+                desc, kTopLeft_GrSurfaceOrigin, SkBudgeted::kNo, bm.getPixels(), bm.rowBytes());
         if (!proxy) {
             return;
         }
@@ -271,7 +271,7 @@
     const GrSurfaceDesc desc = GrImageInfoToSurfaceDesc(bm.info(), *context->caps());
 
     sk_sp<GrTextureProxy> proxy = proxyProvider->createTextureProxy(
-                                        desc, SkBudgeted::kNo,  bm.getPixels(), bm.rowBytes());
+            desc, kTopLeft_GrSurfaceOrigin, SkBudgeted::kNo, bm.getPixels(), bm.rowBytes());
     if (!proxy) {
         return;
     }
@@ -305,13 +305,12 @@
 
     GrSurfaceDesc desc;
     desc.fFlags  = kNone_GrSurfaceFlags;
-    desc.fOrigin = kTopLeft_GrSurfaceOrigin;
     desc.fWidth  = kFullSize;
     desc.fHeight = kFullSize;
     desc.fConfig = kSkia8888_GrPixelConfig;
 
     sk_sp<GrTextureProxy> proxy = proxyProvider->createTextureProxy(
-                                            desc, SkBudgeted::kNo, bm.getPixels(), bm.rowBytes());
+            desc, kTopLeft_GrSurfaceOrigin, SkBudgeted::kNo, bm.getPixels(), bm.rowBytes());
     if (!proxy) {
         return;
     }
diff --git a/tests/TestUtils.cpp b/tests/TestUtils.cpp
index 463a8e9..7878233 100644
--- a/tests/TestUtils.cpp
+++ b/tests/TestUtils.cpp
@@ -81,10 +81,11 @@
         }
 
         copyDstDesc.fFlags = flags;
-        copyDstDesc.fOrigin = (kNone_GrSurfaceFlags == flags) ? kTopLeft_GrSurfaceOrigin
-                                                              : kBottomLeft_GrSurfaceOrigin;
+        auto origin = (kNone_GrSurfaceFlags == flags) ? kTopLeft_GrSurfaceOrigin
+                                                      : kBottomLeft_GrSurfaceOrigin;
 
-        sk_sp<GrSurfaceContext> dstContext(GrSurfaceProxy::TestCopy(context, copyDstDesc, proxy));
+        sk_sp<GrSurfaceContext> dstContext(
+                GrSurfaceProxy::TestCopy(context, copyDstDesc, origin, proxy));
 
         test_read_pixels(reporter, dstContext.get(), expectedPixelValues, testName);
     }
@@ -109,11 +110,11 @@
 
     for (auto flags : { kNone_GrSurfaceFlags, kRenderTarget_GrSurfaceFlag }) {
         copySrcDesc.fFlags = flags;
-        copySrcDesc.fOrigin = (kNone_GrSurfaceFlags == flags) ? kTopLeft_GrSurfaceOrigin
-                                                              : kBottomLeft_GrSurfaceOrigin;
+        auto origin = (kNone_GrSurfaceFlags == flags) ? kTopLeft_GrSurfaceOrigin
+                                                      : kBottomLeft_GrSurfaceOrigin;
 
-        sk_sp<GrTextureProxy> src = proxyProvider->createTextureProxy(copySrcDesc, SkBudgeted::kYes,
-                                                                      pixels.get(), 0);
+        sk_sp<GrTextureProxy> src = proxyProvider->createTextureProxy(
+                copySrcDesc, origin, SkBudgeted::kYes, pixels.get(), 0);
 
         dstContext->copy(src.get());
 
diff --git a/tests/TextureProxyTest.cpp b/tests/TextureProxyTest.cpp
index f81df8e..8d0df6f 100644
--- a/tests/TextureProxyTest.cpp
+++ b/tests/TextureProxyTest.cpp
@@ -30,7 +30,6 @@
 static GrSurfaceDesc make_desc(GrSurfaceFlags flags) {
     GrSurfaceDesc desc;
     desc.fFlags = flags;
-    desc.fOrigin = kBottomLeft_GrSurfaceOrigin;
     desc.fWidth = 64;
     desc.fHeight = 64;
     desc.fConfig = kRGBA_8888_GrPixelConfig;
@@ -46,7 +45,8 @@
                                           GrProxyProvider* proxyProvider, SkBackingFit fit) {
     const GrSurfaceDesc desc = make_desc(kNone_GrSurfaceFlags);
 
-    sk_sp<GrTextureProxy> proxy = proxyProvider->createProxy(desc, fit, SkBudgeted::kYes);
+    sk_sp<GrTextureProxy> proxy =
+            proxyProvider->createProxy(desc, kBottomLeft_GrSurfaceOrigin, fit, SkBudgeted::kYes);
     // Only budgeted & wrapped external proxies get to carry uniqueKeys
     REPORTER_ASSERT(reporter, !proxy->getUniqueKey().isValid());
     return proxy;
@@ -56,7 +56,8 @@
                                             GrProxyProvider* proxyProvider, SkBackingFit fit) {
     const GrSurfaceDesc desc = make_desc(kRenderTarget_GrSurfaceFlag);
 
-    sk_sp<GrTextureProxy> proxy = proxyProvider->createProxy(desc, fit, SkBudgeted::kYes);
+    sk_sp<GrTextureProxy> proxy =
+            proxyProvider->createProxy(desc, kBottomLeft_GrSurfaceOrigin, fit, SkBudgeted::kYes);
     // Only budgeted & wrapped external proxies get to carry uniqueKeys
     REPORTER_ASSERT(reporter, !proxy->getUniqueKey().isValid());
     return proxy;
@@ -66,8 +67,8 @@
                                      GrProxyProvider* proxyProvider, SkBackingFit fit) {
     const GrSurfaceDesc desc = make_desc(kNone_GrSurfaceFlags);
 
-    sk_sp<GrTextureProxy> proxy = proxyProvider->createInstantiatedProxy(desc, fit,
-                                                                         SkBudgeted::kYes);
+    sk_sp<GrTextureProxy> proxy = proxyProvider->createInstantiatedProxy(
+            desc, kBottomLeft_GrSurfaceOrigin, fit, SkBudgeted::kYes);
     // Only budgeted & wrapped external proxies get to carry uniqueKeys
     REPORTER_ASSERT(reporter, !proxy->getUniqueKey().isValid());
     return proxy;
@@ -87,8 +88,8 @@
     const GrSurfaceDesc desc = make_desc(kNone_GrSurfaceFlags);
 
     // Only budgeted & wrapped external proxies get to carry uniqueKeys
-    sk_sp<GrTextureProxy> proxy = proxyProvider->createInstantiatedProxy(desc, fit,
-                                                                         SkBudgeted::kYes, 0);
+    sk_sp<GrTextureProxy> proxy = proxyProvider->createInstantiatedProxy(
+            desc, kBottomLeft_GrSurfaceOrigin, fit, SkBudgeted::kYes, 0);
     SkAssertResult(proxyProvider->assignUniqueKeyToProxy(key, proxy.get()));
     REPORTER_ASSERT(reporter, proxy->getUniqueKey().isValid());
     return proxy;
diff --git a/tests/TransferPixelsTest.cpp b/tests/TransferPixelsTest.cpp
index 1c82ede..e17dfac 100755
--- a/tests/TransferPixelsTest.cpp
+++ b/tests/TransferPixelsTest.cpp
@@ -101,7 +101,6 @@
         // create texture
         GrSurfaceDesc desc;
         desc.fFlags = renderTarget ? kRenderTarget_GrSurfaceFlag : kNone_GrSurfaceFlags;
-        desc.fOrigin = origin;
         desc.fWidth = kTextureWidth;
         desc.fHeight = kTextureHeight;
         desc.fConfig = GrColorTypeToPixelConfig(colorType, srgbEncoding);
diff --git a/tests/VkMakeCopyPipelineTest.cpp b/tests/VkMakeCopyPipelineTest.cpp
index f9a0ec6..77359cd 100644
--- a/tests/VkMakeCopyPipelineTest.cpp
+++ b/tests/VkMakeCopyPipelineTest.cpp
@@ -116,7 +116,6 @@
 
         GrSurfaceDesc surfDesc;
         surfDesc.fFlags = kRenderTarget_GrSurfaceFlag;
-        surfDesc.fOrigin = kTopLeft_GrSurfaceOrigin;
         surfDesc.fWidth = 16;
         surfDesc.fHeight = 16;
         surfDesc.fConfig = kRGBA_8888_GrPixelConfig;
diff --git a/tests/VkUploadPixelsTests.cpp b/tests/VkUploadPixelsTests.cpp
index f35480a..f2d6af3 100644
--- a/tests/VkUploadPixelsTests.cpp
+++ b/tests/VkUploadPixelsTests.cpp
@@ -65,7 +65,6 @@
 
     GrSurfaceDesc surfDesc;
     surfDesc.fFlags = renderTarget ? kRenderTarget_GrSurfaceFlag : kNone_GrSurfaceFlags;
-    surfDesc.fOrigin = kTopLeft_GrSurfaceOrigin;
     surfDesc.fWidth = kWidth;
     surfDesc.fHeight = kHeight;
     surfDesc.fConfig = config;
@@ -74,8 +73,8 @@
     SkColorType ct;
     SkAssertResult(GrPixelConfigToColorType(config, &ct));
 
-    sk_sp<GrTextureProxy> proxy = proxyProvider->createTextureProxy(surfDesc, SkBudgeted::kNo,
-                                                                    srcBuffer, 0);
+    sk_sp<GrTextureProxy> proxy = proxyProvider->createTextureProxy(
+            surfDesc, kTopLeft_GrSurfaceOrigin, SkBudgeted::kNo, srcBuffer, 0);
     REPORTER_ASSERT(reporter, proxy);
     if (proxy) {
         sk_sp<GrSurfaceContext> sContext = context->contextPriv().makeWrappedSurfaceContext(proxy);
@@ -104,9 +103,8 @@
                                                                          2));
     }
 
-    surfDesc.fOrigin = kBottomLeft_GrSurfaceOrigin;
-
-    proxy = proxyProvider->createTextureProxy(surfDesc, SkBudgeted::kNo, srcBuffer, 0);
+    proxy = proxyProvider->createTextureProxy(surfDesc, kBottomLeft_GrSurfaceOrigin,
+                                              SkBudgeted::kNo, srcBuffer, 0);
     REPORTER_ASSERT(reporter, proxy);
     if (proxy) {
         sk_sp<GrSurfaceContext> sContext = context->contextPriv().makeWrappedSurfaceContext(proxy);
diff --git a/tests/WritePixelsTest.cpp b/tests/WritePixelsTest.cpp
index cb12dcf..1f9c9c6 100644
--- a/tests/WritePixelsTest.cpp
+++ b/tests/WritePixelsTest.cpp
@@ -493,8 +493,8 @@
         desc.fHeight = 64;
         desc.fConfig = kRGBA_8888_GrPixelConfig;
 
-        sk_sp<GrTextureProxy> temp = proxyProvider->createProxy(desc, SkBackingFit::kApprox,
-                                                                SkBudgeted::kYes);
+        sk_sp<GrTextureProxy> temp = proxyProvider->createProxy(
+                desc, kTopLeft_GrSurfaceOrigin, SkBackingFit::kApprox, SkBudgeted::kYes);
         temp->instantiate(context->contextPriv().resourceProvider());
     }
 
diff --git a/tools/fiddle/fiddle_main.cpp b/tools/fiddle/fiddle_main.cpp
index 9ade250..891b1ff 100644
--- a/tools/fiddle/fiddle_main.cpp
+++ b/tools/fiddle/fiddle_main.cpp
@@ -128,7 +128,6 @@
 
     GrSurfaceDesc backingDesc;
     backingDesc.fFlags = kNone_GrSurfaceFlags;
-    backingDesc.fOrigin = kTopLeft_GrSurfaceOrigin;
     backingDesc.fWidth = bm.width();
     backingDesc.fHeight = bm.height();
     // This config must match the SkColorType used in draw.cpp in the SkImage and Surface factories
@@ -165,9 +164,9 @@
             texels[i].fRowBytes = 0;
         }
 
-        backingTexture = resourceProvider->createTexture(backingDesc, SkBudgeted::kNo,
-                                                         texels.get(), mipLevelCount,
-                                                         SkDestinationSurfaceColorMode::kLegacy);
+        backingTexture = resourceProvider->createTexture(
+                backingDesc, SkBudgeted::kNo, kTopLeft_GrSurfaceOrigin, texels.get(), mipLevelCount,
+                SkDestinationSurfaceColorMode::kLegacy);
         if (!backingTexture) {
             return false;
         }
@@ -194,9 +193,8 @@
         GrMipLevel level0 = { data.get(), backingDesc.fWidth*sizeof(uint32_t) };
 
         sk_sp<GrTexture> tmp = resourceProvider->createTexture(
-                                                            backingDesc, SkBudgeted::kNo,
-                                                            &level0, 1,
-                                                            SkDestinationSurfaceColorMode::kLegacy);
+                backingDesc, SkBudgeted::kNo, kTopLeft_GrSurfaceOrigin, &level0, 1,
+                SkDestinationSurfaceColorMode::kLegacy);
         if (!tmp || !tmp->asRenderTarget()) {
             return false;
         }
@@ -224,9 +222,8 @@
         }
 
         backingTextureRenderTarget = resourceProvider->createTexture(
-                                                            backingDesc, SkBudgeted::kNo,
-                                                            texels.get(), mipLevelCount,
-                                                            SkDestinationSurfaceColorMode::kLegacy);
+                backingDesc, SkBudgeted::kNo, kTopLeft_GrSurfaceOrigin, texels.get(), mipLevelCount,
+                SkDestinationSurfaceColorMode::kLegacy);
         if (!backingTextureRenderTarget || !backingTextureRenderTarget->asRenderTarget()) {
             return false;
         }