Update SkSurface MakeFromBackend* factories to take an SkColorType.

Bug: skia:
Change-Id: Ib1b03b1181ec937843eac2e8d8cb03ebe53e32c1
Reviewed-on: https://skia-review.googlesource.com/86760
Commit-Queue: Greg Daniel <egdaniel@google.com>
Reviewed-by: Brian Salomon <bsalomon@google.com>
diff --git a/debugger/QT/SkGLWidget.cpp b/debugger/QT/SkGLWidget.cpp
index f80ffaf..baee2bb 100644
--- a/debugger/QT/SkGLWidget.cpp
+++ b/debugger/QT/SkGLWidget.cpp
@@ -56,8 +56,14 @@
     glClear(GL_STENCIL_BUFFER_BIT);
     fCurContext->resetContext();
     GrBackendRenderTarget backendRenderTarget = this->getBackendRenderTarget();
+    SkColorType colorType;
+    if (kRGBA_8888_GrPixelConfig == kSkia8888_GrPixelConfig) {
+        colorType = kRGBA_8888_SkColorType;
+    } else {
+        colorType = kBGRA_8888_SkColorType;
+    }
     fGpuSurface = SkSurface::MakeFromBackendRenderTarget(fCurContext.get(), backendRenderTarget,
-                                                         kBottomLeft_GrSurfaceOrigin,
+                                                         kBottomLeft_GrSurfaceOrigin, colorType,
                                                          nullptr, nullptr);
     fCanvas = fGpuSurface->getCanvas();
 }
@@ -84,11 +90,12 @@
     GR_GL_GetIntegerv(fCurIntf.get(), GR_GL_FRAMEBUFFER_BINDING, &info.fFBOID);
     GR_GL_GetIntegerv(fCurIntf.get(), GR_GL_SAMPLES, &sampleCnt);
     GR_GL_GetIntegerv(fCurIntf.get(), GR_GL_STENCIL_BITS, &stencilBits);
+    // We are on desktop so we assume the internal config is RGBA
+    info.fFormat = GR_GL_RGBA8;
     return GrBackendRenderTarget(SkScalarRoundToInt(this->width()),
                                  SkScalarRoundToInt(this->height()),
                                  sampleCnt,
                                  stencilBits,
-                                 kSkia8888_GrPixelConfig,
                                  info);
 }
 
diff --git a/example/SkiaSDLExample.cpp b/example/SkiaSDLExample.cpp
index 3e23e57..32c59f3 100644
--- a/example/SkiaSDLExample.cpp
+++ b/example/SkiaSDLExample.cpp
@@ -180,6 +180,11 @@
         return success;
     }
 
+    uint32_t windowFormat = SDL_GetWindowPixelFormat(window);
+    int contextType;
+    SDL_GL_GetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, &contextType);
+
+
     int dw, dh;
     SDL_GL_GetDrawableSize(window, &dw, &dh);
 
@@ -201,8 +206,23 @@
     GR_GL_GetIntegerv(interface.get(), GR_GL_FRAMEBUFFER_BINDING, &buffer);
     GrGLFramebufferInfo info;
     info.fFBOID = (GrGLuint) buffer;
-    GrBackendRenderTarget target(dw, dh, kMsaaSampleCount, kStencilBits,
-                                 kSkia8888_GrPixelConfig, info);
+    SkColorType colorType;
+
+    if (SDL_PIXELFORMAT_RGBA8888 == windowFormat) {
+        info.fFormat = GR_GL_RGBA8;
+        colorType = kRGBA_8888_SkColorType;
+    } else {
+        SkASSERT(SDL_PIXELFORMAT_BGRA8888);
+        colorType = kBGRA_8888_SkColorType;
+        if (SDL_GL_CONTEXT_PROFILE_ES == contextType) {
+            info.fFormat = GR_GL_BGRA8;
+        } else {
+            // We assume the internal format is RGBA8 on desktop GL
+            info.fFormat = GR_GL_RGBA8;
+        }
+    }
+
+    GrBackendRenderTarget target(dw, dh, kMsaaSampleCount, kStencilBits, info);
 
     // setup SkSurface
     // To use distance field text, use commented out SkSurfaceProps instead
@@ -212,7 +232,7 @@
 
     sk_sp<SkSurface> surface(SkSurface::MakeFromBackendRenderTarget(grContext.get(), target,
                                                                     kBottomLeft_GrSurfaceOrigin,
-                                                                    nullptr, &props));
+                                                                    colorType, nullptr, &props));
 
     SkCanvas* canvas = surface->getCanvas();
     canvas->scale((float)dw/dm.w, (float)dh/dm.h);
diff --git a/experimental/GLFWTest/glfw_main.cpp b/experimental/GLFWTest/glfw_main.cpp
index e83abc5..358fbb8 100644
--- a/experimental/GLFWTest/glfw_main.cpp
+++ b/experimental/GLFWTest/glfw_main.cpp
@@ -34,14 +34,22 @@
 
     GrGLFramebufferInfo framebufferInfo;
     framebufferInfo.fFBOID = 0;  // assume default framebuffer
+    // We are always using OpenGL and we use RGBA8 internal format for both RGBA and BGRA configs in
+    // OpenGL.
+    framebufferInfo.fFormat = GR_GL_RGBA8;
+    SkColorType colorType;
+    if (kRGBA_8888_GrPixelConfig == kSkia8888_GrPixelConfig) {
+        colorType = kRGBA_8888_SkColorType;
+    } else {
+        colorType = kBGRA_8888_SkColorType;
+    }
     GrBackendRenderTarget backendRenderTarget(w, h,
                                               0, // sample count
                                               0, // stencil bits
-                                              kSkia8888_GrPixelConfig,
                                               framebufferInfo);
 
     sSurface = SkSurface::MakeFromBackendRenderTarget(sContext, backendRenderTarget,
-                                                      kBottomLeft_GrSurfaceOrigin,
+                                                      kBottomLeft_GrSurfaceOrigin, colortype,
                                                       nullptr, nullptr).release();
 }
 
diff --git a/include/core/SkImage.h b/include/core/SkImage.h
index 2a196aa..9ebddc5 100644
--- a/include/core/SkImage.h
+++ b/include/core/SkImage.h
@@ -131,7 +131,7 @@
      *  Create a new image from the specified descriptor. Note - the caller is responsible for
      *  managing the lifetime of the underlying platform texture.
      *
-     *  The GrBackendTexture mush have a valid backed format supplied (GrGLTextureInfo::fFormat,
+     *  The GrBackendTexture must have a valid backend format supplied (GrGLTextureInfo::fFormat,
      *  GrVkImageInfo::fFormat, etc.) in it. The passed in SkColorType informs skia how it should
      *  interpret the backend format supplied by the GrBackendTexture. If the format in the
      *  GrBackendTexture is not compitable with the SkColorType, SkAlphaType, and SkColorSpace we
@@ -152,7 +152,7 @@
      *  valid and unaltered until the specified release-proc is invoked, indicating that Skia
      *  no longer is holding a reference to it.
      *
-     *  The GrBackendTexture mush have a valid backed format supplied (GrGLTextureInfo::fFormat,
+     *  The GrBackendTexture must have a valid backend format supplied (GrGLTextureInfo::fFormat,
      *  GrVkImageInfo::fFormat, etc.) in it. The passed in SkColorType informs skia how it should
      *  interpret the backend format supplied by the GrBackendTexture. If the format in the
      *  GrBackendTexture is not compitable with the SkColorType, SkAlphaType, and SkColorSpace we
@@ -218,7 +218,7 @@
      *  Create a new image from the specified descriptor. Note - Skia will delete or recycle the
      *  texture when the image is released.
      *
-     *  The GrBackendTexture mush have a valid backed format supplied (GrGLTextureInfo::fFormat,
+     *  The GrBackendTexture must have a valid backend format supplied (GrGLTextureInfo::fFormat,
      *  GrVkImageInfo::fFormat, etc.) in it. The passed in SkColorType informs skia how it should
      *  interpret the backend format supplied by the GrBackendTexture. If the format in the
      *  GrBackendTexture is not compitable with the SkColorType, SkAlphaType, and SkColorSpace we
diff --git a/include/core/SkSurface.h b/include/core/SkSurface.h
index f70db73..b4df88c 100644
--- a/include/core/SkSurface.h
+++ b/include/core/SkSurface.h
@@ -99,6 +99,25 @@
                                                    sk_sp<SkColorSpace> colorSpace,
                                                    const SkSurfaceProps* surfaceProps);
 
+    /**
+     *  Used to wrap a pre-existing backend 3D API texture as a SkSurface. Skia will not assume
+     *  ownership of the texture and the client must ensure the texture is valid for the lifetime
+     *  of the SkSurface. If sampleCnt > 0, then we will create an intermediate mssa surface which
+     *  we will use for rendering. We then resolve into the passed in texture.
+     *
+     *  The GrBackendTexture must have a valid backend format supplied (GrGLTextureInfo::fFormat,
+     *  GrVkImageInfo::fFormat, etc.) in it. The passed in SkColorType informs skia how it should
+     *  interpret the backend format supplied by the GrBackendTexture. If the format in the
+     *  GrBackendTexture is not compitable with the sampleCnt, SkColorType, and SkColorSpace we
+     *  will return nullptr.
+     */
+    static sk_sp<SkSurface> MakeFromBackendTexture(GrContext* context,
+                                                   const GrBackendTexture& backendTexture,
+                                                   GrSurfaceOrigin origin, int sampleCnt,
+                                                   SkColorType colorType,
+                                                   sk_sp<SkColorSpace> colorSpace,
+                                                   const SkSurfaceProps* surfaceProps);
+
     static sk_sp<SkSurface> MakeFromBackendRenderTarget(GrContext* context,
                                                 const GrBackendRenderTarget& backendRenderTarget,
                                                 GrSurfaceOrigin origin,
@@ -106,6 +125,20 @@
                                                 const SkSurfaceProps* surfaceProps);
 
     /**
+     *  The GrBackendRenderTarget must have a valid backend format set (GrGLTextureInfo::fFormat,
+     *  GrVkImageInfo::fFormat, etc.) in it. The passed in SkColorType informs skia how it should
+     *  interpret the backend format supplied by the GrBackendRenderTarget. If the format in the
+     *  GrBackendRenderTarget is not compitable with the sampleCnt, SkColorType, and SkColorSpace
+     *  we will return nullptr.
+     */
+    static sk_sp<SkSurface> MakeFromBackendRenderTarget(GrContext* context,
+                                                const GrBackendRenderTarget& backendRenderTarget,
+                                                GrSurfaceOrigin origin,
+                                                SkColorType colorType,
+                                                sk_sp<SkColorSpace> colorSpace,
+                                                const SkSurfaceProps* surfaceProps);
+
+    /**
      *  Used to wrap a pre-existing 3D API texture as a SkSurface. Skia will treat the texture as
      *  a rendering target only, but unlike NewFromBackendRenderTarget, Skia will manage and own
      *  the associated render target objects (but not the provided texture). Skia will not assume
@@ -120,6 +153,27 @@
                                                             const SkSurfaceProps* surfaceProps);
 
     /**
+     *  Used to wrap a pre-existing 3D API texture as a SkSurface. Skia will treat the texture as
+     *  a rendering target only, but unlike NewFromBackendRenderTarget, Skia will manage and own
+     *  the associated render target objects (but not the provided texture). Skia will not assume
+     *  ownership of the texture and the client must ensure the texture is valid for the lifetime
+     *  of the SkSurface.
+     *
+     *  The GrBackendTexture must have a valid backend format supplied (GrGLTextureInfo::fFormat,
+     *  GrVkImageInfo::fFormat, etc.) in it. The passed in SkColorType informs skia how it should
+     *  interpret the backend format supplied by the GrBackendTexture. If the format in the
+     *  GrBackendTexture is not compitable with the sampleCnt, SkColorType, and SkColorSpace we
+     *  will return nullptr.
+     */
+    static sk_sp<SkSurface> MakeFromBackendTextureAsRenderTarget(GrContext* context,
+                                                            const GrBackendTexture& backendTexture,
+                                                            GrSurfaceOrigin origin,
+                                                            int sampleCnt,
+                                                            SkColorType,
+                                                            sk_sp<SkColorSpace> colorSpace,
+                                                            const SkSurfaceProps* surfaceProps);
+
+    /**
      *  Return a new surface whose contents will be drawn to an offscreen
      *  render target, allocated by the surface. The optional shouldCreateWithMips flag is a hint
      *  that this surface may be snapped to an SkImage which will be used with mip maps so we should
diff --git a/include/gpu/GrBackendSurface.h b/include/gpu/GrBackendSurface.h
index 9f77155..f2381c2 100644
--- a/include/gpu/GrBackendSurface.h
+++ b/include/gpu/GrBackendSurface.h
@@ -83,12 +83,10 @@
 
 private:
     // Friending for access to the GrPixelConfig
+    friend class SkImage;
     friend class SkSurface;
-    friend class GrCaps;
     friend class GrGpu;
-    friend class GrGLCaps;
     friend class GrGLGpu;
-    friend class GrVkCaps;
     friend class GrVkGpu;
     GrPixelConfig config() const { return fConfig; }
 
@@ -112,6 +110,8 @@
     // Creates an invalid backend texture.
     GrBackendRenderTarget() : fConfig(kUnknown_GrPixelConfig) {}
 
+    // GrGLTextureInfo::fFormat is ignored
+    // Deprecated: Should use version that does not take a GrPixelConfig instead
     GrBackendRenderTarget(int width,
                           int height,
                           int sampleCnt,
@@ -119,6 +119,13 @@
                           GrPixelConfig config,
                           const GrGLFramebufferInfo& glInfo);
 
+    // The GrGLTextureInfo must have a valid fFormat.
+    GrBackendRenderTarget(int width,
+                          int height,
+                          int sampleCnt,
+                          int stencilBits,
+                          const GrGLFramebufferInfo& glInfo);
+
 #ifdef SK_VULKAN
     GrBackendRenderTarget(int width,
                           int height,
@@ -149,11 +156,10 @@
 private:
     // Friending for access to the GrPixelConfig
     friend class SkSurface;
-    friend class GrCaps;
+    friend class SkSurface_Gpu;
+    friend class SkImage_Gpu;
     friend class GrGpu;
-    friend class GrGLCaps;
     friend class GrGLGpu;
-    friend class GrVkCaps;
     friend class GrVkGpu;
     GrPixelConfig config() const { return fConfig; }
 
diff --git a/include/gpu/GrCaps.h b/include/gpu/GrCaps.h
index 59e0528..0d5b340 100644
--- a/include/gpu/GrCaps.h
+++ b/include/gpu/GrCaps.h
@@ -15,6 +15,7 @@
 #include "SkRefCnt.h"
 #include "SkString.h"
 
+class GrBackendRenderTarget;
 class GrBackendTexture;
 struct GrContextOptions;
 class GrRenderTargetProxy;
@@ -174,10 +175,13 @@
 
     /**
      * Returns true if the GrBackendTexutre can we used with the supplied SkColorType. If it is
-     * compatible, the GrPixelConfig on the GrBackendTexture will be set to a config that matches
-     * the backend format and requested SkColorType.
+     * compatible, the passed in GrPixelConfig will be set to a config that matches the backend
+     * format and requested SkColorType.
      */
-    bool validateBackendTexture(GrBackendTexture* tex, SkColorType ct) const;
+    virtual bool validateBackendTexture(const GrBackendTexture& tex, SkColorType ct,
+                                        GrPixelConfig*) const = 0;
+    virtual bool validateBackendRenderTarget(const GrBackendRenderTarget&, SkColorType,
+                                             GrPixelConfig*) const = 0;
 
 protected:
     /** Subclasses must call this at the end of their constructors in order to apply caps
@@ -238,7 +242,6 @@
     int fMaxClipAnalyticFPs;
 
 private:
-    virtual bool onValidateBackendTexture(GrBackendTexture* tex, SkColorType ct) const = 0;
     virtual void onApplyOptionsOverrides(const GrContextOptions&) {}
     virtual void onDumpJSON(SkJSONWriter*) const {}
 
diff --git a/include/gpu/gl/GrGLTypes.h b/include/gpu/gl/GrGLTypes.h
index 24e50d8..aecba3c 100644
--- a/include/gpu/gl/GrGLTypes.h
+++ b/include/gpu/gl/GrGLTypes.h
@@ -119,6 +119,7 @@
 
 struct GrGLFramebufferInfo {
     GrGLuint fFBOID;
+    GrGLenum fFormat = 0;
 };
 
 GR_STATIC_ASSERT(sizeof(GrBackendObject) >= sizeof(const GrGLFramebufferInfo*));
diff --git a/src/gpu/GrBackendSurface.cpp b/src/gpu/GrBackendSurface.cpp
index a9fd57f..406cb22 100644
--- a/src/gpu/GrBackendSurface.cpp
+++ b/src/gpu/GrBackendSurface.cpp
@@ -127,6 +127,19 @@
         , fBackend(kOpenGL_GrBackend)
         , fGLInfo(glInfo) {}
 
+GrBackendRenderTarget::GrBackendRenderTarget(int width,
+                                             int height,
+                                             int sampleCnt,
+                                             int stencilBits,
+                                             const GrGLFramebufferInfo& glInfo)
+        : fWidth(width)
+        , fHeight(height)
+        , fSampleCnt(sampleCnt)
+        , fStencilBits(stencilBits)
+        , fConfig(GrGLSizedFormatToPixelConfig(glInfo.fFormat))
+        , fBackend(kOpenGL_GrBackend)
+        , fGLInfo(glInfo) {}
+
 #ifdef SK_VULKAN
 const GrVkImageInfo* GrBackendRenderTarget::getVkImageInfo() const {
     if (kVulkan_GrBackend == fBackend) {
diff --git a/src/gpu/GrCaps.cpp b/src/gpu/GrCaps.cpp
index 598cb0a..da32ebf 100644
--- a/src/gpu/GrCaps.cpp
+++ b/src/gpu/GrCaps.cpp
@@ -218,11 +218,3 @@
     writer->endObject();
 }
 
-bool GrCaps::validateBackendTexture(GrBackendTexture* tex, SkColorType ct) const {
-    if (!this->onValidateBackendTexture(tex, ct)) {
-        return false;
-    }
-    return this->isConfigTexturable(tex->fConfig);
-}
-
-
diff --git a/src/gpu/gl/GrGLCaps.cpp b/src/gpu/gl/GrGLCaps.cpp
index 86c8f92..60ecfd2 100644
--- a/src/gpu/gl/GrGLCaps.cpp
+++ b/src/gpu/gl/GrGLCaps.cpp
@@ -2361,62 +2361,82 @@
     return fConfigTable[config].fColorSampleCounts[count-1];
 }
 
-bool GrGLCaps::onValidateBackendTexture(GrBackendTexture* tex, SkColorType ct) const {
-    const GrGLTextureInfo* texInfo = tex->getGLTextureInfo();
-    if (!texInfo) {
-        return false;
-    }
-    GrGLenum format = texInfo->fFormat;
-    tex->fConfig = kUnknown_GrPixelConfig;
+bool validate_sized_format(GrGLenum format, SkColorType ct, GrPixelConfig* config,
+                           GrGLStandard standard) {
+    *config = kUnknown_GrPixelConfig;
 
     switch (ct) {
         case kUnknown_SkColorType:
             return false;
         case kAlpha_8_SkColorType:
             if (GR_GL_ALPHA8 == format) {
-                tex->fConfig = kAlpha_8_as_Alpha_GrPixelConfig;
+                *config = kAlpha_8_as_Alpha_GrPixelConfig;
             } else if (GR_GL_R8 == format) {
-                tex->fConfig = kAlpha_8_as_Red_GrPixelConfig;
+                *config = kAlpha_8_as_Red_GrPixelConfig;
             }
             break;
         case kRGB_565_SkColorType:
             if (GR_GL_RGB565 == format) {
-                tex->fConfig = kRGB_565_GrPixelConfig;
+                *config = kRGB_565_GrPixelConfig;
             }
             break;
         case kARGB_4444_SkColorType:
             if (GR_GL_RGBA4 == format) {
-                tex->fConfig = kRGBA_4444_GrPixelConfig;
+                *config = kRGBA_4444_GrPixelConfig;
             }
             break;
         case kRGBA_8888_SkColorType:
             if (GR_GL_RGBA8 == format) {
-                tex->fConfig = kRGBA_8888_GrPixelConfig;
+                *config = kRGBA_8888_GrPixelConfig;
             } else if (GR_GL_SRGB8_ALPHA8 == format) {
-                tex->fConfig = kSRGBA_8888_GrPixelConfig;
+                *config = kSRGBA_8888_GrPixelConfig;
             }
             break;
         case kBGRA_8888_SkColorType:
-            if (GR_GL_BGRA8 == format) {
-                tex->fConfig = kBGRA_8888_GrPixelConfig;
+            if (GR_GL_RGBA8 == format) {
+                if (kGL_GrGLStandard == standard) {
+                    *config = kBGRA_8888_GrPixelConfig;
+                }
+            } else if (GR_GL_BGRA8 == format) {
+                if (kGLES_GrGLStandard == standard) {
+                    *config = kBGRA_8888_GrPixelConfig;
+                }
             } else if (GR_GL_SRGB8_ALPHA8 == format) {
-                tex->fConfig = kSBGRA_8888_GrPixelConfig;
+                *config = kSBGRA_8888_GrPixelConfig;
             }
             break;
         case kGray_8_SkColorType:
             if (GR_GL_LUMINANCE8 == format) {
-                tex->fConfig = kGray_8_as_Lum_GrPixelConfig;
+                *config = kGray_8_as_Lum_GrPixelConfig;
             } else if (GR_GL_R8 == format) {
-                tex->fConfig = kGray_8_as_Red_GrPixelConfig;
+                *config = kGray_8_as_Red_GrPixelConfig;
             }
             break;
         case kRGBA_F16_SkColorType:
             if (GR_GL_RGBA16F == format) {
-                tex->fConfig = kRGBA_half_GrPixelConfig;
+                *config = kRGBA_half_GrPixelConfig;
             }
             break;
     }
 
-    return kUnknown_GrPixelConfig != tex->fConfig;
+    return kUnknown_GrPixelConfig != *config;
+}
+
+bool GrGLCaps::validateBackendTexture(const GrBackendTexture& tex, SkColorType ct,
+                                      GrPixelConfig* config) const {
+    const GrGLTextureInfo* texInfo = tex.getGLTextureInfo();
+    if (!texInfo) {
+        return false;
+    }
+    return validate_sized_format(texInfo->fFormat, ct, config, fStandard);
+}
+
+bool GrGLCaps::validateBackendRenderTarget(const GrBackendRenderTarget& rt, SkColorType ct,
+                                           GrPixelConfig* config) const {
+    const GrGLFramebufferInfo* fbInfo = rt.getGLFramebufferInfo();
+    if (!fbInfo) {
+        return false;
+    }
+    return validate_sized_format(fbInfo->fFormat, ct, config, fStandard);
 }
 
diff --git a/src/gpu/gl/GrGLCaps.h b/src/gpu/gl/GrGLCaps.h
index 38cbfe8..6efcc21 100644
--- a/src/gpu/gl/GrGLCaps.h
+++ b/src/gpu/gl/GrGLCaps.h
@@ -415,9 +415,12 @@
         return fProgramBinarySupport;
     }
 
-private:
-    bool onValidateBackendTexture(GrBackendTexture*, SkColorType) const override;
+    bool validateBackendTexture(const GrBackendTexture&, SkColorType,
+                                GrPixelConfig*) const override;
+    bool validateBackendRenderTarget(const GrBackendRenderTarget&, SkColorType,
+                                     GrPixelConfig*) const override;
 
+private:
     enum ExternalFormatUsage {
         kTexImage_ExternalFormatUsage,
         kOther_ExternalFormatUsage,
diff --git a/src/gpu/gl/GrGLRenderTarget.cpp b/src/gpu/gl/GrGLRenderTarget.cpp
index 3aa632c..443128d 100644
--- a/src/gpu/gl/GrGLRenderTarget.cpp
+++ b/src/gpu/gl/GrGLRenderTarget.cpp
@@ -82,6 +82,15 @@
     return sk_sp<GrGLRenderTarget>(new GrGLRenderTarget(gpu, desc, idDesc, sb));
 }
 
+GrBackendRenderTarget GrGLRenderTarget::getBackendRenderTarget() const {
+    GrGLFramebufferInfo fbi;
+    fbi.fFBOID = fRTFBOID;
+    fbi.fFormat = this->getGLGpu()->glCaps().configSizedInternalFormat(this->config());
+
+    return GrBackendRenderTarget(this->width(), this->height(), this->numColorSamples(),
+                                 this->numStencilSamples(), fbi);
+}
+
 size_t GrGLRenderTarget::onGpuMemorySize() const {
     return GrSurface::ComputeSize(this->config(), this->width(), this->height(),
                                   fNumSamplesOwnedPerPixel, GrMipMapped::kNo);
diff --git a/src/gpu/gl/GrGLRenderTarget.h b/src/gpu/gl/GrGLRenderTarget.h
index 28c6e3d..a448848 100644
--- a/src/gpu/gl/GrGLRenderTarget.h
+++ b/src/gpu/gl/GrGLRenderTarget.h
@@ -63,13 +63,7 @@
 
     GrBackendObject getRenderTargetHandle() const override { return fRTFBOID; }
 
-    GrBackendRenderTarget getBackendRenderTarget() const override {
-        GrGLFramebufferInfo fbi;
-        fbi.fFBOID = fRTFBOID;
-
-        return GrBackendRenderTarget(this->width(), this->height(), this->numColorSamples(),
-                                     this->numStencilSamples(), this->config(), fbi);
-    }
+    GrBackendRenderTarget getBackendRenderTarget() const override;
 
     bool canAttemptStencilAttachment() const override;
 
diff --git a/src/gpu/gl/GrGLTexture.cpp b/src/gpu/gl/GrGLTexture.cpp
index 597c213..9c7fe22 100644
--- a/src/gpu/gl/GrGLTexture.cpp
+++ b/src/gpu/gl/GrGLTexture.cpp
@@ -107,8 +107,7 @@
 }
 
 GrBackendTexture GrGLTexture::getBackendTexture() const {
-    return GrBackendTexture(this->width(), this->height(), this->config(),
-                            this->texturePriv().mipMapped(), fInfo);
+    return GrBackendTexture(this->width(), this->height(), this->texturePriv().mipMapped(), fInfo);
 }
 
 void GrGLTexture::setMemoryBacking(SkTraceMemoryDump* traceMemoryDump,
diff --git a/src/gpu/mock/GrMockCaps.h b/src/gpu/mock/GrMockCaps.h
index 37bde82..edec556 100644
--- a/src/gpu/mock/GrMockCaps.h
+++ b/src/gpu/mock/GrMockCaps.h
@@ -51,11 +51,17 @@
         return false;
     }
 
-private:
-    bool onValidateBackendTexture(GrBackendTexture* tex, SkColorType ct) const override {
-        return SkToBool(tex->getMockTextureInfo());
+    bool validateBackendTexture(const GrBackendTexture& tex, SkColorType,
+                                GrPixelConfig*) const override {
+        return SkToBool(tex.getMockTextureInfo());
     }
 
+    bool validateBackendRenderTarget(const GrBackendRenderTarget& rt, SkColorType,
+                                     GrPixelConfig*) const override {
+        return false;
+    }
+
+private:
     GrMockOptions fOptions;
     typedef GrCaps INHERITED;
 };
diff --git a/src/gpu/mtl/GrMtlCaps.h b/src/gpu/mtl/GrMtlCaps.h
index bc8aac9..70ff74f 100644
--- a/src/gpu/mtl/GrMtlCaps.h
+++ b/src/gpu/mtl/GrMtlCaps.h
@@ -56,11 +56,16 @@
         return false;
     }
 
-private:
-    bool onValidateBackendTexture(GrBackendTexture* tex, SkColorType ct) const override {
+    bool validateBackendTexture(const GrBackendTexture&, SkColorType,
+                                GrPixelConfig*) const override {
+        return false;
+    }
+    bool validateBackendRenderTarget(const GrBackendRenderTarget&, SkColorType,
+                                     GrPixelConfig*) const override {
         return false;
     }
 
+private:
     void initFeatureSet(MTLFeatureSet featureSet);
 
     void initGrCaps(const id<MTLDevice> device);
diff --git a/src/gpu/vk/GrVkCaps.cpp b/src/gpu/vk/GrVkCaps.cpp
index e6a018b..40cb38f 100644
--- a/src/gpu/vk/GrVkCaps.cpp
+++ b/src/gpu/vk/GrVkCaps.cpp
@@ -415,59 +415,67 @@
     return fConfigTable[config].fColorSampleCounts[count-1];
 }
 
-bool GrVkCaps::onValidateBackendTexture(GrBackendTexture* tex, SkColorType ct) const {
-    const GrVkImageInfo* imageInfo = tex->getVkImageInfo();
+bool validate_image_info(const GrVkImageInfo* imageInfo, SkColorType ct, GrPixelConfig* config) {
     if (!imageInfo) {
         return false;
     }
     VkFormat format = imageInfo->fFormat;
-    tex->fConfig = kUnknown_GrPixelConfig;
+    *config = kUnknown_GrPixelConfig;
 
     switch (ct) {
         case kUnknown_SkColorType:
             return false;
         case kAlpha_8_SkColorType:
             if (VK_FORMAT_R8_UNORM == format) {
-                tex->fConfig = kAlpha_8_as_Red_GrPixelConfig;
+                *config = kAlpha_8_as_Red_GrPixelConfig;
             }
             break;
         case kRGB_565_SkColorType:
             if (VK_FORMAT_R5G6B5_UNORM_PACK16 == format) {
-                tex->fConfig = kRGB_565_GrPixelConfig;
+                *config = kRGB_565_GrPixelConfig;
             }
             break;
         case kARGB_4444_SkColorType:
             if (VK_FORMAT_B4G4R4A4_UNORM_PACK16 == format) {
-                tex->fConfig = kRGBA_4444_GrPixelConfig;
+                *config = kRGBA_4444_GrPixelConfig;
             }
             break;
         case kRGBA_8888_SkColorType:
             if (VK_FORMAT_R8G8B8A8_UNORM == format) {
-                tex->fConfig = kRGBA_8888_GrPixelConfig;
+                *config = kRGBA_8888_GrPixelConfig;
             } else if (VK_FORMAT_R8G8B8A8_SRGB == format) {
-                tex->fConfig = kSRGBA_8888_GrPixelConfig;
+                *config = kSRGBA_8888_GrPixelConfig;
             }
             break;
         case kBGRA_8888_SkColorType:
             if (VK_FORMAT_B8G8R8A8_UNORM == format) {
-                tex->fConfig = kBGRA_8888_GrPixelConfig;
+                *config = kBGRA_8888_GrPixelConfig;
             } else if (VK_FORMAT_B8G8R8A8_SRGB == format) {
-                tex->fConfig = kSBGRA_8888_GrPixelConfig;
+                *config = kSBGRA_8888_GrPixelConfig;
             }
             break;
         case kGray_8_SkColorType:
             if (VK_FORMAT_R8_UNORM == format) {
-                tex->fConfig = kGray_8_as_Red_GrPixelConfig;
+                *config = kGray_8_as_Red_GrPixelConfig;
             }
             break;
         case kRGBA_F16_SkColorType:
             if (VK_FORMAT_R16G16B16A16_SFLOAT == format) {
-                tex->fConfig = kRGBA_half_GrPixelConfig;
+                *config = kRGBA_half_GrPixelConfig;
             }
             break;
     }
 
-    return kUnknown_GrPixelConfig != tex->fConfig;
+    return kUnknown_GrPixelConfig != *config;
 }
 
+bool GrVkCaps::validateBackendTexture(const GrBackendTexture& tex, SkColorType ct,
+                                      GrPixelConfig* config) const {
+    return validate_image_info(tex.getVkImageInfo(), ct, config);
+}
+
+bool GrVkCaps::validateBackendRenderTarget(const GrBackendRenderTarget& rt, SkColorType ct,
+                                           GrPixelConfig* config) const {
+    return validate_image_info(rt.getVkImageInfo(), ct, config);
+}
 
diff --git a/src/gpu/vk/GrVkCaps.h b/src/gpu/vk/GrVkCaps.h
index 8d0ab5d..ad0faf1 100644
--- a/src/gpu/vk/GrVkCaps.h
+++ b/src/gpu/vk/GrVkCaps.h
@@ -111,9 +111,12 @@
     bool initDescForDstCopy(const GrRenderTargetProxy* src, GrSurfaceDesc* desc,
                             bool* rectsMustMatch, bool* disallowSubrect) const override;
 
-private:
-    bool onValidateBackendTexture(GrBackendTexture*, SkColorType) const override;
+    bool validateBackendTexture(const GrBackendTexture&, SkColorType,
+                                GrPixelConfig*) const override;
+    bool validateBackendRenderTarget(const GrBackendRenderTarget&, SkColorType,
+                                     GrPixelConfig*) const override;
 
+private:
     enum VkVendor {
         kAMD_VkVendor = 4098,
         kImagination_VkVendor = 4112,
diff --git a/src/image/SkImage_Gpu.cpp b/src/image/SkImage_Gpu.cpp
index bf80ac0..9d2b949 100644
--- a/src/image/SkImage_Gpu.cpp
+++ b/src/image/SkImage_Gpu.cpp
@@ -297,11 +297,14 @@
                                         const GrBackendTexture& tex, GrSurfaceOrigin origin,
                                         SkAlphaType at, sk_sp<SkColorSpace> cs,
                                         TextureReleaseProc releaseP, ReleaseContext releaseC) {
+    if (!ctx) {
+        return nullptr;
+    }
     return new_wrapped_texture_common(ctx, tex, origin, at, std::move(cs), kBorrow_GrWrapOwnership,
                                       releaseP, releaseC);
 }
 
-bool validate_backend_texture(GrContext* ctx, GrBackendTexture* tex,
+bool validate_backend_texture(GrContext* ctx, const GrBackendTexture& tex, GrPixelConfig* config,
                               SkColorType ct, SkAlphaType at, sk_sp<SkColorSpace> cs) {
     // TODO: Create a SkImageColorInfo struct for color, alpha, and color space so we don't need to
     // create a fake image info here.
@@ -310,15 +313,18 @@
         return false;
     }
 
-    return ctx->caps()->validateBackendTexture(tex, ct);
+    return ctx->caps()->validateBackendTexture(tex, ct, config);
 }
 
 sk_sp<SkImage> SkImage::MakeFromTexture(GrContext* ctx,
                                         const GrBackendTexture& tex, GrSurfaceOrigin origin,
                                         SkColorType ct, SkAlphaType at, sk_sp<SkColorSpace> cs,
                                         TextureReleaseProc releaseP, ReleaseContext releaseC) {
+    if (!ctx) {
+        return nullptr;
+    }
     GrBackendTexture texCopy = tex;
-    if (!validate_backend_texture(ctx, &texCopy, ct, at, cs)) {
+    if (!validate_backend_texture(ctx, texCopy, &texCopy.fConfig, ct, at, cs)) {
         return nullptr;
     }
     return MakeFromTexture(ctx, texCopy, origin, at, cs, releaseP, releaseC);
@@ -336,7 +342,7 @@
                                                SkColorType ct, SkAlphaType at,
                                                sk_sp<SkColorSpace> cs) {
     GrBackendTexture texCopy = tex;
-    if (!validate_backend_texture(ctx, &texCopy, ct, at, cs)) {
+    if (!validate_backend_texture(ctx, texCopy, &texCopy.fConfig, ct, at, cs)) {
         return nullptr;
     }
     return MakeFromAdoptedTexture(ctx, texCopy, origin, at, cs);
diff --git a/src/image/SkSurface.cpp b/src/image/SkSurface.cpp
index 9cef76f..0a684cc 100644
--- a/src/image/SkSurface.cpp
+++ b/src/image/SkSurface.cpp
@@ -258,6 +258,13 @@
     return nullptr;
 }
 
+sk_sp<SkSurface> SkSurface::MakeFromBackendTexture(GrContext*, const GrBackendTexture&,
+                                                   GrSurfaceOrigin origin, int sampleCnt,
+                                                   SkColorType, sk_sp<SkColorSpace>,
+                                                   const SkSurfaceProps*) {
+    return nullptr;
+}
+
 sk_sp<SkSurface> SkSurface::MakeFromBackendRenderTarget(GrContext*,
                                                         const GrBackendRenderTarget&,
                                                         GrSurfaceOrigin origin,
@@ -266,6 +273,15 @@
     return nullptr;
 }
 
+sk_sp<SkSurface> SkSurface::MakeFromBackendRenderTarget(GrContext*,
+                                                        const GrBackendRenderTarget&,
+                                                        GrSurfaceOrigin origin,
+                                                        SkColorType,
+                                                        sk_sp<SkColorSpace>,
+                                                        const SkSurfaceProps*) {
+    return nullptr;
+}
+
 sk_sp<SkSurface> SkSurface::MakeFromBackendTextureAsRenderTarget(GrContext*,
                                                                  const GrBackendTexture&,
                                                                  GrSurfaceOrigin origin,
@@ -275,4 +291,14 @@
     return nullptr;
 }
 
+sk_sp<SkSurface> SkSurface::MakeFromBackendTextureAsRenderTarget(GrContext*,
+                                                                 const GrBackendTexture&,
+                                                                 GrSurfaceOrigin origin,
+                                                                 int sampleCnt,
+                                                                 SkColorType,
+                                                                 sk_sp<SkColorSpace>,
+                                                                 const SkSurfaceProps*) {
+    return nullptr;
+}
+
 #endif
diff --git a/src/image/SkSurface_Gpu.cpp b/src/image/SkSurface_Gpu.cpp
index fc66e43..2bc782b 100644
--- a/src/image/SkSurface_Gpu.cpp
+++ b/src/image/SkSurface_Gpu.cpp
@@ -294,6 +294,52 @@
     return sk_make_sp<SkSurface_Gpu>(std::move(device));
 }
 
+bool validate_backend_texture(GrContext* ctx, const GrBackendTexture& tex, GrPixelConfig* config,
+                              int sampleCnt, SkColorType ct, sk_sp<SkColorSpace> cs,
+                              bool texturable) {
+    // TODO: Create a SkImageColorInfo struct for color, alpha, and color space so we don't need to
+    // create a fake image info here.
+    SkImageInfo info = SkImageInfo::Make(1, 1, ct, kPremul_SkAlphaType, cs);
+
+    if (!SkSurface_Gpu::Valid(info)) {
+        return false;
+    }
+
+    if (!ctx->caps()->validateBackendTexture(tex, ct, config)) {
+        return false;
+    }
+
+    if (!ctx->caps()->isConfigRenderable(*config, sampleCnt > 0)) {
+        return false;
+    }
+
+    if (ctx->caps()->getSampleCount(sampleCnt, *config) != sampleCnt) {
+        return false;
+    }
+
+    if (texturable && !ctx->caps()->isConfigTexturable(*config)) {
+        return false;
+    }
+    return true;
+}
+
+sk_sp<SkSurface> SkSurface::MakeFromBackendTexture(GrContext* context, const GrBackendTexture& tex,
+                                                   GrSurfaceOrigin origin, int sampleCnt,
+                                                   SkColorType colorType,
+                                                   sk_sp<SkColorSpace> colorSpace,
+                                                   const SkSurfaceProps* props) {
+    if (!context) {
+        return nullptr;
+    }
+    GrBackendTexture texCopy = tex;
+    if (!validate_backend_texture(context, texCopy, &texCopy.fConfig,
+                                  sampleCnt, colorType, colorSpace, true)) {
+        return nullptr;
+    }
+
+    return MakeFromBackendTexture(context, texCopy, origin, sampleCnt, colorSpace, props);
+}
+
 sk_sp<SkSurface> SkSurface::MakeFromBackendRenderTarget(GrContext* context,
                                                         const GrBackendRenderTarget& backendRT,
                                                         GrSurfaceOrigin origin,
@@ -325,6 +371,44 @@
     return sk_make_sp<SkSurface_Gpu>(std::move(device));
 }
 
+bool validate_backend_render_target(GrContext* ctx, const GrBackendRenderTarget& rt,
+                                    GrPixelConfig* config, SkColorType ct, sk_sp<SkColorSpace> cs) {
+    // TODO: Create a SkImageColorInfo struct for color, alpha, and color space so we don't need to
+    // create a fake image info here.
+    SkImageInfo info = SkImageInfo::Make(1, 1, ct, kPremul_SkAlphaType, cs);
+
+    if (!SkSurface_Gpu::Valid(info)) {
+        return false;
+    }
+
+    if (!ctx->caps()->validateBackendRenderTarget(rt, ct, config)) {
+        return false;
+    }
+
+    if (!ctx->caps()->isConfigRenderable(*config, false)) {
+        return false;
+    }
+
+    return true;
+}
+
+sk_sp<SkSurface> SkSurface::MakeFromBackendRenderTarget(GrContext* context,
+                                                        const GrBackendRenderTarget& rt,
+                                                        GrSurfaceOrigin origin,
+                                                        SkColorType colorType,
+                                                        sk_sp<SkColorSpace> colorSpace,
+                                                        const SkSurfaceProps* props) {
+    if (!context) {
+        return nullptr;
+    }
+    GrBackendRenderTarget rtCopy = rt;
+    if (!validate_backend_render_target(context, rtCopy, &rtCopy.fConfig, colorType, colorSpace)) {
+        return nullptr;
+    }
+
+    return MakeFromBackendRenderTarget(context, rtCopy, origin, colorSpace, props);
+}
+
 sk_sp<SkSurface> SkSurface::MakeFromBackendTextureAsRenderTarget(GrContext* context,
                                                                  const GrBackendTexture& tex,
                                                                  GrSurfaceOrigin origin,
@@ -357,4 +441,24 @@
     return sk_make_sp<SkSurface_Gpu>(std::move(device));
 }
 
+sk_sp<SkSurface> SkSurface::MakeFromBackendTextureAsRenderTarget(GrContext* context,
+                                                                 const GrBackendTexture& tex,
+                                                                 GrSurfaceOrigin origin,
+                                                                 int sampleCnt,
+                                                                 SkColorType colorType,
+                                                                 sk_sp<SkColorSpace> colorSpace,
+                                                                 const SkSurfaceProps* props) {
+    if (!context) {
+        return nullptr;
+    }
+    GrBackendTexture texCopy = tex;
+    if (!validate_backend_texture(context, texCopy, &texCopy.fConfig,
+                                  sampleCnt, colorType, colorSpace, false)) {
+        return nullptr;
+    }
+
+    return MakeFromBackendTextureAsRenderTarget(context, texCopy, origin, sampleCnt, colorSpace,
+                                                props);
+}
+
 #endif
diff --git a/tests/BlendTest.cpp b/tests/BlendTest.cpp
index 52f41dc..bf985aa 100644
--- a/tests/BlendTest.cpp
+++ b/tests/BlendTest.cpp
@@ -84,8 +84,8 @@
 #if SK_SUPPORT_GPU
 namespace {
 static sk_sp<SkSurface> create_gpu_surface_backend_texture_as_render_target(
-        GrContext* context, int sampleCnt, int width, int height, GrPixelConfig config,
-        GrSurfaceOrigin origin,
+        GrContext* context, int sampleCnt, int width, int height, SkColorType colorType,
+        GrPixelConfig config, GrSurfaceOrigin origin,
         sk_sp<GrTexture>* backingSurface) {
     GrSurfaceDesc backingDesc;
     backingDesc.fFlags = kRenderTarget_GrSurfaceFlag;
@@ -104,7 +104,7 @@
 
     sk_sp<SkSurface> surface =
             SkSurface::MakeFromBackendTextureAsRenderTarget(context, backendTex, origin,
-                                                            sampleCnt, nullptr, nullptr);
+                                                            sampleCnt, colorType, nullptr, nullptr);
 
     return surface;
 }
@@ -158,7 +158,7 @@
         sk_sp<GrTexture> backingSurface;
         // BGRA forces a framebuffer blit on ES2.
         sk_sp<SkSurface> surface = create_gpu_surface_backend_texture_as_render_target(
-                context, sampleCnt, kWidth, kHeight, kConfig, origin, &backingSurface);
+                context, sampleCnt, kWidth, kHeight, kColorType, kConfig, origin, &backingSurface);
 
         if (!surface && sampleCnt > 0) {
             // Some platforms don't support MSAA.
diff --git a/tests/GrMipMappedTest.cpp b/tests/GrMipMappedTest.cpp
index 91fba5f..0ff0d2c 100644
--- a/tests/GrMipMappedTest.cpp
+++ b/tests/GrMipMappedTest.cpp
@@ -53,6 +53,7 @@
                                                                            backendTex,
                                                                            kTopLeft_GrSurfaceOrigin,
                                                                            0,
+                                                                           kRGBA_8888_SkColorType,
                                                                            nullptr,
                                                                            nullptr);
 
@@ -221,6 +222,7 @@
                                                             backendTex,
                                                             kTopLeft_GrSurfaceOrigin,
                                                             0,
+                                                            kRGBA_8888_SkColorType,
                                                             nullptr,
                                                             nullptr);
             } else {
diff --git a/tests/SurfaceTest.cpp b/tests/SurfaceTest.cpp
index 4b58664..0864e32 100644
--- a/tests/SurfaceTest.cpp
+++ b/tests/SurfaceTest.cpp
@@ -598,6 +598,7 @@
 
     sk_sp<SkSurface> surface = SkSurface::MakeFromBackendTexture(context, *outTexture,
                                                                  kTopLeft_GrSurfaceOrigin, sampleCnt,
+                                                                 kRGBA_8888_SkColorType,
                                                                  nullptr, nullptr);
     if (!surface) {
         context->getGpu()->deleteTestingOnlyBackendTexture(outTexture);
@@ -621,7 +622,8 @@
     }
 
     sk_sp<SkSurface> surface = SkSurface::MakeFromBackendTextureAsRenderTarget(
-            context, *outTexture, kTopLeft_GrSurfaceOrigin, sampleCnt, nullptr, nullptr);
+            context, *outTexture, kTopLeft_GrSurfaceOrigin, sampleCnt, kRGBA_8888_SkColorType,
+            nullptr, nullptr);
 
     if (!surface) {
         context->getGpu()->deleteTestingOnlyBackendTexture(outTexture);
@@ -894,6 +896,7 @@
 
         return SkSurface::MakeFromBackendTexture(context, backendTex,
                                                  kTopLeft_GrSurfaceOrigin, 0,
+                                                 info.colorType(),
                                                  sk_ref_sp(info.colorSpace()), nullptr);
     };
 
diff --git a/tests/WritePixelsTest.cpp b/tests/WritePixelsTest.cpp
index bfa0d4d..f909190 100644
--- a/tests/WritePixelsTest.cpp
+++ b/tests/WritePixelsTest.cpp
@@ -430,8 +430,14 @@
         for (int sampleCnt : {0, 4}) {
             GrBackendTexture backendTex = context->getGpu()->createTestingOnlyBackendTexture(
                     nullptr, DEV_W, DEV_H, kSkia8888_GrPixelConfig, true, GrMipMapped::kNo);
+            SkColorType colorType;
+            if (kRGBA_8888_GrPixelConfig == kSkia8888_GrPixelConfig) {
+                colorType = kRGBA_8888_SkColorType;
+            } else {
+                colorType = kBGRA_8888_SkColorType;
+            }
             sk_sp<SkSurface> surface(SkSurface::MakeFromBackendTextureAsRenderTarget(
-                    context, backendTex, origin, sampleCnt, nullptr, nullptr));
+                    context, backendTex, origin, sampleCnt, colorType, nullptr, nullptr));
             if (!surface) {
                 context->getGpu()->deleteTestingOnlyBackendTexture(&backendTex);
                 continue;
diff --git a/tools/fiddle/draw.cpp b/tools/fiddle/draw.cpp
index 05866e3..bbc463c 100644
--- a/tools/fiddle/draw.cpp
+++ b/tools/fiddle/draw.cpp
@@ -33,6 +33,7 @@
         sk_sp<SkImage> tmp = SkImage::MakeFromTexture(context,
                                                       backEndTexture,
                                                       kTopLeft_GrSurfaceOrigin,
+                                                      kRGBA_8888_SkColorType,
                                                       kOpaque_SkAlphaType,
                                                       nullptr);
 
@@ -40,13 +41,14 @@
         sk_sp<SkSurface> tmp2 = SkSurface::MakeFromBackendTexture(context,
                                                                   backEndTextureRenderTarget,
                                                                   kTopLeft_GrSurfaceOrigin,
-                                                                  0, nullptr, nullptr);
+                                                                  0, kRGBA_8888_SkColorType,
+                                                                  nullptr, nullptr);
 
         // Note: this surface should only be renderable (i.e., not textureable)
         sk_sp<SkSurface> tmp3 = SkSurface::MakeFromBackendRenderTarget(context,
                                                                        backEndRenderTarget,
                                                                        kTopLeft_GrSurfaceOrigin,
+                                                                       kRGBA_8888_SkColorType,
                                                                        nullptr, nullptr);
     }
-
 }
diff --git a/tools/fiddle/fiddle_main.cpp b/tools/fiddle/fiddle_main.cpp
index 4c7a087..b22ec55 100644
--- a/tools/fiddle/fiddle_main.cpp
+++ b/tools/fiddle/fiddle_main.cpp
@@ -129,6 +129,7 @@
     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
     backingDesc.fConfig = kRGBA_8888_GrPixelConfig;
     backingDesc.fSampleCnt = 0;
 
diff --git a/tools/sk_app/GLWindowContext.cpp b/tools/sk_app/GLWindowContext.cpp
index d928a7b..9ef5141 100644
--- a/tools/sk_app/GLWindowContext.cpp
+++ b/tools/sk_app/GLWindowContext.cpp
@@ -39,15 +39,6 @@
         this->initializeContext();
         return;
     }
-
-    if (fContext) {
-        // We may not have real sRGB support (ANGLE, in particular), so check for
-        // that, and fall back to L32:
-        fPixelConfig = fContext->caps()->srgbSupport() && fDisplayParams.fColorSpace
-                       ? kSRGBA_8888_GrPixelConfig : kRGBA_8888_GrPixelConfig;
-    } else {
-        fPixelConfig = kUnknown_GrPixelConfig;
-    }
 }
 
 void GLWindowContext::destroyContext() {
@@ -72,16 +63,18 @@
             GR_GL_CALL(fBackendContext.get(), GetIntegerv(GR_GL_FRAMEBUFFER_BINDING,
                                                           &buffer));
             fbInfo.fFBOID = buffer;
+            fbInfo.fFormat = fContext->caps()->srgbSupport() && fDisplayParams.fColorSpace
+                             ? GR_GL_SRGB8_ALPHA8 : GR_GL_RGBA8;
 
             GrBackendRenderTarget backendRT(fWidth,
                                             fHeight,
                                             fSampleCount,
                                             fStencilBits,
-                                            fPixelConfig,
                                             fbInfo);
 
             fSurface = SkSurface::MakeFromBackendRenderTarget(fContext.get(), backendRT,
                                                               kBottomLeft_GrSurfaceOrigin,
+                                                              kRGBA_8888_SkColorType,
                                                               fDisplayParams.fColorSpace,
                                                               &fSurfaceProps);
         }
diff --git a/tools/sk_app/VulkanWindowContext.cpp b/tools/sk_app/VulkanWindowContext.cpp
index 711791d..6237ee0 100644
--- a/tools/sk_app/VulkanWindowContext.cpp
+++ b/tools/sk_app/VulkanWindowContext.cpp
@@ -201,6 +201,20 @@
         return false;
     }
 
+    SkColorType colorType;
+    switch (surfaceFormat) {
+        case VK_FORMAT_R8G8B8A8_UNORM: // fall through
+        case VK_FORMAT_R8G8B8A8_SRGB:
+            colorType = kRGBA_8888_SkColorType;
+            break;
+        case VK_FORMAT_B8G8R8A8_UNORM: // fall through
+        case VK_FORMAT_B8G8R8A8_SRGB:
+            colorType = kBGRA_8888_SkColorType;
+            break;
+        default:
+            return false;
+    }
+
     // If mailbox mode is available, use it, as it is the lowest-latency non-
     // tearing mode. If not, fall back to FIFO which is always available.
     VkPresentModeKHR mode = VK_PRESENT_MODE_FIFO_KHR;
@@ -254,15 +268,12 @@
         fDestroySwapchainKHR(fBackendContext->fDevice, swapchainCreateInfo.oldSwapchain, nullptr);
     }
 
-    this->createBuffers(swapchainCreateInfo.imageFormat);
+    this->createBuffers(swapchainCreateInfo.imageFormat, colorType);
 
     return true;
 }
 
-void VulkanWindowContext::createBuffers(VkFormat format) {
-    fPixelConfig = GrVkFormatToPixelConfig(format);
-    SkASSERT(kUnknown_GrPixelConfig != fPixelConfig);
-
+void VulkanWindowContext::createBuffers(VkFormat format, SkColorType colorType) {
     fGetSwapchainImagesKHR(fBackendContext->fDevice, fSwapchain, &fImageCount, nullptr);
     SkASSERT(fImageCount);
     fImages = new VkImage[fImageCount];
@@ -287,6 +298,7 @@
         fSurfaces[i] = SkSurface::MakeFromBackendTextureAsRenderTarget(fContext.get(), backendTex,
                                                                        kTopLeft_GrSurfaceOrigin,
                                                                        fSampleCount,
+                                                                       colorType,
                                                                        fDisplayParams.fColorSpace,
                                                                        &fSurfaceProps);
     }
diff --git a/tools/sk_app/VulkanWindowContext.h b/tools/sk_app/VulkanWindowContext.h
index d02b114..df6ef33 100644
--- a/tools/sk_app/VulkanWindowContext.h
+++ b/tools/sk_app/VulkanWindowContext.h
@@ -64,7 +64,7 @@
 
     BackbufferInfo* getAvailableBackbuffer();
     bool createSwapchain(int width, int height, const DisplayParams& params);
-    void createBuffers(VkFormat format);
+    void createBuffers(VkFormat format, SkColorType colorType);
     void destroyBuffers();
 
     sk_sp<const GrVkBackendContext> fBackendContext;
diff --git a/tools/sk_app/WindowContext.h b/tools/sk_app/WindowContext.h
index cd4c357..5e7d76d 100644
--- a/tools/sk_app/WindowContext.h
+++ b/tools/sk_app/WindowContext.h
@@ -61,7 +61,6 @@
     int               fWidth;
     int               fHeight;
     DisplayParams     fDisplayParams;
-    GrPixelConfig     fPixelConfig;
     SkSurfaceProps    fSurfaceProps;
 
     // parameters obtained from the native window