Reland "Factor out ContextType from GrContextFactory."

This reverts commit d9cba129434323d2d5d543303fd63730fa1deab3.

Reason for revert: fixing Bazel test runner

Original change's description:
> Revert "Factor out ContextType from GrContextFactory."
>
> This reverts commit d7d56885a49b54fe570b51134668b6ec4179af4b.
>
> Reason for revert: breaking Bazel build
>
> Original change's description:
> > Factor out ContextType from GrContextFactory.
> >
> > This solves a TODO and helps disentangle Graphite from Ganesh's
> > GrContextFactory. (I bumped into this while trying to remove
> > GrBackendApi::kDawn.)
> >
> > Change-Id: Ie2529c2b38fb9f0a188de32fbf33600899e90053
> > Reviewed-on: https://skia-review.googlesource.com/c/skia/+/746788
> > Reviewed-by: Brian Osman <[email protected]>
> > Commit-Queue: John Stiles <[email protected]>
> > Auto-Submit: John Stiles <[email protected]>
>
> Change-Id: I24e1e30eeeba0117ea569c1a222601ec16e0d734
> No-Presubmit: true
> No-Tree-Checks: true
> No-Try: true
> Reviewed-on: https://skia-review.googlesource.com/c/skia/+/747156
> Commit-Queue: John Stiles <[email protected]>
> Bot-Commit: Rubber Stamper <[email protected]>

Change-Id: I9511a30ea9a08e34cfa6985a0ba0094090ffccf0
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/747176
Auto-Submit: John Stiles <[email protected]>
Reviewed-by: Robert Phillips <[email protected]>
Commit-Queue: John Stiles <[email protected]>
diff --git a/BUILD.gn b/BUILD.gn
index 7ad88ff..c42df58 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -1951,6 +1951,8 @@
       "tools/gpu/BackendSurfaceFactory.h",
       "tools/gpu/BackendTextureImageFactory.cpp",
       "tools/gpu/BackendTextureImageFactory.h",
+      "tools/gpu/ContextType.cpp",
+      "tools/gpu/ContextType.h",
       "tools/gpu/FlushFinishTracker.cpp",
       "tools/gpu/FlushFinishTracker.h",
       "tools/gpu/GrContextFactory.cpp",
diff --git a/bench/nanobench.cpp b/bench/nanobench.cpp
index a48ede6..2367dfc 100644
--- a/bench/nanobench.cpp
+++ b/bench/nanobench.cpp
@@ -544,7 +544,7 @@
     return loops;
 }
 
-#define kBogusContextType GrContextFactory::kGL_ContextType
+#define kBogusContextType skgpu::ContextType::kGL
 #define kBogusContextOverrides GrContextFactory::ContextOverrides::kNone
 
 static std::optional<Config> create_config(const SkCommandLineConfig* config) {
diff --git a/dm/DMGpuTestProcs.cpp b/dm/DMGpuTestProcs.cpp
index 359d9a8..b7cc2d6 100644
--- a/dm/DMGpuTestProcs.cpp
+++ b/dm/DMGpuTestProcs.cpp
@@ -26,42 +26,42 @@
 
 namespace skiatest {
 
-bool IsGLContextType(sk_gpu_test::GrContextFactory::ContextType type) {
-    return GrBackendApi::kOpenGL == GrContextFactory::ContextTypeBackend(type);
+bool IsGLContextType(skgpu::ContextType type) {
+    return GrBackendApi::kOpenGL == sk_gpu_test::GrContextFactory::ContextTypeBackend(type);
 }
-bool IsVulkanContextType(sk_gpu_test::GrContextFactory::ContextType type) {
-    return GrBackendApi::kVulkan == GrContextFactory::ContextTypeBackend(type);
+bool IsVulkanContextType(skgpu::ContextType type) {
+    return GrBackendApi::kVulkan == sk_gpu_test::GrContextFactory::ContextTypeBackend(type);
 }
-bool IsMetalContextType(sk_gpu_test::GrContextFactory::ContextType type) {
-    return GrBackendApi::kMetal == GrContextFactory::ContextTypeBackend(type);
+bool IsMetalContextType(skgpu::ContextType type) {
+    return GrBackendApi::kMetal == sk_gpu_test::GrContextFactory::ContextTypeBackend(type);
 }
-bool IsDirect3DContextType(sk_gpu_test::GrContextFactory::ContextType type) {
-    return GrBackendApi::kDirect3D == GrContextFactory::ContextTypeBackend(type);
+bool IsDirect3DContextType(skgpu::ContextType type) {
+    return GrBackendApi::kDirect3D == sk_gpu_test::GrContextFactory::ContextTypeBackend(type);
 }
-bool IsDawnContextType(sk_gpu_test::GrContextFactory::ContextType type) {
-    return GrBackendApi::kDawn == GrContextFactory::ContextTypeBackend(type);
+bool IsDawnContextType(skgpu::ContextType type) {
+    return GrBackendApi::kDawn == sk_gpu_test::GrContextFactory::ContextTypeBackend(type);
 }
-bool IsRenderingGLContextType(sk_gpu_test::GrContextFactory::ContextType type) {
+bool IsRenderingGLContextType(skgpu::ContextType type) {
     return IsGLContextType(type) && GrContextFactory::IsRenderingContext(type);
 }
-bool IsMockContextType(sk_gpu_test::GrContextFactory::ContextType type) {
-    return type == GrContextFactory::kMock_ContextType;
+bool IsMockContextType(skgpu::ContextType type) {
+    return type == skgpu::ContextType::kMock;
 }
 
 void RunWithGaneshTestContexts(GrContextTestFn* testFn, GrContextTypeFilterFn* filter,
                                Reporter* reporter, const GrContextOptions& options) {
 #if defined(SK_BUILD_FOR_UNIX) || defined(SK_BUILD_FOR_WIN) || defined(SK_BUILD_FOR_MAC)
-    static constexpr auto kNativeGLType = GrContextFactory::kGL_ContextType;
+    static constexpr auto kNativeGLType = skgpu::ContextType::kGL;
 #else
-    static constexpr auto kNativeGLType = GrContextFactory::kGLES_ContextType;
+    static constexpr auto kNativeGLType = skgpu::ContextType::kGLES;
 #endif
 
-    for (int typeInt = 0; typeInt < GrContextFactory::kContextTypeCnt; ++typeInt) {
-        GrContextFactory::ContextType contextType = (GrContextFactory::ContextType) typeInt;
+    for (int typeInt = 0; typeInt < skgpu::kContextTypeCount; ++typeInt) {
+        skgpu::ContextType contextType = static_cast<skgpu::ContextType>(typeInt);
         // Use "native" instead of explicitly trying OpenGL and OpenGL ES. Do not use GLES on
         // desktop since tests do not account for not fixing http://skbug.com/2809
-        if (contextType == GrContextFactory::kGL_ContextType ||
-            contextType == GrContextFactory::kGLES_ContextType) {
+        if (contextType == skgpu::ContextType::kGL ||
+            contextType == skgpu::ContextType::kGLES) {
             if (contextType != kNativeGLType) {
                 continue;
             }
@@ -76,7 +76,7 @@
             continue;
         }
 
-        ReporterContext ctx(reporter, SkString(GrContextFactory::ContextTypeName(contextType)));
+        ReporterContext ctx(reporter, SkString(skgpu::ContextTypeName(contextType)));
         if (ctxInfo.directContext()) {
             (*testFn)(reporter, ctxInfo);
             // In case the test changed the current context make sure we move it back before
@@ -97,8 +97,8 @@
                                  Reporter* reporter,
                                  const skgpu::graphite::ContextOptions& ctxOptions) {
     ContextFactory factory(ctxOptions);
-    for (int typeInt = 0; typeInt < GrContextFactory::kContextTypeCnt; ++typeInt) {
-        GrContextFactory::ContextType contextType = (GrContextFactory::ContextType)typeInt;
+    for (int typeInt = 0; typeInt < skgpu::kContextTypeCount; ++typeInt) {
+        skgpu::ContextType contextType = static_cast<skgpu::ContextType>(typeInt);
         if (filter && !(*filter)(contextType)) {
             continue;
         }
@@ -108,7 +108,7 @@
             continue;
         }
 
-        ReporterContext ctx(reporter, SkString(GrContextFactory::ContextTypeName(contextType)));
+        ReporterContext ctx(reporter, SkString(skgpu::ContextTypeName(contextType)));
         (*test)(reporter, context);
     }
 }
diff --git a/dm/DMSrcSink.h b/dm/DMSrcSink.h
index 47bf93f..6e22e34 100644
--- a/dm/DMSrcSink.h
+++ b/dm/DMSrcSink.h
@@ -381,7 +381,7 @@
                   std::function<void(GrDirectContext*)> initContext = nullptr,
                   std::function<SkCanvas*(SkCanvas*)> wrapCanvas = nullptr) const;
 
-    sk_gpu_test::GrContextFactory::ContextType contextType() const { return fContextType; }
+    skgpu::ContextType contextType() const { return fContextType; }
     const sk_gpu_test::GrContextFactory::ContextOverrides& contextOverrides() const {
         return fContextOverrides;
     }
@@ -404,7 +404,7 @@
     bool readBack(SkSurface*, SkBitmap* dst) const;
 
 private:
-    sk_gpu_test::GrContextFactory::ContextType        fContextType;
+    skgpu::ContextType                                fContextType;
     sk_gpu_test::GrContextFactory::ContextOverrides   fContextOverrides;
     SkCommandLineConfigGpu::SurfType                  fSurfType;
     int                                               fSampleCount;
@@ -573,8 +573,6 @@
 
 class GraphiteSink : public Sink {
 public:
-    using ContextType = sk_gpu_test::GrContextFactory::ContextType;
-
     GraphiteSink(const SkCommandLineConfigGraphite*);
 
     Result draw(const Src&, SkBitmap*, SkWStream*, SkString*) const override;
@@ -588,7 +586,7 @@
 
 private:
     skgpu::graphite::ContextOptions fBaseContextOptions;
-    ContextType fContextType;
+    skgpu::ContextType fContextType;
     SkColorType fColorType;
     SkAlphaType fAlphaType;
     sk_sp<SkColorSpace> fColorSpace;
diff --git a/fuzz/FuzzCanvas.cpp b/fuzz/FuzzCanvas.cpp
index 284333d..268a79b 100644
--- a/fuzz/FuzzCanvas.cpp
+++ b/fuzz/FuzzCanvas.cpp
@@ -1622,7 +1622,7 @@
 
 DEF_FUZZ(MockGPUCanvas, fuzz) {
     sk_gpu_test::GrContextFactory f;
-    fuzz_ganesh(fuzz, f.get(sk_gpu_test::GrContextFactory::kMock_ContextType));
+    fuzz_ganesh(fuzz, f.get(skgpu::ContextType::kMock));
 }
 #endif
 
@@ -1643,9 +1643,9 @@
 
 DEF_FUZZ(NativeGLCanvas, fuzz) {
     sk_gpu_test::GrContextFactory f;
-    auto context = f.get(sk_gpu_test::GrContextFactory::kGL_ContextType);
+    auto context = f.get(skgpu::ContextType::kGL);
     if (!context) {
-        context = f.get(sk_gpu_test::GrContextFactory::kGLES_ContextType);
+        context = f.get(skgpu::ContextType::kGLES);
     }
     if (FLAGS_gpuInfo) {
         dump_GPU_info(context);
diff --git a/fuzz/FuzzCreateDDL.cpp b/fuzz/FuzzCreateDDL.cpp
index ec9da26..8b8bbaa 100644
--- a/fuzz/FuzzCreateDDL.cpp
+++ b/fuzz/FuzzCreateDDL.cpp
@@ -25,7 +25,7 @@
  * The fuzzer aims to fuzz the use of GrDeferredDisplayList. It mainly consists of
  * three parts.
  * 1. In create_surface_characterization, (make_characterization) Create GrSurfaceCharacterization
- * by using GrDirectContext of kGL_ContextType as it can be applied on all platform, and
+ * by using GrDirectContext of ContextType::kGL as it can be applied on all platform, and
  * (make_surface) create a GPU backend surface of the same GrDirectContext
  * 2. (make_ddl) Create GrDeferredDisplayListRecorder from the GrSurfaceCharacterization, and test
  * the recoder's corresponding canvas.
@@ -209,7 +209,7 @@
     fuzz->nextEnum(&origin, GrSurfaceOrigin::kTopLeft_GrSurfaceOrigin);
 
     sk_gpu_test::GrContextFactory factory;
-    auto ctxInfo = factory.getContextInfo(sk_gpu_test::GrContextFactory::kGL_ContextType);
+    auto ctxInfo = factory.getContextInfo(skgpu::ContextType::kGL);
 
     GrDirectContext* dContext = ctxInfo.directContext();
     if (!dContext) {
diff --git a/fuzz/FuzzDDLThreading.cpp b/fuzz/FuzzDDLThreading.cpp
index 86e25fc..545302e 100644
--- a/fuzz/FuzzDDLThreading.cpp
+++ b/fuzz/FuzzDDLThreading.cpp
@@ -301,5 +301,5 @@
 }
 
 DEF_FUZZ(DDLThreadingGL, fuzz) {
-    DDLFuzzer(fuzz, ContextType::kGL_ContextType).run();
+    DDLFuzzer(fuzz, skgpu::ContextType::kGL).run();
 }
diff --git a/fuzz/FuzzPrecompile.cpp b/fuzz/FuzzPrecompile.cpp
index efc1536..7bc7399 100644
--- a/fuzz/FuzzPrecompile.cpp
+++ b/fuzz/FuzzPrecompile.cpp
@@ -411,11 +411,11 @@
 
     sk_gpu_test::GrContextFactory::ContextType contextType;
 #if defined(SK_METAL)
-    contextType = sk_gpu_test::GrContextFactory::kMetal_ContextType;
+    contextType = skgpu::ContextType::kMetal;
 #elif defined(SK_VULKAN)
-    contextType = sk_gpu_test::GrContextFactory::kVulkan_ContextType;
+    contextType = skgpu::ContextType::kVulkan;
 #else
-    contextType = sk_gpu_test::GrContextFactory::kMock_ContextType;
+    contextType = skgpu::ContextType::kMock;
 #endif
 
     auto [_, context] = factory.getContextInfo(contextType);
diff --git a/gm/surface_manager/GaneshGLSurfaceManager.cpp b/gm/surface_manager/GaneshGLSurfaceManager.cpp
index a4d6743..33dff86 100644
--- a/gm/surface_manager/GaneshGLSurfaceManager.cpp
+++ b/gm/surface_manager/GaneshGLSurfaceManager.cpp
@@ -48,7 +48,7 @@
         GrContextOptions grCtxOptions;
         auto testFactory = std::make_unique<sk_gpu_test::GrContextFactory>(grCtxOptions);
         sk_gpu_test::ContextInfo contextInfo = testFactory.get()->getContextInfo(
-                sk_gpu_test::GrContextFactory::kGLES_ContextType,
+                skgpu::ContextType::kGLES,
                 sk_gpu_test::GrContextFactory::ContextOverrides::kNone);
         GrDirectContext* context = contextInfo.directContext();
         SkASSERT_RELEASE(context);
diff --git a/modules/canvaskit/gm_bindings.cpp b/modules/canvaskit/gm_bindings.cpp
index e5ec1de..361db91 100644
--- a/modules/canvaskit/gm_bindings.cpp
+++ b/modules/canvaskit/gm_bindings.cpp
@@ -32,6 +32,7 @@
 #include "tools/ResourceFactory.h"
 #include "tools/flags/CommandLineFlags.h"
 #include "tools/fonts/TestFontMgr.h"
+#include "tools/gpu/ContextType.h"
 
 using namespace emscripten;
 
@@ -267,27 +268,27 @@
 
 namespace skiatest {
 
-using ContextType = sk_gpu_test::GrContextFactory::ContextType;
+using ContextType = skgpu::ContextType;
 
 // These are the supported GrContextTypeFilterFn. They are defined in Test.h and implemented here.
-bool IsGLContextType(ContextType ct) {
+bool IsGLContextType(skgpu::ContextType ct) {
     return GrBackendApi::kOpenGL == sk_gpu_test::GrContextFactory::ContextTypeBackend(ct);
 }
-bool IsRenderingGLContextType(ContextType ct) {
+bool IsRenderingGLContextType(skgpu::ContextType ct) {
     return IsGLContextType(ct) && sk_gpu_test::GrContextFactory::IsRenderingContext(ct);
 }
-bool IsMockContextType(ContextType ct) {
-    return ct == ContextType::kMock_ContextType;
+bool IsMockContextType(skgpu::ContextType ct) {
+    return ct == skgpu::ContextType::kMock;
 }
 // These are not supported
-bool IsVulkanContextType(ContextType) {return false;}
-bool IsMetalContextType(ContextType) {return false;}
-bool IsDirect3DContextType(ContextType) {return false;}
-bool IsDawnContextType(ContextType) {return false;}
+bool IsVulkanContextType(ContextType) { return false; }
+bool IsMetalContextType(ContextType) { return false; }
+bool IsDirect3DContextType(ContextType) { return false; }
+bool IsDawnContextType(ContextType) { return false; }
 
 void RunWithGaneshTestContexts(GrContextTestFn* testFn, GrContextTypeFilterFn* filter,
                                Reporter* reporter, const GrContextOptions& options) {
-    for (auto contextType : {ContextType::kGLES_ContextType, ContextType::kMock_ContextType}) {
+    for (auto contextType : {skgpu::ContextType::kGLES, skgpu::ContextType::kMock}) {
         if (filter && !(*filter)(contextType)) {
             continue;
         }
diff --git a/modules/skottie/src/SkottieTool.cpp b/modules/skottie/src/SkottieTool.cpp
index 957ef05..8e30fa9 100644
--- a/modules/skottie/src/SkottieTool.cpp
+++ b/modules/skottie/src/SkottieTool.cpp
@@ -324,8 +324,7 @@
     GPUGenerator(FrameSink* sink, const SkMatrix& matrix)
         : FrameGenerator(sink)
     {
-        fCtx = fFactory.getContextInfo(sk_gpu_test::GrContextFactory::kGL_ContextType)
-                           .directContext();
+        fCtx = fFactory.getContextInfo(skgpu::ContextType::kGL).directContext();
         fSurface = SkSurfaces::RenderTarget(fCtx,
                                             skgpu::Budgeted::kNo,
                                             SkImageInfo::MakeN32Premul(FLAGS_width, FLAGS_height),
diff --git a/tests/BackendAllocationTest.cpp b/tests/BackendAllocationTest.cpp
index 13929fd..5873753 100644
--- a/tests/BackendAllocationTest.cpp
+++ b/tests/BackendAllocationTest.cpp
@@ -50,6 +50,7 @@
 #include "tests/Test.h"
 #include "tests/TestUtils.h"
 #include "tools/ToolUtils.h"
+#include "tools/gpu/ContextType.h"
 #include "tools/gpu/ManagedBackendTexture.h"
 #include "tools/gpu/ProxyUtils.h"
 
@@ -756,8 +757,8 @@
 }
 
 DEF_GANESH_TEST(ColorTypeBackendAllocationTest, reporter, options, CtsEnforcement::kApiLevel_T) {
-    for (int t = 0; t < sk_gpu_test::GrContextFactory::kContextTypeCnt; ++t) {
-        auto type = static_cast<sk_gpu_test::GrContextFactory::ContextType>(t);
+    for (int t = 0; t < skgpu::kContextTypeCount; ++t) {
+        auto type = static_cast<skgpu::ContextType>(t);
         if (!sk_gpu_test::GrContextFactory::IsRenderingContext(type)) {
             continue;
         }
diff --git a/tests/BazelTestRunner.cpp b/tests/BazelTestRunner.cpp
index e3b016b..ed29599 100644
--- a/tests/BazelTestRunner.cpp
+++ b/tests/BazelTestRunner.cpp
@@ -21,6 +21,7 @@
 #include "include/gpu/GrDirectContext.h"
 #include "include/gpu/GrTypes.h"
 #include "include/private/gpu/ganesh/GrTypesPriv.h"
+#include "tools/gpu/ContextType.h"
 #include "tools/gpu/TestContext.h"
 #endif
 
@@ -50,46 +51,46 @@
 
 #if defined(SK_GANESH)
 namespace skiatest {
-bool IsGLContextType(sk_gpu_test::GrContextFactory::ContextType type) {
+bool IsGLContextType(skgpu::ContextType type) {
     return GrBackendApi::kOpenGL == sk_gpu_test::GrContextFactory::ContextTypeBackend(type);
 }
-bool IsVulkanContextType(sk_gpu_test::GrContextFactory::ContextType type) {
+bool IsVulkanContextType(skgpu::ContextType type) {
     return GrBackendApi::kVulkan == sk_gpu_test::GrContextFactory::ContextTypeBackend(type);
 }
-bool IsMetalContextType(sk_gpu_test::GrContextFactory::ContextType type) {
+bool IsMetalContextType(skgpu::ContextType type) {
     return GrBackendApi::kMetal == sk_gpu_test::GrContextFactory::ContextTypeBackend(type);
 }
-bool IsDirect3DContextType(sk_gpu_test::GrContextFactory::ContextType type) {
+bool IsDirect3DContextType(skgpu::ContextType type) {
     return GrBackendApi::kDirect3D == sk_gpu_test::GrContextFactory::ContextTypeBackend(type);
 }
-bool IsDawnContextType(sk_gpu_test::GrContextFactory::ContextType type) {
+bool IsDawnContextType(skgpu::ContextType type) {
     return GrBackendApi::kDawn == sk_gpu_test::GrContextFactory::ContextTypeBackend(type);
 }
-bool IsRenderingGLContextType(sk_gpu_test::GrContextFactory::ContextType type) {
+bool IsRenderingGLContextType(skgpu::ContextType type) {
     return IsGLContextType(type) && sk_gpu_test::GrContextFactory::IsRenderingContext(type);
 }
-bool IsMockContextType(sk_gpu_test::GrContextFactory::ContextType type) {
-    return type == sk_gpu_test::GrContextFactory::kMock_ContextType;
+bool IsMockContextType(skgpu::ContextType type) {
+    return type == skgpu::ContextType::kMock;
 }
 
-sk_gpu_test::GrContextFactory::ContextType compiledInContextTypes[] = {
+skgpu::ContextType compiledInContextTypes[] = {
 #if defined(SK_GL)
     // Use "native" instead of explicitly trying both OpenGL and OpenGL ES. Do not use GLES on
     // desktop since tests do not account for not fixing http://skbug.com/2809
 #if defined(SK_BUILD_FOR_UNIX) || defined(SK_BUILD_FOR_WIN) || defined(SK_BUILD_FOR_MAC)
-    sk_gpu_test::GrContextFactory::kGL_ContextType,
+    skgpu::ContextType::kGL,
 #else
-    sk_gpu_test::GrContextFactory::kGLES_ContextType,
+    skgpu::ContextType::kGLES,
 #endif
 #endif // defined(SK_GL)
 #if defined(SK_VULKAN)
-    sk_gpu_test::GrContextFactory::kVulkan_ContextType,
+    skgpu::ContextType::kVulkan,
 #endif
 #if defined(SK_DAWN)
-    sk_gpu_test::GrContextFactory::kDawn_ContextType,
+    skgpu::ContextType::kDawn,
 #endif
 // TODO(kjlubick) Other Ganesh backends
-    sk_gpu_test::GrContextFactory::kMock_ContextType,
+    skgpu::ContextType::kMock,
 };
 
 // The macros defined in Test.h eventually call into this function. For each GPU backend that is
@@ -98,7 +99,7 @@
                                Reporter* reporter, const GrContextOptions& options) {
     sk_gpu_test::GrContextFactory factory(options);
 
-    for (sk_gpu_test::GrContextFactory::ContextType ctxType : compiledInContextTypes) {
+    for (skgpu::ContextType ctxType : compiledInContextTypes) {
         if (filter && !(*filter)(ctxType)) {
             continue;
         }
diff --git a/tests/GrContextAbandonTest.cpp b/tests/GrContextAbandonTest.cpp
index 0aac2ee..af50311 100644
--- a/tests/GrContextAbandonTest.cpp
+++ b/tests/GrContextAbandonTest.cpp
@@ -9,6 +9,7 @@
 #include "include/gpu/GrDirectContext.h"
 #include "tests/CtsEnforcement.h"
 #include "tests/Test.h"
+#include "tools/gpu/ContextType.h"
 #include "tools/gpu/FenceSync.h"
 
 struct GrContextOptions;
@@ -17,9 +18,9 @@
 
 DEF_GANESH_TEST(GrContext_abandonContext, reporter, options, CtsEnforcement::kApiLevel_T) {
     for (int testType = 0; testType < 6; ++testType) {
-        for (int i = 0; i < GrContextFactory::kContextTypeCnt; ++i) {
+        for (int i = 0; i < skgpu::kContextTypeCount; ++i) {
             GrContextFactory testFactory(options);
-            GrContextFactory::ContextType ctxType = (GrContextFactory::ContextType) i;
+            auto ctxType = static_cast<skgpu::ContextType>(i);
             ContextInfo info = testFactory.getContextInfo(ctxType);
             if (auto context = info.directContext()) {
                 switch (testType) {
diff --git a/tests/GrContextFactoryTest.cpp b/tests/GrContextFactoryTest.cpp
index 85ca362..44cf7a5 100644
--- a/tests/GrContextFactoryTest.cpp
+++ b/tests/GrContextFactoryTest.cpp
@@ -12,6 +12,7 @@
 #include "src/gpu/ganesh/GrDirectContextPriv.h"
 #include "tests/CtsEnforcement.h"
 #include "tests/Test.h"
+#include "tools/gpu/ContextType.h"
 #include "tools/gpu/FenceSync.h"
 
 #include <memory>
@@ -19,9 +20,9 @@
 using namespace sk_gpu_test;
 
 DEF_GANESH_TEST(GrContextFactory_abandon, reporter, options, CtsEnforcement::kNever) {
-    for (int i = 0; i < GrContextFactory::kContextTypeCnt; ++i) {
+    for (int i = 0; i < skgpu::kContextTypeCount; ++i) {
         GrContextFactory testFactory(options);
-        GrContextFactory::ContextType ctxType = (GrContextFactory::ContextType) i;
+        skgpu::ContextType ctxType = static_cast<skgpu::ContextType>(i);
         ContextInfo info1 = testFactory.getContextInfo(ctxType);
         if (!info1.directContext()) {
             continue;
@@ -44,9 +45,9 @@
 }
 
 DEF_GANESH_TEST(GrContextFactory_sharedContexts, reporter, options, CtsEnforcement::kApiLevel_T) {
-    for (int i = 0; i < GrContextFactory::kContextTypeCnt; ++i) {
+    for (int i = 0; i < skgpu::kContextTypeCount; ++i) {
         GrContextFactory testFactory(options);
-        GrContextFactory::ContextType ctxType = static_cast<GrContextFactory::ContextType>(i);
+        skgpu::ContextType ctxType = static_cast<skgpu::ContextType>(i);
         ContextInfo info1 = testFactory.getContextInfo(ctxType);
         if (!info1.directContext()) {
             continue;
@@ -82,7 +83,7 @@
 }
 
 DEF_GANESH_TEST(GrContextFactory_executorAndTaskGroup, reporter, options, CtsEnforcement::kNever) {
-    for (int i = 0; i < GrContextFactory::kContextTypeCnt; ++i) {
+    for (int i = 0; i < skgpu::kContextTypeCount; ++i) {
         // Verify that contexts have a task group iff we supply an executor with context options
         GrContextOptions contextOptions = options;
         contextOptions.fExecutor = nullptr;
@@ -92,7 +93,7 @@
         contextOptions.fExecutor = threadPool.get();
         GrContextFactory threadedFactory(contextOptions);
 
-        GrContextFactory::ContextType ctxType = static_cast<GrContextFactory::ContextType>(i);
+        skgpu::ContextType ctxType = static_cast<skgpu::ContextType>(i);
         ContextInfo serialInfo = serialFactory.getContextInfo(ctxType);
         if (auto serialContext = serialInfo.directContext()) {
             REPORTER_ASSERT(reporter, nullptr == serialContext->priv().getTaskGroup());
diff --git a/tests/GrContextOOM.cpp b/tests/GrContextOOM.cpp
index 95fa815..47d5314 100644
--- a/tests/GrContextOOM.cpp
+++ b/tests/GrContextOOM.cpp
@@ -21,14 +21,15 @@
 #include "include/gpu/ganesh/SkSurfaceGanesh.h"
 #include "tests/CtsEnforcement.h"
 #include "tests/Test.h"
+#include "tools/gpu/ContextType.h"
 
 DEF_GANESH_TEST(GrContext_oomed, reporter, originalOptions, CtsEnforcement::kApiLevel_T) {
     GrContextOptions options = originalOptions;
     options.fRandomGLOOM = true;
     options.fSkipGLErrorChecks = GrContextOptions::Enable::kNo;
     sk_gpu_test::GrContextFactory factory(options);
-    for (int ct = 0; ct < sk_gpu_test::GrContextFactory::kContextTypeCnt; ++ct) {
-        auto contextType = static_cast<sk_gpu_test::GrContextFactory::ContextType>(ct);
+    for (int ct = 0; ct < skgpu::kContextTypeCount; ++ct) {
+        auto contextType = static_cast<skgpu::ContextType>(ct);
         auto context = factory.get(contextType);
         if (!context) {
             continue;
diff --git a/tests/GrDDLImageTest.cpp b/tests/GrDDLImageTest.cpp
index 9ae143c..b0ee84b 100644
--- a/tests/GrDDLImageTest.cpp
+++ b/tests/GrDDLImageTest.cpp
@@ -24,14 +24,15 @@
 #include "include/private/chromium/GrSurfaceCharacterization.h"
 #include "tests/CtsEnforcement.h"
 #include "tests/Test.h"
+#include "tools/gpu/ContextType.h"
 
 class GrRecordingContext;
 struct GrContextOptions;
 
 DEF_GANESH_TEST(GrDDLImage_MakeSubset, reporter, options, CtsEnforcement::kApiLevel_T) {
     sk_gpu_test::GrContextFactory factory(options);
-    for (int ct = 0; ct < sk_gpu_test::GrContextFactory::kContextTypeCnt; ++ct) {
-        auto contextType = static_cast<sk_gpu_test::GrContextFactory::ContextType>(ct);
+    for (int ct = 0; ct < skgpu::kContextTypeCount; ++ct) {
+        auto contextType = static_cast<skgpu::ContextType>(ct);
         auto dContext = factory.get(contextType);
         if (!dContext) {
             continue;
diff --git a/tests/GrMeshTest.cpp b/tests/GrMeshTest.cpp
index 9947f41..dda48f7 100644
--- a/tests/GrMeshTest.cpp
+++ b/tests/GrMeshTest.cpp
@@ -76,7 +76,7 @@
 
 #if 0
 #include "tools/ToolUtils.h"
-#define WRITE_PNG_CONTEXT_TYPE kANGLE_D3D11_ES3_ContextType
+#define WRITE_PNG_CONTEXT_TYPE kANGLE_D3D11_ES3
 #endif
 
 SKGPU_DECLARE_STATIC_UNIQUE_KEY(gIndexBufferKey);
@@ -149,8 +149,8 @@
                      std::function<void(DrawMeshHelper*)> executeFn);
 
 #ifdef WRITE_PNG_CONTEXT_TYPE
-static bool IsContextTypeForOutputPNGs(skiatest::GrContextFactoryContextType type) {
-    return type == skiatest::GrContextFactoryContextType::WRITE_PNG_CONTEXT_TYPE;
+static bool IsContextTypeForOutputPNGs(skgpu::ContextType type) {
+    return type == skgpu::ContextType::WRITE_PNG_CONTEXT_TYPE;
 }
 DEF_GANESH_TEST_FOR_CONTEXTS(GrMeshTest, IsContextTypeForOutputPNGs, reporter, ctxInfo, nullptr) {
 #else
diff --git a/tests/GrPorterDuffTest.cpp b/tests/GrPorterDuffTest.cpp
index 0843cbf..d02c825 100644
--- a/tests/GrPorterDuffTest.cpp
+++ b/tests/GrPorterDuffTest.cpp
@@ -35,6 +35,7 @@
 #include "src/gpu/ganesh/effects/GrPorterDuffXferProcessor.h"
 #include "tests/CtsEnforcement.h"
 #include "tests/Test.h"
+#include "tools/gpu/ContextType.h"
 #include "tools/gpu/ManagedBackendTexture.h"
 
 #include <initializer_list>
@@ -1086,7 +1087,7 @@
     GrContextOptions opts = options;
     opts.fSuppressDualSourceBlending = true;
     sk_gpu_test::GrContextFactory mockFactory(opts);
-    auto ctx = mockFactory.get(sk_gpu_test::GrContextFactory::kMock_ContextType);
+    auto ctx = mockFactory.get(skgpu::ContextType::kMock);
     if (!ctx) {
         SK_ABORT("Failed to create mock context without ARB_blend_func_extended.");
     }
diff --git a/tests/GrSurfaceTest.cpp b/tests/GrSurfaceTest.cpp
index d6489c0..9149bf0 100644
--- a/tests/GrSurfaceTest.cpp
+++ b/tests/GrSurfaceTest.cpp
@@ -53,6 +53,7 @@
 #include "src/gpu/ganesh/TestFormatColorTypeCombination.h"
 #include "tests/CtsEnforcement.h"
 #include "tests/Test.h"
+#include "tools/gpu/ContextType.h"
 #include "tools/gpu/ManagedBackendTexture.h"
 
 #include <cstdint>
@@ -280,9 +281,9 @@
     SkISize desc;
     desc.fWidth = desc.fHeight = kSize;
 
-    for (int ct = 0; ct < sk_gpu_test::GrContextFactory::kContextTypeCnt; ++ct) {
+    for (int ct = 0; ct < skgpu::kContextTypeCount; ++ct) {
         sk_gpu_test::GrContextFactory factory(options);
-        auto contextType = static_cast<sk_gpu_test::GrContextFactory::ContextType>(ct);
+        auto contextType = static_cast<skgpu::ContextType>(ct);
         if (!sk_gpu_test::GrContextFactory::IsRenderingContext(contextType)) {
             continue;
         }
diff --git a/tests/ImageTest.cpp b/tests/ImageTest.cpp
index a855d72..8d62242 100644
--- a/tests/ImageTest.cpp
+++ b/tests/ImageTest.cpp
@@ -658,7 +658,7 @@
 
 DEF_GANESH_TEST(AbandonedContextImage, reporter, options, CtsEnforcement::kApiLevel_T) {
     using Factory = sk_gpu_test::GrContextFactory;
-    for (int ct = 0; ct < Factory::kContextTypeCnt; ++ct) {
+    for (int ct = 0; ct < skgpu::kContextTypeCount; ++ct) {
         auto type = static_cast<Factory::ContextType>(ct);
         std::unique_ptr<Factory> factory(new Factory);
         if (!factory->get(type)) {
@@ -980,9 +980,9 @@
 static void test_cross_context_image(skiatest::Reporter* reporter, const GrContextOptions& options,
                                      const char* testName,
                                      std::function<sk_sp<SkImage>(GrDirectContext*)> imageMaker) {
-    for (int i = 0; i < GrContextFactory::kContextTypeCnt; ++i) {
+    for (int i = 0; i < skgpu::kContextTypeCount; ++i) {
         GrContextFactory testFactory(options);
-        GrContextFactory::ContextType ctxType = static_cast<GrContextFactory::ContextType>(i);
+        skgpu::ContextType ctxType = static_cast<skgpu::ContextType>(i);
         ContextInfo ctxInfo = testFactory.getContextInfo(ctxType);
         auto dContext = ctxInfo.directContext();
         if (!dContext) {
@@ -1164,9 +1164,9 @@
         SkAutoPixmapStorage pixmap;
         pixmap.alloc(SkImageInfo::Make(4, 4, ct, kPremul_SkAlphaType));
 
-        for (int i = 0; i < GrContextFactory::kContextTypeCnt; ++i) {
+        for (int i = 0; i < skgpu::kContextTypeCount; ++i) {
             GrContextFactory testFactory(options);
-            GrContextFactory::ContextType ctxType = static_cast<GrContextFactory::ContextType>(i);
+            skgpu::ContextType ctxType = static_cast<skgpu::ContextType>(i);
             ContextInfo ctxInfo = testFactory.getContextInfo(ctxType);
             auto dContext = ctxInfo.directContext();
             if (!dContext || !dContext->priv().caps()->crossContextTextureSupport()) {
diff --git a/tests/PinnedImageTest.cpp b/tests/PinnedImageTest.cpp
index 9328584..fc93587 100644
--- a/tests/PinnedImageTest.cpp
+++ b/tests/PinnedImageTest.cpp
@@ -29,6 +29,7 @@
 #include "src/gpu/ganesh/image/GrImageUtils.h"
 #include "tests/CtsEnforcement.h"
 #include "tests/Test.h"
+#include "tools/gpu/ContextType.h"
 #include "tools/gpu/FenceSync.h"
 
 #include <string>
@@ -120,8 +121,8 @@
     GrMockOptions options;
     sk_sp<GrDirectContext> mockContext = GrDirectContext::MakeMock(&options);
 
-    for (int i = 0; i < GrContextFactory::kContextTypeCnt; ++i) {
-        GrContextFactory::ContextType ctxType = (GrContextFactory::ContextType) i;
+    for (int i = 0; i < skgpu::kContextTypeCount; ++i) {
+        auto ctxType = static_cast<skgpu::ContextType>(i);
 
         {
             sk_sp<SkImage> img;
diff --git a/tests/ProgramsTest.cpp b/tests/ProgramsTest.cpp
index a8849d5..1e13e68 100644
--- a/tests/ProgramsTest.cpp
+++ b/tests/ProgramsTest.cpp
@@ -396,9 +396,9 @@
         // On Angle D3D we will hit a limit of out variables if we use too many stages. This is
         // particularly true on D3D9 with a low limit on varyings and the fact that every varying is
         // packed as though it has 4 components.
-        if (ctxInfo.type() == sk_gpu_test::GrContextFactory::kANGLE_D3D9_ES2_ContextType) {
+        if (ctxInfo.type() == skgpu::ContextType::kANGLE_D3D9_ES2) {
             maxStages = 2;
-        } else if (ctxInfo.type() == sk_gpu_test::GrContextFactory::kANGLE_D3D11_ES2_ContextType) {
+        } else if (ctxInfo.type() == skgpu::ContextType::kANGLE_D3D11_ES2) {
             maxStages = 3;
         }
     }
@@ -423,8 +423,8 @@
             maxTreeLevels = 3;
         }
 #endif
-        if (ctxInfo.type() == sk_gpu_test::GrContextFactory::kANGLE_D3D9_ES2_ContextType ||
-            ctxInfo.type() == sk_gpu_test::GrContextFactory::kANGLE_D3D11_ES2_ContextType) {
+        if (ctxInfo.type() == skgpu::ContextType::kANGLE_D3D9_ES2 ||
+            ctxInfo.type() == skgpu::ContextType::kANGLE_D3D11_ES2) {
             // On Angle D3D we will hit a limit of out variables if we use too many stages.
             maxTreeLevels = 2;
         }
diff --git a/tests/PromiseImageTest.cpp b/tests/PromiseImageTest.cpp
index 4c28ccc..e28d80f 100644
--- a/tests/PromiseImageTest.cpp
+++ b/tests/PromiseImageTest.cpp
@@ -36,6 +36,7 @@
 #include "src/gpu/ganesh/GrTexture.h"
 #include "tests/CtsEnforcement.h"
 #include "tests/Test.h"
+#include "tools/gpu/ContextType.h"
 #include "tools/gpu/FenceSync.h"
 #include "tools/gpu/ManagedBackendTexture.h"
 
@@ -238,8 +239,8 @@
         dContext->releaseResourcesAndAbandonContext();
     };
 
-    for (int type = 0; type < sk_gpu_test::GrContextFactory::kContextTypeCnt; ++type) {
-        auto contextType = static_cast<sk_gpu_test::GrContextFactory::ContextType>(type);
+    for (int type = 0; type < skgpu::kContextTypeCount; ++type) {
+        auto contextType = static_cast<skgpu::ContextType>(type);
         // These tests are difficult to get working with Vulkan. See http://skbug.com/8705
         // and http://skbug.com/8275
         // Also problematic on Dawn; see http://skbug.com/10326
diff --git a/tests/ReadWritePixelsGpuTest.cpp b/tests/ReadWritePixelsGpuTest.cpp
index b025f53..aae9b6c 100644
--- a/tests/ReadWritePixelsGpuTest.cpp
+++ b/tests/ReadWritePixelsGpuTest.cpp
@@ -57,6 +57,7 @@
 #include "tools/ToolUtils.h"
 #include "tools/gpu/BackendSurfaceFactory.h"
 #include "tools/gpu/BackendTextureImageFactory.h"
+#include "tools/gpu/ContextType.h"
 
 #include <algorithm>
 #include <array>
@@ -696,7 +697,7 @@
     rules.fUncontainedRectSucceeds = false;
     // TODO: some mobile GPUs have issues reading back sRGB src data with GLES -- skip for now
     // b/296440036
-    if (ctxInfo.type() == sk_gpu_test::GrContextFactory::kGLES_ContextType) {
+    if (ctxInfo.type() == skgpu::ContextType::kGLES) {
         rules.fSkipSRGBCT = true;
     }
 
@@ -776,12 +777,12 @@
     rules.fUncontainedRectSucceeds = false;
     // TODO: some mobile GPUs have issues reading back sRGB src data with GLES -- skip for now
     // b/296440036
-    if (ctxInfo.type() == sk_gpu_test::GrContextFactory::kGLES_ContextType) {
+    if (ctxInfo.type() == skgpu::ContextType::kGLES) {
         rules.fSkipSRGBCT = true;
     }
     // TODO: D3D on Intel has issues reading back 16-bit src data -- skip for now
     // b/296440036
-    if (ctxInfo.type() == sk_gpu_test::GrContextFactory::kDirect3D_ContextType) {
+    if (ctxInfo.type() == skgpu::ContextType::kDirect3D) {
         rules.fSkip16BitCT = true;
     }
 
@@ -839,8 +840,8 @@
         kReleaseAndAbandon_DestroyContext_FreeResult,
         kAbandon_DestroyContext_FreeResult,
     };
-    for (int t = 0; t < sk_gpu_test::GrContextFactory::kContextTypeCnt; ++t) {
-        auto type = static_cast<sk_gpu_test::GrContextFactory::ContextType>(t);
+    for (int t = 0; t < skgpu::kContextTypeCount; ++t) {
+        auto type = static_cast<skgpu::ContextType>(t);
         for (auto sequence : {ShutdownSequence::kFreeResult_DestroyContext,
                               ShutdownSequence::kDestroyContext_FreeResult,
                               ShutdownSequence::kFreeResult_ReleaseAndAbandon_DestroyContext,
@@ -851,8 +852,7 @@
                               ShutdownSequence::kAbandon_DestroyContext_FreeResult}) {
             // Vulkan and D3D context abandoning without resource release has issues outside of the
             // scope of this test.
-            if ((type == sk_gpu_test::GrContextFactory::kVulkan_ContextType ||
-                 type == sk_gpu_test::GrContextFactory::kDirect3D_ContextType) &&
+            if ((type == skgpu::ContextType::kVulkan || type == skgpu::ContextType::kDirect3D) &&
                 (sequence == ShutdownSequence::kFreeResult_ReleaseAndAbandon_DestroyContext ||
                  sequence == ShutdownSequence::kFreeResult_Abandon_DestroyContext ||
                  sequence == ShutdownSequence::kReleaseAndAbandon_FreeResult_DestroyContext ||
@@ -915,7 +915,7 @@
                         case ReadType::kYUVA: readTypeStr = "yuva"; break;
                     }
                     ERRORF(reporter, "Callback failed on %s. read type is: %s",
-                           sk_gpu_test::GrContextFactory::ContextTypeName(type), readTypeStr);
+                           skgpu::ContextTypeName(type), readTypeStr);
                     continue;
                 }
                 // For vulkan we need to release all refs to the GrDirectContext before trying to
diff --git a/tests/ResourceCacheTest.cpp b/tests/ResourceCacheTest.cpp
index 18ff498..94fd69e 100644
--- a/tests/ResourceCacheTest.cpp
+++ b/tests/ResourceCacheTest.cpp
@@ -49,6 +49,7 @@
 #include "src/gpu/ganesh/GrTextureProxy.h"
 #include "tests/CtsEnforcement.h"
 #include "tests/Test.h"
+#include "tools/gpu/ContextType.h"
 #include "tools/gpu/ManagedBackendTexture.h"
 
 #include <chrono>
@@ -114,10 +115,10 @@
     context->setResourceCacheLimit(oldMaxBytes);
 }
 
-static bool is_rendering_and_not_angle_es3(sk_gpu_test::GrContextFactory::ContextType type) {
-    if (type == sk_gpu_test::GrContextFactory::kANGLE_D3D11_ES3_ContextType ||
-        type == sk_gpu_test::GrContextFactory::kANGLE_GL_ES3_ContextType ||
-        type == sk_gpu_test::GrContextFactory::kANGLE_Metal_ES3_ContextType) {
+static bool is_rendering_and_not_angle_es3(skgpu::ContextType type) {
+    if (type == skgpu::ContextType::kANGLE_D3D11_ES3 ||
+        type == skgpu::ContextType::kANGLE_GL_ES3 ||
+        type == skgpu::ContextType::kANGLE_Metal_ES3) {
         return false;
     }
     return sk_gpu_test::GrContextFactory::IsRenderingContext(type);
diff --git a/tests/SkSLTest.cpp b/tests/SkSLTest.cpp
index 227062f..1226c5e 100644
--- a/tests/SkSLTest.cpp
+++ b/tests/SkSLTest.cpp
@@ -544,7 +544,7 @@
 
 
 #if defined(SK_GANESH)
-static bool is_rendering_context_but_not_dawn(sk_gpu_test::GrContextFactory::ContextType type) {
+static bool is_rendering_context_but_not_dawn(skgpu::ContextType type) {
     return sk_gpu_test::GrContextFactory::IsRenderingContext(type) &&
            sk_gpu_test::GrContextFactory::ContextTypeBackend(type) != GrBackendApi::kDawn;
 }
@@ -564,10 +564,10 @@
 #endif
 
 #if defined(SK_GRAPHITE)
-static bool is_native_context_or_dawn(sk_gpu_test::GrContextFactory::ContextType type) {
+static bool is_native_context_or_dawn(skgpu::ContextType type) {
     // This avoids re-testing Dawn over and over again against every possible API.
     return sk_gpu_test::GrContextFactory::IsNativeBackend(type) ||
-           type == sk_gpu_test::GrContextFactory::kDawn_ContextType;
+           type == skgpu::ContextType::kDawn;
 }
 
 static void force_wgsl_in_dawn(skgpu::graphite::ContextOptions* options) {
diff --git a/tests/SurfaceSemaphoreTest.cpp b/tests/SurfaceSemaphoreTest.cpp
index 7fa8e7f..2492294 100644
--- a/tests/SurfaceSemaphoreTest.cpp
+++ b/tests/SurfaceSemaphoreTest.cpp
@@ -31,6 +31,7 @@
 #include "src/gpu/ganesh/GrDirectContextPriv.h"
 #include "tests/CtsEnforcement.h"
 #include "tests/Test.h"
+#include "tools/gpu/ContextType.h"
 #include "tools/gpu/TestContext.h"
 
 #include <string>
@@ -215,19 +216,18 @@
 #ifdef SK_GL
 DEF_GANESH_TEST(SurfaceSemaphores, reporter, options, CtsEnforcement::kApiLevel_T) {
 #if defined(SK_BUILD_FOR_UNIX) || defined(SK_BUILD_FOR_WIN) || defined(SK_BUILD_FOR_MAC)
-    static constexpr auto kNativeGLType = sk_gpu_test::GrContextFactory::kGL_ContextType;
+    static constexpr auto kNativeGLType = skgpu::ContextType::kGL;
 #else
-    static constexpr auto kNativeGLType = sk_gpu_test::GrContextFactory::kGLES_ContextType;
+    static constexpr auto kNativeGLType = skgpu::ContextType::kGLES;
 #endif
 
-    for (int typeInt = 0; typeInt < sk_gpu_test::GrContextFactory::kContextTypeCnt; ++typeInt) {
+    for (int typeInt = 0; typeInt < skgpu::kContextTypeCount; ++typeInt) {
         for (auto flushType : {FlushType::kSurface, FlushType::kImage, FlushType::kContext}) {
-            sk_gpu_test::GrContextFactory::ContextType contextType =
-                    (sk_gpu_test::GrContextFactory::ContextType) typeInt;
+            skgpu::ContextType contextType = static_cast<skgpu::ContextType>(typeInt);
             // Use "native" instead of explicitly trying OpenGL and OpenGL ES. Do not use GLES on
             // desktop since tests do not account for not fixing http://skbug.com/2809
-            if (contextType == sk_gpu_test::GrContextFactory::kGL_ContextType ||
-                contextType == sk_gpu_test::GrContextFactory::kGLES_ContextType) {
+            if (contextType == skgpu::ContextType::kGL ||
+                contextType == skgpu::ContextType::kGLES) {
                 if (contextType != kNativeGLType) {
                     continue;
                 }
@@ -237,8 +237,7 @@
             if (!sk_gpu_test::GrContextFactory::IsRenderingContext(contextType)) {
                 continue;
             }
-            skiatest::ReporterContext ctx(
-                   reporter, SkString(sk_gpu_test::GrContextFactory::ContextTypeName(contextType)));
+            skiatest::ReporterContext ctx(reporter, SkString(skgpu::ContextTypeName(contextType)));
             if (ctxInfo.directContext()) {
                 sk_gpu_test::ContextInfo child1 =
                         factory.getSharedContextInfo(ctxInfo.directContext(), 0);
diff --git a/tests/Test.h b/tests/Test.h
index 3324b68..ef6e9ac 100644
--- a/tests/Test.h
+++ b/tests/Test.h
@@ -15,6 +15,10 @@
 #include "tests/CtsEnforcement.h"
 #include "tools/Registry.h"
 
+#if defined(SK_GANESH) || defined(SK_GRAPHITE)
+namespace skgpu { enum class ContextType; }
+#endif
+
 #if defined(SK_GANESH)
 #include "tools/gpu/GrContextFactory.h" // IWYU pragma: export (because it is used by a macro)
 #else
@@ -193,13 +197,13 @@
 using TestRegistry = sk_tools::Registry<Test>;
 
 #if defined(SK_GANESH)
-using GrContextFactoryContextType = sk_gpu_test::GrContextFactory::ContextType;
+using GpuContextType = skgpu::ContextType;
 #else
-using GrContextFactoryContextType = nullptr_t;
+using GpuContextType = nullptr_t;
 #endif
 
 typedef void GrContextTestFn(Reporter*, const sk_gpu_test::ContextInfo&);
-typedef bool GrContextTypeFilterFn(GrContextFactoryContextType);
+typedef bool GrContextTypeFilterFn(GpuContextType);
 
 // We want to run the same test against potentially multiple Ganesh backends. Test runners should
 // implement this function by calling the testFn with a fresh ContextInfo if that backend matches
@@ -210,13 +214,13 @@
 
 // These context filters should be implemented by test runners and return true if the backend was
 // compiled in (i.e. is supported) and matches the criteria indicated by the name of the filter.
-extern bool IsGLContextType(GrContextFactoryContextType);
-extern bool IsVulkanContextType(GrContextFactoryContextType);
-extern bool IsMetalContextType(GrContextFactoryContextType);
-extern bool IsDawnContextType(GrContextFactoryContextType);
-extern bool IsDirect3DContextType(GrContextFactoryContextType);
-extern bool IsRenderingGLContextType(GrContextFactoryContextType);
-extern bool IsMockContextType(GrContextFactoryContextType);
+extern bool IsGLContextType(GpuContextType);
+extern bool IsVulkanContextType(GpuContextType);
+extern bool IsMetalContextType(GpuContextType);
+extern bool IsDawnContextType(GpuContextType);
+extern bool IsDirect3DContextType(GpuContextType);
+extern bool IsRenderingGLContextType(GpuContextType);
+extern bool IsMockContextType(GpuContextType);
 
 namespace graphite {
 
diff --git a/tests/VkDrawableTest.cpp b/tests/VkDrawableTest.cpp
index 7e0b3c1..7ddd0a2 100644
--- a/tests/VkDrawableTest.cpp
+++ b/tests/VkDrawableTest.cpp
@@ -36,6 +36,7 @@
 #include "src/gpu/ganesh/vk/GrVkUtil.h"
 #include "tests/CtsEnforcement.h"
 #include "tests/Test.h"
+#include "tools/gpu/ContextType.h"
 
 #include <vulkan/vulkan_core.h>
 #include <cstdint>
@@ -292,16 +293,14 @@
 }
 
 DEF_GANESH_TEST(VkDrawableImportTest, reporter, options, CtsEnforcement::kApiLevel_T) {
-    for (int typeInt = 0; typeInt < sk_gpu_test::GrContextFactory::kContextTypeCnt; ++typeInt) {
-        sk_gpu_test::GrContextFactory::ContextType contextType =
-                (sk_gpu_test::GrContextFactory::ContextType) typeInt;
-        if (contextType != sk_gpu_test::GrContextFactory::kVulkan_ContextType) {
+    for (int typeInt = 0; typeInt < skgpu::kContextTypeCount; ++typeInt) {
+        skgpu::ContextType contextType = static_cast<skgpu::ContextType>(typeInt);
+        if (contextType != skgpu::ContextType::kVulkan) {
             continue;
         }
         sk_gpu_test::GrContextFactory factory(options);
         sk_gpu_test::ContextInfo ctxInfo = factory.getContextInfo(contextType);
-        skiatest::ReporterContext ctx(
-                   reporter, SkString(sk_gpu_test::GrContextFactory::ContextTypeName(contextType)));
+        skiatest::ReporterContext ctx(reporter, SkString(skgpu::ContextTypeName(contextType)));
         if (ctxInfo.directContext()) {
             sk_gpu_test::ContextInfo child =
                     factory.getSharedContextInfo(ctxInfo.directContext(), 0);
diff --git a/tests/VkHardwareBufferTest.cpp b/tests/VkHardwareBufferTest.cpp
index ce4eac4..e31ed44 100644
--- a/tests/VkHardwareBufferTest.cpp
+++ b/tests/VkHardwareBufferTest.cpp
@@ -150,7 +150,7 @@
 };
 
 bool EGLTestHelper::init(skiatest::Reporter* reporter) {
-    fGLESContextInfo = fFactory.getContextInfo(sk_gpu_test::GrContextFactory::kGLES_ContextType);
+    fGLESContextInfo = fFactory.getContextInfo(skgpu::ContextType::kGLES);
     fDirectContext = fGLESContextInfo.directContext();
     fGLCtx = fGLESContextInfo.glContext();
     if (!fDirectContext || !fGLCtx) {
diff --git a/tools/flags/CommonFlagsConfig.cpp b/tools/flags/CommonFlagsConfig.cpp
index 4d06b6c..37a3afa 100644
--- a/tools/flags/CommonFlagsConfig.cpp
+++ b/tools/flags/CommonFlagsConfig.cpp
@@ -303,65 +303,65 @@
                                  bool*                                outFakeGLESVersion2) {
     *outFakeGLESVersion2 = false;
     if (value.equals("gl")) {
-        *outContextType = GrContextFactory::kGL_ContextType;
+        *outContextType = skgpu::ContextType::kGL;
         return true;
     }
     if (value.equals("gles")) {
-        *outContextType = GrContextFactory::kGLES_ContextType;
+        *outContextType = skgpu::ContextType::kGLES;
         return true;
     }
     if (value.equals("glesfakev2")) {
-        *outContextType = GrContextFactory::kGLES_ContextType;
+        *outContextType = skgpu::ContextType::kGLES;
         *outFakeGLESVersion2 = true;
         return true;
     }
     if (value.equals("angle_d3d9_es2")) {
-        *outContextType = GrContextFactory::kANGLE_D3D9_ES2_ContextType;
+        *outContextType = skgpu::ContextType::kANGLE_D3D9_ES2;
         return true;
     }
     if (value.equals("angle_d3d11_es2")) {
-        *outContextType = GrContextFactory::kANGLE_D3D11_ES2_ContextType;
+        *outContextType = skgpu::ContextType::kANGLE_D3D11_ES2;
         return true;
     }
     if (value.equals("angle_d3d11_es3")) {
-        *outContextType = GrContextFactory::kANGLE_D3D11_ES3_ContextType;
+        *outContextType = skgpu::ContextType::kANGLE_D3D11_ES3;
         return true;
     }
     if (value.equals("angle_gl_es2")) {
-        *outContextType = GrContextFactory::kANGLE_GL_ES2_ContextType;
+        *outContextType = skgpu::ContextType::kANGLE_GL_ES2;
         return true;
     }
     if (value.equals("angle_gl_es3")) {
-        *outContextType = GrContextFactory::kANGLE_GL_ES3_ContextType;
+        *outContextType = skgpu::ContextType::kANGLE_GL_ES3;
         return true;
     }
     if (value.equals("angle_mtl_es2")) {
-        *outContextType = GrContextFactory::kANGLE_Metal_ES2_ContextType;
+        *outContextType = skgpu::ContextType::kANGLE_Metal_ES2;
         return true;
     }
     if (value.equals("angle_mtl_es3")) {
-        *outContextType = GrContextFactory::kANGLE_Metal_ES3_ContextType;
+        *outContextType = skgpu::ContextType::kANGLE_Metal_ES3;
         return true;
     }
     if (value.equals("mock")) {
-        *outContextType = GrContextFactory::kMock_ContextType;
+        *outContextType = skgpu::ContextType::kMock;
         return true;
     }
 #ifdef SK_VULKAN
     if (value.equals("vulkan")) {
-        *outContextType = GrContextFactory::kVulkan_ContextType;
+        *outContextType = skgpu::ContextType::kVulkan;
         return true;
     }
 #endif
 #ifdef SK_METAL
     if (value.equals("metal")) {
-        *outContextType = GrContextFactory::kMetal_ContextType;
+        *outContextType = skgpu::ContextType::kMetal;
         return true;
     }
 #endif
 #ifdef SK_DIRECT3D
     if (value.equals("direct3d")) {
-        *outContextType = GrContextFactory::kDirect3D_ContextType;
+        *outContextType = skgpu::ContextType::kDirect3D;
         return true;
     }
 #endif
@@ -477,49 +477,49 @@
         }
 #ifdef SK_DAWN
         if (optionValue->equals("dawn")) {
-            *outContextType = sk_gpu_test::GrContextFactory::kDawn_ContextType;
+            *outContextType = skgpu::ContextType::kDawn;
             return true;
         }
         if (optionValue->equals("dawn_d3d11")) {
-            *outContextType = sk_gpu_test::GrContextFactory::kDawn_D3D11_ContextType;
+            *outContextType = skgpu::ContextType::kDawn_D3D11;
             return true;
         }
         if (optionValue->equals("dawn_d3d12")) {
-            *outContextType = sk_gpu_test::GrContextFactory::kDawn_D3D12_ContextType;
+            *outContextType = skgpu::ContextType::kDawn_D3D12;
             return true;
         }
         if (optionValue->equals("dawn_mtl")) {
-            *outContextType = sk_gpu_test::GrContextFactory::kDawn_Metal_ContextType;
+            *outContextType = skgpu::ContextType::kDawn_Metal;
             return true;
         }
         if (optionValue->equals("dawn_vk")) {
-            *outContextType = sk_gpu_test::GrContextFactory::kDawn_Vulkan_ContextType;
+            *outContextType = skgpu::ContextType::kDawn_Vulkan;
             return true;
         }
         if (optionValue->equals("dawn_gl")) {
-            *outContextType = sk_gpu_test::GrContextFactory::kDawn_OpenGL_ContextType;
+            *outContextType = skgpu::ContextType::kDawn_OpenGL;
             return true;
         }
         if (optionValue->equals("dawn_gles")) {
-            *outContextType = sk_gpu_test::GrContextFactory::kDawn_OpenGLES_ContextType;
+            *outContextType = skgpu::ContextType::kDawn_OpenGLES;
             return true;
         }
 #endif
 #ifdef SK_DIRECT3D
         if (optionValue->equals("direct3d")) {
-            *outContextType = sk_gpu_test::GrContextFactory::kDirect3D_ContextType;
+            *outContextType = skgpu::ContextType::kDirect3D;
             return true;
         }
 #endif
 #ifdef SK_METAL
         if (optionValue->equals("metal")) {
-            *outContextType = sk_gpu_test::GrContextFactory::kMetal_ContextType;
+            *outContextType = skgpu::ContextType::kMetal;
             return true;
         }
 #endif
 #ifdef SK_VULKAN
         if (optionValue->equals("vulkan")) {
-            *outContextType = sk_gpu_test::GrContextFactory::kVulkan_ContextType;
+            *outContextType = skgpu::ContextType::kVulkan;
             return true;
         }
 #endif
@@ -605,7 +605,7 @@
                                                       const TArray<SkString>& vias,
                                                       const SkString&         options) {
     // Defaults for GPU backend.
-    SkCommandLineConfigGpu::ContextType contextType         = GrContextFactory::kGL_ContextType;
+    SkCommandLineConfigGpu::ContextType contextType         = skgpu::ContextType::kGL;
     bool                                useDIText           = false;
     bool                                useDMSAA            = false;
     int                                 samples             = 1;
@@ -680,9 +680,9 @@
 SkCommandLineConfigGraphite* parse_command_line_config_graphite(const SkString& tag,
                                                                 const TArray<SkString>& vias,
                                                                 const SkString& options) {
-    using ContextType = sk_gpu_test::GrContextFactory::ContextType;
+    using ContextType = skgpu::ContextType;
 
-    ContextType contextType = sk_gpu_test::GrContextFactory::kMetal_ContextType;
+    ContextType contextType = skgpu::ContextType::kMetal;
     SkColorType colorType = kRGBA_8888_SkColorType;
     SkAlphaType alphaType = kPremul_SkAlphaType;
     bool wgsl = false;
diff --git a/tools/flags/CommonFlagsConfig.h b/tools/flags/CommonFlagsConfig.h
index dfb153c..845e779 100644
--- a/tools/flags/CommonFlagsConfig.h
+++ b/tools/flags/CommonFlagsConfig.h
@@ -53,7 +53,7 @@
 class SkCommandLineConfigGpu : public SkCommandLineConfig {
 public:
     enum class SurfType { kDefault, kBackendTexture, kBackendRenderTarget };
-    typedef sk_gpu_test::GrContextFactory::ContextType      ContextType;
+    typedef skgpu::ContextType                              ContextType;
     typedef sk_gpu_test::GrContextFactory::ContextOverrides ContextOverrides;
 
     SkCommandLineConfigGpu(const SkString&           tag,
@@ -113,7 +113,7 @@
 
 class SkCommandLineConfigGraphite : public SkCommandLineConfig {
 public:
-    using ContextType = sk_gpu_test::GrContextFactory::ContextType;
+    using ContextType = skgpu::ContextType;
 
     SkCommandLineConfigGraphite(const SkString& tag,
                                 const skia_private::TArray<SkString>& viaParts,
diff --git a/tools/gpu/BUILD.bazel b/tools/gpu/BUILD.bazel
index 205c01c..a525500 100644
--- a/tools/gpu/BUILD.bazel
+++ b/tools/gpu/BUILD.bazel
@@ -12,6 +12,8 @@
         "BackendSurfaceFactory.h",
         "BackendTextureImageFactory.cpp",
         "BackendTextureImageFactory.h",
+        "ContextType.cpp",
+        "ContextType.h",
         "FenceSync.h",
         "FlushFinishTracker.cpp",
         "FlushFinishTracker.h",
diff --git a/tools/gpu/ContextType.cpp b/tools/gpu/ContextType.cpp
new file mode 100644
index 0000000..38bde72
--- /dev/null
+++ b/tools/gpu/ContextType.cpp
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2023 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "include/core/SkTypes.h"
+#include "tools/gpu/ContextType.h"
+
+namespace skgpu {
+
+const char* ContextTypeName(skgpu::ContextType contextType) {
+    switch (contextType) {
+        case ContextType::kGL:
+            return "OpenGL";
+        case ContextType::kGLES:
+            return "OpenGLES";
+        case ContextType::kANGLE_D3D9_ES2:
+            return "ANGLE D3D9 ES2";
+        case ContextType::kANGLE_D3D11_ES2:
+            return "ANGLE D3D11 ES2";
+        case ContextType::kANGLE_D3D11_ES3:
+            return "ANGLE D3D11 ES3";
+        case ContextType::kANGLE_GL_ES2:
+            return "ANGLE GL ES2";
+        case ContextType::kANGLE_GL_ES3:
+            return "ANGLE GL ES3";
+        case ContextType::kANGLE_Metal_ES2:
+            return "ANGLE Metal ES2";
+        case ContextType::kANGLE_Metal_ES3:
+            return "ANGLE Metal ES3";
+        case ContextType::kVulkan:
+            return "Vulkan";
+        case ContextType::kMetal:
+            return "Metal";
+        case ContextType::kDirect3D:
+            return "Direct3D";
+        case ContextType::kDawn:
+            return "Dawn";
+        case ContextType::kDawn_D3D11:
+            return "Dawn D3D11";
+        case ContextType::kDawn_D3D12:
+            return "Dawn D3D12";
+        case ContextType::kDawn_Metal:
+            return "Dawn Metal";
+        case ContextType::kDawn_Vulkan:
+            return "Dawn Vulkan";
+        case ContextType::kDawn_OpenGL:
+            return "Dawn OpenGL";
+        case ContextType::kDawn_OpenGLES:
+            return "Dawn OpenGLES";
+        case ContextType::kMock:
+            return "Mock";
+    }
+    SkUNREACHABLE;
+}
+
+}  // namespace skgpu
diff --git a/tools/gpu/ContextType.h b/tools/gpu/ContextType.h
new file mode 100644
index 0000000..361d99a
--- /dev/null
+++ b/tools/gpu/ContextType.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2023 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef ContextType_DEFINED
+#define ContextType_DEFINED
+
+namespace skgpu {
+
+// The availability of context types is subject to platform and build configuration
+// restrictions.
+enum class ContextType {
+    kGL,               //! OpenGL context.
+    kGLES,             //! OpenGL ES context.
+    kANGLE_D3D9_ES2,   //! ANGLE on Direct3D9 OpenGL ES 2 context.
+    kANGLE_D3D11_ES2,  //! ANGLE on Direct3D11 OpenGL ES 2 context.
+    kANGLE_D3D11_ES3,  //! ANGLE on Direct3D11 OpenGL ES 3 context.
+    kANGLE_GL_ES2,     //! ANGLE on OpenGL OpenGL ES 2 context.
+    kANGLE_GL_ES3,     //! ANGLE on OpenGL OpenGL ES 3 context.
+    kANGLE_Metal_ES2,  //! ANGLE on Metal ES 2 context.
+    kANGLE_Metal_ES3,  //! ANGLE on Metal ES 3 context.
+    kVulkan,           //! Vulkan
+    kMetal,            //! Metal
+    kDirect3D,         //! Direct3D 12
+    kDawn,             //! Dawn
+    kDawn_D3D11,       //! Dawn on Direct3D11
+    kDawn_D3D12,       //! Dawn on Direct3D12
+    kDawn_Metal,       //! Dawn on Metal
+    kDawn_Vulkan,      //! Dawn on Vulkan
+    kDawn_OpenGL,      //! Dawn on OpenGL
+    kDawn_OpenGLES,    //! Dawn on OpenGL ES
+    kMock,             //! Mock context that does not draw.
+    kLastContextType = kMock
+};
+
+static const int kContextTypeCount = (int)ContextType::kLastContextType + 1;
+
+const char* ContextTypeName(skgpu::ContextType contextType);
+
+}  // namespace skgpu
+
+#endif
diff --git a/tools/gpu/GrContextFactory.cpp b/tools/gpu/GrContextFactory.cpp
index 937534b..1a6e662 100644
--- a/tools/gpu/GrContextFactory.cpp
+++ b/tools/gpu/GrContextFactory.cpp
@@ -170,14 +170,14 @@
                     ? static_cast<GLTestContext*>(primaryContext->fTestContext) : nullptr;
             GLTestContext* glCtx;
             switch (type) {
-                case kGL_ContextType:
+                case ContextType::kGL:
                     glCtx = CreatePlatformGLTestContext(kGL_GrGLStandard, glShareContext);
                     break;
-                case kGLES_ContextType:
+                case ContextType::kGLES:
                     glCtx = CreatePlatformGLTestContext(kGLES_GrGLStandard, glShareContext);
                     break;
 #if SK_ANGLE
-                case kANGLE_D3D9_ES2_ContextType:
+                case ContextType::kANGLE_D3D9_ES2:
                     glCtx = MakeANGLETestContext(ANGLEBackend::kD3D9, ANGLEContextVersion::kES2,
                                                  glShareContext).release();
                     // Chrome will only run on D3D9 with NVIDIA for 2012 and earlier drivers.
@@ -191,27 +191,27 @@
                         }
                     }
                     break;
-                case kANGLE_D3D11_ES2_ContextType:
+                case ContextType::kANGLE_D3D11_ES2:
                     glCtx = MakeANGLETestContext(ANGLEBackend::kD3D11, ANGLEContextVersion::kES2,
                                                  glShareContext).release();
                     break;
-                case kANGLE_D3D11_ES3_ContextType:
+                case ContextType::kANGLE_D3D11_ES3:
                     glCtx = MakeANGLETestContext(ANGLEBackend::kD3D11, ANGLEContextVersion::kES3,
                                                  glShareContext).release();
                     break;
-                case kANGLE_GL_ES2_ContextType:
+                case ContextType::kANGLE_GL_ES2:
                     glCtx = MakeANGLETestContext(ANGLEBackend::kOpenGL, ANGLEContextVersion::kES2,
                                                  glShareContext).release();
                     break;
-                case kANGLE_GL_ES3_ContextType:
+                case ContextType::kANGLE_GL_ES3:
                     glCtx = MakeANGLETestContext(ANGLEBackend::kOpenGL, ANGLEContextVersion::kES3,
                                                  glShareContext).release();
                     break;
-                case kANGLE_Metal_ES2_ContextType:
+                case ContextType::kANGLE_Metal_ES2:
                     glCtx = MakeANGLETestContext(ANGLEBackend::kMetal, ANGLEContextVersion::kES2,
                                                  glShareContext).release();
                     break;
-                case kANGLE_Metal_ES3_ContextType:
+                case ContextType::kANGLE_Metal_ES3:
                     glCtx = MakeANGLETestContext(ANGLEBackend::kMetal, ANGLEContextVersion::kES3,
                                                  glShareContext).release();
                     break;
@@ -234,7 +234,7 @@
         case GrBackendApi::kVulkan: {
             VkTestContext* vkSharedContext = primaryContext
                     ? static_cast<VkTestContext*>(primaryContext->fTestContext) : nullptr;
-            SkASSERT(kVulkan_ContextType == type);
+            SkASSERT(ContextType::kVulkan == type);
             testCtx.reset(CreatePlatformVkTestContext(vkSharedContext));
             if (!testCtx) {
                 return ContextInfo();
@@ -259,7 +259,7 @@
         case GrBackendApi::kMetal: {
             MtlTestContext* mtlSharedContext = primaryContext
                     ? static_cast<MtlTestContext*>(primaryContext->fTestContext) : nullptr;
-            SkASSERT(kMetal_ContextType == type);
+            SkASSERT(ContextType::kMetal == type);
             testCtx.reset(CreatePlatformMtlTestContext(mtlSharedContext));
             if (!testCtx) {
                 return ContextInfo();
@@ -271,7 +271,7 @@
         case GrBackendApi::kDirect3D: {
             D3DTestContext* d3dSharedContext = primaryContext
                     ? static_cast<D3DTestContext*>(primaryContext->fTestContext) : nullptr;
-            SkASSERT(kDirect3D_ContextType == type);
+            SkASSERT(ContextType::kDirect3D == type);
             testCtx.reset(CreatePlatformD3DTestContext(d3dSharedContext));
             if (!testCtx) {
                 return ContextInfo();
@@ -281,7 +281,7 @@
 #endif
         case GrBackendApi::kMock: {
             TestContext* sharedContext = primaryContext ? primaryContext->fTestContext : nullptr;
-            SkASSERT(kMock_ContextType == type);
+            SkASSERT(ContextType::kMock == type);
             testCtx.reset(CreateMockTestContext(sharedContext));
             if (!testCtx) {
                 return ContextInfo();
diff --git a/tools/gpu/GrContextFactory.h b/tools/gpu/GrContextFactory.h
index a701d14..8880d38 100644
--- a/tools/gpu/GrContextFactory.h
+++ b/tools/gpu/GrContextFactory.h
@@ -12,11 +12,12 @@
 #include "include/gpu/GrDirectContext.h"
 
 #include "include/private/base/SkTArray.h"
+#include "tools/gpu/ContextType.h"
+#include "tools/gpu/TestContext.h"
 
 #ifdef SK_GL
 #include "tools/gpu/gl/GLTestContext.h"
 #endif
-#include "tools/gpu/TestContext.h"
 
 struct GrVkBackendContext;
 
@@ -32,33 +33,7 @@
  */
 class GrContextFactory : SkNoncopyable {
 public:
-    // The availability of context types is subject to platform and build configuration
-    // restrictions.
-    enum ContextType {
-        kGL_ContextType,                 //! OpenGL context.
-        kGLES_ContextType,               //! OpenGL ES context.
-        kANGLE_D3D9_ES2_ContextType,     //! ANGLE on Direct3D9 OpenGL ES 2 context.
-        kANGLE_D3D11_ES2_ContextType,    //! ANGLE on Direct3D11 OpenGL ES 2 context.
-        kANGLE_D3D11_ES3_ContextType,    //! ANGLE on Direct3D11 OpenGL ES 3 context.
-        kANGLE_GL_ES2_ContextType,       //! ANGLE on OpenGL OpenGL ES 2 context.
-        kANGLE_GL_ES3_ContextType,       //! ANGLE on OpenGL OpenGL ES 3 context.
-        kANGLE_Metal_ES2_ContextType,    //! ANGLE on Metal ES 2 context.
-        kANGLE_Metal_ES3_ContextType,    //! ANGLE on Metal ES 3 context.
-        kVulkan_ContextType,             //! Vulkan
-        kMetal_ContextType,              //! Metal
-        kDirect3D_ContextType,           //! Direct3D 12
-        kDawn_ContextType,               //! Dawn
-        kDawn_D3D11_ContextType,         //! Dawn on Direct3D11
-        kDawn_D3D12_ContextType,         //! Dawn on Direct3D12
-        kDawn_Metal_ContextType,         //! Dawn on Metal
-        kDawn_Vulkan_ContextType,        //! Dawn on Vulkan
-        kDawn_OpenGL_ContextType,        //! Dawn on Vulkan
-        kDawn_OpenGLES_ContextType,      //! Dawn on Vulkan
-        kMock_ContextType,               //! Mock context that does not draw.
-        kLastContextType = kMock_ContextType
-    };
-
-    static const int kContextTypeCnt = kLastContextType + 1;
+    using ContextType = skgpu::ContextType;
 
     /**
      * Overrides for the initial GrContextOptions provided at construction time, and required
@@ -73,7 +48,7 @@
 
     static bool IsRenderingContext(ContextType type) {
         switch (type) {
-            case kMock_ContextType:
+            case ContextType::kMock:
                 return false;
             default:
                 return true;
@@ -82,11 +57,11 @@
 
     static bool IsNativeBackend(ContextType type) {
         switch (type) {
-            case kDirect3D_ContextType:
-            case kGL_ContextType:
-            case kGLES_ContextType:
-            case kMetal_ContextType:
-            case kVulkan_ContextType:
+            case ContextType::kDirect3D:
+            case ContextType::kGL:
+            case ContextType::kGLES:
+            case ContextType::kMetal:
+            case ContextType::kVulkan:
                 return true;
             default:
                 // Mock doesn't use the GPU, and Dawn and ANGLE add a layer between Skia and the
@@ -97,73 +72,27 @@
 
     static GrBackendApi ContextTypeBackend(ContextType type) {
         switch (type) {
-            case kVulkan_ContextType:
+            case ContextType::kVulkan:
                 return GrBackendApi::kVulkan;
-            case kMetal_ContextType:
+            case ContextType::kMetal:
                 return GrBackendApi::kMetal;
-            case kDirect3D_ContextType:
+            case ContextType::kDirect3D:
                 return GrBackendApi::kDirect3D;
-            case kDawn_ContextType:
-            case kDawn_D3D11_ContextType:
-            case kDawn_D3D12_ContextType:
-            case kDawn_Metal_ContextType:
-            case kDawn_Vulkan_ContextType:
-            case kDawn_OpenGL_ContextType:
-            case kDawn_OpenGLES_ContextType:
+            case ContextType::kDawn:
+            case ContextType::kDawn_D3D11:
+            case ContextType::kDawn_D3D12:
+            case ContextType::kDawn_Metal:
+            case ContextType::kDawn_Vulkan:
+            case ContextType::kDawn_OpenGL:
+            case ContextType::kDawn_OpenGLES:
                 return GrBackendApi::kDawn;
-            case kMock_ContextType:
+            case ContextType::kMock:
                 return GrBackendApi::kMock;
             default:
                 return GrBackendApi::kOpenGL;
         }
     }
 
-    static const char* ContextTypeName(ContextType contextType) {
-        switch (contextType) {
-            case kGL_ContextType:
-                return "OpenGL";
-            case kGLES_ContextType:
-                return "OpenGLES";
-            case kANGLE_D3D9_ES2_ContextType:
-                return "ANGLE D3D9 ES2";
-            case kANGLE_D3D11_ES2_ContextType:
-                return "ANGLE D3D11 ES2";
-            case kANGLE_D3D11_ES3_ContextType:
-                return "ANGLE D3D11 ES3";
-            case kANGLE_GL_ES2_ContextType:
-                return "ANGLE GL ES2";
-            case kANGLE_GL_ES3_ContextType:
-                return "ANGLE GL ES3";
-            case kANGLE_Metal_ES2_ContextType:
-                return "ANGLE Metal ES2";
-            case kANGLE_Metal_ES3_ContextType:
-                return "ANGLE Metal ES3";
-            case kVulkan_ContextType:
-                return "Vulkan";
-            case kMetal_ContextType:
-                return "Metal";
-            case kDirect3D_ContextType:
-                return "Direct3D";
-            case kDawn_ContextType:
-                return "Dawn";
-            case kDawn_D3D11_ContextType:
-                return "Dawn D3D11";
-            case kDawn_D3D12_ContextType:
-                return "Dawn D3D12";
-            case kDawn_Metal_ContextType:
-                return "Dawn Metal";
-            case kDawn_Vulkan_ContextType:
-                return "Dawn Vulkan";
-            case kDawn_OpenGL_ContextType:
-                return "Dawn OpenGL";
-            case kDawn_OpenGLES_ContextType:
-                return "Dawn OpenGLES";
-            case kMock_ContextType:
-                return "Mock";
-        }
-        SK_ABORT("Unreachable");
-    }
-
     explicit GrContextFactory(const GrContextOptions& opts);
     GrContextFactory();
 
@@ -221,7 +150,7 @@
     ContextInfo(const ContextInfo&) = default;
     ContextInfo& operator=(const ContextInfo&) = default;
 
-    GrContextFactory::ContextType type() const { return fType; }
+    skgpu::ContextType type() const { return fType; }
     GrBackendApi backend() const { return GrContextFactory::ContextTypeBackend(fType); }
 
     GrDirectContext* directContext() const { return fContext; }
@@ -237,13 +166,13 @@
     const GrContextOptions& options() const { return fOptions; }
 
 private:
-    ContextInfo(GrContextFactory::ContextType type,
+    ContextInfo(skgpu::ContextType type,
                 TestContext* testContext,
                 GrDirectContext* context,
                 const GrContextOptions& options)
             : fType(type), fTestContext(testContext), fContext(context), fOptions(options) {}
 
-    GrContextFactory::ContextType fType = GrContextFactory::kGL_ContextType;
+    skgpu::ContextType fType = skgpu::ContextType::kGL;
     // Valid until the factory destroys it via abandonContexts() or destroyContexts().
     TestContext* fTestContext = nullptr;
     GrDirectContext* fContext = nullptr;
diff --git a/tools/graphite/ContextFactory.cpp b/tools/graphite/ContextFactory.cpp
index e02c5e9..b975df5 100644
--- a/tools/graphite/ContextFactory.cpp
+++ b/tools/graphite/ContextFactory.cpp
@@ -27,7 +27,7 @@
     , fContext(std::move(other.fContext)) {
 }
 
-ContextFactory::ContextInfo::ContextInfo(GrContextFactory::ContextType type,
+ContextFactory::ContextInfo::ContextInfo(skgpu::ContextType type,
                                          std::unique_ptr<GraphiteTestContext> testContext,
                                          std::unique_ptr<skgpu::graphite::Context> context)
     : fType(type)
@@ -42,7 +42,7 @@
 ContextFactory::~ContextFactory() {}
 
 std::tuple<GraphiteTestContext*, skgpu::graphite::Context*> ContextFactory::getContextInfo(
-        GrContextFactory::ContextType type) {
+        skgpu::ContextType type) {
 
     for (ContextInfo& c : fContexts) {
         if (c.type() == type) {
@@ -53,17 +53,17 @@
     std::unique_ptr<GraphiteTestContext> testCtx;
 
     switch (type) {
-        case GrContextFactory::kMetal_ContextType: {
+        case skgpu::ContextType::kMetal: {
 #ifdef SK_METAL
             testCtx = graphite::MtlTestContext::Make();
 #endif
         } break;
-        case GrContextFactory::kVulkan_ContextType: {
+        case skgpu::ContextType::kVulkan: {
 #ifdef SK_VULKAN
             testCtx = graphite::VulkanTestContext::Make();
 #endif
         } break;
-        case GrContextFactory::kDawn_ContextType:
+        case skgpu::ContextType::kDawn:
         {
 #ifdef SK_DAWN
             // Pass nullopt for default backend.
@@ -72,14 +72,13 @@
         } break;
 #ifdef SK_DAWN
 
-#define CASE(TYPE)                                                              \
-        case GrContextFactory::kDawn_##TYPE##_ContextType:                      \
-        {                                                                       \
-            testCtx = graphite::DawnTestContext::Make(wgpu::BackendType::TYPE); \
-        } break;
+#define CASE(TYPE)                                                          \
+    case skgpu::ContextType::kDawn_##TYPE:                                  \
+        testCtx = graphite::DawnTestContext::Make(wgpu::BackendType::TYPE); \
+        break;
 #else
-#define CASE(TYPE)                                                              \
-        case GrContextFactory::kDawn_##TYPE##_ContextType:                      \
+#define CASE(TYPE)                         \
+    case skgpu::ContextType::kDawn_##TYPE: \
         break;
 #endif // SK_DAWN
         CASE(D3D11)
diff --git a/tools/graphite/ContextFactory.h b/tools/graphite/ContextFactory.h
index 5f4a9b3..a0a724f 100644
--- a/tools/graphite/ContextFactory.h
+++ b/tools/graphite/ContextFactory.h
@@ -12,15 +12,9 @@
 #include "include/core/SkRefCnt.h"
 #include "include/gpu/graphite/ContextOptions.h"
 #include "include/gpu/graphite/GraphiteTypes.h"
+#include "tools/gpu/ContextType.h"
 #include "tools/graphite/GraphiteTestContext.h"
 
-// TODO: This is only included to get access to GrContextFactory::ContextType. We should instead
-// move all of tools/gpu/ into tools/gpu/ganesh and tools/graphite into tools/gpu/graphite. Then in
-// tools gpu we can have files for shared things between ganesh and graphite like ContextType.
-#include "tools/gpu/GrContextFactory.h"
-
-using sk_gpu_test::GrContextFactory;
-
 namespace skgpu::graphite {
     class Context;
 }
@@ -35,7 +29,7 @@
         ContextInfo(ContextInfo&& other);
         ~ContextInfo() = default;
 
-        GrContextFactory::ContextType type() const { return fType; }
+        skgpu::ContextType type() const { return fType; }
 
         skgpu::graphite::Context* context() const { return fContext.get(); }
         GraphiteTestContext* testContext() const { return fTestContext.get(); }
@@ -43,12 +37,12 @@
     private:
         friend class ContextFactory; // for ctor
 
-        ContextInfo(GrContextFactory::ContextType type,
+        ContextInfo(skgpu::ContextType type,
                     std::unique_ptr<GraphiteTestContext> testContext,
                     std::unique_ptr<skgpu::graphite::Context> context);
 
-        GrContextFactory::ContextType             fType = GrContextFactory::kMock_ContextType;
-        std::unique_ptr<GraphiteTestContext>      fTestContext;
+        skgpu::ContextType fType = skgpu::ContextType::kMock;
+        std::unique_ptr<GraphiteTestContext> fTestContext;
         std::unique_ptr<skgpu::graphite::Context> fContext;
     };
 
@@ -60,7 +54,7 @@
     ~ContextFactory();
 
     std::tuple<GraphiteTestContext*, skgpu::graphite::Context*> getContextInfo(
-            GrContextFactory::ContextType);
+            skgpu::ContextType);
 
 private:
     std::vector<ContextInfo> fContexts;
diff --git a/tools/skiaserve/Request.cpp b/tools/skiaserve/Request.cpp
index 7f45000..a33d8cf 100644
--- a/tools/skiaserve/Request.cpp
+++ b/tools/skiaserve/Request.cpp
@@ -58,10 +58,10 @@
 SkCanvas* Request::getCanvas() {
 #ifdef SK_GL
     GrContextFactory* factory = fContextFactory;
-    GLTestContext* gl = factory->getContextInfo(GrContextFactory::kGL_ContextType,
+    GLTestContext* gl = factory->getContextInfo(skgpu::ContextType::kGL,
             GrContextFactory::ContextOverrides::kNone).glContext();
     if (!gl) {
-        gl = factory->getContextInfo(GrContextFactory::kGLES_ContextType,
+        gl = factory->getContextInfo(skgpu::ContextType::kGLES,
                                      GrContextFactory::ContextOverrides::kNone).glContext();
     }
     if (gl) {
@@ -100,10 +100,10 @@
 }
 
 GrDirectContext* Request::directContext() {
-    auto result = fContextFactory->get(GrContextFactory::kGL_ContextType,
+    auto result = fContextFactory->get(skgpu::ContextType::kGL,
                                        GrContextFactory::ContextOverrides::kNone);
     if (!result) {
-        result = fContextFactory->get(GrContextFactory::kGLES_ContextType,
+        result = fContextFactory->get(skgpu::ContextType::kGLES,
                                       GrContextFactory::ContextOverrides::kNone);
     }
     return result;
diff --git a/tools/skottie2movie.cpp b/tools/skottie2movie.cpp
index dec7e14..11a1b33 100644
--- a/tools/skottie2movie.cpp
+++ b/tools/skottie2movie.cpp
@@ -53,7 +53,7 @@
         return -1;
     }
 
-    auto contextType = sk_gpu_test::GrContextFactory::kGL_ContextType;
+    auto contextType = skgpu::ContextType::kGL;
     GrContextOptions grCtxOptions;
     sk_gpu_test::GrContextFactory factory(grCtxOptions);
 
diff --git a/tools/skqp/src/skqp_GpuTestProcs.cpp b/tools/skqp/src/skqp_GpuTestProcs.cpp
index 22e1c9a..3d246e3 100644
--- a/tools/skqp/src/skqp_GpuTestProcs.cpp
+++ b/tools/skqp/src/skqp_GpuTestProcs.cpp
@@ -30,23 +30,23 @@
 
 namespace skiatest {
 
-bool IsGLContextType(sk_gpu_test::GrContextFactory::ContextType type) {
-    return GrBackendApi::kOpenGL == GrContextFactory::ContextTypeBackend(type);
+bool IsGLContextType(skgpu::ContextType type) {
+    return GrBackendApi::kOpenGL == sk_gpu_test::GrContextFactory::ContextTypeBackend(type);
 }
-bool IsVulkanContextType(sk_gpu_test::GrContextFactory::ContextType type) {
-    return GrBackendApi::kVulkan == GrContextFactory::ContextTypeBackend(type);
+bool IsVulkanContextType(skgpu::ContextType type) {
+    return GrBackendApi::kVulkan == sk_gpu_test::GrContextFactory::ContextTypeBackend(type);
 }
-bool IsRenderingGLContextType(sk_gpu_test::GrContextFactory::ContextType type) {
+bool IsRenderingGLContextType(skgpu::ContextType type) {
     return IsGLContextType(type) && GrContextFactory::IsRenderingContext(type);
 }
-bool IsMockContextType(sk_gpu_test::GrContextFactory::ContextType type) {
-    return type == GrContextFactory::kMock_ContextType;
+bool IsMockContextType(skgpu::ContextType type) {
+    return type == skgpu::ContextType::kMock;
 }
 
 // These are not supported
-bool IsMetalContextType(sk_gpu_test::GrContextFactory::ContextType type) { return false; }
-bool IsDirect3DContextType(sk_gpu_test::GrContextFactory::ContextType type) { return false; }
-bool IsDawnContextType(sk_gpu_test::GrContextFactory::ContextType type) { return false; }
+bool IsMetalContextType(skgpu::ContextType type) { return false; }
+bool IsDirect3DContextType(skgpu::ContextType type) { return false; }
+bool IsDawnContextType(skgpu::ContextType type) { return false; }
 
 static bool vk_has_physical_devices() {
     static bool supported = false;
@@ -67,19 +67,18 @@
 
 #if defined(SK_BUILD_FOR_UNIX) || defined(SK_BUILD_FOR_WIN) || defined(SK_BUILD_FOR_MAC)
 // Used for testing on desktop machines.
-static constexpr auto kNativeGLType = GrContextFactory::kGL_ContextType;
+static constexpr auto kNativeGLType = skgpu::ContextType::kGL;
 #else
-static constexpr auto kNativeGLType = GrContextFactory::kGLES_ContextType;
+static constexpr auto kNativeGLType = skgpu::ContextType::kGLES;
 #endif
 
 #ifdef SK_BUILD_FOR_ANDROID
-static_assert(kNativeGLType == GrContextFactory::kGLES_ContextType, "CTS requires GLES");
+static_assert(kNativeGLType == skgpu::ContextType::kGLES, "CTS requires GLES");
 #endif
 
-static bool skip_context(GrContextFactory::ContextType contextType) {
+static bool skip_context(skgpu::ContextType contextType) {
     // Use "native" instead of explicitly trying both OpenGL and OpenGL ES.
-    if (contextType == GrContextFactory::kGL_ContextType ||
-        contextType == GrContextFactory::kGLES_ContextType) {
+    if (contextType == skgpu::ContextType::kGL || contextType == skgpu::ContextType::kGLES) {
         if (contextType != kNativeGLType) {
             return true;
         }
@@ -88,7 +87,7 @@
     // The Android CDD (https://source.android.com/compatibility/12/android-12-cdd.pdf) does not
     // require Vulkan, but if it enumerates at least one VkPhysicalDevice then it is expected that
     // Vulkan is supported
-    if (contextType == GrContextFactory::kVulkan_ContextType && !vk_has_physical_devices()) {
+    if (contextType == skgpu::ContextType::kVulkan && !vk_has_physical_devices()) {
         return true;
     }
     return false;
@@ -98,8 +97,8 @@
                                GrContextTypeFilterFn* filter,
                                Reporter* reporter,
                                const GrContextOptions& options) {
-    for (int typeInt = 0; typeInt < GrContextFactory::kContextTypeCnt; ++typeInt) {
-        GrContextFactory::ContextType contextType = (GrContextFactory::ContextType)typeInt;
+    for (int typeInt = 0; typeInt < skgpu::kContextTypeCount; ++typeInt) {
+        skgpu::ContextType contextType = static_cast<skgpu::ContextType>(typeInt);
         if (skip_context(contextType)) {
             continue;
         }
@@ -112,7 +111,7 @@
         sk_gpu_test::GrContextFactory factory(options);
         sk_gpu_test::ContextInfo ctxInfo = factory.getContextInfo(contextType);
 
-        ReporterContext ctx(reporter, SkString(GrContextFactory::ContextTypeName(contextType)));
+        ReporterContext ctx(reporter, SkString(skgpu::ContextTypeName(contextType)));
         if (ctxInfo.directContext()) {
             ctxInfo.testContext()->makeCurrent();
             (*testFn)(reporter, ctxInfo);
@@ -144,23 +143,22 @@
     SkFILEWStream out(dstPath);
     out.writeText("[\n");
 
-    GrContextFactory::ContextType contextsToDump[] = {skiatest::kNativeGLType,
-                                                      GrContextFactory::kVulkan_ContextType};
+    skgpu::ContextType contextsToDump[] = {skiatest::kNativeGLType, skgpu::ContextType::kVulkan};
 
     for (auto contextType : contextsToDump) {
         std::unique_ptr<TestContext> testCtx;
         switch (contextType) {
 #ifdef SK_GL
-            case GrContextFactory::kGL_ContextType:
+            case skgpu::ContextType::kGL:
                 testCtx.reset(sk_gpu_test::CreatePlatformGLTestContext(kGL_GrGLStandard, nullptr));
                 break;
-            case GrContextFactory::kGLES_ContextType:
+            case skgpu::ContextType::kGLES:
                 testCtx.reset(
                         sk_gpu_test::CreatePlatformGLTestContext(kGLES_GrGLStandard, nullptr));
                 break;
 #endif
 #ifdef SK_VULKAN
-            case GrContextFactory::kVulkan_ContextType:
+            case skgpu::ContextType::kVulkan:
                 testCtx.reset(sk_gpu_test::CreatePlatformVkTestContext(nullptr));
                 break;
 #endif