Add backend safe classes for passing in external texture and render targets into gpu

This CL adds the GrBackend* classes as well as just updates the API for SkSurface and
SkImage. The implementation on SkSurface/Image and the plumbing down into Ganesh will
be in an additional CL.

Besides the change to use the type safe classes, we also pull the SurfaceFlags, origin,
samples, out of the descriptor and pass those in directly.

Bug: skia:
Change-Id: I9702981fe26c3d5d7d2cbcf6977ba569d356d854
Reviewed-on: https://skia-review.googlesource.com/13122
Commit-Queue: Greg Daniel <egdaniel@google.com>
Reviewed-by: Brian Salomon <bsalomon@google.com>
diff --git a/gn/gpu.gni b/gn/gpu.gni
index bf90837..84b9456 100644
--- a/gn/gpu.gni
+++ b/gn/gpu.gni
@@ -8,6 +8,7 @@
 _include = get_path_info("../include", "abspath")
 
 skia_gpu_sources = [
+  "$_include/gpu/GrBackendSurface.h",
   "$_include/gpu/GrBlend.h",
   "$_include/gpu/GrBuffer.h",
   "$_include/gpu/GrCaps.h",
@@ -63,6 +64,7 @@
   "$_src/gpu/GrAuditTrail.cpp",
   "$_src/gpu/GrAutoLocaleSetter.h",
   "$_src/gpu/GrAllocator.h",
+  "$_src/gpu/GrBackendSurface.cpp",
   "$_src/gpu/GrBitmapTextureMaker.cpp",
   "$_src/gpu/GrBitmapTextureMaker.h",
   "$_src/gpu/GrBlend.cpp",
diff --git a/include/core/SkImage.h b/include/core/SkImage.h
index ace4fe7..c52ad3d 100644
--- a/include/core/SkImage.h
+++ b/include/core/SkImage.h
@@ -25,6 +25,7 @@
 class SkPixelSerializer;
 class SkString;
 class SkSurface;
+class GrBackendTexture;
 class GrContext;
 class GrContextThreadSafeProxy;
 class GrTexture;
@@ -67,7 +68,7 @@
      *  its pixel memory is shareable, it may be shared instead of copied.
      */
     static sk_sp<SkImage> MakeFromBitmap(const SkBitmap&);
-    
+
     /**
      *  Construct a new SkImage based on the given ImageGenerator. Returns NULL on error.
      *  This function will always take ownership of the passed generator.
@@ -90,6 +91,9 @@
      *  managing the lifetime of the underlying platform texture.
      *
      *  Will return NULL if the specified descriptor is unsupported.
+     *
+     *  It is preferred to use the new methods which take a GrBackendTexture instead of a
+     *  GrBackendTextureDesc. This method will eventually be removed.
      */
     static sk_sp<SkImage> MakeFromTexture(GrContext* ctx, const GrBackendTextureDesc& desc) {
         return MakeFromTexture(ctx, desc, kPremul_SkAlphaType, nullptr, nullptr, nullptr);
@@ -108,6 +112,9 @@
      *  no longer is holding a reference to it.
      *
      *  Will return NULL if the specified descriptor is unsupported.
+     *
+     *  It is preferred to use the new methods which take a GrBackendTexture instead of a
+     *  GrBackendTextureDesc. This method will eventually be removed.
      */
     static sk_sp<SkImage> MakeFromTexture(GrContext* ctx, const GrBackendTextureDesc& desc,
                                           SkAlphaType at, TextureReleaseProc trp,
@@ -121,21 +128,63 @@
     *  no longer is holding a reference to it.
     *
     *  Will return NULL if the specified descriptor is unsupported.
+     *
+     *  It is preferred to use the new methods which take a GrBackendTexture instead of a
+     *  GrBackendTextureDesc. This method will eventually be removed.
     */
     static sk_sp<SkImage> MakeFromTexture(GrContext*, const GrBackendTextureDesc&, SkAlphaType,
                                           sk_sp<SkColorSpace>, TextureReleaseProc, ReleaseContext);
 
     /**
+     *  Create a new image from the specified descriptor. Note - the caller is responsible for
+     *  managing the lifetime of the underlying platform texture.
+     *
+     *  Will return NULL if the specified backend texture is unsupported.
+     */
+    static sk_sp<SkImage> MakeFromTexture(GrContext* ctx,
+                                          const GrBackendTexture& tex, GrSurfaceOrigin origin,
+                                          SkAlphaType at, sk_sp<SkColorSpace> cs) {
+        return MakeFromTexture(ctx, tex, origin, at, cs, nullptr, nullptr);
+    }
+
+    /**
+     *  Create a new image from the GrBackendTexture. The underlying platform texture must stay
+     *  valid and unaltered until the specified release-proc is invoked, indicating that Skia
+     *  no longer is holding a reference to it.
+     *
+     *  Will return NULL if the specified backend texture is unsupported.
+     */
+    static sk_sp<SkImage> MakeFromTexture(GrContext*,
+                                          const GrBackendTexture&, GrSurfaceOrigin origin,
+                                          SkAlphaType, sk_sp<SkColorSpace>,
+                                          TextureReleaseProc, ReleaseContext);
+
+
+    /**
      *  Create a new image from the specified descriptor. Note - Skia will delete or recycle the
      *  texture when the image is released.
      *
      *  Will return NULL if the specified descriptor is unsupported.
+     *
+     *  It is preferred to use the new methods which take a GrBackendTexture instead of a
+     *  GrBackendTextureDesc. This method will eventually be removed.
      */
     static sk_sp<SkImage> MakeFromAdoptedTexture(GrContext*, const GrBackendTextureDesc&,
                                                  SkAlphaType = kPremul_SkAlphaType,
                                                  sk_sp<SkColorSpace> = nullptr);
 
     /**
+     *  Create a new image from the specified descriptor. Note - Skia will delete or recycle the
+     *  texture when the image is released.
+     *
+     *  Will return NULL if the specified backend texture is unsupported.
+     */
+    static sk_sp<SkImage> MakeFromAdoptedTexture(GrContext*,
+                                                 const GrBackendTexture&, GrSurfaceOrigin,
+                                                 SkAlphaType = kPremul_SkAlphaType,
+                                                 sk_sp<SkColorSpace> = nullptr);
+
+    /**
      *  Create a new image by copying the pixels from the specified y, u, v textures. The data
      *  from the textures is immediately ingested into the image and the textures can be modified or
      *  deleted after the function returns. The image will have the dimensions of the y texture.
diff --git a/include/core/SkSurface.h b/include/core/SkSurface.h
index 0e2239a..efa2428 100644
--- a/include/core/SkSurface.h
+++ b/include/core/SkSurface.h
@@ -14,6 +14,7 @@
 
 class SkCanvas;
 class SkPaint;
+class GrBackendRenderTarget;
 class GrContext;
 class GrRenderTarget;
 
@@ -88,6 +89,16 @@
                                                    sk_sp<SkColorSpace>, const SkSurfaceProps*);
 
     /**
+     *  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.
+     */
+    static sk_sp<SkSurface> MakeFromBackendTexture(GrContext*, const GrBackendTexture&,
+                                                   GrSurfaceOrigin origin, int sampleCnt,
+                                                   sk_sp<SkColorSpace>, const SkSurfaceProps*);
+
+    /**
      *  Used to wrap a pre-existing 3D API rendering target as a SkSurface. Skia will not assume
      *  ownership of the render target and the client must ensure the render target is valid for the
      *  lifetime of the SkSurface.
@@ -97,6 +108,12 @@
                                                         sk_sp<SkColorSpace>,
                                                         const SkSurfaceProps*);
 
+    static sk_sp<SkSurface> MakeFromBackendRenderTarget(GrContext*,
+                                                        const GrBackendRenderTarget&,
+                                                        GrSurfaceOrigin origin,
+                                                        sk_sp<SkColorSpace>,
+                                                        const SkSurfaceProps*);
+
     /**
      *  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
@@ -108,6 +125,13 @@
     static sk_sp<SkSurface> MakeFromBackendTextureAsRenderTarget(
         GrContext*, const GrBackendTextureDesc&, sk_sp<SkColorSpace>, const SkSurfaceProps*);
 
+    static sk_sp<SkSurface> MakeFromBackendTextureAsRenderTarget(GrContext*,
+                                                                 const GrBackendTexture&,
+                                                                 GrSurfaceOrigin origin,
+                                                                 int sampleCnt,
+                                                                 sk_sp<SkColorSpace>,
+                                                                 const SkSurfaceProps*);
+
     /**
      * Legacy versions of the above factories, without color space support. These create "legacy"
      * surfaces that operate without gamma correction or color management.
diff --git a/include/gpu/GrBackendSurface.h b/include/gpu/GrBackendSurface.h
new file mode 100644
index 0000000..e588b8a
--- /dev/null
+++ b/include/gpu/GrBackendSurface.h
@@ -0,0 +1,114 @@
+/*
+ * Copyright 2017 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef GrBackendSurface_DEFINED
+#define GrBackendSurface_DEFINED
+
+#include "GrTypes.h"
+
+struct GrVkImageInfo;
+struct GrGLTextureInfo;
+
+class GrBackendTexture {
+public:
+    GrBackendTexture(int width,
+                     int height,
+                     GrVkImageInfo* vkInfo);
+
+    GrBackendTexture(int width,
+                     int height,
+                     GrPixelConfig config,
+                     GrGLTextureInfo* glInfo);
+
+    int width() const { return fWidth; }
+    int height() const { return fHeight; }
+    GrPixelConfig config() const { return fConfig; }
+    GrBackend backend() const {return fBackend; }
+
+    // If the backend API is Vulkan, this returns a pointer to the GrVkImageInfo struct. Otherwise
+    // it returns nullptr.
+    GrVkImageInfo* getVkImageInfo();
+
+    // If the backend API is GL, this returns a pointer to the GrGLTextureInfo struct. Otherwise
+    // it returns nullptr.
+    GrGLTextureInfo* getGLTextureInfo();
+
+private:
+    // Temporary constructor which can be used to convert from a GrBackendTextureDesc.
+    GrBackendTexture(const GrBackendTextureDesc& desc, GrBackend backend);
+
+    // Friending for access to above constructor taking a GrBackendTextureDesc
+    friend class SkImage;
+    friend class SkSurface;
+
+    int fWidth;         //<! width in pixels
+    int fHeight;        //<! height in pixels
+    GrPixelConfig fConfig;
+    GrBackend fBackend;
+
+    union {
+        GrVkImageInfo*   fVkInfo;
+        GrGLTextureInfo* fGLInfo;
+        GrBackendObject  fHandle;
+    };
+};
+
+class GrBackendRenderTarget {
+public:
+    GrBackendRenderTarget(int width,
+                          int height,
+                          int sampleCnt,
+                          int stencilBits,
+                          GrVkImageInfo* vkInfo);
+
+    GrBackendRenderTarget(int width,
+                          int height,
+                          int sampleCnt,
+                          int stencilBits,
+                          GrPixelConfig config,
+                          GrGLTextureInfo* glInfo);
+
+    int width() const { return fWidth; }
+    int height() const { return fHeight; }
+    int sampleCnt() const { return fSampleCnt; }
+    int stencilBits() const { return fStencilBits; }
+    GrPixelConfig config() const { return fConfig; }
+    GrBackend backend() const {return fBackend; }
+
+    // If the backend API is Vulkan, this returns a pointer to the GrVkImageInfo struct. Otherwise
+    // it returns nullptr.
+    GrVkImageInfo* getVkImageInfo();
+
+    // If the backend API is GL, this returns a pointer to the GrGLTextureInfo struct. Otherwise
+    // it returns nullptr.
+    GrGLTextureInfo* getGLTextureInfo();
+
+private:
+    // Temporary constructor which can be used to convert from a GrBackendRenderTargetDesc.
+    GrBackendRenderTarget(const GrBackendRenderTargetDesc& desc, GrBackend backend);
+
+    // Friending for access to above constructor taking a GrBackendTextureDesc
+    friend class SkSurface;
+
+    int fWidth;         //<! width in pixels
+    int fHeight;        //<! height in pixels
+
+    int fSampleCnt;
+    int fStencilBits;
+    GrPixelConfig fConfig;
+
+    GrBackend fBackend;
+
+    union {
+        GrVkImageInfo*   fVkInfo;
+        GrGLTextureInfo* fGLInfo;
+        GrBackendObject  fHandle;
+    };
+};
+
+#endif
+
diff --git a/src/gpu/GrBackendSurface.cpp b/src/gpu/GrBackendSurface.cpp
new file mode 100644
index 0000000..9bf85cb
--- /dev/null
+++ b/src/gpu/GrBackendSurface.cpp
@@ -0,0 +1,120 @@
+/*
+ * Copyright 2017 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "GrBackendSurface.h"
+
+#ifdef SK_VULKAN
+#include "vk/GrVkTypes.h"
+#include "vk/GrVkUtil.h"
+GrBackendTexture::GrBackendTexture(int width,
+                                   int height,
+                                   GrVkImageInfo* vkInfo)
+        : fWidth(width)
+        , fHeight(height)
+        , fConfig(GrVkFormatToPixelConfig(vkInfo->fFormat))
+        , fBackend(kVulkan_GrBackend)
+        , fVkInfo(vkInfo) {}
+#endif // SK_VULKAN
+
+GrBackendTexture::GrBackendTexture(int width,
+                                   int height,
+                                   GrPixelConfig config,
+                                   GrGLTextureInfo* glInfo)
+        : fWidth(width)
+        , fHeight(height)
+        , fConfig(config)
+        , fBackend(kOpenGL_GrBackend)
+        , fGLInfo(glInfo) {}
+
+GrBackendTexture::GrBackendTexture(const GrBackendTextureDesc& desc, GrBackend backend)
+        : fWidth(desc.fWidth)
+        , fHeight(desc.fHeight)
+        , fConfig(kVulkan_GrBackend == backend
+#ifdef SK_VULKAN
+                  ? GrVkFormatToPixelConfig(((GrVkImageInfo*)desc.fTextureHandle)->fFormat)
+#else
+                  ? kUnknown_GrPixelConfig
+#endif
+                  : desc.fConfig)
+        , fBackend(backend)
+        , fHandle(desc.fTextureHandle) {}
+
+GrVkImageInfo* GrBackendTexture::getVkImageInfo() {
+    if (kVulkan_GrBackend == fBackend) {
+        return fVkInfo;
+    }
+    return nullptr;
+}
+
+GrGLTextureInfo* GrBackendTexture::getGLTextureInfo() {
+    if (kOpenGL_GrBackend == fBackend) {
+        return fGLInfo;
+    }
+    return nullptr;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifdef SK_VULKAN
+GrBackendRenderTarget::GrBackendRenderTarget(int width,
+                                             int height,
+                                             int sampleCnt,
+                                             int stencilBits,
+                                             GrVkImageInfo* vkInfo)
+        : fWidth(width)
+        , fHeight(height)
+        , fSampleCnt(sampleCnt)
+        , fStencilBits(stencilBits)
+        , fConfig(GrVkFormatToPixelConfig(vkInfo->fFormat))
+        , fBackend(kVulkan_GrBackend)
+        , fVkInfo(vkInfo) {}
+#endif // SK_VULKAN
+
+GrBackendRenderTarget::GrBackendRenderTarget(int width,
+                                             int height,
+                                             int sampleCnt,
+                                             int stencilBits,
+                                             GrPixelConfig config,
+                                             GrGLTextureInfo* glInfo)
+        : fWidth(width)
+        , fHeight(height)
+        , fSampleCnt(sampleCnt)
+        , fStencilBits(stencilBits)
+        , fConfig(config)
+        , fBackend(kOpenGL_GrBackend)
+        , fGLInfo(glInfo) {}
+
+GrBackendRenderTarget::GrBackendRenderTarget(const GrBackendRenderTargetDesc& desc,
+                                             GrBackend backend)
+        : fWidth(desc.fWidth)
+        , fHeight(desc.fHeight)
+        , fSampleCnt(desc.fSampleCnt)
+        , fStencilBits(desc.fStencilBits)
+        , fConfig(kVulkan_GrBackend == backend
+#ifdef SK_VULKAN
+                  ? GrVkFormatToPixelConfig(((GrVkImageInfo*)desc.fRenderTargetHandle)->fFormat)
+#else
+                  ? kUnknown_GrPixelConfig
+#endif
+                  : desc.fConfig)
+        , fBackend(backend)
+        , fHandle(desc.fRenderTargetHandle) {}
+
+GrVkImageInfo* GrBackendRenderTarget::getVkImageInfo() {
+    if (kVulkan_GrBackend == fBackend) {
+        return fVkInfo;
+    }
+    return nullptr;
+}
+
+GrGLTextureInfo* GrBackendRenderTarget::getGLTextureInfo() {
+    if (kOpenGL_GrBackend == fBackend) {
+        return fGLInfo;
+    }
+    return nullptr;
+}
+
diff --git a/src/gpu/vk/GrVkGpu.cpp b/src/gpu/vk/GrVkGpu.cpp
index c9f5903..a483ccb 100644
--- a/src/gpu/vk/GrVkGpu.cpp
+++ b/src/gpu/vk/GrVkGpu.cpp
@@ -948,7 +948,7 @@
     }
 
     // setup memory barrier
-    SkASSERT(GrVkFormatToPixelConfig(tex->imageFormat(), nullptr));
+    SkASSERT(kUnknown_GrPixelConfig != GrVkFormatToPixelConfig(tex->imageFormat()));
     VkImageAspectFlags aspectFlags = VK_IMAGE_ASPECT_COLOR_BIT;
     VkImageMemoryBarrier imageMemoryBarrier = {
         VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,          // sType
diff --git a/src/gpu/vk/GrVkImage.cpp b/src/gpu/vk/GrVkImage.cpp
index c3302a2..b3c103a 100644
--- a/src/gpu/vk/GrVkImage.cpp
+++ b/src/gpu/vk/GrVkImage.cpp
@@ -20,7 +20,7 @@
         case VK_FORMAT_D32_SFLOAT_S8_UINT:
             return VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
         default:
-            SkASSERT(GrVkFormatToPixelConfig(format, nullptr));
+            SkASSERT(kUnknown_GrPixelConfig != GrVkFormatToPixelConfig(format));
             return VK_IMAGE_ASPECT_COLOR_BIT;
     }
 }
diff --git a/src/gpu/vk/GrVkUtil.cpp b/src/gpu/vk/GrVkUtil.cpp
index 1fdf69c..ec71fb0 100644
--- a/src/gpu/vk/GrVkUtil.cpp
+++ b/src/gpu/vk/GrVkUtil.cpp
@@ -69,58 +69,40 @@
     return false;
 }
 
-bool GrVkFormatToPixelConfig(VkFormat format, GrPixelConfig* config) {
-    GrPixelConfig dontCare;
-    if (!config) {
-        config = &dontCare;
-    }
-
+GrPixelConfig GrVkFormatToPixelConfig(VkFormat format) {
     switch (format) {
         case VK_FORMAT_R8G8B8A8_UNORM:
-            *config = kRGBA_8888_GrPixelConfig;
-            break;
+            return kRGBA_8888_GrPixelConfig;
         case VK_FORMAT_B8G8R8A8_UNORM:
-            *config = kBGRA_8888_GrPixelConfig;
-            break;
+            return kBGRA_8888_GrPixelConfig;
         case VK_FORMAT_R8G8B8A8_SRGB:
-            *config = kSRGBA_8888_GrPixelConfig;
-            break;
+            return kSRGBA_8888_GrPixelConfig;
         case VK_FORMAT_B8G8R8A8_SRGB:
-            *config = kSBGRA_8888_GrPixelConfig;
-            break;
+            return kSBGRA_8888_GrPixelConfig;
         case VK_FORMAT_R8G8B8A8_SINT:
-            *config = kRGBA_8888_sint_GrPixelConfig;
-            break;
+            return kRGBA_8888_sint_GrPixelConfig;
         case VK_FORMAT_R5G6B5_UNORM_PACK16:
-            *config = kRGB_565_GrPixelConfig;
+            return kRGB_565_GrPixelConfig;
             break;
         case VK_FORMAT_B4G4R4A4_UNORM_PACK16:
             // R4G4B4A4 is not required to be supported so we actually
             // store RGBA_4444 data as B4G4R4A4.
-            *config = kRGBA_4444_GrPixelConfig;
-            break;
+            return kRGBA_4444_GrPixelConfig;
         case VK_FORMAT_R8_UNORM:
-            *config = kAlpha_8_GrPixelConfig;
-            break;
+            return kAlpha_8_GrPixelConfig;
         case VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK:
-            *config = kETC1_GrPixelConfig;      // this conversion seems a bit sketchy
-            break;
+            return kETC1_GrPixelConfig;      // this conversion seems a bit sketchy
         case VK_FORMAT_R32G32B32A32_SFLOAT:
-            *config = kRGBA_float_GrPixelConfig;
-            break;
+            return kRGBA_float_GrPixelConfig;
         case VK_FORMAT_R32G32_SFLOAT:
-            *config = kRG_float_GrPixelConfig;
-            break;
+            return kRG_float_GrPixelConfig;
         case VK_FORMAT_R16G16B16A16_SFLOAT:
-            *config = kRGBA_half_GrPixelConfig;
-            break;
+            return kRGBA_half_GrPixelConfig;
         case VK_FORMAT_R16_SFLOAT:
-            *config = kAlpha_half_GrPixelConfig;
-            break;
+            return kAlpha_half_GrPixelConfig;
         default:
-            return false;
+            return kUnknown_GrPixelConfig;
     }
-    return true;
 }
 
 bool GrVkFormatIsSRGB(VkFormat format, VkFormat* linearFormat) {
diff --git a/src/gpu/vk/GrVkUtil.h b/src/gpu/vk/GrVkUtil.h
index ba07bca..72ed483 100644
--- a/src/gpu/vk/GrVkUtil.h
+++ b/src/gpu/vk/GrVkUtil.h
@@ -35,7 +35,7 @@
 /**
 * Returns the GrPixelConfig for the given vulkan texture format
 */
-bool GrVkFormatToPixelConfig(VkFormat format, GrPixelConfig* config);
+GrPixelConfig GrVkFormatToPixelConfig(VkFormat format);
 
 /**
  * Returns true if the given vulkan texture format is sRGB encoded.
diff --git a/src/image/SkImage.cpp b/src/image/SkImage.cpp
index 9db4ed1..9866acf 100644
--- a/src/image/SkImage.cpp
+++ b/src/image/SkImage.cpp
@@ -339,6 +339,13 @@
     return nullptr;
 }
 
+sk_sp<SkImage> SkImage::MakeFromTexture(GrContext* ctx,
+                                        const GrBackendTexture& tex, GrSurfaceOrigin origin,
+                                        SkAlphaType at, sk_sp<SkColorSpace> cs,
+                                        TextureReleaseProc releaseP, ReleaseContext releaseC) {
+    return nullptr;
+}
+
 size_t SkImage::getDeferredTextureImageData(const GrContextThreadSafeProxy&,
                                             const DeferredTextureImageUsageParams[],
                                             int paramCnt, void* buffer,
@@ -356,6 +363,12 @@
     return nullptr;
 }
 
+sk_sp<SkImage> SkImage::MakeFromAdoptedTexture(GrContext* ctx,
+                                               const GrBackendTexture& tex, GrSurfaceOrigin origin,
+                                               SkAlphaType at, sk_sp<SkColorSpace> cs) {
+    return nullptr;
+}
+
 sk_sp<SkImage> SkImage::MakeFromYUVTexturesCopy(GrContext* ctx, SkYUVColorSpace space,
                                                 const GrBackendObject yuvTextureHandles[3],
                                                 const SkISize yuvSizes[3],
diff --git a/src/image/SkImage_Gpu.cpp b/src/image/SkImage_Gpu.cpp
index 932bb38..0e74f68 100644
--- a/src/image/SkImage_Gpu.cpp
+++ b/src/image/SkImage_Gpu.cpp
@@ -289,6 +289,23 @@
                                       nullptr, nullptr);
 }
 
+sk_sp<SkImage> SkImage::MakeFromTexture(GrContext* ctx,
+                                        const GrBackendTexture& tex, GrSurfaceOrigin origin,
+                                        SkAlphaType at, sk_sp<SkColorSpace> cs,
+                                        TextureReleaseProc releaseP, ReleaseContext releaseC) {
+    // This function is not implemented yet
+    sk_throw();
+    return nullptr;
+}
+
+sk_sp<SkImage> SkImage::MakeFromAdoptedTexture(GrContext* ctx,
+                                               const GrBackendTexture& tex, GrSurfaceOrigin origin,
+                                               SkAlphaType at, sk_sp<SkColorSpace> cs) {
+    // This function is not implemented yet
+    sk_throw();
+    return nullptr;
+}
+
 static sk_sp<SkImage> make_from_yuv_textures_copy(GrContext* ctx, SkYUVColorSpace colorSpace,
                                                   bool nv12,
                                                   const GrBackendObject yuvTextureHandles[],
diff --git a/src/image/SkSurface.cpp b/src/image/SkSurface.cpp
index 55aab3e..cd2a5f1 100644
--- a/src/image/SkSurface.cpp
+++ b/src/image/SkSurface.cpp
@@ -201,6 +201,12 @@
     return nullptr;
 }
 
+sk_sp<SkSurface> SkSurface::MakeFromBackendTexture(GrContext*, const GrBackendTexture&,
+                                                   GrSurfaceOrigin origin, int sampleCnt,
+                                                   sk_sp<SkColorSpace>, const SkSurfaceProps*) {
+    return nullptr;
+}
+
 sk_sp<SkSurface> SkSurface::MakeFromBackendRenderTarget(GrContext*,
                                                         const GrBackendRenderTargetDesc&,
                                                         sk_sp<SkColorSpace>,
@@ -208,8 +214,27 @@
     return nullptr;
 }
 
-sk_sp<SkSurface> MakeFromBackendTextureAsRenderTarget(GrContext*, const GrBackendTextureDesc&,
-                                                      sk_sp<SkColorSpace>, const SkSurfaceProps*) {
+sk_sp<SkSurface> SkSurface::MakeFromBackendRenderTarget(GrContext*,
+                                                        const GrBackendRenderTarget&,
+                                                        GrSurfaceOrigin origin,
+                                                        sk_sp<SkColorSpace>,
+                                                        const SkSurfaceProps*) {
+    return nullptr;
+}
+
+sk_sp<SkSurface> SkSurface::MakeFromBackendTextureAsRenderTarget(GrContext*,
+                                                                 const GrBackendTextureDesc&,
+                                                                 sk_sp<SkColorSpace>,
+                                                                 const SkSurfaceProps*) {
+    return nullptr;
+}
+
+sk_sp<SkSurface> SkSurface::MakeFromBackendTextureAsRenderTarget(GrContext*,
+                                                                 const GrBackendTexture&,
+                                                                 GrSurfaceOrigin origin,
+                                                                 int sampleCnt,
+                                                                 sk_sp<SkColorSpace>,
+                                                                 const SkSurfaceProps*) {
     return nullptr;
 }
 
diff --git a/src/image/SkSurface_Gpu.cpp b/src/image/SkSurface_Gpu.cpp
index cef355e..f024c41 100644
--- a/src/image/SkSurface_Gpu.cpp
+++ b/src/image/SkSurface_Gpu.cpp
@@ -243,6 +243,14 @@
     return sk_make_sp<SkSurface_Gpu>(std::move(device));
 }
 
+sk_sp<SkSurface> SkSurface::MakeFromBackendTexture(GrContext*, const GrBackendTexture&,
+                                                   GrSurfaceOrigin origin, int sampleCnt,
+                                                   sk_sp<SkColorSpace>, const SkSurfaceProps*) {
+    // This function is not implemented yet
+    sk_throw();
+    return nullptr;
+}
+
 sk_sp<SkSurface> SkSurface::MakeFromBackendRenderTarget(GrContext* context,
                                                         const GrBackendRenderTargetDesc& desc,
                                                         sk_sp<SkColorSpace> colorSpace,
@@ -271,6 +279,16 @@
     return sk_make_sp<SkSurface_Gpu>(std::move(device));
 }
 
+sk_sp<SkSurface> SkSurface::MakeFromBackendRenderTarget(GrContext*,
+                                                        const GrBackendRenderTarget&,
+                                                        GrSurfaceOrigin origin,
+                                                        sk_sp<SkColorSpace>,
+                                                        const SkSurfaceProps*) {
+    // This function is not implemented yet
+    sk_throw();
+    return nullptr;
+}
+
 sk_sp<SkSurface> SkSurface::MakeFromBackendTextureAsRenderTarget(GrContext* context,
                                                                  const GrBackendTextureDesc& desc,
                                                                  sk_sp<SkColorSpace> colorSpace,
@@ -299,4 +317,15 @@
     return sk_make_sp<SkSurface_Gpu>(std::move(device));
 }
 
+sk_sp<SkSurface> SkSurface::MakeFromBackendTextureAsRenderTarget(GrContext*,
+                                                                 const GrBackendTexture&,
+                                                                 GrSurfaceOrigin origin,
+                                                                 int sampleCnt,
+                                                                 sk_sp<SkColorSpace>,
+                                                                 const SkSurfaceProps*) {
+    // This function is not implemented yet
+    sk_throw();
+    return nullptr;
+}
+
 #endif
diff --git a/tools/viewer/sk_app/VulkanWindowContext.cpp b/tools/viewer/sk_app/VulkanWindowContext.cpp
index 8e8c059..0749978 100644
--- a/tools/viewer/sk_app/VulkanWindowContext.cpp
+++ b/tools/viewer/sk_app/VulkanWindowContext.cpp
@@ -175,8 +175,8 @@
     auto srgbColorSpace = SkColorSpace::MakeSRGB();
     bool wantSRGB = srgbColorSpace == params.fColorSpace;
     for (uint32_t i = 0; i < surfaceFormatCount; ++i) {
-        GrPixelConfig config;
-        if (GrVkFormatToPixelConfig(surfaceFormats[i].format, &config) &&
+        GrPixelConfig config = GrVkFormatToPixelConfig(surfaceFormats[i].format);
+        if (kUnknown_GrPixelConfig != config &&
             GrPixelConfigIsSRGB(config) == wantSRGB) {
             surfaceFormat = surfaceFormats[i].format;
             colorSpace = surfaceFormats[i].colorSpace;
@@ -250,7 +250,8 @@
 }
 
 void VulkanWindowContext::createBuffers(VkFormat format) {
-    GrVkFormatToPixelConfig(format, &fPixelConfig);
+    fPixelConfig = GrVkFormatToPixelConfig(format);
+    SkASSERT(kUnknown_GrPixelConfig != fPixelConfig);
 
     fGetSwapchainImagesKHR(fBackendContext->fDevice, fSwapchain, &fImageCount, nullptr);
     SkASSERT(fImageCount);