Generate list of GPU contexts outside tests

Use DEF_GPUTEST_FOR_*_CONTEXT macros to obtain the
test GPU context.

Makes changing the context -related classes easier,
since not all tests need to be changed.

BUG=skia:2992

Review URL: https://codereview.chromium.org/1448873002
diff --git a/tests/BlurTest.cpp b/tests/BlurTest.cpp
index 89f3a0a..f5bb215 100644
--- a/tests/BlurTest.cpp
+++ b/tests/BlurTest.cpp
@@ -99,8 +99,7 @@
     return true;
 }
 
-static void test_blur_drawing(skiatest::Reporter* reporter) {
-
+DEF_TEST(BlurDrawing, reporter) {
     SkPaint paint;
     paint.setColor(SK_ColorGRAY);
     paint.setStyle(SkPaint::kStroke_Style);
@@ -276,15 +275,9 @@
 #if SK_SUPPORT_GPU
 #if 0
 // temporary disable; see below for explanation
-static bool gpu_blur_path(GrContextFactory* factory, const SkPath& path,
+static bool gpu_blur_path(GrContext* context, const SkPath& path,
                           SkScalar gaussianSigma,
                           int* result, int resultCount) {
-
-    GrContext* grContext = factory->get(GrContextFactory::kNative_GLContextType);
-    if (nullptr == grContext) {
-        return false;
-    }
-
     GrSurfaceDesc desc;
     desc.fConfig = kSkia8888_GrPixelConfig;
     desc.fFlags = kRenderTarget_GrSurfaceFlag;
@@ -326,8 +319,7 @@
 }
 
 // Test out the normal blur style with a wide range of sigmas
-static void test_sigma_range(skiatest::Reporter* reporter, GrContextFactory* factory) {
-
+DEF_GPUTEST_FOR_RENDERING_CONTEXTS(BlurSigmaRange, reporter, context) {
     static const int kSize = 100;
 
     // The geometry is offset a smidge to trigger:
@@ -365,7 +357,7 @@
 #if SK_SUPPORT_GPU
 #if 0
         int gpuResult[kSize];
-        bool haveGPUResult = gpu_blur_path(factory, rectPath, sigma, gpuResult, kSize);
+        bool haveGPUResult = gpu_blur_path(context, rectPath, sigma, gpuResult, kSize);
         // Disabling this test for now -- I don't think it's a legit comparison.
         // Will continue to investigate this.
         if (haveGPUResult) {
@@ -507,7 +499,7 @@
     test_delete_looper(reporter, builder.detachLooper(), sigma, style, quality, false);
 }
 
-static void test_asABlur(skiatest::Reporter* reporter) {
+DEF_TEST(BlurAsABlur, reporter) {
     const SkBlurStyle styles[] = {
         kNormal_SkBlurStyle, kSolid_SkBlurStyle, kOuter_SkBlurStyle, kInner_SkBlurStyle
     };
@@ -566,9 +558,3 @@
 }
 
 ///////////////////////////////////////////////////////////////////////////////////////////
-
-DEF_GPUTEST(Blur, reporter, factory) {
-    test_blur_drawing(reporter);
-    test_sigma_range(reporter, factory);
-    test_asABlur(reporter);
-}
diff --git a/tests/ClipBoundsTest.cpp b/tests/ClipBoundsTest.cpp
index 781ee87..d8df62e 100644
--- a/tests/ClipBoundsTest.cpp
+++ b/tests/ClipBoundsTest.cpp
@@ -10,13 +10,11 @@
 // This is a GR test
 #if SK_SUPPORT_GPU
 #include "GrClipMaskManager.h"
-#include "GrContextFactory.h"
-#include "SkGpuDevice.h"
+#include "GrContext.h"
 
 // Ensure that the 'getConservativeBounds' calls are returning bounds clamped
 // to the render target
-static void test_clip_bounds(skiatest::Reporter* reporter, GrContext* context) {
-
+DEF_GPUTEST_FOR_RENDERING_CONTEXTS(GrClipBounds, reporter, context) {
     static const int kXSize = 100;
     static const int kYSize = 100;
 
@@ -68,18 +66,4 @@
     REPORTER_ASSERT(reporter, isIntersectionOfRects);
 }
 
-DEF_GPUTEST(GrClipBounds, reporter, factory) {
-    for (int type = 0; type < GrContextFactory::kLastGLContextType; ++type) {
-        GrContextFactory::GLContextType glType = static_cast<GrContextFactory::GLContextType>(type);
-        if (!GrContextFactory::IsRenderingGLContext(glType)) {
-            continue;
-        }
-        GrContext* context = factory->get(glType);
-        if (nullptr == context) {
-            continue;
-        }
-        test_clip_bounds(reporter, context);
-    }
-}
-
 #endif
diff --git a/tests/FloatingPointTextureTest.cpp b/tests/FloatingPointTextureTest.cpp
index c5103c8..04f73c7 100644
--- a/tests/FloatingPointTextureTest.cpp
+++ b/tests/FloatingPointTextureTest.cpp
@@ -14,19 +14,17 @@
 
 #include <float.h>
 #include "Test.h"
+
 #if SK_SUPPORT_GPU
 #include "GrContext.h"
 #include "GrTexture.h"
-#include "GrContextFactory.h"
-
-#include "SkGpuDevice.h"
 #include "SkHalf.h"
 
 static const int DEV_W = 100, DEV_H = 100;
 static const SkIRect DEV_RECT = SkIRect::MakeWH(DEV_W, DEV_H);
 
 template <typename T>
-void runFPTest(skiatest::Reporter* reporter, GrContextFactory* factory,
+void runFPTest(skiatest::Reporter* reporter, GrContext* context,
                T min, T max, T epsilon, T maxInt, int arraySize, GrPixelConfig config) {
     SkTDArray<T> controlPixelData, readBuffer;
     controlPixelData.setCount(arraySize);
@@ -40,43 +38,30 @@
     }
 
     for (int origin = 0; origin < 2; ++origin) {
-        for (int glCtxType = 0; glCtxType < GrContextFactory::kGLContextTypeCnt; ++glCtxType) {
-            GrSurfaceDesc desc;
-            desc.fFlags = kRenderTarget_GrSurfaceFlag;
-            desc.fWidth = DEV_W;
-            desc.fHeight = DEV_H;
-            desc.fConfig = config;
-            desc.fOrigin = 0 == origin ?
+        GrSurfaceDesc desc;
+        desc.fFlags = kRenderTarget_GrSurfaceFlag;
+        desc.fWidth = DEV_W;
+        desc.fHeight = DEV_H;
+        desc.fConfig = config;
+        desc.fOrigin = 0 == origin ?
             kTopLeft_GrSurfaceOrigin : kBottomLeft_GrSurfaceOrigin;
-
-            GrContextFactory::GLContextType type =
-                static_cast<GrContextFactory::GLContextType>(glCtxType);
-            if (!GrContextFactory::IsRenderingGLContext(type)) {
-                continue;
-            }
-            GrContext* context = factory->get(type);
-            if (nullptr == context) {
-                continue;
-            }
-
-            SkAutoTUnref<GrTexture> fpTexture(context->textureProvider()->createTexture(
-                desc, false, controlPixelData.begin(), 0));
-            // Floating point textures are NOT supported everywhere
-            if (nullptr == fpTexture) {
-                continue;
-            }
-            fpTexture->readPixels(0, 0, DEV_W, DEV_H, desc.fConfig, readBuffer.begin(), 0);
-            REPORTER_ASSERT(reporter,
-                0 == memcmp(readBuffer.begin(), controlPixelData.begin(), readBuffer.bytes()));
+        SkAutoTUnref<GrTexture> fpTexture(context->textureProvider()->createTexture(
+            desc, false, controlPixelData.begin(), 0));
+        // Floating point textures are NOT supported everywhere
+        if (nullptr == fpTexture) {
+            continue;
         }
+        fpTexture->readPixels(0, 0, DEV_W, DEV_H, desc.fConfig, readBuffer.begin(), 0);
+        REPORTER_ASSERT(reporter,
+                        0 == memcmp(readBuffer.begin(), controlPixelData.begin(), readBuffer.bytes()));
     }
 }
 
 static const int FP_CONTROL_ARRAY_SIZE = DEV_W * DEV_H * 4/*RGBA*/;
 static const float kMaxIntegerRepresentableInSPFloatingPoint = 16777216;  // 2 ^ 24
 
-DEF_GPUTEST(FloatingPointTextureTest, reporter, factory) {
-    runFPTest<float>(reporter, factory, FLT_MIN, FLT_MAX, FLT_EPSILON,
+DEF_GPUTEST_FOR_RENDERING_CONTEXTS(FloatingPointTextureTest, reporter, context) {
+    runFPTest<float>(reporter, context, FLT_MIN, FLT_MAX, FLT_EPSILON,
                      kMaxIntegerRepresentableInSPFloatingPoint, 
                      FP_CONTROL_ARRAY_SIZE, kRGBA_float_GrPixelConfig);
 }
@@ -84,16 +69,16 @@
 static const int HALF_ALPHA_CONTROL_ARRAY_SIZE = DEV_W * DEV_H * 1 /*alpha-only*/;
 static const SkHalf kMaxIntegerRepresentableInHalfFloatingPoint = 0x6800;  // 2 ^ 11
 
-DEF_GPUTEST(HalfFloatAlphaTextureTest, reporter, factory) {
-    runFPTest<SkHalf>(reporter, factory, SK_HalfMin, SK_HalfMax, SK_HalfEpsilon,
+DEF_GPUTEST_FOR_RENDERING_CONTEXTS(HalfFloatAlphaTextureTest, reporter, context) {
+    runFPTest<SkHalf>(reporter, context, SK_HalfMin, SK_HalfMax, SK_HalfEpsilon,
         kMaxIntegerRepresentableInHalfFloatingPoint,
         HALF_ALPHA_CONTROL_ARRAY_SIZE, kAlpha_half_GrPixelConfig);
 }
 
 static const int HALF_RGBA_CONTROL_ARRAY_SIZE = DEV_W * DEV_H * 4 /*RGBA*/;
 
-DEF_GPUTEST(HalfFloatRGBATextureTest, reporter, factory) {
-    runFPTest<SkHalf>(reporter, factory, SK_HalfMin, SK_HalfMax, SK_HalfEpsilon,
+DEF_GPUTEST_FOR_RENDERING_CONTEXTS(HalfFloatRGBATextureTest, reporter, context) {
+    runFPTest<SkHalf>(reporter, context, SK_HalfMin, SK_HalfMax, SK_HalfEpsilon,
         kMaxIntegerRepresentableInHalfFloatingPoint,
         HALF_RGBA_CONTROL_ARRAY_SIZE, kRGBA_half_GrPixelConfig);
 }
diff --git a/tests/GpuColorFilterTest.cpp b/tests/GpuColorFilterTest.cpp
index c707380..830c7df 100644
--- a/tests/GpuColorFilterTest.cpp
+++ b/tests/GpuColorFilterTest.cpp
@@ -12,7 +12,6 @@
 #if SK_SUPPORT_GPU
 
 #include "GrContext.h"
-#include "GrContextFactory.h"
 #include "GrFragmentProcessor.h"
 #include "GrInvariantOutput.h"
 #include "SkGr.h"
@@ -34,7 +33,7 @@
     return color & mask;
 }
 
-static void test_getConstantColorComponents(skiatest::Reporter* reporter, GrContext* grContext) {
+DEF_GPUTEST_FOR_ALL_CONTEXTS(GpuColorFilter, reporter, context) {
     struct GetConstantComponentTestCase {
         // "Shape drawn with"
         uint32_t inputComponents; // "rgb of", "red of", "alpha of", ...
@@ -102,7 +101,7 @@
         const GetConstantComponentTestCase& test = filterTests[i];
         SkAutoTUnref<SkColorFilter> cf(
             SkColorFilter::CreateModeFilter(test.filterColor, test.filterMode));
-        SkAutoTUnref<const GrFragmentProcessor> fp( cf->asFragmentProcessor(grContext));
+        SkAutoTUnref<const GrFragmentProcessor> fp( cf->asFragmentProcessor(context));
         REPORTER_ASSERT(reporter, fp);
         GrInvariantOutput inout(test.inputColor,
                                 static_cast<GrColorComponentFlags>(test.inputComponents),
@@ -114,17 +113,4 @@
     }
 }
 
-DEF_GPUTEST(GpuColorFilter, reporter, factory) {
-    for (int type = 0; type < GrContextFactory::kLastGLContextType; ++type) {
-        GrContextFactory::GLContextType glType = static_cast<GrContextFactory::GLContextType>(type);
-
-        GrContext* grContext = factory->get(glType);
-        if (nullptr == grContext) {
-            continue;
-        }
-
-        test_getConstantColorComponents(reporter, grContext);
-    }
-}
-
 #endif
diff --git a/tests/GpuDrawPathTest.cpp b/tests/GpuDrawPathTest.cpp
index 7a6be6d..b0d483b 100644
--- a/tests/GpuDrawPathTest.cpp
+++ b/tests/GpuDrawPathTest.cpp
@@ -10,7 +10,6 @@
 #if SK_SUPPORT_GPU
 
 #include "GrContext.h"
-#include "GrContextFactory.h"
 #include "GrPath.h"
 #include "GrStrokeInfo.h"
 #include "SkBitmap.h"
@@ -24,6 +23,8 @@
 #include "SkSurface.h"
 #include "Test.h"
 
+#include <initializer_list>
+
 static void test_drawPathEmpty(skiatest::Reporter*, SkCanvas* canvas) {
     // Filling an empty path should not crash.
     SkPaint paint;
@@ -76,43 +77,22 @@
     fill_and_stroke(canvas, oval1, oval2, dashEffect);
 }
 
-DEF_GPUTEST(GpuDrawPath, reporter, factory) {
-    for (int type = 0; type < GrContextFactory::kLastGLContextType; ++type) {
-        GrContextFactory::GLContextType glType = static_cast<GrContextFactory::GLContextType>(type);
-
-        GrContext* grContext = factory->get(glType);
-        if (nullptr == grContext) {
-            continue;
-        }
-        static const int sampleCounts[] = { 0, 4, 16 };
-
-        for (size_t i = 0; i < SK_ARRAY_COUNT(sampleCounts); ++i) {
+DEF_GPUTEST_FOR_ALL_CONTEXTS(GpuDrawPath, reporter, context) {
+    for (auto& test_func : { &test_drawPathEmpty, &test_drawSameRectOvals }) {
+        for (auto& sampleCount : {0, 4, 16}) {
             SkImageInfo info = SkImageInfo::MakeN32Premul(255, 255);
-            
             SkAutoTUnref<SkSurface> surface(
-                SkSurface::NewRenderTarget(grContext, SkSurface::kNo_Budgeted, info,
-                                           sampleCounts[i], nullptr));
+                SkSurface::NewRenderTarget(context, SkSurface::kNo_Budgeted, info,
+                                           sampleCount, nullptr));
             if (!surface) {
                 continue;
             }
-            test_drawPathEmpty(reporter, surface->getCanvas());
+            test_func(reporter, surface->getCanvas());
         }
     }
 }
 
-DEF_GPUTEST(GpuDrawPathSameRectOvals, reporter, factory) {
-    GrContext* grContext = factory->get(GrContextFactory::kNVPR_GLContextType);
-    if (!grContext) {
-        return;
-    }
-
-    SkAutoTUnref<SkSurface> surface(
-        SkSurface::NewRenderTarget(grContext, SkSurface::kNo_Budgeted,
-                                   SkImageInfo::MakeN32Premul(255, 255), 4));
-    test_drawSameRectOvals(reporter, surface->getCanvas());
-}
-
-DEF_TEST(GrPathKeys, reporter) {
+DEF_GPUTEST(GrPathKeys, reporter, /*factory*/) {
     // Keys should not ignore conic weights.
     SkPath path1, path2;
     path1.setIsVolatile(true);
diff --git a/tests/GpuLayerCacheTest.cpp b/tests/GpuLayerCacheTest.cpp
index 3d3a507..ba51340 100644
--- a/tests/GpuLayerCacheTest.cpp
+++ b/tests/GpuLayerCacheTest.cpp
@@ -8,7 +8,6 @@
 #if SK_SUPPORT_GPU
 
 #include "GrContext.h"
-#include "GrContextFactory.h"
 #include "GrLayerCache.h"
 #include "GrResourceCache.h"
 #include "SkPictureRecorder.h"
@@ -108,7 +107,7 @@
 // In particular it checks its interaction with the resource cache (w.r.t.
 // locking & unlocking textures).
 // TODO: need to add checks on VRAM usage!
-DEF_GPUTEST(GpuLayerCache, reporter, factory) {
+DEF_GPUTEST_FOR_RENDERING_CONTEXTS(GpuLayerCache, reporter, context) {
     // Add one more layer than can fit in the atlas
     static const int kInitialNumLayers = TestingAccess::NumPlots() + 1;
 
@@ -116,269 +115,255 @@
     GrResourceCache::Stats stats;
 #endif
 
-    for (int i = 0; i < GrContextFactory::kGLContextTypeCnt; ++i) {
-        GrContextFactory::GLContextType glCtxType = (GrContextFactory::GLContextType) i;
+    SkAutoTUnref<const SkPicture> picture;
 
-        if (!GrContextFactory::IsRenderingGLContext(glCtxType)) {
-            continue;
-        }
+    {
+        SkPictureRecorder recorder;
+        SkCanvas* c = recorder.beginRecording(1, 1);
+        // Draw something, anything, to prevent an empty-picture optimization,
+        // which is a singleton and never purged.
+        c->drawRect(SkRect::MakeWH(1,1), SkPaint());
+        picture.reset(recorder.endRecording());
+    }
 
-        GrContext* context = factory->get(glCtxType);
+    GrResourceCache* resourceCache = context->getResourceCache();
 
-        if (nullptr == context) {
-            continue;
-        }
+    GrLayerCache cache(context);
 
-        SkAutoTUnref<const SkPicture> picture;
+    create_layers(reporter, &cache, *picture, kInitialNumLayers, 0);
 
-        {
-            SkPictureRecorder recorder;
-            SkCanvas* c = recorder.beginRecording(1, 1);
-                // Draw something, anything, to prevent an empty-picture optimization,
-                // which is a singleton and never purged.
-                c->drawRect(SkRect::MakeWH(1,1), SkPaint());
-            picture.reset(recorder.endRecording());
-        }
+    for (int i = 0; i < kInitialNumLayers; ++i) {
+        int key[1] = { i + 1 };
+        GrCachedLayer* layer = TestingAccess::Find(&cache, picture->uniqueID(), SkMatrix::I(),
+                                                   key, 1);
+        REPORTER_ASSERT(reporter, layer);
 
-        GrResourceCache* resourceCache = context->getResourceCache();
-
-        GrLayerCache cache(context);
-
-        create_layers(reporter, &cache, *picture, kInitialNumLayers, 0);
-
-        for (int i = 0; i < kInitialNumLayers; ++i) {
-            int key[1] = { i + 1 };
-            GrCachedLayer* layer = TestingAccess::Find(&cache, picture->uniqueID(), SkMatrix::I(),
-                                                       key, 1);
-            REPORTER_ASSERT(reporter, layer);
-
-            lock_layer(reporter, &cache, layer);
-
-#if GR_CACHE_STATS
-            resourceCache->getStats(&stats);
-#endif
-
-            // The first 4 layers should be in the atlas (and thus have non-empty rects)
-            if (i < TestingAccess::NumPlots()) {
-                REPORTER_ASSERT(reporter, layer->isAtlased());
-#if GR_CACHE_STATS
-                REPORTER_ASSERT(reporter, 1 == stats.fTotal);
-#endif
-            } else {
-                // The 5th layer couldn't fit in the atlas
-                REPORTER_ASSERT(reporter, !layer->isAtlased());
-#if GR_CACHE_STATS
-                REPORTER_ASSERT(reporter, 2 == stats.fTotal);
-#endif
-            }
-        }
-
-        // Unlock the textures
-        for (int i = 0; i < kInitialNumLayers; ++i) {
-            int key[1] = { i+1 };
-
-            GrCachedLayer* layer = TestingAccess::Find(&cache, picture->uniqueID(), SkMatrix::I(),
-                                                       key, 1);
-            REPORTER_ASSERT(reporter, layer);
-            cache.removeUse(layer);
-        }
+        lock_layer(reporter, &cache, layer);
 
 #if GR_CACHE_STATS
         resourceCache->getStats(&stats);
-        REPORTER_ASSERT(reporter, 2 == stats.fTotal);
-        // The floating layer is purgeable the cache is not
-        REPORTER_ASSERT(reporter, 1 == stats.fNumPurgeable);
-        REPORTER_ASSERT(reporter, 1 == stats.fNumNonPurgeable);
 #endif
 
-        for (int i = 0; i < kInitialNumLayers; ++i) {
-            int key[1] = { i+1 };
+        // The first 4 layers should be in the atlas (and thus have non-empty rects)
+        if (i < TestingAccess::NumPlots()) {
+            REPORTER_ASSERT(reporter, layer->isAtlased());
+#if GR_CACHE_STATS
+            REPORTER_ASSERT(reporter, 1 == stats.fTotal);
+#endif
+        } else {
+            // The 5th layer couldn't fit in the atlas
+            REPORTER_ASSERT(reporter, !layer->isAtlased());
+#if GR_CACHE_STATS
+            REPORTER_ASSERT(reporter, 2 == stats.fTotal);
+#endif
+        }
+    }
 
-            GrCachedLayer* layer = TestingAccess::Find(&cache, picture->uniqueID(), SkMatrix::I(),
-                                                       key, 1);
-            REPORTER_ASSERT(reporter, layer);
+    // Unlock the textures
+    for (int i = 0; i < kInitialNumLayers; ++i) {
+        int key[1] = { i+1 };
 
-            // All the layers should be unlocked
-            REPORTER_ASSERT(reporter, !layer->locked());
+        GrCachedLayer* layer = TestingAccess::Find(&cache, picture->uniqueID(), SkMatrix::I(),
+                                                   key, 1);
+        REPORTER_ASSERT(reporter, layer);
+        cache.removeUse(layer);
+    }
 
-            // When hoisted layers aren't cached they are aggressively removed
-            // from the atlas
+#if GR_CACHE_STATS
+    resourceCache->getStats(&stats);
+    REPORTER_ASSERT(reporter, 2 == stats.fTotal);
+    // The floating layer is purgeable the cache is not
+    REPORTER_ASSERT(reporter, 1 == stats.fNumPurgeable);
+    REPORTER_ASSERT(reporter, 1 == stats.fNumNonPurgeable);
+#endif
+
+    for (int i = 0; i < kInitialNumLayers; ++i) {
+        int key[1] = { i+1 };
+
+        GrCachedLayer* layer = TestingAccess::Find(&cache, picture->uniqueID(), SkMatrix::I(),
+                                                   key, 1);
+        REPORTER_ASSERT(reporter, layer);
+
+        // All the layers should be unlocked
+        REPORTER_ASSERT(reporter, !layer->locked());
+
+        // When hoisted layers aren't cached they are aggressively removed
+        // from the atlas
 #if GR_CACHE_HOISTED_LAYERS
-            // The first 4 layers should still be in the atlas.
-            if (i < 4) {
-                REPORTER_ASSERT(reporter, layer->texture());
-                REPORTER_ASSERT(reporter, layer->isAtlased());
-            } else {
+        // The first 4 layers should still be in the atlas.
+        if (i < 4) {
+            REPORTER_ASSERT(reporter, layer->texture());
+            REPORTER_ASSERT(reporter, layer->isAtlased());
+        } else {
 #endif
-                // The final layer should not be atlased.
-                REPORTER_ASSERT(reporter, nullptr == layer->texture());
-                REPORTER_ASSERT(reporter, !layer->isAtlased());
+            // The final layer should not be atlased.
+            REPORTER_ASSERT(reporter, nullptr == layer->texture());
+            REPORTER_ASSERT(reporter, !layer->isAtlased());
 #if GR_CACHE_HOISTED_LAYERS
-            }
-#endif
         }
-
-        // Let go of the backing texture
-        cache.end();
-        REPORTER_ASSERT(reporter, nullptr == TestingAccess::GetBackingTexture(&cache));
-
-#if GR_CACHE_STATS
-        resourceCache->getStats(&stats);
-        REPORTER_ASSERT(reporter, 2 == stats.fTotal);
-        // Now both the floater and the atlas are purgeable
-        REPORTER_ASSERT(reporter, 2 == stats.fNumPurgeable);
-#endif
-
-        // re-attach to the backing texture
-        cache.begin();
-        REPORTER_ASSERT(reporter, TestingAccess::GetBackingTexture(&cache));
-
-#if GR_CACHE_STATS
-        resourceCache->getStats(&stats);
-        REPORTER_ASSERT(reporter, 2 == stats.fTotal);
-        // The atlas is restored to being non-purgeable
-        REPORTER_ASSERT(reporter, 1 == stats.fNumPurgeable);
-        REPORTER_ASSERT(reporter, 1 == stats.fNumNonPurgeable);
-#endif
-
-        {
-            int key[1] = { kInitialNumLayers+1 };
-
-            // Add an additional layer. Since all the layers are unlocked this
-            // will force out the first atlased layer
-            create_layers(reporter, &cache, *picture, 1, kInitialNumLayers);
-            GrCachedLayer* layer = TestingAccess::Find(&cache, picture->uniqueID(), SkMatrix::I(),
-                                                       key, 1);
-            REPORTER_ASSERT(reporter, layer);
-
-            lock_layer(reporter, &cache, layer);
-            cache.removeUse(layer);
-        }
-
-        for (int i = 0; i < kInitialNumLayers+1; ++i) {
-            int key[1] = { i+1 };
-
-            GrCachedLayer* layer = TestingAccess::Find(&cache, picture->uniqueID(), SkMatrix::I(),
-                                                       key, 1);
-#if GR_CACHE_HOISTED_LAYERS
-            // 3 old layers plus the new one should be in the atlas.
-            if (1 == i || 2 == i || 3 == i || 5 == i) {
-                REPORTER_ASSERT(reporter, layer);
-                REPORTER_ASSERT(reporter, !layer->locked());
-                REPORTER_ASSERT(reporter, layer->texture());
-                REPORTER_ASSERT(reporter, layer->isAtlased());
-            } else if (4 == i) {
-#endif
-                // The one that was never atlased should still be around
-                REPORTER_ASSERT(reporter, layer);
-
-                REPORTER_ASSERT(reporter, nullptr == layer->texture());
-                REPORTER_ASSERT(reporter, !layer->isAtlased());
-#if GR_CACHE_HOISTED_LAYERS
-            } else {
-                // The one bumped out of the atlas (i.e., 0) should be gone
-                REPORTER_ASSERT(reporter, nullptr == layer);
-            }
-#endif
-        }
-
-        //--------------------------------------------------------------------
-        // Free them all SkGpuDevice-style. This will not free up the
-        // atlas' texture but will eliminate all the layers.
-        TestingAccess::Purge(&cache, picture->uniqueID());
-
-        REPORTER_ASSERT(reporter, TestingAccess::NumLayers(&cache) == 0);
-
-#if GR_CACHE_STATS
-        resourceCache->getStats(&stats);
-        REPORTER_ASSERT(reporter, 2 == stats.fTotal);
-        // Atlas isn't purgeable
-        REPORTER_ASSERT(reporter, 1 == stats.fNumPurgeable);
-        REPORTER_ASSERT(reporter, 1 == stats.fNumNonPurgeable);
-#endif
-
-        //--------------------------------------------------------------------
-        // Test out the GrContext-style purge. This should remove all the layers
-        // and the atlas.
-        // Re-create the layers
-        create_layers(reporter, &cache, *picture, kInitialNumLayers, 0);
-
-        // Free them again GrContext-style. This should free up everything.
-        cache.freeAll();
-
-        REPORTER_ASSERT(reporter, TestingAccess::NumLayers(&cache) == 0);
-
-        REPORTER_ASSERT(reporter, nullptr == TestingAccess::GetBackingTexture(&cache));
-
-#if GR_CACHE_STATS
-        resourceCache->getStats(&stats);
-        REPORTER_ASSERT(reporter, 2 == stats.fTotal);
-        REPORTER_ASSERT(reporter, 2 == stats.fNumPurgeable);
-#endif
-
-        // Purge the resource cache ...
-        resourceCache->purgeAllUnlocked();
-
-#if GR_CACHE_STATS
-        resourceCache->getStats(&stats);
-        REPORTER_ASSERT(reporter, 0 == stats.fTotal);
-#endif
-
-        // and try to re-attach to the backing texture. This should fail
-        cache.begin();
-        REPORTER_ASSERT(reporter, nullptr == TestingAccess::GetBackingTexture(&cache));
-
-        //--------------------------------------------------------------------
-        // Test out the MessageBus-style purge. This will not free the atlas
-        // but should eliminate the free-floating layers.
-        create_layers(reporter, &cache, *picture, kInitialNumLayers, 0);
-
-        // Allocate/use the layers
-        for (int i = 0; i < kInitialNumLayers; ++i) {
-            int key[1] = { i + 1 };
-            GrCachedLayer* layer = TestingAccess::Find(&cache, picture->uniqueID(), SkMatrix::I(),
-                                                       key, 1);
-            REPORTER_ASSERT(reporter, layer);
-
-            lock_layer(reporter, &cache, layer);
-        }
-
-#if GR_CACHE_STATS
-        resourceCache->getStats(&stats);
-        REPORTER_ASSERT(reporter, 2 == stats.fTotal);
-        REPORTER_ASSERT(reporter, 2 == stats.fNumNonPurgeable);
-#endif
-
-        // Unlock the textures
-        for (int i = 0; i < kInitialNumLayers; ++i) {
-            int key[1] = { i+1 };
-
-            GrCachedLayer* layer = TestingAccess::Find(&cache, picture->uniqueID(), SkMatrix::I(),
-                                                       key, 1);
-            REPORTER_ASSERT(reporter, layer);
-            cache.removeUse(layer);
-        }
-
-        picture.reset(nullptr);
-        cache.processDeletedPictures();
-
-        REPORTER_ASSERT(reporter, TestingAccess::NumLayers(&cache) == 0);
-
-#if GR_CACHE_STATS
-        resourceCache->getStats(&stats);
-        REPORTER_ASSERT(reporter, 2 == stats.fTotal);
-        REPORTER_ASSERT(reporter, 1 == stats.fNumPurgeable);
-        REPORTER_ASSERT(reporter, 1 == stats.fNumNonPurgeable);
-#endif
-
-        cache.end();
-
-#if GR_CACHE_STATS
-        resourceCache->getStats(&stats);
-        REPORTER_ASSERT(reporter, 2 == stats.fTotal);
-        REPORTER_ASSERT(reporter, 2 == stats.fNumPurgeable);
 #endif
     }
+
+    // Let go of the backing texture
+    cache.end();
+    REPORTER_ASSERT(reporter, nullptr == TestingAccess::GetBackingTexture(&cache));
+
+#if GR_CACHE_STATS
+    resourceCache->getStats(&stats);
+    REPORTER_ASSERT(reporter, 2 == stats.fTotal);
+    // Now both the floater and the atlas are purgeable
+    REPORTER_ASSERT(reporter, 2 == stats.fNumPurgeable);
+#endif
+
+    // re-attach to the backing texture
+    cache.begin();
+    REPORTER_ASSERT(reporter, TestingAccess::GetBackingTexture(&cache));
+
+#if GR_CACHE_STATS
+    resourceCache->getStats(&stats);
+    REPORTER_ASSERT(reporter, 2 == stats.fTotal);
+    // The atlas is restored to being non-purgeable
+    REPORTER_ASSERT(reporter, 1 == stats.fNumPurgeable);
+    REPORTER_ASSERT(reporter, 1 == stats.fNumNonPurgeable);
+#endif
+
+    {
+        int key[1] = { kInitialNumLayers+1 };
+
+        // Add an additional layer. Since all the layers are unlocked this
+        // will force out the first atlased layer
+        create_layers(reporter, &cache, *picture, 1, kInitialNumLayers);
+        GrCachedLayer* layer = TestingAccess::Find(&cache, picture->uniqueID(), SkMatrix::I(),
+                                                   key, 1);
+        REPORTER_ASSERT(reporter, layer);
+
+        lock_layer(reporter, &cache, layer);
+        cache.removeUse(layer);
+    }
+
+    for (int i = 0; i < kInitialNumLayers+1; ++i) {
+        int key[1] = { i+1 };
+
+        GrCachedLayer* layer = TestingAccess::Find(&cache, picture->uniqueID(), SkMatrix::I(),
+                                                   key, 1);
+#if GR_CACHE_HOISTED_LAYERS
+        // 3 old layers plus the new one should be in the atlas.
+        if (1 == i || 2 == i || 3 == i || 5 == i) {
+            REPORTER_ASSERT(reporter, layer);
+            REPORTER_ASSERT(reporter, !layer->locked());
+            REPORTER_ASSERT(reporter, layer->texture());
+            REPORTER_ASSERT(reporter, layer->isAtlased());
+        } else if (4 == i) {
+#endif
+            // The one that was never atlased should still be around
+            REPORTER_ASSERT(reporter, layer);
+
+            REPORTER_ASSERT(reporter, nullptr == layer->texture());
+            REPORTER_ASSERT(reporter, !layer->isAtlased());
+#if GR_CACHE_HOISTED_LAYERS
+        } else {
+            // The one bumped out of the atlas (i.e., 0) should be gone
+            REPORTER_ASSERT(reporter, nullptr == layer);
+        }
+#endif
+    }
+
+    //--------------------------------------------------------------------
+    // Free them all SkGpuDevice-style. This will not free up the
+    // atlas' texture but will eliminate all the layers.
+    TestingAccess::Purge(&cache, picture->uniqueID());
+
+    REPORTER_ASSERT(reporter, TestingAccess::NumLayers(&cache) == 0);
+
+#if GR_CACHE_STATS
+    resourceCache->getStats(&stats);
+    REPORTER_ASSERT(reporter, 2 == stats.fTotal);
+    // Atlas isn't purgeable
+    REPORTER_ASSERT(reporter, 1 == stats.fNumPurgeable);
+    REPORTER_ASSERT(reporter, 1 == stats.fNumNonPurgeable);
+#endif
+
+    //--------------------------------------------------------------------
+    // Test out the GrContext-style purge. This should remove all the layers
+    // and the atlas.
+    // Re-create the layers
+    create_layers(reporter, &cache, *picture, kInitialNumLayers, 0);
+
+    // Free them again GrContext-style. This should free up everything.
+    cache.freeAll();
+
+    REPORTER_ASSERT(reporter, TestingAccess::NumLayers(&cache) == 0);
+
+    REPORTER_ASSERT(reporter, nullptr == TestingAccess::GetBackingTexture(&cache));
+
+#if GR_CACHE_STATS
+    resourceCache->getStats(&stats);
+    REPORTER_ASSERT(reporter, 2 == stats.fTotal);
+    REPORTER_ASSERT(reporter, 2 == stats.fNumPurgeable);
+#endif
+
+    // Purge the resource cache ...
+    resourceCache->purgeAllUnlocked();
+
+#if GR_CACHE_STATS
+    resourceCache->getStats(&stats);
+    REPORTER_ASSERT(reporter, 0 == stats.fTotal);
+#endif
+
+    // and try to re-attach to the backing texture. This should fail
+    cache.begin();
+    REPORTER_ASSERT(reporter, nullptr == TestingAccess::GetBackingTexture(&cache));
+
+    //--------------------------------------------------------------------
+    // Test out the MessageBus-style purge. This will not free the atlas
+    // but should eliminate the free-floating layers.
+    create_layers(reporter, &cache, *picture, kInitialNumLayers, 0);
+
+    // Allocate/use the layers
+    for (int i = 0; i < kInitialNumLayers; ++i) {
+        int key[1] = { i + 1 };
+        GrCachedLayer* layer = TestingAccess::Find(&cache, picture->uniqueID(), SkMatrix::I(),
+                                                   key, 1);
+        REPORTER_ASSERT(reporter, layer);
+
+        lock_layer(reporter, &cache, layer);
+    }
+
+#if GR_CACHE_STATS
+    resourceCache->getStats(&stats);
+    REPORTER_ASSERT(reporter, 2 == stats.fTotal);
+    REPORTER_ASSERT(reporter, 2 == stats.fNumNonPurgeable);
+#endif
+
+    // Unlock the textures
+    for (int i = 0; i < kInitialNumLayers; ++i) {
+        int key[1] = { i+1 };
+
+        GrCachedLayer* layer = TestingAccess::Find(&cache, picture->uniqueID(), SkMatrix::I(),
+                                                   key, 1);
+        REPORTER_ASSERT(reporter, layer);
+        cache.removeUse(layer);
+    }
+
+    picture.reset(nullptr);
+    cache.processDeletedPictures();
+
+    REPORTER_ASSERT(reporter, TestingAccess::NumLayers(&cache) == 0);
+
+#if GR_CACHE_STATS
+    resourceCache->getStats(&stats);
+    REPORTER_ASSERT(reporter, 2 == stats.fTotal);
+    REPORTER_ASSERT(reporter, 1 == stats.fNumPurgeable);
+    REPORTER_ASSERT(reporter, 1 == stats.fNumNonPurgeable);
+#endif
+
+    cache.end();
+
+#if GR_CACHE_STATS
+    resourceCache->getStats(&stats);
+    REPORTER_ASSERT(reporter, 2 == stats.fTotal);
+    REPORTER_ASSERT(reporter, 2 == stats.fNumPurgeable);
+#endif
 }
 
 #endif
diff --git a/tests/GrDrawTargetTest.cpp b/tests/GrDrawTargetTest.cpp
index ce3da80..bbc2b91 100644
--- a/tests/GrDrawTargetTest.cpp
+++ b/tests/GrDrawTargetTest.cpp
@@ -11,28 +11,14 @@
 
 #include "GrCaps.h"
 #include "GrContext.h"
-#include "GrContextFactory.h"
 #include "GrGpu.h"
 
-static void test_print(skiatest::Reporter*, const GrCaps* caps) {
+DEF_GPUTEST_FOR_ALL_CONTEXTS(GrDrawTargetPrint, reporter, context) {
     // This used to assert.
-    SkString result = caps->dump();
+    SkString result = context->caps()->dump();
     SkASSERT(!result.isEmpty());
-    SkString shaderResult = caps->shaderCaps()->dump();
+    SkString shaderResult = context->caps()->shaderCaps()->dump();
     SkASSERT(!shaderResult.isEmpty());
 }
 
-DEF_GPUTEST(GrDrawTarget, reporter, factory) {
-    for (int type = 0; type < GrContextFactory::kLastGLContextType; ++type) {
-        GrContextFactory::GLContextType glType = static_cast<GrContextFactory::GLContextType>(type);
-
-        GrContext* grContext = factory->get(glType);
-        if (nullptr == grContext) {
-            continue;
-        }
-
-        test_print(reporter, grContext->caps());
-    }
-}
-
 #endif
diff --git a/tests/GrPorterDuffTest.cpp b/tests/GrPorterDuffTest.cpp
index f1c1961..5755c81 100644
--- a/tests/GrPorterDuffTest.cpp
+++ b/tests/GrPorterDuffTest.cpp
@@ -27,16 +27,9 @@
 static void test_color_opaque_no_coverage(skiatest::Reporter* reporter, const GrCaps& caps);
 static void test_lcd_coverage(skiatest::Reporter* reporter, const GrCaps& caps);
 static void test_lcd_coverage_fallback_case(skiatest::Reporter* reporter, const GrCaps& caps);
-static void test_no_dual_source_blending(skiatest::Reporter* reporter);
 
-DEF_GPUTEST(GrPorterDuff, reporter, factory) {
-    GrContext* ctx = factory->get(GrContextFactory::kNull_GLContextType);
-    if (!ctx) {
-        SkFAIL("Failed to create null context.");
-        return;
-    }
-
-    const GrCaps& caps = *ctx->getGpu()->caps();
+DEF_GPUTEST_FOR_NULL_CONTEXT(GrPorterDuff, reporter, context) {
+    const GrCaps& caps = *context->getGpu()->caps();
     if (!caps.shaderCaps()->dualSourceBlendingSupport()) {
         SkFAIL("Null context does not support dual source blending.");
         return;
@@ -48,7 +41,6 @@
     test_color_opaque_no_coverage(reporter, caps);
     test_lcd_coverage(reporter, caps);
     test_lcd_coverage_fallback_case(reporter, caps);
-    test_no_dual_source_blending(reporter);
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -1154,12 +1146,11 @@
     TEST_ASSERT(blendInfo.fWriteColor);
 }
 
-static void test_no_dual_source_blending(skiatest::Reporter* reporter) {
+DEF_GPUTEST(PorterDuffNoDualSourceBlending, reporter, /*factory*/) {
     GrContextOptions opts;
     opts.fSuppressDualSourceBlending = true;
-    GrContextFactory factory(opts);
-    factory.get(GrContextFactory::kNull_GLContextType);
-    GrContext* ctx = factory.get(GrContextFactory::kNull_GLContextType);
+    GrContextFactory mockFactory(opts);
+    GrContext* ctx = mockFactory.get(GrContextFactory::kNull_GLContextType);
     if (!ctx) {
         SkFAIL("Failed to create null context without ARB_blend_func_extended.");
         return;
@@ -1172,7 +1163,8 @@
     }
 
     GrBackendObject backendTex =
-        ctx->getGpu()->createTestingOnlyBackendTexture(nullptr, 100, 100, kRGBA_8888_GrPixelConfig);
+        ctx->getGpu()->createTestingOnlyBackendTexture(nullptr, 100, 100,
+                                                           kRGBA_8888_GrPixelConfig);
     GrBackendTextureDesc fakeDesc;
     fakeDesc.fConfig = kRGBA_8888_GrPixelConfig;
     fakeDesc.fWidth = fakeDesc.fHeight = 100;
diff --git a/tests/GrSurfaceTest.cpp b/tests/GrSurfaceTest.cpp
index bc24d1c..4b7dbd3 100644
--- a/tests/GrSurfaceTest.cpp
+++ b/tests/GrSurfaceTest.cpp
@@ -10,7 +10,6 @@
 #if SK_SUPPORT_GPU
 
 #include "GrContext.h"
-#include "GrContextFactory.h"
 #include "GrGpu.h"
 #include "GrRenderTarget.h"
 #include "GrTexture.h"
@@ -19,58 +18,55 @@
 
 // Tests that GrSurface::asTexture(), GrSurface::asRenderTarget(), and static upcasting of texture
 // and render targets to GrSurface all work as expected.
-DEF_GPUTEST(GrSurface, reporter, factory) {
-    GrContext* context = factory->get(GrContextFactory::kNull_GLContextType);
-    if (context) {
-        GrSurfaceDesc desc;
-        desc.fConfig = kSkia8888_GrPixelConfig;
-        desc.fFlags = kRenderTarget_GrSurfaceFlag;
-        desc.fWidth = 256;
-        desc.fHeight = 256;
-        desc.fSampleCnt = 0;
-        GrSurface* texRT1 = context->textureProvider()->createTexture(desc, false, nullptr, 0);
+DEF_GPUTEST_FOR_NULL_CONTEXT(GrSurface, reporter, context) {
+    GrSurfaceDesc desc;
+    desc.fConfig = kSkia8888_GrPixelConfig;
+    desc.fFlags = kRenderTarget_GrSurfaceFlag;
+    desc.fWidth = 256;
+    desc.fHeight = 256;
+    desc.fSampleCnt = 0;
+    GrSurface* texRT1 = context->textureProvider()->createTexture(desc, false, nullptr, 0);
 
-        REPORTER_ASSERT(reporter, texRT1 == texRT1->asRenderTarget());
-        REPORTER_ASSERT(reporter, texRT1 == texRT1->asTexture());
-        REPORTER_ASSERT(reporter, static_cast<GrSurface*>(texRT1->asRenderTarget()) ==
-                                  texRT1->asTexture());
-        REPORTER_ASSERT(reporter, texRT1->asRenderTarget() ==
-                                  static_cast<GrSurface*>(texRT1->asTexture()));
-        REPORTER_ASSERT(reporter, static_cast<GrSurface*>(texRT1->asRenderTarget()) ==
-                                  static_cast<GrSurface*>(texRT1->asTexture()));
+    REPORTER_ASSERT(reporter, texRT1 == texRT1->asRenderTarget());
+    REPORTER_ASSERT(reporter, texRT1 == texRT1->asTexture());
+    REPORTER_ASSERT(reporter, static_cast<GrSurface*>(texRT1->asRenderTarget()) ==
+                    texRT1->asTexture());
+    REPORTER_ASSERT(reporter, texRT1->asRenderTarget() ==
+                    static_cast<GrSurface*>(texRT1->asTexture()));
+    REPORTER_ASSERT(reporter, static_cast<GrSurface*>(texRT1->asRenderTarget()) ==
+                    static_cast<GrSurface*>(texRT1->asTexture()));
 
-        desc.fFlags = kNone_GrSurfaceFlags;
-        GrSurface* tex1 = context->textureProvider()->createTexture(desc, false, nullptr, 0);
-        REPORTER_ASSERT(reporter, nullptr == tex1->asRenderTarget());
-        REPORTER_ASSERT(reporter, tex1 == tex1->asTexture());
-        REPORTER_ASSERT(reporter, static_cast<GrSurface*>(tex1) == tex1->asTexture());
+    desc.fFlags = kNone_GrSurfaceFlags;
+    GrSurface* tex1 = context->textureProvider()->createTexture(desc, false, nullptr, 0);
+    REPORTER_ASSERT(reporter, nullptr == tex1->asRenderTarget());
+    REPORTER_ASSERT(reporter, tex1 == tex1->asTexture());
+    REPORTER_ASSERT(reporter, static_cast<GrSurface*>(tex1) == tex1->asTexture());
 
-        GrBackendObject backendTex = context->getGpu()->createTestingOnlyBackendTexture(
-            nullptr, 256, 256, kSkia8888_GrPixelConfig);
+    GrBackendObject backendTex = context->getGpu()->createTestingOnlyBackendTexture(
+        nullptr, 256, 256, kSkia8888_GrPixelConfig);
 
-        GrBackendTextureDesc backendDesc;
-        backendDesc.fConfig = kSkia8888_GrPixelConfig;
-        backendDesc.fFlags = kRenderTarget_GrBackendTextureFlag;
-        backendDesc.fWidth = 256;
-        backendDesc.fHeight = 256;
-        backendDesc.fSampleCnt = 0;
-        backendDesc.fTextureHandle = backendTex;
-        GrSurface* texRT2 = context->textureProvider()->wrapBackendTexture(
-            backendDesc, kBorrow_GrWrapOwnership);
-        REPORTER_ASSERT(reporter, texRT2 == texRT2->asRenderTarget());
-        REPORTER_ASSERT(reporter, texRT2 == texRT2->asTexture());
-        REPORTER_ASSERT(reporter, static_cast<GrSurface*>(texRT2->asRenderTarget()) ==
-                                  texRT2->asTexture());
-        REPORTER_ASSERT(reporter, texRT2->asRenderTarget() ==
-                                  static_cast<GrSurface*>(texRT2->asTexture()));
-        REPORTER_ASSERT(reporter, static_cast<GrSurface*>(texRT2->asRenderTarget()) ==
-                                  static_cast<GrSurface*>(texRT2->asTexture()));
+    GrBackendTextureDesc backendDesc;
+    backendDesc.fConfig = kSkia8888_GrPixelConfig;
+    backendDesc.fFlags = kRenderTarget_GrBackendTextureFlag;
+    backendDesc.fWidth = 256;
+    backendDesc.fHeight = 256;
+    backendDesc.fSampleCnt = 0;
+    backendDesc.fTextureHandle = backendTex;
+    GrSurface* texRT2 = context->textureProvider()->wrapBackendTexture(
+        backendDesc, kBorrow_GrWrapOwnership);
+    REPORTER_ASSERT(reporter, texRT2 == texRT2->asRenderTarget());
+    REPORTER_ASSERT(reporter, texRT2 == texRT2->asTexture());
+    REPORTER_ASSERT(reporter, static_cast<GrSurface*>(texRT2->asRenderTarget()) ==
+                    texRT2->asTexture());
+    REPORTER_ASSERT(reporter, texRT2->asRenderTarget() ==
+                    static_cast<GrSurface*>(texRT2->asTexture()));
+    REPORTER_ASSERT(reporter, static_cast<GrSurface*>(texRT2->asRenderTarget()) ==
+                    static_cast<GrSurface*>(texRT2->asTexture()));
 
-        texRT1->unref();
-        texRT2->unref();
-        tex1->unref();
-        context->getGpu()->deleteTestingOnlyBackendTexture(backendTex);
-    }
+    texRT1->unref();
+    texRT2->unref();
+    tex1->unref();
+    context->getGpu()->deleteTestingOnlyBackendTexture(backendTex);
 }
 
 #endif
diff --git a/tests/GrTextureMipMapInvalidationTest.cpp b/tests/GrTextureMipMapInvalidationTest.cpp
index f046f8f..e0a1282 100644
--- a/tests/GrTextureMipMapInvalidationTest.cpp
+++ b/tests/GrTextureMipMapInvalidationTest.cpp
@@ -10,7 +10,6 @@
 #if SK_SUPPORT_GPU
 
 #include "GrContext.h"
-#include "GrContextFactory.h"
 #include "GrTexture.h"
 #include "GrTexturePriv.h"
 #include "SkCanvas.h"
@@ -20,47 +19,44 @@
 
 // Tests that GrSurface::asTexture(), GrSurface::asRenderTarget(), and static upcasting of texture
 // and render targets to GrSurface all work as expected.
-DEF_GPUTEST(GrTextureMipMapInvalidationTest, reporter, factory) {
-    GrContext* context = factory->get(GrContextFactory::kNull_GLContextType);
-    if (context) {
-        GrSurfaceDesc desc;
-        desc.fConfig = kSkia8888_GrPixelConfig;
-        desc.fFlags = kRenderTarget_GrSurfaceFlag;
-        desc.fWidth = 256;
-        desc.fHeight = 256;
-        desc.fSampleCnt = 0;
-        GrSurface* texRT1 = context->textureProvider()->createTexture(desc, false, nullptr, 0);
-        GrSurface* texRT2 = context->textureProvider()->createTexture(desc, false, nullptr, 0);
-        REPORTER_ASSERT(reporter, nullptr != texRT1);
-        REPORTER_ASSERT(reporter, nullptr != texRT2);
-        GrTexture* tex = texRT1->asTexture();
-        REPORTER_ASSERT(reporter, nullptr != tex);
-        SkBitmap bitmap;
-        GrWrapTextureInBitmap(tex, 256, 256, false, &bitmap);
+DEF_GPUTEST_FOR_NULL_CONTEXT(GrTextureMipMapInvalidationTest, reporter, context) {
+    GrSurfaceDesc desc;
+    desc.fConfig = kSkia8888_GrPixelConfig;
+    desc.fFlags = kRenderTarget_GrSurfaceFlag;
+    desc.fWidth = 256;
+    desc.fHeight = 256;
+    desc.fSampleCnt = 0;
+    GrSurface* texRT1 = context->textureProvider()->createTexture(desc, false, nullptr, 0);
+    GrSurface* texRT2 = context->textureProvider()->createTexture(desc, false, nullptr, 0);
+    REPORTER_ASSERT(reporter, nullptr != texRT1);
+    REPORTER_ASSERT(reporter, nullptr != texRT2);
+    GrTexture* tex = texRT1->asTexture();
+    REPORTER_ASSERT(reporter, nullptr != tex);
+    SkBitmap bitmap;
+    GrWrapTextureInBitmap(tex, 256, 256, false, &bitmap);
 
-        // No mipmaps initially
-        REPORTER_ASSERT(reporter, false == tex->texturePriv().hasMipMaps());
+    // No mipmaps initially
+    REPORTER_ASSERT(reporter, false == tex->texturePriv().hasMipMaps());
 
-        // Painting with downscale and medium filter quality should result in mipmap creation
-        SkSurface* surface = SkSurface::NewRenderTargetDirect(texRT2->asRenderTarget());
-        SkPaint paint;
-        paint.setFilterQuality(kMedium_SkFilterQuality);
-        surface->getCanvas()->scale(0.2f, 0.2f);
-        surface->getCanvas()->drawBitmap(bitmap, 0, 0, &paint);
-        context->flush();
+    // Painting with downscale and medium filter quality should result in mipmap creation
+    SkSurface* surface = SkSurface::NewRenderTargetDirect(texRT2->asRenderTarget());
+    SkPaint paint;
+    paint.setFilterQuality(kMedium_SkFilterQuality);
+    surface->getCanvas()->scale(0.2f, 0.2f);
+    surface->getCanvas()->drawBitmap(bitmap, 0, 0, &paint);
+    context->flush();
 
-        REPORTER_ASSERT(reporter, true == tex->texturePriv().hasMipMaps());
-        REPORTER_ASSERT(reporter, false == tex->texturePriv().mipMapsAreDirty());
+    REPORTER_ASSERT(reporter, true == tex->texturePriv().hasMipMaps());
+    REPORTER_ASSERT(reporter, false == tex->texturePriv().mipMapsAreDirty());
 
-        // Invalidating the contents of the bitmap should invalidate the mipmap, but not de-allocate
-        bitmap.notifyPixelsChanged();
-        REPORTER_ASSERT(reporter, true == tex->texturePriv().hasMipMaps());
-        REPORTER_ASSERT(reporter, true == tex->texturePriv().mipMapsAreDirty());
+    // Invalidating the contents of the bitmap should invalidate the mipmap, but not de-allocate
+    bitmap.notifyPixelsChanged();
+    REPORTER_ASSERT(reporter, true == tex->texturePriv().hasMipMaps());
+    REPORTER_ASSERT(reporter, true == tex->texturePriv().mipMapsAreDirty());
 
-        surface->unref();
-        texRT1->unref();
-        texRT2->unref();
-    }
+    surface->unref();
+    texRT1->unref();
+    texRT2->unref();
 }
 
 #endif
diff --git a/tests/ImageFilterTest.cpp b/tests/ImageFilterTest.cpp
index 4b55274..2619c6f 100644
--- a/tests/ImageFilterTest.cpp
+++ b/tests/ImageFilterTest.cpp
@@ -38,7 +38,7 @@
 #include "Test.h"
 
 #if SK_SUPPORT_GPU
-#include "GrContextFactory.h"
+#include "GrContext.h"
 #include "SkGpuDevice.h"
 #endif
 
@@ -1261,11 +1261,7 @@
 
 #if SK_SUPPORT_GPU
 
-DEF_GPUTEST(ImageFilterCropRectGPU, reporter, factory) {
-    GrContext* context = factory->get(static_cast<GrContextFactory::GLContextType>(0));
-    if (nullptr == context) {
-        return;
-    }
+DEF_GPUTEST_FOR_NATIVE_CONTEXT(ImageFilterCropRect_Gpu, reporter, context) {
     const SkSurfaceProps props(SkSurfaceProps::kLegacyFontHost_InitType);
 
     SkAutoTUnref<SkGpuDevice> device(SkGpuDevice::Create(context,
@@ -1279,11 +1275,7 @@
     test_crop_rects(&proxy, reporter);
 }
 
-DEF_GPUTEST(HugeBlurImageFilterGPU, reporter, factory) {
-    GrContext* context = factory->get(static_cast<GrContextFactory::GLContextType>(0));
-    if (nullptr == context) {
-        return;
-    }
+DEF_GPUTEST_FOR_NATIVE_CONTEXT(HugeBlurImageFilter_Gpu, reporter, context) {
     const SkSurfaceProps props(SkSurfaceProps::kLegacyFontHost_InitType);
 
     SkAutoTUnref<SkGpuDevice> device(SkGpuDevice::Create(context,
@@ -1297,11 +1289,7 @@
     test_huge_blur(&canvas, reporter);
 }
 
-DEF_GPUTEST(XfermodeImageFilterCroppedInputGPU, reporter, factory) {
-    GrContext* context = factory->get(static_cast<GrContextFactory::GLContextType>(0));
-    if (nullptr == context) {
-        return;
-    }
+DEF_GPUTEST_FOR_NATIVE_CONTEXT(XfermodeImageFilterCroppedInput_Gpu, reporter, context) {
     const SkSurfaceProps props(SkSurfaceProps::kLegacyFontHost_InitType);
 
     SkAutoTUnref<SkGpuDevice> device(SkGpuDevice::Create(context,
@@ -1315,11 +1303,7 @@
     test_xfermode_cropped_input(&canvas, reporter);
 }
 
-DEF_GPUTEST(TestNegativeBlurSigmaGPU, reporter, factory) {
-    GrContext* context = factory->get(static_cast<GrContextFactory::GLContextType>(0));
-    if (nullptr == context) {
-        return;
-    }
+DEF_GPUTEST_FOR_NATIVE_CONTEXT(TestNegativeBlurSigma_Gpu, reporter, context) {
     const SkSurfaceProps props(SkSurfaceProps::kLegacyFontHost_InitType);
 
     SkAutoTUnref<SkGpuDevice> device(SkGpuDevice::Create(context,
diff --git a/tests/ImageIsOpaqueTest.cpp b/tests/ImageIsOpaqueTest.cpp
index 48ac9f9..5d7003f 100644
--- a/tests/ImageIsOpaqueTest.cpp
+++ b/tests/ImageIsOpaqueTest.cpp
@@ -9,7 +9,7 @@
 #include "Test.h"
 
 #if SK_SUPPORT_GPU
-#include "GrContextFactory.h"
+#include "GrContext.h"
 #endif
 #include "SkImage.h"
 #include "SkSurface.h"
@@ -65,31 +65,17 @@
 
 #if SK_SUPPORT_GPU
 
-DEF_GPUTEST(ImageIsOpaqueTest_GPU, reporter, factory) {
-    for (int i = 0; i < GrContextFactory::kGLContextTypeCnt; ++i) {
-        GrContextFactory::GLContextType glCtxType = (GrContextFactory::GLContextType) i;
+DEF_GPUTEST_FOR_RENDERING_CONTEXTS(ImageIsOpaqueTest_Gpu, reporter, context) {
+    SkImageInfo infoTransparent = SkImageInfo::MakeN32Premul(5, 5);
+    SkAutoTUnref<SkSurface> surfaceTransparent(
+        SkSurface::NewRenderTarget(context, SkSurface::kNo_Budgeted, infoTransparent));
+    check_isopaque(reporter, surfaceTransparent, false);
 
-        if (!GrContextFactory::IsRenderingGLContext(glCtxType)) {
-            continue;
-        }
+    SkImageInfo infoOpaque = SkImageInfo::MakeN32(5, 5, kOpaque_SkAlphaType);
+    SkAutoTUnref<SkSurface> surfaceOpaque(
+        SkSurface::NewRenderTarget(context,SkSurface::kNo_Budgeted, infoOpaque));
 
-        GrContext* context = factory->get(glCtxType);
-
-        if (nullptr == context) {
-            continue;
-        }
-
-        SkImageInfo infoTransparent = SkImageInfo::MakeN32Premul(5, 5);
-        SkAutoTUnref<SkSurface> surfaceTransparent(
-            SkSurface::NewRenderTarget(context,SkSurface::kNo_Budgeted, infoTransparent));
-        check_isopaque(reporter, surfaceTransparent, false);
-
-        SkImageInfo infoOpaque = SkImageInfo::MakeN32(5, 5, kOpaque_SkAlphaType);
-        SkAutoTUnref<SkSurface> surfaceOpaque(
-            SkSurface::NewRenderTarget(context,SkSurface::kNo_Budgeted, infoOpaque));
-
-        check_isopaque(reporter, surfaceOpaque, true);
-    }
+    check_isopaque(reporter, surfaceOpaque, true);
 }
 
 #endif
diff --git a/tests/ImageNewShaderTest.cpp b/tests/ImageNewShaderTest.cpp
index c01fbe7..2c25b90 100644
--- a/tests/ImageNewShaderTest.cpp
+++ b/tests/ImageNewShaderTest.cpp
@@ -5,17 +5,17 @@
  * found in the LICENSE file.
  */
 
-#include "SkTypes.h"
-#if SK_SUPPORT_GPU
-#include "GrContextFactory.h"
-#endif
 #include "SkCanvas.h"
 #include "SkImage.h"
 #include "SkShader.h"
 #include "SkSurface.h"
-
+#include "SkTypes.h"
 #include "Test.h"
 
+#if SK_SUPPORT_GPU
+#include "GrContext.h"
+#endif
+
 void testBitmapEquality(skiatest::Reporter* reporter, SkBitmap& bm1, SkBitmap& bm2) {
     SkAutoLockPixels lockBm1(bm1);
     SkAutoLockPixels lockBm2(bm2);
@@ -143,29 +143,15 @@
     runShaderTest(reporter, sourceSurface.get(), destinationSurface.get(), info);
 }
 
-DEF_GPUTEST(ImageNewShader_GPU, reporter, factory) {
-    for (int i = 0; i < GrContextFactory::kGLContextTypeCnt; ++i) {
-        GrContextFactory::GLContextType glCtxType = (GrContextFactory::GLContextType) i;
+DEF_GPUTEST_FOR_RENDERING_CONTEXTS(ImageNewShader_GPU, reporter, context) {
+    //  GPU -> GPU
+    gpuToGpu(reporter, context);
 
-        if (!GrContextFactory::IsRenderingGLContext(glCtxType)) {
-            continue;
-        }
+    //  GPU -> RASTER
+    gpuToRaster(reporter, context);
 
-        GrContext* context = factory->get(glCtxType);
-
-        if (nullptr == context) {
-            continue;
-        }
-
-        //  GPU -> GPU
-        gpuToGpu(reporter, context);
-
-        //  GPU -> RASTER
-        gpuToRaster(reporter, context);
-
-        //  RASTER -> GPU
-        rasterToGpu(reporter, context);
-    }
+    //  RASTER -> GPU
+    rasterToGpu(reporter, context);
 }
 
 #endif
diff --git a/tests/PictureTest.cpp b/tests/PictureTest.cpp
index dee24e3..1575456 100644
--- a/tests/PictureTest.cpp
+++ b/tests/PictureTest.cpp
@@ -31,10 +31,6 @@
 #include "SkStream.h"
 #include "sk_tool_utils.h"
 
-#if SK_SUPPORT_GPU
-#include "SkSurface.h"
-#include "GrContextFactory.h"
-#endif
 #include "Test.h"
 
 #include "SkLumaColorFilter.h"
diff --git a/tests/PremulAlphaRoundTripTest.cpp b/tests/PremulAlphaRoundTripTest.cpp
index 211006a..7f94485 100644
--- a/tests/PremulAlphaRoundTripTest.cpp
+++ b/tests/PremulAlphaRoundTripTest.cpp
@@ -12,7 +12,7 @@
 #include "sk_tool_utils.h"
 
 #if SK_SUPPORT_GPU
-#include "GrContextFactory.h"
+#include "GrContext.h"
 #include "SkGpuDevice.h"
 #endif
 
@@ -63,72 +63,55 @@
     canvas->writePixels(info, bmp.getPixels(), bmp.rowBytes(), 0, 0);
 }
 
-DEF_GPUTEST(PremulAlphaRoundTrip, reporter, factory) {
-    const SkImageInfo info = SkImageInfo::MakeN32Premul(256, 256);
+static void test_premul_alpha_roundtrip(skiatest::Reporter* reporter, SkBaseDevice* device) {
+    SkCanvas canvas(device);
+    for (size_t upmaIdx = 0; upmaIdx < SK_ARRAY_COUNT(gUnpremul); ++upmaIdx) {
+        fillCanvas(&canvas, gUnpremul[upmaIdx].fColorType, gUnpremul[upmaIdx].fPackProc);
 
-    for (int dtype = 0; dtype < 2; ++dtype) {
+        const SkImageInfo info = SkImageInfo::Make(256, 256, gUnpremul[upmaIdx].fColorType,
+                                                   kUnpremul_SkAlphaType);
+        SkBitmap readBmp1;
+        readBmp1.allocPixels(info);
+        SkBitmap readBmp2;
+        readBmp2.allocPixels(info);
 
-        int glCtxTypeCnt = 1;
-#if SK_SUPPORT_GPU
-        if (0 != dtype)  {
-            glCtxTypeCnt = GrContextFactory::kGLContextTypeCnt;
-        }
-#endif
-        SkSurfaceProps props(SkSurfaceProps::kLegacyFontHost_InitType);
-        for (int glCtxType = 0; glCtxType < glCtxTypeCnt; ++glCtxType) {
-            SkAutoTUnref<SkBaseDevice> device;
-            if (0 == dtype) {
-                device.reset(SkBitmapDevice::Create(info, props));
-            } else {
-#if SK_SUPPORT_GPU
-                GrContextFactory::GLContextType type =
-                    static_cast<GrContextFactory::GLContextType>(glCtxType);
-                if (!GrContextFactory::IsRenderingGLContext(type)) {
-                    continue;
+        readBmp1.eraseColor(0);
+        readBmp2.eraseColor(0);
+
+        canvas.readPixels(&readBmp1, 0, 0);
+        sk_tool_utils::write_pixels(&canvas, readBmp1, 0, 0, gUnpremul[upmaIdx].fColorType,
+                                    kUnpremul_SkAlphaType);
+        canvas.readPixels(&readBmp2, 0, 0);
+
+        bool success = true;
+        for (int y = 0; y < 256 && success; ++y) {
+            const uint32_t* pixels1 = readBmp1.getAddr32(0, y);
+            const uint32_t* pixels2 = readBmp2.getAddr32(0, y);
+            for (int x = 0; x < 256 && success; ++x) {
+                // We see sporadic failures here. May help to see where it goes wrong.
+                if (pixels1[x] != pixels2[x]) {
+                    SkDebugf("%x != %x, x = %d, y = %d\n", pixels1[x], pixels2[x], x, y);
                 }
-                GrContext* ctx = factory->get(type);
-                if (nullptr == ctx) {
-                    continue;
-                }
-                device.reset(SkGpuDevice::Create(ctx, SkSurface::kNo_Budgeted, info, 0, &props,
-                                                 SkGpuDevice::kUninit_InitContents));
-#else
-                continue;
-#endif
-            }
-            SkCanvas canvas(device);
-
-            for (size_t upmaIdx = 0; upmaIdx < SK_ARRAY_COUNT(gUnpremul); ++upmaIdx) {
-                fillCanvas(&canvas, gUnpremul[upmaIdx].fColorType, gUnpremul[upmaIdx].fPackProc);
-
-                const SkImageInfo info = SkImageInfo::Make(256, 256, gUnpremul[upmaIdx].fColorType,
-                                                           kUnpremul_SkAlphaType);
-                SkBitmap readBmp1;
-                readBmp1.allocPixels(info);
-                SkBitmap readBmp2;
-                readBmp2.allocPixels(info);
-
-                readBmp1.eraseColor(0);
-                readBmp2.eraseColor(0);
-
-                canvas.readPixels(&readBmp1, 0, 0);
-                sk_tool_utils::write_pixels(&canvas, readBmp1, 0, 0, gUnpremul[upmaIdx].fColorType,
-                                            kUnpremul_SkAlphaType);
-                canvas.readPixels(&readBmp2, 0, 0);
-
-                bool success = true;
-                for (int y = 0; y < 256 && success; ++y) {
-                    const uint32_t* pixels1 = readBmp1.getAddr32(0, y);
-                    const uint32_t* pixels2 = readBmp2.getAddr32(0, y);
-                    for (int x = 0; x < 256 && success; ++x) {
-                        // We see sporadic failures here. May help to see where it goes wrong.
-                        if (pixels1[x] != pixels2[x]) {
-                            SkDebugf("%x != %x, x = %d, y = %d\n", pixels1[x], pixels2[x], x, y);
-                        }
-                        REPORTER_ASSERT(reporter, success = pixels1[x] == pixels2[x]);
-                    }
-                }
+                REPORTER_ASSERT(reporter, success = pixels1[x] == pixels2[x]);
             }
         }
     }
 }
+
+DEF_TEST(PremulAlphaRoundTrip, reporter) {
+    const SkImageInfo info = SkImageInfo::MakeN32Premul(256, 256);
+    SkSurfaceProps props(SkSurfaceProps::kLegacyFontHost_InitType);
+    SkAutoTUnref<SkBaseDevice> device(SkBitmapDevice::Create(info, props));
+    test_premul_alpha_roundtrip(reporter, device);
+}
+#if SK_SUPPORT_GPU
+DEF_GPUTEST_FOR_RENDERING_CONTEXTS(PremulAlphaRoundTrip_Gpu, reporter, context) {
+    const SkImageInfo info = SkImageInfo::MakeN32Premul(256, 256);
+    SkSurfaceProps props(SkSurfaceProps::kLegacyFontHost_InitType);
+    SkAutoTUnref<SkBaseDevice> device(
+        SkGpuDevice::Create(context, SkSurface::kNo_Budgeted, info, 0, &props,
+                            SkGpuDevice::kUninit_InitContents));
+    test_premul_alpha_roundtrip(reporter, device);
+}
+#endif
+
diff --git a/tests/ReadPixelsTest.cpp b/tests/ReadPixelsTest.cpp
index 97088b7..0ab25ca 100644
--- a/tests/ReadPixelsTest.cpp
+++ b/tests/ReadPixelsTest.cpp
@@ -13,11 +13,12 @@
 #include "Test.h"
 
 #if SK_SUPPORT_GPU
-#include "GrContextFactory.h"
-#include "SkGpuDevice.h"
+#include "GrContext.h"
 #include "SkGr.h"
 #endif
 
+#include <initializer_list>
+
 static const int DEV_W = 100, DEV_H = 100;
 static const SkIRect DEV_RECT = SkIRect::MakeWH(DEV_W, DEV_H);
 static const SkRect DEV_RECT_S = SkRect::MakeWH(DEV_W * SK_Scalar1,
@@ -257,190 +258,193 @@
     }
 }
 
-DEF_GPUTEST(ReadPixels, reporter, factory) {
-    const SkIRect testRects[] = {
-        // entire thing
-        DEV_RECT,
-        // larger on all sides
-        SkIRect::MakeLTRB(-10, -10, DEV_W + 10, DEV_H + 10),
-        // fully contained
-        SkIRect::MakeLTRB(DEV_W / 4, DEV_H / 4, 3 * DEV_W / 4, 3 * DEV_H / 4),
-        // outside top left
-        SkIRect::MakeLTRB(-10, -10, -1, -1),
-        // touching top left corner
-        SkIRect::MakeLTRB(-10, -10, 0, 0),
-        // overlapping top left corner
-        SkIRect::MakeLTRB(-10, -10, DEV_W / 4, DEV_H / 4),
-        // overlapping top left and top right corners
-        SkIRect::MakeLTRB(-10, -10, DEV_W  + 10, DEV_H / 4),
-        // touching entire top edge
-        SkIRect::MakeLTRB(-10, -10, DEV_W  + 10, 0),
-        // overlapping top right corner
-        SkIRect::MakeLTRB(3 * DEV_W / 4, -10, DEV_W  + 10, DEV_H / 4),
-        // contained in x, overlapping top edge
-        SkIRect::MakeLTRB(DEV_W / 4, -10, 3 * DEV_W  / 4, DEV_H / 4),
-        // outside top right corner
-        SkIRect::MakeLTRB(DEV_W + 1, -10, DEV_W + 10, -1),
-        // touching top right corner
-        SkIRect::MakeLTRB(DEV_W, -10, DEV_W + 10, 0),
-        // overlapping top left and bottom left corners
-        SkIRect::MakeLTRB(-10, -10, DEV_W / 4, DEV_H + 10),
-        // touching entire left edge
-        SkIRect::MakeLTRB(-10, -10, 0, DEV_H + 10),
-        // overlapping bottom left corner
-        SkIRect::MakeLTRB(-10, 3 * DEV_H / 4, DEV_W / 4, DEV_H + 10),
-        // contained in y, overlapping left edge
-        SkIRect::MakeLTRB(-10, DEV_H / 4, DEV_W / 4, 3 * DEV_H / 4),
-        // outside bottom left corner
-        SkIRect::MakeLTRB(-10, DEV_H + 1, -1, DEV_H + 10),
-        // touching bottom left corner
-        SkIRect::MakeLTRB(-10, DEV_H, 0, DEV_H + 10),
-        // overlapping bottom left and bottom right corners
-        SkIRect::MakeLTRB(-10, 3 * DEV_H / 4, DEV_W + 10, DEV_H + 10),
-        // touching entire left edge
-        SkIRect::MakeLTRB(0, DEV_H, DEV_W, DEV_H + 10),
-        // overlapping bottom right corner
-        SkIRect::MakeLTRB(3 * DEV_W / 4, 3 * DEV_H / 4, DEV_W + 10, DEV_H + 10),
-        // overlapping top right and bottom right corners
-        SkIRect::MakeLTRB(3 * DEV_W / 4, -10, DEV_W + 10, DEV_H + 10),
-    };
+static const struct {
+    SkColorType fColorType;
+    SkAlphaType fAlphaType;
+} gReadPixelsConfigs[] = {
+    { kRGBA_8888_SkColorType,   kPremul_SkAlphaType },
+    { kRGBA_8888_SkColorType,   kUnpremul_SkAlphaType },
+    { kBGRA_8888_SkColorType,   kPremul_SkAlphaType },
+    { kBGRA_8888_SkColorType,   kUnpremul_SkAlphaType },
+};
+const SkIRect gReadPixelsTestRects[] = {
+    // entire thing
+    DEV_RECT,
+    // larger on all sides
+    SkIRect::MakeLTRB(-10, -10, DEV_W + 10, DEV_H + 10),
+    // fully contained
+    SkIRect::MakeLTRB(DEV_W / 4, DEV_H / 4, 3 * DEV_W / 4, 3 * DEV_H / 4),
+    // outside top left
+    SkIRect::MakeLTRB(-10, -10, -1, -1),
+    // touching top left corner
+    SkIRect::MakeLTRB(-10, -10, 0, 0),
+    // overlapping top left corner
+    SkIRect::MakeLTRB(-10, -10, DEV_W / 4, DEV_H / 4),
+    // overlapping top left and top right corners
+    SkIRect::MakeLTRB(-10, -10, DEV_W  + 10, DEV_H / 4),
+    // touching entire top edge
+    SkIRect::MakeLTRB(-10, -10, DEV_W  + 10, 0),
+    // overlapping top right corner
+    SkIRect::MakeLTRB(3 * DEV_W / 4, -10, DEV_W  + 10, DEV_H / 4),
+    // contained in x, overlapping top edge
+    SkIRect::MakeLTRB(DEV_W / 4, -10, 3 * DEV_W  / 4, DEV_H / 4),
+    // outside top right corner
+    SkIRect::MakeLTRB(DEV_W + 1, -10, DEV_W + 10, -1),
+    // touching top right corner
+    SkIRect::MakeLTRB(DEV_W, -10, DEV_W + 10, 0),
+    // overlapping top left and bottom left corners
+    SkIRect::MakeLTRB(-10, -10, DEV_W / 4, DEV_H + 10),
+    // touching entire left edge
+    SkIRect::MakeLTRB(-10, -10, 0, DEV_H + 10),
+    // overlapping bottom left corner
+    SkIRect::MakeLTRB(-10, 3 * DEV_H / 4, DEV_W / 4, DEV_H + 10),
+    // contained in y, overlapping left edge
+    SkIRect::MakeLTRB(-10, DEV_H / 4, DEV_W / 4, 3 * DEV_H / 4),
+    // outside bottom left corner
+    SkIRect::MakeLTRB(-10, DEV_H + 1, -1, DEV_H + 10),
+    // touching bottom left corner
+    SkIRect::MakeLTRB(-10, DEV_H, 0, DEV_H + 10),
+    // overlapping bottom left and bottom right corners
+    SkIRect::MakeLTRB(-10, 3 * DEV_H / 4, DEV_W + 10, DEV_H + 10),
+    // touching entire left edge
+    SkIRect::MakeLTRB(0, DEV_H, DEV_W, DEV_H + 10),
+    // overlapping bottom right corner
+    SkIRect::MakeLTRB(3 * DEV_W / 4, 3 * DEV_H / 4, DEV_W + 10, DEV_H + 10),
+    // overlapping top right and bottom right corners
+    SkIRect::MakeLTRB(3 * DEV_W / 4, -10, DEV_W + 10, DEV_H + 10),
+};
 
-    for (int dtype = 0; dtype < 3; ++dtype) {
-        int glCtxTypeCnt = 1;
-#if SK_SUPPORT_GPU
-        // On the GPU we will also try reading back from a non-renderable texture.
-        SkAutoTUnref<GrTexture> texture;
+static void test_readpixels(skiatest::Reporter* reporter, SkSurface* surface) {
+    SkCanvas* canvas = surface->getCanvas();
+    fill_src_canvas(canvas);
+    for (size_t rect = 0; rect < SK_ARRAY_COUNT(gReadPixelsTestRects); ++rect) {
+        const SkIRect& srcRect = gReadPixelsTestRects[rect];
+        for (BitmapInit bmi = kFirstBitmapInit; bmi < kBitmapInitCnt; bmi = nextBMI(bmi)) {
+            for (size_t c = 0; c < SK_ARRAY_COUNT(gReadPixelsConfigs); ++c) {
+                SkBitmap bmp;
+                init_bitmap(&bmp, srcRect, bmi,
+                            gReadPixelsConfigs[c].fColorType, gReadPixelsConfigs[c].fAlphaType);
 
-        if (0 != dtype)  {
-            glCtxTypeCnt = GrContextFactory::kGLContextTypeCnt;
-        }
-#endif
-        const SkImageInfo info = SkImageInfo::MakeN32Premul(DEV_W, DEV_H);
-        for (int glCtxType = 0; glCtxType < glCtxTypeCnt; ++glCtxType) {
-            SkAutoTUnref<SkSurface> surface;
-            if (0 == dtype) {
-                surface.reset(SkSurface::NewRaster(info));
+                // if the bitmap has pixels allocated before the readPixels,
+                // note that and fill them with pattern
+                bool startsWithPixels = !bmp.isNull();
+                if (startsWithPixels) {
+                    fill_dst_bmp_with_init_data(&bmp);
+                }
+                uint32_t idBefore = surface->generationID();
+                bool success = canvas->readPixels(&bmp, srcRect.fLeft, srcRect.fTop);
+                uint32_t idAfter = surface->generationID();
+
+                // we expect to succeed when the read isn't fully clipped
+                // out.
+                bool expectSuccess = SkIRect::Intersects(srcRect, DEV_RECT);
+                // determine whether we expected the read to succeed.
+                REPORTER_ASSERT(reporter, success == expectSuccess);
+                // read pixels should never change the gen id
+                REPORTER_ASSERT(reporter, idBefore == idAfter);
+
+                if (success || startsWithPixels) {
+                    check_read(reporter, bmp, srcRect.fLeft, srcRect.fTop,
+                               success, startsWithPixels);
+                } else {
+                    // if we had no pixels beforehand and the readPixels
+                    // failed then our bitmap should still not have pixels
+                    REPORTER_ASSERT(reporter, bmp.isNull());
+                }
+            }
+            // check the old webkit version of readPixels that clips the
+            // bitmap size
+            SkBitmap wkbmp;
+            bool success = canvas->readPixels(srcRect, &wkbmp);
+            SkIRect clippedRect = DEV_RECT;
+            if (clippedRect.intersect(srcRect)) {
+                REPORTER_ASSERT(reporter, success);
+                REPORTER_ASSERT(reporter, kN32_SkColorType == wkbmp.colorType());
+                REPORTER_ASSERT(reporter, kPremul_SkAlphaType == wkbmp.alphaType());
+                check_read(reporter, wkbmp, clippedRect.fLeft,
+                           clippedRect.fTop, true, false);
             } else {
-#if SK_SUPPORT_GPU
-                GrContextFactory::GLContextType type =
-                    static_cast<GrContextFactory::GLContextType>(glCtxType);
-                if (!GrContextFactory::IsRenderingGLContext(type)) {
-                    continue;
-                }
-                GrContext* context = factory->get(type);
-                if (nullptr == context) {
-                    continue;
-                }
-                GrSurfaceDesc desc;
-                desc.fFlags = kRenderTarget_GrSurfaceFlag;
-                desc.fWidth = DEV_W;
-                desc.fHeight = DEV_H;
-                desc.fConfig = kSkia8888_GrPixelConfig;
-                desc.fOrigin = 1 == dtype ? kBottomLeft_GrSurfaceOrigin : kTopLeft_GrSurfaceOrigin;
-                SkAutoTUnref<GrTexture> surfaceTexture(
-                    context->textureProvider()->createTexture(desc, false));
-                surface.reset(SkSurface::NewRenderTargetDirect(surfaceTexture->asRenderTarget()));
-                desc.fFlags = kNone_GrSurfaceFlags;
-
-                texture.reset(context->textureProvider()->createTexture(desc, false));
-#else
-                continue;
-#endif
+                REPORTER_ASSERT(reporter, !success);
             }
-            SkCanvas& canvas = *surface->getCanvas();
-            fill_src_canvas(&canvas);
-
+        }
+    }
+}
+DEF_TEST(ReadPixels, reporter) {
+    const SkImageInfo info = SkImageInfo::MakeN32Premul(DEV_W, DEV_H);
+    SkAutoTUnref<SkSurface> surface(SkSurface::NewRaster(info));
+    test_readpixels(reporter, surface);
+}
 #if SK_SUPPORT_GPU
-            if (texture) {
-                fill_src_texture(texture);
-            }
+DEF_GPUTEST_FOR_RENDERING_CONTEXTS(ReadPixels_Gpu, reporter, context) {
+    for (auto& origin : {kBottomLeft_GrSurfaceOrigin, kTopLeft_GrSurfaceOrigin}) {
+        GrSurfaceDesc desc;
+        desc.fFlags = kRenderTarget_GrSurfaceFlag;
+        desc.fWidth = DEV_W;
+        desc.fHeight = DEV_H;
+        desc.fConfig = kSkia8888_GrPixelConfig;
+        desc.fOrigin = origin;
+        SkAutoTUnref<GrTexture> surfaceTexture(
+            context->textureProvider()->createTexture(desc, false));
+        SkAutoTUnref<SkSurface> surface(SkSurface::NewRenderTargetDirect(surfaceTexture->asRenderTarget()));
+        desc.fFlags = kNone_GrSurfaceFlags;
+        test_readpixels(reporter, surface);
+    }
+}
 #endif
 
-            static const struct {
-                SkColorType fColorType;
-                SkAlphaType fAlphaType;
-            } gReadConfigs[] = {
-                { kRGBA_8888_SkColorType,   kPremul_SkAlphaType },
-                { kRGBA_8888_SkColorType,   kUnpremul_SkAlphaType },
-                { kBGRA_8888_SkColorType,   kPremul_SkAlphaType },
-                { kBGRA_8888_SkColorType,   kUnpremul_SkAlphaType },
-            };
-            for (size_t rect = 0; rect < SK_ARRAY_COUNT(testRects); ++rect) {
-                const SkIRect& srcRect = testRects[rect];
-                for (BitmapInit bmi = kFirstBitmapInit; bmi < kBitmapInitCnt; bmi = nextBMI(bmi)) {
-                    for (size_t c = 0; c < SK_ARRAY_COUNT(gReadConfigs); ++c) {
-                        SkBitmap bmp;
-                        init_bitmap(&bmp, srcRect, bmi,
-                                    gReadConfigs[c].fColorType, gReadConfigs[c].fAlphaType);
-
-                        // if the bitmap has pixels allocated before the readPixels,
-                        // note that and fill them with pattern
-                        bool startsWithPixels = !bmp.isNull();
-                        if (startsWithPixels) {
-                            fill_dst_bmp_with_init_data(&bmp);
-                        }
-                        uint32_t idBefore = surface->generationID();
-                        bool success = canvas.readPixels(&bmp, srcRect.fLeft, srcRect.fTop);
-                        uint32_t idAfter = surface->generationID();
-
-                        // we expect to succeed when the read isn't fully clipped
-                        // out.
-                        bool expectSuccess = SkIRect::Intersects(srcRect, DEV_RECT);
-                        // determine whether we expected the read to succeed.
-                        REPORTER_ASSERT(reporter, success == expectSuccess);
-                        // read pixels should never change the gen id
-                        REPORTER_ASSERT(reporter, idBefore == idAfter);
-
-                        if (success || startsWithPixels) {
-                            check_read(reporter, bmp, srcRect.fLeft, srcRect.fTop,
-                                       success, startsWithPixels);
-                        } else {
-                            // if we had no pixels beforehand and the readPixels
-                            // failed then our bitmap should still not have pixels
-                            REPORTER_ASSERT(reporter, bmp.isNull());
-                        }
 #if SK_SUPPORT_GPU
-                        // Try doing the read directly from a non-renderable texture
-                        if (texture && startsWithPixels) {
-                            fill_dst_bmp_with_init_data(&bmp);
-                            GrPixelConfig dstConfig =
-                                SkImageInfo2GrPixelConfig(gReadConfigs[c].fColorType,
-                                                          gReadConfigs[c].fAlphaType,
-                                                          kLinear_SkColorProfileType);
-                            uint32_t flags = 0;
-                            if (gReadConfigs[c].fAlphaType == kUnpremul_SkAlphaType) {
-                                flags = GrContext::kUnpremul_PixelOpsFlag;
-                            }
-                            bmp.lockPixels();
-                            success = texture->readPixels(srcRect.fLeft, srcRect.fTop, bmp.width(),
-                                                bmp.height(), dstConfig, bmp.getPixels(),
-                                                bmp.rowBytes(), flags);
-                            bmp.unlockPixels();
-                            check_read(reporter, bmp, srcRect.fLeft, srcRect.fTop,
-                                       success, true);
-                        }
-#endif
+static void test_readpixels_texture(skiatest::Reporter* reporter, GrTexture* texture) {
+    fill_src_texture(texture);
+    for (size_t rect = 0; rect < SK_ARRAY_COUNT(gReadPixelsTestRects); ++rect) {
+        const SkIRect& srcRect = gReadPixelsTestRects[rect];
+        for (BitmapInit bmi = kFirstBitmapInit; bmi < kBitmapInitCnt; bmi = nextBMI(bmi)) {
+            for (size_t c = 0; c < SK_ARRAY_COUNT(gReadPixelsConfigs); ++c) {
+                SkBitmap bmp;
+                init_bitmap(&bmp, srcRect, bmi,
+                            gReadPixelsConfigs[c].fColorType, gReadPixelsConfigs[c].fAlphaType);
+
+                // if the bitmap has pixels allocated before the readPixels,
+                // note that and fill them with pattern
+                bool startsWithPixels = !bmp.isNull();
+                // Try doing the read directly from a non-renderable texture
+                if (startsWithPixels) {
+                    fill_dst_bmp_with_init_data(&bmp);
+                    GrPixelConfig dstConfig =
+                            SkImageInfo2GrPixelConfig(gReadPixelsConfigs[c].fColorType,
+                                                      gReadPixelsConfigs[c].fAlphaType,
+                                                      kLinear_SkColorProfileType);
+                    uint32_t flags = 0;
+                    if (gReadPixelsConfigs[c].fAlphaType == kUnpremul_SkAlphaType) {
+                        flags = GrContext::kUnpremul_PixelOpsFlag;
                     }
-                    // check the old webkit version of readPixels that clips the
-                    // bitmap size
-                    SkBitmap wkbmp;
-                    bool success = canvas.readPixels(srcRect, &wkbmp);
-                    SkIRect clippedRect = DEV_RECT;
-                    if (clippedRect.intersect(srcRect)) {
-                        REPORTER_ASSERT(reporter, success);
-                        REPORTER_ASSERT(reporter, kN32_SkColorType == wkbmp.colorType());
-                        REPORTER_ASSERT(reporter, kPremul_SkAlphaType == wkbmp.alphaType());
-                        check_read(reporter, wkbmp, clippedRect.fLeft,
-                                   clippedRect.fTop, true, false);
-                    } else {
-                        REPORTER_ASSERT(reporter, !success);
-                    }
+                    bmp.lockPixels();
+                    bool success = texture->readPixels(srcRect.fLeft, srcRect.fTop, bmp.width(),
+                                                       bmp.height(), dstConfig, bmp.getPixels(),
+                                                       bmp.rowBytes(), flags);
+                    bmp.unlockPixels();
+                    check_read(reporter, bmp, srcRect.fLeft, srcRect.fTop,
+                               success, true);
                 }
             }
         }
     }
 }
-
+DEF_GPUTEST_FOR_RENDERING_CONTEXTS(ReadPixels_Texture, reporter, context) {
+    // On the GPU we will also try reading back from a non-renderable texture.
+    for (auto& origin : {kBottomLeft_GrSurfaceOrigin, kTopLeft_GrSurfaceOrigin}) {
+        SkAutoTUnref<GrTexture> texture;
+        GrSurfaceDesc desc;
+        desc.fFlags = kRenderTarget_GrSurfaceFlag;
+        desc.fWidth = DEV_W;
+        desc.fHeight = DEV_H;
+        desc.fConfig = kSkia8888_GrPixelConfig;
+        desc.fOrigin = origin;
+        desc.fFlags = kNone_GrSurfaceFlags;
+        texture.reset(context->textureProvider()->createTexture(desc, false));
+        test_readpixels_texture(reporter, texture);
+    }
+}
+#endif
 /////////////////////
 #if SK_SUPPORT_GPU
 
@@ -560,13 +564,7 @@
  *
  *  https://bug.skia.org/4351
  */
-DEF_GPUTEST(ReadPixels_Subset_Gpu, reporter, factory) {
-    GrContext* ctx = factory->get(GrContextFactory::kNative_GLContextType);
-    if (!ctx) {
-        REPORTER_ASSERT(reporter, false);
-        return;
-    }
-
+DEF_GPUTEST_FOR_NATIVE_CONTEXT(ReadPixels_Subset_Gpu, reporter, context) {
     SkBitmap bitmap;
     make_ringed_bitmap(&bitmap, 6, 6);
     const SkIRect subset = SkIRect::MakeLTRB(2, 2, 4, 4);
@@ -575,7 +573,7 @@
     SkBitmap bm_subset, tx_subset;
 
     // ... one from a texture-subset
-    SkAutoTUnref<GrTexture> fullTx(GrRefCachedBitmapTexture(ctx, bitmap,
+    SkAutoTUnref<GrTexture> fullTx(GrRefCachedBitmapTexture(context, bitmap,
                                                             GrTextureParams::ClampNoFilter()));
     SkBitmap tx_full;
     GrWrapTextureInBitmap(fullTx, bitmap.width(), bitmap.height(), true, &tx_full);
@@ -584,7 +582,7 @@
     // ... one from a bitmap-subset
     SkBitmap tmp_subset;
     bitmap.extractSubset(&tmp_subset, subset);
-    SkAutoTUnref<GrTexture> subsetTx(GrRefCachedBitmapTexture(ctx, tmp_subset,
+    SkAutoTUnref<GrTexture> subsetTx(GrRefCachedBitmapTexture(context, tmp_subset,
                                                               GrTextureParams::ClampNoFilter()));
     GrWrapTextureInBitmap(subsetTx, tmp_subset.width(), tmp_subset.height(), true, &bm_subset);
 
@@ -593,8 +591,8 @@
 
     // do they draw the same?
     const SkImageInfo info = SkImageInfo::MakeN32Premul(128, 128);
-    SkAutoTUnref<SkSurface> surfA(SkSurface::NewRenderTarget(ctx, SkSurface::kNo_Budgeted, info, 0));
-    SkAutoTUnref<SkSurface> surfB(SkSurface::NewRenderTarget(ctx, SkSurface::kNo_Budgeted, info, 0));
+    SkAutoTUnref<SkSurface> surfA(SkSurface::NewRenderTarget(context, SkSurface::kNo_Budgeted, info, 0));
+    SkAutoTUnref<SkSurface> surfB(SkSurface::NewRenderTarget(context, SkSurface::kNo_Budgeted, info, 0));
 
     if (false) {
         //
diff --git a/tests/ReadWriteAlphaTest.cpp b/tests/ReadWriteAlphaTest.cpp
index 301bf6b..a40f2c6 100644
--- a/tests/ReadWriteAlphaTest.cpp
+++ b/tests/ReadWriteAlphaTest.cpp
@@ -10,106 +10,95 @@
 // This test is specific to the GPU backend.
 #if SK_SUPPORT_GPU && !defined(SK_BUILD_FOR_ANDROID)
 
-#include "GrContextFactory.h"
+#include "GrContext.h"
 #include "SkGpuDevice.h"
 
 static const int X_SIZE = 12;
 static const int Y_SIZE = 12;
 
-DEF_GPUTEST(ReadWriteAlpha, reporter, factory) {
-    for (int type = 0; type < GrContextFactory::kLastGLContextType; ++type) {
-        GrContextFactory::GLContextType glType = static_cast<GrContextFactory::GLContextType>(type);
-        if (!GrContextFactory::IsRenderingGLContext(glType)) {
-            continue;
-        }
-        GrContext* context = factory->get(glType);
-        if (nullptr == context) {
-            continue;
-        }
+DEF_GPUTEST_FOR_RENDERING_CONTEXTS(ReadWriteAlpha, reporter, context) {
+    unsigned char textureData[X_SIZE][Y_SIZE];
 
-        unsigned char textureData[X_SIZE][Y_SIZE];
+    memset(textureData, 0, X_SIZE * Y_SIZE);
 
-        memset(textureData, 0, X_SIZE * Y_SIZE);
+    GrSurfaceDesc desc;
 
-        GrSurfaceDesc desc;
+    // let Skia know we will be using this texture as a render target
+    desc.fFlags     = kRenderTarget_GrSurfaceFlag;
+    // it is a single channel texture
+    desc.fConfig    = kAlpha_8_GrPixelConfig;
+    desc.fWidth     = X_SIZE;
+    desc.fHeight    = Y_SIZE;
 
-        // let Skia know we will be using this texture as a render target
-        desc.fFlags     = kRenderTarget_GrSurfaceFlag;
-        // it is a single channel texture
-        desc.fConfig    = kAlpha_8_GrPixelConfig;
-        desc.fWidth     = X_SIZE;
-        desc.fHeight    = Y_SIZE;
-
-        // We are initializing the texture with zeros here
-        GrTexture* texture = context->textureProvider()->createTexture(desc, false, textureData, 0);
-        if (!texture) {
-            return;
-        }
-
-        SkAutoTUnref<GrTexture> au(texture);
-
-        // create a distinctive texture
-        for (int y = 0; y < Y_SIZE; ++y) {
-            for (int x = 0; x < X_SIZE; ++x) {
-                textureData[x][y] = x*Y_SIZE+y;
-            }
-        }
-
-        // upload the texture
-        texture->writePixels(0, 0, desc.fWidth, desc.fHeight, desc.fConfig,
-                             textureData, 0);
-
-        unsigned char readback[X_SIZE][Y_SIZE];
-
-        // clear readback to something non-zero so we can detect readback failures
-        memset(readback, 0x1, X_SIZE * Y_SIZE);
-
-        // read the texture back
-        texture->readPixels(0, 0, desc.fWidth, desc.fHeight, desc.fConfig,
-                            readback, 0);
-
-        // make sure the original & read back versions match
-        bool match = true;
-
-        for (int y = 0; y < Y_SIZE; ++y) {
-            for (int x = 0; x < X_SIZE; ++x) {
-                if (textureData[x][y] != readback[x][y]) {
-                    match = false;
-                }
-            }
-        }
-
-        REPORTER_ASSERT(reporter, match);
-
-        // Now try writing on the single channel texture
-        SkSurfaceProps props(SkSurfaceProps::kLegacyFontHost_InitType);
-        SkAutoTUnref<SkBaseDevice> device(SkGpuDevice::Create(texture->asRenderTarget(), &props,
-                                                              SkGpuDevice::kUninit_InitContents));
-        SkCanvas canvas(device);
-
-        SkPaint paint;
-
-        const SkRect rect = SkRect::MakeLTRB(-10, -10, X_SIZE + 10, Y_SIZE + 10);
-
-        paint.setColor(SK_ColorWHITE);
-
-        canvas.drawRect(rect, paint);
-
-        texture->readPixels(0, 0, desc.fWidth, desc.fHeight, desc.fConfig,
-                            readback, 0);
-
-        match = true;
-
-        for (int y = 0; y < Y_SIZE; ++y) {
-            for (int x = 0; x < X_SIZE; ++x) {
-                if (0xFF != readback[x][y]) {
-                    match = false;
-                }
-            }
-        }
-
-        REPORTER_ASSERT(reporter, match);
+    // We are initializing the texture with zeros here
+    GrTexture* texture = context->textureProvider()->createTexture(desc, false, textureData, 0);
+    if (!texture) {
+        return;
     }
+
+    SkAutoTUnref<GrTexture> au(texture);
+
+    // create a distinctive texture
+    for (int y = 0; y < Y_SIZE; ++y) {
+        for (int x = 0; x < X_SIZE; ++x) {
+            textureData[x][y] = x*Y_SIZE+y;
+        }
+    }
+
+    // upload the texture
+    texture->writePixels(0, 0, desc.fWidth, desc.fHeight, desc.fConfig,
+                         textureData, 0);
+
+    unsigned char readback[X_SIZE][Y_SIZE];
+
+    // clear readback to something non-zero so we can detect readback failures
+    memset(readback, 0x1, X_SIZE * Y_SIZE);
+
+    // read the texture back
+    texture->readPixels(0, 0, desc.fWidth, desc.fHeight, desc.fConfig,
+                        readback, 0);
+
+    // make sure the original & read back versions match
+    bool match = true;
+
+    for (int y = 0; y < Y_SIZE; ++y) {
+        for (int x = 0; x < X_SIZE; ++x) {
+            if (textureData[x][y] != readback[x][y]) {
+                match = false;
+            }
+        }
+    }
+
+    REPORTER_ASSERT(reporter, match);
+
+    // Now try writing on the single channel texture
+    SkSurfaceProps props(SkSurfaceProps::kLegacyFontHost_InitType);
+    SkAutoTUnref<SkBaseDevice> device(SkGpuDevice::Create(texture->asRenderTarget(), &props,
+                                                          SkGpuDevice::kUninit_InitContents));
+    SkCanvas canvas(device);
+
+    SkPaint paint;
+
+    const SkRect rect = SkRect::MakeLTRB(-10, -10, X_SIZE + 10, Y_SIZE + 10);
+
+    paint.setColor(SK_ColorWHITE);
+
+    canvas.drawRect(rect, paint);
+
+    texture->readPixels(0, 0, desc.fWidth, desc.fHeight, desc.fConfig,
+                        readback, 0);
+
+    match = true;
+
+    for (int y = 0; y < Y_SIZE; ++y) {
+        for (int x = 0; x < X_SIZE; ++x) {
+            if (0xFF != readback[x][y]) {
+                match = false;
+            }
+        }
+    }
+
+    REPORTER_ASSERT(reporter, match);
 }
 
 #endif
diff --git a/tests/RecordReplaceDrawTest.cpp b/tests/RecordReplaceDrawTest.cpp
index 46f6af3..fe8f347 100644
--- a/tests/RecordReplaceDrawTest.cpp
+++ b/tests/RecordReplaceDrawTest.cpp
@@ -9,7 +9,7 @@
 
 #if SK_SUPPORT_GPU
 
-#include "GrContextFactory.h"
+#include "GrContext.h"
 #include "GrLayerCache.h"
 #include "GrRecordReplaceDraw.h"
 #include "RecordTestUtils.h"
@@ -140,20 +140,9 @@
     }
 }
 
-DEF_GPUTEST(RecordReplaceDraw, r, factory) {
-    for (int type = 0; type < GrContextFactory::kLastGLContextType; ++type) {
-        GrContextFactory::GLContextType glType = static_cast<GrContextFactory::GLContextType>(type);
-        if (!GrContextFactory::IsRenderingGLContext(glType)) {
-            continue;
-        }
-        GrContext* context = factory->get(glType);
-        if (nullptr == context) {
-            continue;
-        }
-
-        test_replacements(r, context, false);
-        test_replacements(r, context, true);
-    }
+DEF_GPUTEST_FOR_RENDERING_CONTEXTS(RecordReplaceDraw, r, context) {
+    test_replacements(r, context, false);
+    test_replacements(r, context, true);
 }
 
 #endif
diff --git a/tests/ResourceCacheTest.cpp b/tests/ResourceCacheTest.cpp
index 08d3678..ee8d7c7 100644
--- a/tests/ResourceCacheTest.cpp
+++ b/tests/ResourceCacheTest.cpp
@@ -30,7 +30,17 @@
 static const int gHeight = 480;
 
 ////////////////////////////////////////////////////////////////////////////////
-static void test_cache(skiatest::Reporter* reporter, GrContext* context, SkCanvas* canvas) {
+DEF_GPUTEST_FOR_RENDERING_CONTEXTS(ResourceCacheCache, reporter, context) {
+    GrSurfaceDesc desc;
+    desc.fConfig = kSkia8888_GrPixelConfig;
+    desc.fFlags = kRenderTarget_GrSurfaceFlag;
+    desc.fWidth = gWidth;
+    desc.fHeight = gHeight;
+    SkImageInfo info = SkImageInfo::MakeN32Premul(gWidth, gHeight);
+    SkAutoTUnref<SkSurface> surface(SkSurface::NewRenderTarget(context,
+                                                               SkSurface::kNo_Budgeted, info));
+    SkCanvas* canvas = surface->getCanvas();
+
     const SkIRect size = SkIRect::MakeWH(gWidth, gHeight);
 
     SkBitmap src;
@@ -70,7 +80,7 @@
     context->setResourceCacheLimits(oldMaxNum, oldMaxBytes);
 }
 
-static void test_stencil_buffers(skiatest::Reporter* reporter, GrContext* context) {
+DEF_GPUTEST_FOR_RENDERING_CONTEXTS(ResourceCacheStencilBuffers, reporter, context) {
     GrSurfaceDesc smallDesc;
     smallDesc.fFlags = kRenderTarget_GrSurfaceFlag;
     smallDesc.fConfig = kSkia8888_GrPixelConfig;
@@ -176,7 +186,7 @@
     }
 }
 
-static void test_wrapped_resources(skiatest::Reporter* reporter, GrContext* context) {
+DEF_GPUTEST_FOR_RENDERING_CONTEXTS(ResourceCacheWrappedResources, reporter, context) {
     const GrGpu* gpu = context->getGpu();
     // this test is only valid for GL
     if (!gpu || !gpu->glContextForTesting()) {
@@ -1284,30 +1294,7 @@
     resource->resourcePriv().removeUniqueKey();
 }
 
-////////////////////////////////////////////////////////////////////////////////
-DEF_GPUTEST(ResourceCache, reporter, factory) {
-    for (int type = 0; type < GrContextFactory::kLastGLContextType; ++type) {
-        GrContextFactory::GLContextType glType = static_cast<GrContextFactory::GLContextType>(type);
-        if (!GrContextFactory::IsRenderingGLContext(glType)) {
-            continue;
-        }
-        GrContext* context = factory->get(glType);
-        if (nullptr == context) {
-            continue;
-        }
-        GrSurfaceDesc desc;
-        desc.fConfig = kSkia8888_GrPixelConfig;
-        desc.fFlags = kRenderTarget_GrSurfaceFlag;
-        desc.fWidth = gWidth;
-        desc.fHeight = gHeight;
-        SkImageInfo info = SkImageInfo::MakeN32Premul(gWidth, gHeight);
-        SkAutoTUnref<SkSurface> surface(SkSurface::NewRenderTarget(context,
-                                                                   SkSurface::kNo_Budgeted, info));
-        test_cache(reporter, context, surface->getCanvas());
-        test_stencil_buffers(reporter, context);
-        test_wrapped_resources(reporter, context);
-    }
-
+DEF_GPUTEST(ResourceCacheMisc, reporter, factory) {
     // The below tests create their own mock contexts.
     test_no_key(reporter);
     test_budgeting(reporter);
diff --git a/tests/SRGBReadWritePixelsTest.cpp b/tests/SRGBReadWritePixelsTest.cpp
index 7e0b721..20b2783 100644
--- a/tests/SRGBReadWritePixelsTest.cpp
+++ b/tests/SRGBReadWritePixelsTest.cpp
@@ -7,11 +7,10 @@
 
 #include "Test.h"
 #if SK_SUPPORT_GPU
-#include "SkCanvas.h"
-
-#include "SkSurface.h"
-#include "GrContextFactory.h"
 #include "GrCaps.h"
+#include "GrContext.h"
+#include "SkCanvas.h"
+#include "SkSurface.h"
 
 // using anonymous namespace because these functions are used as template params.
 namespace {
@@ -139,7 +138,7 @@
 
 // TODO: Add tests for copySurface between srgb/linear textures. Add tests for unpremul/premul
 // conversion during read/write along with srgb/linear conversions.
-DEF_GPUTEST(SRGBReadWritePixels, reporter, factory) {
+DEF_GPUTEST_FOR_RENDERING_CONTEXTS(SRGBReadWritePixels, reporter, context) {
 #if defined(GOOGLE3)
     // Stack frame size is limited in GOOGLE3.
     static const int kW = 63;
@@ -155,87 +154,78 @@
         }
     }
 
-    for (int t = 0; t < GrContextFactory::kGLContextTypeCnt; ++t) {
-        GrContextFactory::GLContextType glType = (GrContextFactory::GLContextType) t;
-        GrContext* context;
-        // We allow more error on GPUs with lower precision shader variables.
-        if (!GrContextFactory::IsRenderingGLContext(glType) || !(context = factory->get(glType))) {
-            continue;
+    GrSurfaceDesc desc;
+    desc.fFlags = kRenderTarget_GrSurfaceFlag;
+    desc.fWidth = kW;
+    desc.fHeight = kH;
+    desc.fConfig = kSRGBA_8888_GrPixelConfig;
+    if (context->caps()->isConfigRenderable(desc.fConfig, false) &&
+        context->caps()->isConfigTexturable(desc.fConfig)) {
+        SkAutoTUnref<GrTexture> tex(context->textureProvider()->createTexture(desc, false));
+        if (!tex) {
+            ERRORF(reporter, "Could not create SRGBA texture.");
+            return;
         }
 
-        GrSurfaceDesc desc;
-        desc.fFlags = kRenderTarget_GrSurfaceFlag;
-        desc.fWidth = kW;
-        desc.fHeight = kH;
-        desc.fConfig = kSRGBA_8888_GrPixelConfig;
-        if (context->caps()->isConfigRenderable(desc.fConfig, false) &&
-            context->caps()->isConfigTexturable(desc.fConfig)) {
-            SkAutoTUnref<GrTexture> tex(context->textureProvider()->createTexture(desc, false));
-            if (!tex) {
-                ERRORF(reporter, "Could not create SRGBA texture.");
-                continue;
-            }
+        float error = context->caps()->shaderCaps()->floatPrecisionVaries() ? 1.2f  : 0.5f;
 
-            float error = context->caps()->shaderCaps()->floatPrecisionVaries() ? 1.2f  : 0.5f;
+        // Write srgba data and read as srgba and then as rgba
+        if (tex->writePixels(0, 0, kW, kH, kSRGBA_8888_GrPixelConfig, origData)) {
+            // For the all-srgba case, we allow a small error only for devices that have
+            // precision variation because the srgba data gets converted to linear and back in
+            // the shader.
+            float smallError = context->caps()->shaderCaps()->floatPrecisionVaries() ? 1.f :
+                    0.0f;
+            read_and_check_pixels(reporter, tex, origData, kSRGBA_8888_GrPixelConfig,
+                                  check_srgb_to_linear_to_srgb_conversion, smallError,
+                                  "write/read srgba to srgba texture");
+            read_and_check_pixels(reporter, tex, origData, kRGBA_8888_GrPixelConfig,
+                                  check_srgb_to_linear_conversion, error,
+                                  "write srgba/read rgba with srgba texture");
+        } else {
+            ERRORF(reporter, "Could not write srgba data to srgba texture.");
+        }
 
-            // Write srgba data and read as srgba and then as rgba
-            if (tex->writePixels(0, 0, kW, kH, kSRGBA_8888_GrPixelConfig, origData)) {
-                // For the all-srgba case, we allow a small error only for devices that have
-                // precision variation because the srgba data gets converted to linear and back in
-                // the shader.
-                float smallError = context->caps()->shaderCaps()->floatPrecisionVaries() ? 1.f :
-                                                                                           0.0f;
-                read_and_check_pixels(reporter, tex, origData, kSRGBA_8888_GrPixelConfig,
-                                      check_srgb_to_linear_to_srgb_conversion, smallError,
-                                      "write/read srgba to srgba texture");
-                read_and_check_pixels(reporter, tex, origData, kRGBA_8888_GrPixelConfig,
-                                      check_srgb_to_linear_conversion, error,
-                                      "write srgba/read rgba with srgba texture");
-            } else {
-                ERRORF(reporter, "Could not write srgba data to srgba texture.");
-            }
+        // Now verify that we can write linear data
+        if (tex->writePixels(0, 0, kW, kH, kRGBA_8888_GrPixelConfig, origData)) {
+            // We allow more error on GPUs with lower precision shader variables.
+            read_and_check_pixels(reporter, tex, origData, kSRGBA_8888_GrPixelConfig,
+                                  check_linear_to_srgb_conversion, error,
+                                  "write rgba/read srgba with srgba texture");
+            read_and_check_pixels(reporter, tex, origData, kRGBA_8888_GrPixelConfig,
+                                  check_linear_to_srgb_to_linear_conversion, error,
+                                  "write/read rgba with srgba texture");
+        } else {
+            ERRORF(reporter, "Could not write rgba data to srgba texture.");
+        }
 
-            // Now verify that we can write linear data
-            if (tex->writePixels(0, 0, kW, kH, kRGBA_8888_GrPixelConfig, origData)) {
-                // We allow more error on GPUs with lower precision shader variables.
-                read_and_check_pixels(reporter, tex, origData, kSRGBA_8888_GrPixelConfig,
-                                      check_linear_to_srgb_conversion, error,
-                                      "write rgba/read srgba with srgba texture");
-                read_and_check_pixels(reporter, tex, origData, kRGBA_8888_GrPixelConfig,
-                                      check_linear_to_srgb_to_linear_conversion, error,
-                                      "write/read rgba with srgba texture");
-            } else {
-                ERRORF(reporter, "Could not write rgba data to srgba texture.");
-            }
+        desc.fConfig = kRGBA_8888_GrPixelConfig;
+        tex.reset(context->textureProvider()->createTexture(desc, false));
+        if (!tex) {
+            ERRORF(reporter, "Could not create RGBA texture.");
+            return;
+        }
 
-            desc.fConfig = kRGBA_8888_GrPixelConfig;
-            tex.reset(context->textureProvider()->createTexture(desc, false));
-            if (!tex) {
-                ERRORF(reporter, "Could not create RGBA texture.");
-                continue;
-            }
+        // Write srgba data to a rgba texture and read back as srgba and rgba
+        if (tex->writePixels(0, 0, kW, kH, kSRGBA_8888_GrPixelConfig, origData)) {
+            read_and_check_pixels(reporter, tex, origData, kSRGBA_8888_GrPixelConfig,
+                                  check_srgb_to_linear_to_srgb_conversion, error,
+                                  "write/read srgba to rgba texture");
+            read_and_check_pixels(reporter, tex, origData, kRGBA_8888_GrPixelConfig,
+                                  check_srgb_to_linear_conversion, error,
+                                  "write srgba/read rgba to rgba texture");
+        } else {
+            ERRORF(reporter, "Could not write srgba data to rgba texture.");
+        }
 
-            // Write srgba data to a rgba texture and read back as srgba and rgba
-            if (tex->writePixels(0, 0, kW, kH, kSRGBA_8888_GrPixelConfig, origData)) {
-               read_and_check_pixels(reporter, tex, origData, kSRGBA_8888_GrPixelConfig,
-                                      check_srgb_to_linear_to_srgb_conversion, error,
-                                      "write/read srgba to rgba texture");
-               read_and_check_pixels(reporter, tex, origData, kRGBA_8888_GrPixelConfig,
-                                     check_srgb_to_linear_conversion, error,
-                                     "write srgba/read rgba to rgba texture");
-            } else {
-                ERRORF(reporter, "Could not write srgba data to rgba texture.");
-            }
-
-            // Write rgba data to a rgba texture and read back as srgba
-            if (tex->writePixels(0, 0, kW, kH, kRGBA_8888_GrPixelConfig, origData)) {
-                read_and_check_pixels(reporter, tex, origData, kSRGBA_8888_GrPixelConfig,
-                                      check_linear_to_srgb_conversion, 1.2f,
-                                      "write rgba/read srgba to rgba texture");
-            } else {
-                ERRORF(reporter, "Could not write rgba data to rgba texture.");
-            }
-}
+        // Write rgba data to a rgba texture and read back as srgba
+        if (tex->writePixels(0, 0, kW, kH, kRGBA_8888_GrPixelConfig, origData)) {
+            read_and_check_pixels(reporter, tex, origData, kSRGBA_8888_GrPixelConfig,
+                                  check_linear_to_srgb_conversion, 1.2f,
+                                  "write rgba/read srgba to rgba texture");
+        } else {
+            ERRORF(reporter, "Could not write rgba data to rgba texture.");
+        }
     }
 }
 #endif
diff --git a/tests/TessellatingPathRendererTests.cpp b/tests/TessellatingPathRendererTests.cpp
index a6eabfd..db0ed37 100644
--- a/tests/TessellatingPathRendererTests.cpp
+++ b/tests/TessellatingPathRendererTests.cpp
@@ -8,7 +8,7 @@
 #include "SkPath.h"
 
 #if SK_SUPPORT_GPU
-#include "GrContextFactory.h"
+#include "GrContext.h"
 #include "GrTest.h"
 #include "Test.h"
 #include "batches/GrTessellatingPathRenderer.h"
@@ -252,11 +252,7 @@
     tess.drawPath(args);
 }
 
-DEF_GPUTEST(TessellatingPathRendererTests, reporter, factory) {
-    GrContext* context = factory->get(static_cast<GrContextFactory::GLContextType>(0));
-    if (nullptr == context) {
-        return;
-    }
+DEF_GPUTEST_FOR_NATIVE_CONTEXT(TessellatingPathRendererTests, reporter, context) {
     GrSurfaceDesc desc;
     desc.fFlags = kRenderTarget_GrSurfaceFlag;
     desc.fWidth = 800;
diff --git a/tests/TextBlobCacheTest.cpp b/tests/TextBlobCacheTest.cpp
index 3a548c7..6aa6c20 100644
--- a/tests/TextBlobCacheTest.cpp
+++ b/tests/TextBlobCacheTest.cpp
@@ -24,7 +24,7 @@
 #include "Test.h"
 
 #if SK_SUPPORT_GPU
-#include "GrContextFactory.h"
+#include "GrContext.h"
 #include "GrTest.h"
 
 struct TextBlobWrapper {
@@ -52,24 +52,21 @@
 static const int kHeight = 768;
 
 // This test hammers the GPU textblobcache and font atlas
-static void text_blob_cache_inner(skiatest::Reporter* reporter, GrContextFactory* factory,
+static void text_blob_cache_inner(skiatest::Reporter* reporter, GrContext* context,
                                   int maxTotalText, int maxGlyphID, int maxFamilies, bool normal,
                                   bool stressTest) {
     // setup surface
     uint32_t flags = 0;
     SkSurfaceProps props(flags, SkSurfaceProps::kLegacyFontHost_InitType);
 
-    // We don't typically actually draw with this unittest
-    GrContext* ctx = factory->get(GrContextFactory::kNull_GLContextType);
-
     // configure our context for maximum stressing of cache and atlas
     if (stressTest) {
-        GrTest::SetupAlwaysEvictAtlas(ctx);
-        ctx->setTextBlobCacheLimit_ForTesting(0);
+        GrTest::SetupAlwaysEvictAtlas(context);
+        context->setTextBlobCacheLimit_ForTesting(0);
     }
 
     SkImageInfo info = SkImageInfo::Make(kWidth, kHeight, kN32_SkColorType, kPremul_SkAlphaType);
-    SkAutoTUnref<SkSurface> surface(SkSurface::NewRenderTarget(ctx, SkSurface::kNo_Budgeted, info,
+    SkAutoTUnref<SkSurface> surface(SkSurface::NewRenderTarget(context, SkSurface::kNo_Budgeted, info,
                                                                0, &props));
     REPORTER_ASSERT(reporter, surface);
     if (!surface) {
@@ -149,30 +146,30 @@
     draw(canvasNoLCD, 2, blobs);
 
     // test draw after free
-    ctx->freeGpuResources();
+    context->freeGpuResources();
     draw(canvas, 1, blobs);
 
-    ctx->freeGpuResources();
+    context->freeGpuResources();
     draw(canvasNoLCD, 1, blobs);
 
     // test draw after abandon
-    ctx->abandonContext();
+    context->abandonContext();
     draw(canvas, 1, blobs);
 }
 
-DEF_GPUTEST(TextBlobCache, reporter, factory) {
-    text_blob_cache_inner(reporter, factory, 1024, 256, 30, true, false);
+DEF_GPUTEST_FOR_NULL_CONTEXT(TextBlobCache, reporter, context) {
+    text_blob_cache_inner(reporter, context, 1024, 256, 30, true, false);
 }
 
-DEF_GPUTEST(TextBlobStressCache, reporter, factory) {
-    text_blob_cache_inner(reporter, factory, 256, 256, 10, true, true);
+DEF_GPUTEST_FOR_NULL_CONTEXT(TextBlobStressCache, reporter, context) {
+    text_blob_cache_inner(reporter, context, 256, 256, 10, true, true);
 }
 
-DEF_GPUTEST(TextBlobAbnormal, reporter, factory) {
-    text_blob_cache_inner(reporter, factory, 256, 256, 10, false, false);
+DEF_GPUTEST_FOR_NULL_CONTEXT(TextBlobAbnormal, reporter, context) {
+    text_blob_cache_inner(reporter, context, 256, 256, 10, false, false);
 }
 
-DEF_GPUTEST(TextBlobStressAbnormal, reporter, factory) {
-    text_blob_cache_inner(reporter, factory, 256, 256, 10, false, true);
+DEF_GPUTEST_FOR_NULL_CONTEXT(TextBlobStressAbnormal, reporter, context) {
+    text_blob_cache_inner(reporter, context, 256, 256, 10, false, true);
 }
 #endif
diff --git a/tests/WritePixelsTest.cpp b/tests/WritePixelsTest.cpp
index c4010b7..6d672f7 100644
--- a/tests/WritePixelsTest.cpp
+++ b/tests/WritePixelsTest.cpp
@@ -14,13 +14,11 @@
 #include "sk_tool_utils.h"
 
 #if SK_SUPPORT_GPU
-#include "GrContextFactory.h"
-#include "SkGpuDevice.h"
-#else
-class GrContext;
-class GrContextFactory;
+#include "GrContext.h"
 #endif
 
+#include <initializer_list>
+
 static const int DEV_W = 100, DEV_H = 100;
 static const SkIRect DEV_RECT = SkIRect::MakeWH(DEV_W, DEV_H);
 static const SkRect DEV_RECT_S = SkRect::MakeWH(DEV_W * SK_Scalar1,
@@ -254,28 +252,6 @@
     return true;
 }
 
-enum DevType {
-    kRaster_DevType,
-#if SK_SUPPORT_GPU
-    kGpu_BottomLeft_DevType,
-    kGpu_TopLeft_DevType,
-#endif
-};
-
-struct CanvasConfig {
-    DevType fDevType;
-    bool fTightRowBytes;
-};
-
-static const CanvasConfig gCanvasConfigs[] = {
-    {kRaster_DevType, true},
-    {kRaster_DevType, false},
-#if SK_SUPPORT_GPU
-    {kGpu_BottomLeft_DevType, true}, // row bytes has no meaning on gpu devices
-    {kGpu_TopLeft_DevType, true}, // row bytes has no meaning on gpu devices
-#endif
-};
-
 #include "SkMallocPixelRef.h"
 
 // This is a tricky pattern, because we have to setConfig+rowBytes AND specify
@@ -295,36 +271,6 @@
     sk_free(pixels);
 }
 
-static SkSurface* create_surface(const CanvasConfig& c, GrContext* grCtx) {
-    SkImageInfo info = SkImageInfo::MakeN32Premul(DEV_W, DEV_H);
-    switch (c.fDevType) {
-        case kRaster_DevType: {
-            const size_t rowBytes = c.fTightRowBytes ? info.minRowBytes() : 4 * DEV_W + 100;
-            const size_t size = info.getSafeSize(rowBytes);
-            void* pixels = sk_malloc_throw(size);
-            // if rowBytes isn't tight then set the padding to a known value
-            if (!c.fTightRowBytes) {
-                memset(pixels, DEV_PAD, size);
-            }
-            return SkSurface::NewRasterDirectReleaseProc(info, pixels, rowBytes, free_pixels, nullptr);
-        }
-#if SK_SUPPORT_GPU
-        case kGpu_BottomLeft_DevType:
-        case kGpu_TopLeft_DevType:
-            GrSurfaceDesc desc;
-            desc.fFlags = kRenderTarget_GrSurfaceFlag;
-            desc.fWidth = DEV_W;
-            desc.fHeight = DEV_H;
-            desc.fConfig = kSkia8888_GrPixelConfig;
-            desc.fOrigin = kGpu_TopLeft_DevType == c.fDevType ?
-                kTopLeft_GrSurfaceOrigin : kBottomLeft_GrSurfaceOrigin;
-            SkAutoTUnref<GrTexture> texture(grCtx->textureProvider()->createTexture(desc, false));
-            return SkSurface::NewRenderTargetDirect(texture->asRenderTarget());
-#endif
-    }
-    return nullptr;
-}
-
 static bool setup_bitmap(SkBitmap* bm, SkColorType ct, SkAlphaType at, int w, int h, int tightRB) {
     size_t rowBytes = tightRB ? 0 : 4 * w + 60;
     SkImageInfo info = SkImageInfo::Make(w, h, ct, at);
@@ -346,7 +292,7 @@
     canvas->writePixels(info, &pixel, sizeof(SkPMColor), 0, 0);
 }
 
-static void test_surface_genid(skiatest::Reporter* reporter) {
+DEF_TEST(WritePixelsSurfaceGenID, reporter) {
     const SkImageInfo info = SkImageInfo::MakeN32Premul(100, 100);
     SkAutoTUnref<SkSurface> surface(SkSurface::NewRaster(info));
     uint32_t genID1 = surface->generationID();
@@ -355,11 +301,7 @@
     REPORTER_ASSERT(reporter, genID1 != genID2);
 }
 
-DEF_GPUTEST(WritePixels, reporter, factory) {
-    test_surface_genid(reporter);
-
-    SkCanvas canvas;
-
+static void test_write_pixels(skiatest::Reporter* reporter, SkSurface* surface) {
     const SkIRect testRects[] = {
         // entire thing
         DEV_RECT,
@@ -407,72 +349,73 @@
         SkIRect::MakeLTRB(3 * DEV_W / 4, -10, DEV_W + 10, DEV_H + 10),
     };
 
-    for (size_t i = 0; i < SK_ARRAY_COUNT(gCanvasConfigs); ++i) {
-        int glCtxTypeCnt = 1;
-#if SK_SUPPORT_GPU
-        bool isGPUDevice = kGpu_TopLeft_DevType == gCanvasConfigs[i].fDevType ||
-                           kGpu_BottomLeft_DevType == gCanvasConfigs[i].fDevType;
-        if (isGPUDevice) {
-            glCtxTypeCnt = GrContextFactory::kGLContextTypeCnt;
-        }
-#endif
-        for (int glCtxType = 0; glCtxType < glCtxTypeCnt; ++glCtxType) {
-            GrContext* context = nullptr;
-#if SK_SUPPORT_GPU
-            if (isGPUDevice) {
-                GrContextFactory::GLContextType type =
-                    static_cast<GrContextFactory::GLContextType>(glCtxType);
-                if (!GrContextFactory::IsRenderingGLContext(type)) {
-                    continue;
-                }
-                context = factory->get(type);
-                if (nullptr == context) {
-                    continue;
-                }
-            }
-#endif
+    SkCanvas& canvas = *surface->getCanvas();
 
-            SkAutoTUnref<SkSurface> surface(create_surface(gCanvasConfigs[i], context));
-            SkCanvas& canvas = *surface->getCanvas();
+    static const struct {
+        SkColorType fColorType;
+        SkAlphaType fAlphaType;
+    } gSrcConfigs[] = {
+        { kRGBA_8888_SkColorType, kPremul_SkAlphaType },
+        { kRGBA_8888_SkColorType, kUnpremul_SkAlphaType },
+        { kBGRA_8888_SkColorType, kPremul_SkAlphaType },
+        { kBGRA_8888_SkColorType, kUnpremul_SkAlphaType },
+    };
+    for (size_t r = 0; r < SK_ARRAY_COUNT(testRects); ++r) {
+        const SkIRect& rect = testRects[r];
+        for (int tightBmp = 0; tightBmp < 2; ++tightBmp) {
+            for (size_t c = 0; c < SK_ARRAY_COUNT(gSrcConfigs); ++c) {
+                const SkColorType ct = gSrcConfigs[c].fColorType;
+                const SkAlphaType at = gSrcConfigs[c].fAlphaType;
 
-            static const struct {
-                SkColorType fColorType;
-                SkAlphaType fAlphaType;
-            } gSrcConfigs[] = {
-                { kRGBA_8888_SkColorType, kPremul_SkAlphaType },
-                { kRGBA_8888_SkColorType, kUnpremul_SkAlphaType },
-                { kBGRA_8888_SkColorType, kPremul_SkAlphaType },
-                { kBGRA_8888_SkColorType, kUnpremul_SkAlphaType },
-            };
-            for (size_t r = 0; r < SK_ARRAY_COUNT(testRects); ++r) {
-                const SkIRect& rect = testRects[r];
-                for (int tightBmp = 0; tightBmp < 2; ++tightBmp) {
-                    for (size_t c = 0; c < SK_ARRAY_COUNT(gSrcConfigs); ++c) {
-                        const SkColorType ct = gSrcConfigs[c].fColorType;
-                        const SkAlphaType at = gSrcConfigs[c].fAlphaType;
+                fill_canvas(&canvas);
+                SkBitmap bmp;
+                REPORTER_ASSERT(reporter, setup_bitmap(&bmp, ct, at, rect.width(),
+                                                       rect.height(), SkToBool(tightBmp)));
+                uint32_t idBefore = surface->generationID();
 
-                        fill_canvas(&canvas);
-                        SkBitmap bmp;
-                        REPORTER_ASSERT(reporter, setup_bitmap(&bmp, ct, at, rect.width(),
-                                                               rect.height(), SkToBool(tightBmp)));
-                        uint32_t idBefore = surface->generationID();
+                // sk_tool_utils::write_pixels(&canvas, bmp, rect.fLeft, rect.fTop, ct, at);
+                canvas.writePixels(bmp, rect.fLeft, rect.fTop);
 
-                       // sk_tool_utils::write_pixels(&canvas, bmp, rect.fLeft, rect.fTop, ct, at);
-                        canvas.writePixels(bmp, rect.fLeft, rect.fTop);
+                uint32_t idAfter = surface->generationID();
+                REPORTER_ASSERT(reporter, check_write(reporter, &canvas, bmp,
+                                                      rect.fLeft, rect.fTop));
 
-                        uint32_t idAfter = surface->generationID();
-                        REPORTER_ASSERT(reporter, check_write(reporter, &canvas, bmp,
-                                                              rect.fLeft, rect.fTop));
-
-                        // we should change the genID iff pixels were actually written.
-                        SkIRect canvasRect = SkIRect::MakeSize(canvas.getDeviceSize());
-                        SkIRect writeRect = SkIRect::MakeXYWH(rect.fLeft, rect.fTop,
-                                                              bmp.width(), bmp.height());
-                        bool intersects = SkIRect::Intersects(canvasRect, writeRect) ;
-                        REPORTER_ASSERT(reporter, intersects == (idBefore != idAfter));
-                    }
-                }
+                // we should change the genID iff pixels were actually written.
+                SkIRect canvasRect = SkIRect::MakeSize(canvas.getDeviceSize());
+                SkIRect writeRect = SkIRect::MakeXYWH(rect.fLeft, rect.fTop,
+                                                      bmp.width(), bmp.height());
+                bool intersects = SkIRect::Intersects(canvasRect, writeRect) ;
+                REPORTER_ASSERT(reporter, intersects == (idBefore != idAfter));
             }
         }
     }
 }
+DEF_TEST(WritePixels, reporter) {
+    const SkImageInfo info = SkImageInfo::MakeN32Premul(DEV_W, DEV_H);
+    for (auto& tightRowBytes : { true, false }) {
+        const size_t rowBytes = tightRowBytes ? info.minRowBytes() : 4 * DEV_W + 100;
+        const size_t size = info.getSafeSize(rowBytes);
+        void* pixels = sk_malloc_throw(size);
+        // if rowBytes isn't tight then set the padding to a known value
+        if (!tightRowBytes) {
+            memset(pixels, DEV_PAD, size);
+        }
+        SkAutoTUnref<SkSurface> surface(SkSurface::NewRasterDirectReleaseProc(info, pixels, rowBytes, free_pixels, nullptr));
+        test_write_pixels(reporter, surface);
+    }
+}
+#if SK_SUPPORT_GPU
+DEF_GPUTEST_FOR_RENDERING_CONTEXTS(WritePixels_Gpu, reporter, context) {
+    for (auto& origin : { kTopLeft_GrSurfaceOrigin, kBottomLeft_GrSurfaceOrigin }) {
+        GrSurfaceDesc desc;
+        desc.fFlags = kRenderTarget_GrSurfaceFlag;
+        desc.fWidth = DEV_W;
+        desc.fHeight = DEV_H;
+        desc.fConfig = kSkia8888_GrPixelConfig;
+        desc.fOrigin = origin;
+        SkAutoTUnref<GrTexture> texture(context->textureProvider()->createTexture(desc, false));
+        SkAutoTUnref<SkSurface> surface(SkSurface::NewRenderTargetDirect(texture->asRenderTarget()));
+        test_write_pixels(reporter, surface);
+    }
+}
+#endif