Add Make[backend] calls for creating GrContexts

Docs-Preview: https://skia.org/?cl=26369
Bug: skia:
Change-Id: I460ee63e466f85b05918479f068a2e5ca2d70550
Reviewed-on: https://skia-review.googlesource.com/26369
Commit-Queue: Greg Daniel <egdaniel@google.com>
Reviewed-by: Brian Salomon <bsalomon@google.com>
diff --git a/bench/GrResourceCacheBench.cpp b/bench/GrResourceCacheBench.cpp
index 9c9ca35..d78af0a 100644
--- a/bench/GrResourceCacheBench.cpp
+++ b/bench/GrResourceCacheBench.cpp
@@ -69,7 +69,7 @@
     }
 
     void onDraw(int loops, SkCanvas* canvas) override {
-        sk_sp<GrContext> context(GrContext::Create(kMock_GrBackend, (GrBackendContext) nullptr));
+        sk_sp<GrContext> context(GrContext::MakeMock(nullptr));
         if (nullptr == context) {
             return;
         }
@@ -115,7 +115,7 @@
     }
 
     void onDelayedSetup() override {
-        fContext.reset(GrContext::Create(kMock_GrBackend, (GrBackendContext) nullptr));
+        fContext = GrContext::MakeMock(nullptr);
         if (!fContext) {
             return;
         }
diff --git a/debugger/QT/SkGLWidget.cpp b/debugger/QT/SkGLWidget.cpp
index a60ae0f..0c65be0 100644
--- a/debugger/QT/SkGLWidget.cpp
+++ b/debugger/QT/SkGLWidget.cpp
@@ -42,7 +42,7 @@
     fGpuSurface = nullptr;
     fCanvas = nullptr;
 
-    fCurContext.reset(GrContext::Create(kOpenGL_GrBackend, (GrBackendContext) fCurIntf.get()));
+    fCurContext = GrContext::MakeGL(fCurIntf.get());
 }
 
 void SkGLWidget::createRenderTarget() {
diff --git a/example/HelloWorld.cpp b/example/HelloWorld.cpp
index 464ec44..2375e00 100644
--- a/example/HelloWorld.cpp
+++ b/example/HelloWorld.cpp
@@ -70,7 +70,7 @@
     fInterface = GrGLCreateNativeInterface();
     SkASSERT(NULL != fInterface);
 
-    fContext = GrContext::Create(kOpenGL_GrBackend, (GrBackendContext)fInterface);
+    fContext = GrContext::MakeGL(fInterface).release();
     SkASSERT(NULL != fContext);
 
     this->setUpGpuBackedSurface();
diff --git a/example/SkiaSDLExample.cpp b/example/SkiaSDLExample.cpp
index 813485f..3c4dccc 100644
--- a/example/SkiaSDLExample.cpp
+++ b/example/SkiaSDLExample.cpp
@@ -187,8 +187,7 @@
     sk_sp<const GrGLInterface> interface(GrGLCreateNativeInterface());
 
     // setup contexts
-    sk_sp<GrContext> grContext(GrContext::Create(kOpenGL_GrBackend,
-                                                 (GrBackendContext)interface.get()));
+    sk_sp<GrContext> grContext(GrContext::MakeGL(interface.get()));
     SkASSERT(grContext);
 
     // Wrap the frame buffer object attached to the screen in a Skia render target so Skia can
diff --git a/experimental/GLFWTest/glfw_main.cpp b/experimental/GLFWTest/glfw_main.cpp
index 63ea1f1..6b8412c 100644
--- a/experimental/GLFWTest/glfw_main.cpp
+++ b/experimental/GLFWTest/glfw_main.cpp
@@ -31,8 +31,8 @@
 
 
 static void init_skia(int w, int h) {
-    sContext = GrContext::Create(kOpenGL_GrBackend, 0);
-    
+    sContext = GrContext::MakeGL(nullptr).release();
+
     GrBackendRenderTargetDesc desc;
     desc.fWidth = w;
     desc.fHeight = h;
diff --git a/experimental/SkV8Example/SkV8Example.cpp b/experimental/SkV8Example/SkV8Example.cpp
index a6a2a7e..ca63e07 100644
--- a/experimental/SkV8Example/SkV8Example.cpp
+++ b/experimental/SkV8Example/SkV8Example.cpp
@@ -78,8 +78,7 @@
         }
 
         fCurIntf = GrGLCreateNativeInterface();
-        fCurContext = GrContext::Create(
-                kOpenGL_GrBackend, (GrBackendContext) fCurIntf);
+        fCurContext = GrContext::MakeGL(fCurIntf).release();
         if (NULL == fCurIntf || NULL == fCurContext) {
             printf("Failed to initialize GL.");
             exit(1);
diff --git a/experimental/iOSSampleApp/SkSampleUIView.mm b/experimental/iOSSampleApp/SkSampleUIView.mm
index b1e0487..39eef56 100644
--- a/experimental/iOSSampleApp/SkSampleUIView.mm
+++ b/experimental/iOSSampleApp/SkSampleUIView.mm
@@ -89,8 +89,7 @@
         
         SkASSERT(NULL == fCurContext);
         if (SkOSWindow::kNone_BackEndType != fBackend) {
-            fCurContext = GrContext::Create(kOpenGL_GrBackend,
-                                            (GrBackendContext) fCurIntf);
+            fCurContext = GrContext::MakeGL(fCurIntf).release();
         }
         
         if ((NULL == fCurContext || NULL == fCurIntf) &&
diff --git a/include/gpu/GrContext.h b/include/gpu/GrContext.h
index f48b8db..b5d2f74 100644
--- a/include/gpu/GrContext.h
+++ b/include/gpu/GrContext.h
@@ -22,12 +22,14 @@
 class GrContextThreadSafeProxy;
 class GrDrawingManager;
 struct GrDrawOpAtlasConfig;
-class GrRenderTargetContext;
 class GrFragmentProcessor;
+struct GrGLInterface;
 class GrGpu;
 class GrIndexBuffer;
+struct GrMockOptions;
 class GrOvalRenderer;
 class GrPath;
+class GrRenderTargetContext;
 class GrResourceEntry;
 class GrResourceCache;
 class GrResourceProvider;
@@ -37,6 +39,7 @@
 class GrTextContext;
 class GrTextureProxy;
 class GrVertexBuffer;
+struct GrVkBackendContext;
 class GrSwizzle;
 class SkTraceMemoryDump;
 
@@ -51,6 +54,14 @@
     static GrContext* Create(GrBackend, GrBackendContext, const GrContextOptions& options);
     static GrContext* Create(GrBackend, GrBackendContext);
 
+    static sk_sp<GrContext> MakeGL(const GrGLInterface*, const GrContextOptions&);
+    static sk_sp<GrContext> MakeGL(const GrGLInterface*);
+
+#ifdef SK_VULKAN
+    static sk_sp<GrContext> MakeVulkan(const GrVkBackendContext*, const GrContextOptions&);
+    static sk_sp<GrContext> MakeVulkan(const GrVkBackendContext*);
+#endif
+
 #ifdef SK_METAL
     /**
      * Makes a GrContext which uses Metal as the backend. The device parameter is an MTLDevice
@@ -59,8 +70,12 @@
      * GrContext is destroyed.
      */
     static sk_sp<GrContext> MakeMetal(void* device, void* queue, const GrContextOptions& options);
+    static sk_sp<GrContext> MakeMetal(void* device, void* queue);
 #endif
 
+    static sk_sp<GrContext> MakeMock(const GrMockOptions*, const GrContextOptions&);
+    static sk_sp<GrContext> MakeMock(const GrMockOptions*);
+
     virtual ~GrContext();
 
     sk_sp<GrContextThreadSafeProxy> threadSafeProxy();
diff --git a/include/gpu/gl/GrGLInterface.h b/include/gpu/gl/GrGLInterface.h
index 56e655d..f178532 100644
--- a/include/gpu/gl/GrGLInterface.h
+++ b/include/gpu/gl/GrGLInterface.h
@@ -17,8 +17,8 @@
 /**
  * Rather than depend on platform-specific GL headers and libraries, we require
  * the client to provide a struct of GL function pointers. This struct can be
- * specified per-GrContext as a parameter to GrContext::Create. If NULL is
- * passed to Create then a "default" GL interface is created. If the default is
+ * specified per-GrContext as a parameter to GrContext::MakeGL. If NULL is
+ * passed to MakeGL then a "default" GL interface is created. If the default is
  * also NULL GrContext creation will fail.
  *
  * The default interface is returned by GrGLDefaultInterface. This function's
diff --git a/samplecode/SampleApp.cpp b/samplecode/SampleApp.cpp
index 1676fc3..c36e2e8 100644
--- a/samplecode/SampleApp.cpp
+++ b/samplecode/SampleApp.cpp
@@ -276,8 +276,7 @@
         }
 
         SkASSERT(nullptr == fCurContext);
-        fCurContext = GrContext::Create(kOpenGL_GrBackend, (GrBackendContext) fCurIntf,
-                                        backendOptions.fGrContextOptions);
+        fCurContext = GrContext::MakeGL(fCurIntf, backendOptions.fGrContextOptions).release();
 
         if (nullptr == fCurContext || nullptr == fCurIntf) {
             // We need some context and interface to see results
diff --git a/site/user/api/canvas.md b/site/user/api/canvas.md
index d9e1559..d6aa7b6 100644
--- a/site/user/api/canvas.md
+++ b/site/user/api/canvas.md
@@ -98,7 +98,7 @@
         // context in a platform-specific way. Alternatively, you may create your own GrGLInterface and
         // initialize it however you like to attach to an alternate OpenGL implementation or intercept
         // Skia's OpenGL calls.
-        GrContext* context = GrContext::Create(kOpenGL_GrBackend, (GrBackendContext) interface);
+        sk_sp<GrContext> context = GrContext::MakeGL(interface);
         SkImageInfo info = SkImageInfo:: MakeN32Premul(width, height);
         sk_sp<SkSurface> gpuSurface(
                 SkSurface::MakeRenderTarget(context, SkBudgeted::kNo, info));
diff --git a/site/user/special/vulkan.md b/site/user/special/vulkan.md
index 8dfd26a..5b5c2d9 100644
--- a/site/user/special/vulkan.md
+++ b/site/user/special/vulkan.md
@@ -21,7 +21,7 @@
 Using the Vulkan Backend
 ------------------------
 
-To create a GrContext that is backed by Vulkan the client creates a Vulkan device and queue, initializes a GrVkBackendContext to describe the context, and then calls GrContext::Create:
+To create a GrContext that is backed by Vulkan the client creates a Vulkan device and queue, initializes a GrVkBackendContext to describe the context, and then calls GrContext::MakeVulkan:
 
 <!--?prettify lang=c++?-->
     sk_sp<GrVkBackendContext> vkContext = new GrVkBackendContext;
@@ -31,7 +31,7 @@
     vkBackendContext.fInterface.reset(GrVkCreateInterface(instance, vkPhysDevice, extensionFlags);
     ...
 
-    sk_sp<GrContext> context = GrContext::Create(kVulkan_GrBackend, (GrBackendContext) vkBackendContext);
+    sk_sp<GrContext> context = GrContext::MakeVulkan(vkBackendContext);
 
 When using the Vulkan backend the GrBackendObject field in
 GrBackendRenderTargetDesc and GrBackendTextureDesc is interpeted as a pointer
diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp
index 88fe379..19343ac 100644
--- a/src/gpu/GrContext.cpp
+++ b/src/gpu/GrContext.cpp
@@ -29,9 +29,14 @@
 #include "effects/GrConfigConversionEffect.h"
 #include "text/GrTextBlobCache.h"
 
+#include "gl/GrGLGpu.h"
+#include "mock/GrMockGpu.h"
 #ifdef SK_METAL
 #include "mtl/GrMtlTrampoline.h"
 #endif
+#ifdef SK_VULKAN
+#include "vk/GrVkGpu.h"
+#endif
 
 #define ASSERT_OWNED_PROXY(P) \
 SkASSERT(!(P) || !((P)->priv().peekTexture()) || (P)->priv().peekTexture()->getContext() == this)
@@ -66,7 +71,71 @@
     return context.release();
 }
 
+sk_sp<GrContext> GrContext::MakeGL(const GrGLInterface* interface) {
+    GrContextOptions defaultOptions;
+    return MakeGL(interface, defaultOptions);
+}
+
+sk_sp<GrContext> GrContext::MakeGL(const GrGLInterface* interface,
+                                   const GrContextOptions& options) {
+    sk_sp<GrContext> context(new GrContext);
+    context->fGpu = GrGLGpu::Create(interface, options, context.get());
+    if (!context->fGpu) {
+        return nullptr;
+    }
+    context->fBackend = kOpenGL_GrBackend;
+    if (!context->init(options)) {
+        return nullptr;
+    }
+    return context;
+}
+
+sk_sp<GrContext> GrContext::MakeMock(const GrMockOptions* mockOptions) {
+    GrContextOptions defaultOptions;
+    return MakeMock(mockOptions, defaultOptions);
+}
+
+sk_sp<GrContext> GrContext::MakeMock(const GrMockOptions* mockOptions,
+                                     const GrContextOptions& options) {
+    sk_sp<GrContext> context(new GrContext);
+    context->fGpu = GrMockGpu::Create(mockOptions, options, context.get());
+    if (!context->fGpu) {
+        return nullptr;
+    }
+    context->fBackend = kMock_GrBackend;
+    if (!context->init(options)) {
+        return nullptr;
+    }
+    return context;
+}
+
+#ifdef SK_VULKAN
+sk_sp<GrContext> GrContext::MakeVulkan(const GrVkBackendContext* backendContext) {
+    GrContextOptions defaultOptions;
+    return MakeVulkan(backendContext, defaultOptions);
+}
+
+sk_sp<GrContext> GrContext::MakeVulkan(const GrVkBackendContext* backendContext,
+                                       const GrContextOptions& options) {
+    sk_sp<GrContext> context(new GrContext);
+    context->fGpu = GrVkGpu::Create(backendContext, options, context.get());
+    if (!context->fGpu) {
+        return nullptr;
+    }
+    context->fBackend = kVulkan_GrBackend;
+    if (!context->init(options)) {
+        return nullptr;
+    }
+    return context;
+}
+#endif
+
 #ifdef SK_METAL
+sk_sp<GrContext> GrContext::MakeMetal(void* device, void* queue) {
+    GrContextOptions defaultOptions;
+    return MakeMetal(device, queue, defaultOptions);
+}
+
 sk_sp<GrContext> GrContext::MakeMetal(void* device, void* queue, const GrContextOptions& options) {
     sk_sp<GrContext> context(new GrContext);
     context->fGpu = GrMtlTrampoline::CreateGpu(context.get(), options, device, queue);
diff --git a/src/gpu/gl/GrGLGpu.cpp b/src/gpu/gl/GrGLGpu.cpp
index 49be761..0bab551 100644
--- a/src/gpu/gl/GrGLGpu.cpp
+++ b/src/gpu/gl/GrGLGpu.cpp
@@ -184,8 +184,12 @@
 
 GrGpu* GrGLGpu::Create(GrBackendContext backendContext, const GrContextOptions& options,
                        GrContext* context) {
-    sk_sp<const GrGLInterface> glInterface(
-        reinterpret_cast<const GrGLInterface*>(backendContext));
+    return Create(reinterpret_cast<const GrGLInterface*>(backendContext), options, context);
+}
+
+GrGpu* GrGLGpu::Create(const GrGLInterface* interface, const GrContextOptions& options,
+                       GrContext* context) {
+    sk_sp<const GrGLInterface> glInterface(interface);
     if (!glInterface) {
         glInterface.reset(GrGLDefaultInterface());
     } else {
diff --git a/src/gpu/gl/GrGLGpu.h b/src/gpu/gl/GrGLGpu.h
index 9b6e004..5acf806 100644
--- a/src/gpu/gl/GrGLGpu.h
+++ b/src/gpu/gl/GrGLGpu.h
@@ -38,6 +38,8 @@
 public:
     static GrGpu* Create(GrBackendContext backendContext, const GrContextOptions& options,
                          GrContext* context);
+    static GrGpu* Create(const GrGLInterface*, const GrContextOptions& options,
+                         GrContext* context);
     ~GrGLGpu() override;
 
     void disconnect(DisconnectType) override;
diff --git a/src/gpu/mock/GrMockGpu.cpp b/src/gpu/mock/GrMockGpu.cpp
index 1778ee2..614e627 100644
--- a/src/gpu/mock/GrMockGpu.cpp
+++ b/src/gpu/mock/GrMockGpu.cpp
@@ -26,14 +26,19 @@
 
 GrGpu* GrMockGpu::Create(GrBackendContext backendContext, const GrContextOptions& contextOptions,
                          GrContext* context) {
-    static const GrMockOptions kDefaultOptions = GrMockOptions();
-    const GrMockOptions* options = reinterpret_cast<const GrMockOptions*>(backendContext);
-    if (!options) {
-        options = &kDefaultOptions;
-    }
-    return new GrMockGpu(context, *options, contextOptions);
+    return Create(reinterpret_cast<const GrMockOptions*>(backendContext), contextOptions, context);
 }
 
+GrGpu* GrMockGpu::Create(const GrMockOptions* mockOptions, const GrContextOptions& contextOptions,
+                         GrContext* context) {
+    static const GrMockOptions kDefaultOptions = GrMockOptions();
+    if (!mockOptions) {
+        mockOptions = &kDefaultOptions;
+    }
+    return new GrMockGpu(context, *mockOptions, contextOptions);
+}
+
+
 GrGpuCommandBuffer* GrMockGpu::createCommandBuffer(const GrGpuCommandBuffer::LoadAndStoreInfo&,
                                                    const GrGpuCommandBuffer::LoadAndStoreInfo&) {
     return new GrMockGpuCommandBuffer(this);
diff --git a/src/gpu/mock/GrMockGpu.h b/src/gpu/mock/GrMockGpu.h
index e31570a..d29d4cf 100644
--- a/src/gpu/mock/GrMockGpu.h
+++ b/src/gpu/mock/GrMockGpu.h
@@ -20,6 +20,7 @@
 class GrMockGpu : public GrGpu {
 public:
     static GrGpu* Create(GrBackendContext, const GrContextOptions&, GrContext*);
+    static GrGpu* Create(const GrMockOptions*, const GrContextOptions&, GrContext*);
 
     ~GrMockGpu() override {}
 
diff --git a/src/gpu/vk/GrVkGpu.cpp b/src/gpu/vk/GrVkGpu.cpp
index d7094b7..d1e535e 100644
--- a/src/gpu/vk/GrVkGpu.cpp
+++ b/src/gpu/vk/GrVkGpu.cpp
@@ -76,19 +76,22 @@
 
 GrGpu* GrVkGpu::Create(GrBackendContext backendContext, const GrContextOptions& options,
                        GrContext* context) {
-    const GrVkBackendContext* vkBackendContext =
-        reinterpret_cast<const GrVkBackendContext*>(backendContext);
-    if (!vkBackendContext) {
+    return Create(reinterpret_cast<const GrVkBackendContext*>(backendContext), options, context);
+}
+
+GrGpu* GrVkGpu::Create(const GrVkBackendContext* backendContext, const GrContextOptions& options,
+                       GrContext* context) {
+    if (!backendContext) {
         return nullptr;
     } else {
-        vkBackendContext->ref();
+        backendContext->ref();
     }
 
-    if (!vkBackendContext->fInterface->validate(vkBackendContext->fExtensions)) {
+    if (!backendContext->fInterface->validate(backendContext->fExtensions)) {
         return nullptr;
     }
 
-    return new GrVkGpu(context, options, vkBackendContext);
+    return new GrVkGpu(context, options, backendContext);
 }
 
 ////////////////////////////////////////////////////////////////////////////////
diff --git a/src/gpu/vk/GrVkGpu.h b/src/gpu/vk/GrVkGpu.h
index 419e9e3..7e95ca4 100644
--- a/src/gpu/vk/GrVkGpu.h
+++ b/src/gpu/vk/GrVkGpu.h
@@ -40,6 +40,8 @@
 public:
     static GrGpu* Create(GrBackendContext backendContext, const GrContextOptions& options,
                          GrContext* context);
+    static GrGpu* Create(const GrVkBackendContext*, const GrContextOptions& options,
+                         GrContext* context);
 
     ~GrVkGpu() override;
 
diff --git a/tests/EGLImageTest.cpp b/tests/EGLImageTest.cpp
index 84a6bfd..784ec5d 100644
--- a/tests/EGLImageTest.cpp
+++ b/tests/EGLImageTest.cpp
@@ -21,8 +21,9 @@
 
 using sk_gpu_test::GLTestContext;
 
-static void cleanup(GLTestContext* glctx0, GrGLuint texID0, GLTestContext* glctx1, GrContext* grctx1,
-                    const GrGLTextureInfo* grbackendtex1, GrEGLImage image1) {
+static void cleanup(GLTestContext* glctx0, GrGLuint texID0, GLTestContext* glctx1,
+                    sk_sp<GrContext> grctx1, const GrGLTextureInfo* grbackendtex1,
+                    GrEGLImage image1) {
     if (glctx1) {
         glctx1->makeCurrent();
         if (grctx1) {
@@ -31,7 +32,6 @@
                 GrBackendObject handle = reinterpret_cast<GrBackendObject>(grbackendtex1);
                 gpu1->deleteTestingOnlyBackendTexture(handle, false);
             }
-            grctx1->unref();
         }
         if (GR_EGL_NO_IMAGE != image1) {
             glctx1->destroyEGLImage(image1);
@@ -63,7 +63,7 @@
     if (!glCtx1) {
         return;
     }
-    GrContext* context1 = GrContext::Create(kOpenGL_GrBackend, (GrBackendContext)glCtx1->gl());
+    sk_sp<GrContext> context1 = GrContext::MakeGL(glCtx1->gl());
     const GrGLTextureInfo* backendTexture1 = nullptr;
     GrEGLImage image = GR_EGL_NO_IMAGE;
     GrGLTextureInfo externalTexture;
diff --git a/tests/GpuSampleLocationsTest.cpp b/tests/GpuSampleLocationsTest.cpp
index 6c5d4a6..0f8fd7f 100644
--- a/tests/GpuSampleLocationsTest.cpp
+++ b/tests/GpuSampleLocationsTest.cpp
@@ -186,7 +186,7 @@
 
 DEF_GPUTEST(GLSampleLocations, reporter, /*factory*/) {
     GLTestSampleLocationsInterface testInterface;
-    sk_sp<GrContext> ctx(GrContext::Create(kOpenGL_GrBackend, testInterface));
+    sk_sp<GrContext> ctx(GrContext::MakeGL(&testInterface));
 
     // This test relies on at least 2 samples.
     int supportedSample = ctx->caps()->getSampleCount(2, kRGBA_8888_GrPixelConfig);
diff --git a/tests/ResourceCacheTest.cpp b/tests/ResourceCacheTest.cpp
index b27aaea..48f50a0 100644
--- a/tests/ResourceCacheTest.cpp
+++ b/tests/ResourceCacheTest.cpp
@@ -358,7 +358,7 @@
 class Mock {
 public:
     Mock(int maxCnt, size_t maxBytes) {
-        fContext.reset(GrContext::Create(kMock_GrBackend, (GrBackendContext) nullptr));
+        fContext = GrContext::MakeMock(nullptr);
         SkASSERT(fContext);
         fContext->setResourceCacheLimits(maxCnt, maxBytes);
         GrResourceCache* cache = fContext->getResourceCache();
diff --git a/tools/fiddle/egl_context.cpp b/tools/fiddle/egl_context.cpp
index 107bb4f..696a86f 100644
--- a/tools/fiddle/egl_context.cpp
+++ b/tools/fiddle/egl_context.cpp
@@ -77,5 +77,5 @@
     }
     eglTerminate(eglDpy);
 
-    return sk_sp<GrContext>(GrContext::Create(kOpenGL_GrBackend, (GrBackendContext)interface));
+    return sk_sp<GrContext>(GrContext::MakeGL(interface));
 }
diff --git a/tools/fiddle/mesa_context.cpp b/tools/fiddle/mesa_context.cpp
index 3b3726b..89902ec 100644
--- a/tools/fiddle/mesa_context.cpp
+++ b/tools/fiddle/mesa_context.cpp
@@ -27,7 +27,5 @@
     if (!mesa) {
         return nullptr;
     }
-    return sk_sp<GrContext>(GrContext::Create(
-                kOpenGL_GrBackend,
-                reinterpret_cast<intptr_t>(mesa.get())));
+    return GrContext::MakeGL(mesa.get());
 }
diff --git a/tools/gpu/GrContextFactory.cpp b/tools/gpu/GrContextFactory.cpp
index 0686b79..b3ca1d9 100644
--- a/tools/gpu/GrContextFactory.cpp
+++ b/tools/gpu/GrContextFactory.cpp
@@ -133,8 +133,6 @@
     }
 
     std::unique_ptr<TestContext> testCtx;
-    GrBackendContext backendContext = 0;
-    sk_sp<const GrGLInterface> glInterface;
     GrBackend backend = ContextTypeBackend(type);
     switch (backend) {
         case kOpenGL_GrBackend: {
@@ -194,8 +192,6 @@
                 return ContextInfo();
             }
             testCtx.reset(glCtx);
-            glInterface.reset(SkRef(glCtx->gl()));
-            backendContext = reinterpret_cast<GrBackendContext>(glInterface.get());
             break;
         }
 #ifdef SK_VULKAN
@@ -220,7 +216,6 @@
                     fSentinelGLContext.reset(CreatePlatformGLTestContext(kGLES_GrGLStandard));
                 }
             }
-            backendContext = testCtx->backendContext();
             break;
         }
 #endif
@@ -244,7 +239,6 @@
             if (!testCtx) {
                 return ContextInfo();
             }
-            backendContext = testCtx->backendContext();
             break;
         }
         default:
@@ -266,9 +260,6 @@
         grOptions.fAvoidStencilBuffers = true;
     }
     sk_sp<GrContext> grCtx = testCtx->makeGrContext(grOptions);
-    if (!grCtx.get() && kMetal_GrBackend != backend) {
-        grCtx.reset(GrContext::Create(backend, backendContext, grOptions));
-    }
     if (!grCtx.get()) {
         return ContextInfo();
     }
diff --git a/tools/gpu/gl/GLTestContext.cpp b/tools/gpu/gl/GLTestContext.cpp
index abbb8a6..91fa82f 100644
--- a/tools/gpu/gl/GLTestContext.cpp
+++ b/tools/gpu/gl/GLTestContext.cpp
@@ -7,6 +7,7 @@
 
 #include "GLTestContext.h"
 
+#include "GrContext.h"
 #include "GpuTimer.h"
 #include "gl/GrGLUtil.h"
 
@@ -286,4 +287,9 @@
                                      externalFormat, externalType, data));
     return id;
 }
+
+sk_sp<GrContext> GLTestContext::makeGrContext(const GrContextOptions& options) {
+    return GrContext::MakeGL(fGL.get(), options);
+}
+
 }  // namespace sk_gpu_test
diff --git a/tools/gpu/gl/GLTestContext.h b/tools/gpu/gl/GLTestContext.h
index f5afa31..701000e 100644
--- a/tools/gpu/gl/GLTestContext.h
+++ b/tools/gpu/gl/GLTestContext.h
@@ -75,6 +75,8 @@
         }
     }
 
+    sk_sp<GrContext> makeGrContext(const GrContextOptions& options) override;
+
 protected:
     GLTestContext();
 
diff --git a/tools/gpu/mock/MockTestContext.cpp b/tools/gpu/mock/MockTestContext.cpp
index 56cd68c..68941ad 100644
--- a/tools/gpu/mock/MockTestContext.cpp
+++ b/tools/gpu/mock/MockTestContext.cpp
@@ -10,6 +10,8 @@
 
 #include "MockTestContext.h"
 
+#include "GrContext.h"
+
 namespace {
 
 class MockTestContext : public sk_gpu_test::TestContext {
@@ -25,6 +27,10 @@
     void submit() override {}
     void finish() override {}
 
+    sk_sp<GrContext> makeGrContext(const GrContextOptions& options) override {
+        return GrContext::MakeMock(nullptr, options);
+    }
+
 protected:
     void teardown() override {}
     void onPlatformMakeCurrent() const override {}
diff --git a/tools/gpu/vk/VkTestContext.cpp b/tools/gpu/vk/VkTestContext.cpp
index 125ead2..e329583 100644
--- a/tools/gpu/vk/VkTestContext.cpp
+++ b/tools/gpu/vk/VkTestContext.cpp
@@ -9,6 +9,7 @@
 
 #ifdef SK_VULKAN
 
+#include "GrContext.h"
 #include "vk/GrVkInterface.h"
 #include "vk/GrVkUtil.h"
 #include <vulkan/vulkan.h>
@@ -131,6 +132,10 @@
 
     void finish() override {}
 
+    sk_sp<GrContext> makeGrContext(const GrContextOptions& options) override {
+        return GrContext::MakeVulkan(fVk.get(), options);
+    }
+
 protected:
     void teardown() override {
         INHERITED::teardown();
diff --git a/tools/viewer/sk_app/GLWindowContext.cpp b/tools/viewer/sk_app/GLWindowContext.cpp
index 2f0d5dc..682fcbf 100644
--- a/tools/viewer/sk_app/GLWindowContext.cpp
+++ b/tools/viewer/sk_app/GLWindowContext.cpp
@@ -31,11 +31,10 @@
 
 void GLWindowContext::initializeContext() {
     this->onInitializeContext();
-    SkASSERT(nullptr == fContext);
+    SkASSERT(!fContext);
 
     fBackendContext.reset(GrGLCreateNativeInterface());
-    fContext = GrContext::Create(kOpenGL_GrBackend, (GrBackendContext)fBackendContext.get(),
-                                 fDisplayParams.fGrContextOptions);
+    fContext = GrContext::MakeGL(fBackendContext.get(), fDisplayParams.fGrContextOptions);
     if (!fContext && fDisplayParams.fMSAASampleCount) {
         fDisplayParams.fMSAASampleCount /= 2;
         this->initializeContext();
@@ -58,8 +57,7 @@
     if (fContext) {
         // in case we have outstanding refs to this guy (lua?)
         fContext->abandonContext();
-        fContext->unref();
-        fContext = nullptr;
+        fContext.reset();
     }
 
     fBackendContext.reset(nullptr);
@@ -83,7 +81,7 @@
                                             fPixelConfig,
                                             fbInfo);
 
-            fSurface = SkSurface::MakeFromBackendRenderTarget(fContext, backendRT,
+            fSurface = SkSurface::MakeFromBackendRenderTarget(fContext.get(), backendRT,
                                                               kBottomLeft_GrSurfaceOrigin,
                                                               fDisplayParams.fColorSpace,
                                                               &fSurfaceProps);
diff --git a/tools/viewer/sk_app/VulkanWindowContext.cpp b/tools/viewer/sk_app/VulkanWindowContext.cpp
index 261206c..a9124d5 100644
--- a/tools/viewer/sk_app/VulkanWindowContext.cpp
+++ b/tools/viewer/sk_app/VulkanWindowContext.cpp
@@ -67,8 +67,7 @@
     GET_DEV_PROC(AcquireNextImageKHR);
     GET_DEV_PROC(QueuePresentKHR);
 
-    fContext = GrContext::Create(kVulkan_GrBackend, (GrBackendContext) fBackendContext.get(),
-                                 fDisplayParams.fGrContextOptions);
+    fContext = GrContext::MakeVulkan(fBackendContext.get(), fDisplayParams.fGrContextOptions);
 
     fSurface = fCreateVkSurfaceFn(instance);
     if (VK_NULL_HANDLE == fSurface) {
@@ -280,7 +279,7 @@
 
         GrBackendTexture backendTex(fWidth, fHeight, info);
 
-        fSurfaces[i] = SkSurface::MakeFromBackendTextureAsRenderTarget(fContext, backendTex,
+        fSurfaces[i] = SkSurface::MakeFromBackendTextureAsRenderTarget(fContext.get(), backendTex,
                                                                        kTopLeft_GrSurfaceOrigin,
                                                                        fSampleCount,
                                                                        fDisplayParams.fColorSpace,
@@ -412,7 +411,7 @@
         fSurface = VK_NULL_HANDLE;
     }
 
-    fContext->unref();
+    fContext.reset();
 
     fBackendContext.reset(nullptr);
 }
diff --git a/tools/viewer/sk_app/WindowContext.h b/tools/viewer/sk_app/WindowContext.h
index fbd2756..cd4c357 100644
--- a/tools/viewer/sk_app/WindowContext.h
+++ b/tools/viewer/sk_app/WindowContext.h
@@ -8,11 +8,11 @@
 #define WindowContext_DEFINED
 
 #include "DisplayParams.h"
+#include "GrContext.h"
 #include "GrTypes.h"
 #include "SkRefCnt.h"
 #include "SkSurfaceProps.h"
 
-class GrContext;
 class SkSurface;
 class GrRenderTarget;
 
@@ -46,7 +46,7 @@
     }
 
     virtual GrBackendContext getBackendContext() = 0;
-    GrContext* getGrContext() const { return fContext; }
+    GrContext* getGrContext() const { return fContext.get(); }
 
     int width() const { return fWidth; }
     int height() const { return fHeight; }
@@ -56,7 +56,7 @@
 protected:
     virtual bool isGpuContext() { return true;  }
 
-    GrContext*        fContext;
+    sk_sp<GrContext>        fContext;
 
     int               fWidth;
     int               fHeight;