diff --git a/tests/ImageTest.cpp b/tests/ImageTest.cpp
index 4768b8b..d139ca7 100644
--- a/tests/ImageTest.cpp
+++ b/tests/ImageTest.cpp
@@ -361,3 +361,433 @@
     SkAutoTUnref<SkImage> img(SkImage::NewFromBitmap(bm));
     REPORTER_ASSERT(r, img.get() != nullptr);
 }
+
+// TODO: The tests below were moved from SurfaceTests and should be reformatted.
+
+enum ImageType {
+    kRasterCopy_ImageType,
+    kRasterData_ImageType,
+    kRasterProc_ImageType,
+    kGpu_ImageType,
+    kCodec_ImageType,
+};
+
+#include "SkImageGenerator.h"
+
+class EmptyGenerator : public SkImageGenerator {
+public:
+    EmptyGenerator() : SkImageGenerator(SkImageInfo::MakeN32Premul(0, 0)) {}
+};
+
+static void test_empty_image(skiatest::Reporter* reporter) {
+    const SkImageInfo info = SkImageInfo::Make(0, 0, kN32_SkColorType, kPremul_SkAlphaType);
+    
+    REPORTER_ASSERT(reporter, nullptr == SkImage::NewRasterCopy(info, nullptr, 0));
+    REPORTER_ASSERT(reporter, nullptr == SkImage::NewRasterData(info, nullptr, 0));
+    REPORTER_ASSERT(reporter, nullptr == SkImage::NewFromRaster(info, nullptr, 0, nullptr, nullptr));
+    REPORTER_ASSERT(reporter, nullptr == SkImage::NewFromGenerator(new EmptyGenerator));
+}
+
+static void test_image(skiatest::Reporter* reporter) {
+    SkImageInfo info = SkImageInfo::MakeN32Premul(1, 1);
+    size_t rowBytes = info.minRowBytes();
+    size_t size = info.getSafeSize(rowBytes);
+    SkData* data = SkData::NewUninitialized(size);
+
+    REPORTER_ASSERT(reporter, data->unique());
+    SkImage* image = SkImage::NewRasterData(info, data, rowBytes);
+    REPORTER_ASSERT(reporter, !data->unique());
+    image->unref();
+    REPORTER_ASSERT(reporter, data->unique());
+    data->unref();
+}
+
+// Want to ensure that our Release is called when the owning image is destroyed
+struct ReleaseDataContext {
+    skiatest::Reporter* fReporter;
+    SkData*             fData;
+
+    static void Release(const void* pixels, void* context) {
+        ReleaseDataContext* state = (ReleaseDataContext*)context;
+        REPORTER_ASSERT(state->fReporter, state->fData);
+        state->fData->unref();
+        state->fData = nullptr;
+    }
+};
+
+// May we (soon) eliminate the need to keep testing this, by hiding the bloody device!
+#include "SkDevice.h"
+static uint32_t get_legacy_gen_id(SkSurface* surf) {
+    SkBaseDevice* device = surf->getCanvas()->getDevice_just_for_deprecated_compatibility_testing();
+    return device->accessBitmap(false).getGenerationID();
+}
+
+/*
+ *  Test legacy behavor of bumping the surface's device's bitmap's genID when we access its
+ *  texture handle for writing.
+ *
+ *  Note: this needs to be tested separately from checking newImageSnapshot, as calling that
+ *  can also incidentally bump the genID (when a new backing surface is created).
+ */
+template <class F>
+static void test_texture_handle_genID(skiatest::Reporter* reporter, SkSurface* surf, F f) {
+    const uint32_t gen0 = get_legacy_gen_id(surf);
+    f(surf, SkSurface::kFlushRead_BackendHandleAccess);
+    const uint32_t gen1 = get_legacy_gen_id(surf);
+    REPORTER_ASSERT(reporter, gen0 == gen1);
+
+    f(surf, SkSurface::kFlushWrite_BackendHandleAccess);
+    const uint32_t gen2 = get_legacy_gen_id(surf);
+    REPORTER_ASSERT(reporter, gen0 != gen2);
+
+    f(surf, SkSurface::kDiscardWrite_BackendHandleAccess);
+    const uint32_t gen3 = get_legacy_gen_id(surf);
+    REPORTER_ASSERT(reporter, gen0 != gen3);
+    REPORTER_ASSERT(reporter, gen2 != gen3);
+}
+
+template <class F>
+static void test_backend_handle(skiatest::Reporter* reporter, SkSurface* surf, F f) {
+    SkAutoTUnref<SkImage> image0(surf->newImageSnapshot());
+    GrBackendObject obj = f(surf, SkSurface::kFlushRead_BackendHandleAccess);
+    REPORTER_ASSERT(reporter, obj != 0);
+    SkAutoTUnref<SkImage> image1(surf->newImageSnapshot());
+    // just read access should not affect the snapshot
+    REPORTER_ASSERT(reporter, image0->uniqueID() == image1->uniqueID());
+
+    obj = f(surf, SkSurface::kFlushWrite_BackendHandleAccess);
+    REPORTER_ASSERT(reporter, obj != 0);
+    SkAutoTUnref<SkImage> image2(surf->newImageSnapshot());
+    // expect a new image, since we claimed we would write
+    REPORTER_ASSERT(reporter, image0->uniqueID() != image2->uniqueID());
+
+    obj = f(surf, SkSurface::kDiscardWrite_BackendHandleAccess);
+    REPORTER_ASSERT(reporter, obj != 0);
+    SkAutoTUnref<SkImage> image3(surf->newImageSnapshot());
+    // expect a new(er) image, since we claimed we would write
+    REPORTER_ASSERT(reporter, image0->uniqueID() != image3->uniqueID());
+    REPORTER_ASSERT(reporter, image2->uniqueID() != image3->uniqueID());
+}
+
+static SkImage* create_image(skiatest::Reporter* reporter,
+                             ImageType imageType, GrContext* context, SkColor color,
+                             ReleaseDataContext* releaseContext) {
+    const SkPMColor pmcolor = SkPreMultiplyColor(color);
+    const SkImageInfo info = SkImageInfo::MakeN32Premul(10, 10);
+    const size_t rowBytes = info.minRowBytes();
+    const size_t size = rowBytes * info.height();
+
+    SkAutoTUnref<SkData> data(SkData::NewUninitialized(size));
+    void* addr = data->writable_data();
+    sk_memset32((SkPMColor*)addr, pmcolor, SkToInt(size >> 2));
+
+    switch (imageType) {
+        case kRasterCopy_ImageType:
+            return SkImage::NewRasterCopy(info, addr, rowBytes);
+        case kRasterData_ImageType:
+            return SkImage::NewRasterData(info, data, rowBytes);
+        case kRasterProc_ImageType:
+            SkASSERT(releaseContext);
+            releaseContext->fData = SkRef(data.get());
+            return SkImage::NewFromRaster(info, addr, rowBytes,
+                                          ReleaseDataContext::Release, releaseContext);
+        case kGpu_ImageType: {
+            SkAutoTUnref<SkSurface> surf(
+                SkSurface::NewRenderTarget(context, SkSurface::kNo_Budgeted, info, 0));
+            surf->getCanvas()->clear(color);
+            // test our backing texture / rendertarget while were here...
+            auto textureAccessorFunc =
+                    [](SkSurface* surf, SkSurface::BackendHandleAccess access) -> GrBackendObject {
+                        return surf->getTextureHandle(access); };
+            auto renderTargetAccessorFunc =
+                    [](SkSurface* surf, SkSurface::BackendHandleAccess access) -> GrBackendObject {
+                        GrBackendObject obj;
+                        SkAssertResult(surf->getRenderTargetHandle(&obj, access));
+                        return obj; };
+            test_backend_handle(reporter, surf, textureAccessorFunc);
+            test_backend_handle(reporter, surf, renderTargetAccessorFunc);
+            test_texture_handle_genID(reporter, surf, textureAccessorFunc);
+            test_texture_handle_genID(reporter, surf, renderTargetAccessorFunc);
+
+            // redraw so our returned image looks as expected.
+            surf->getCanvas()->clear(color);
+            return surf->newImageSnapshot();
+        }
+        case kCodec_ImageType: {
+            SkBitmap bitmap;
+            bitmap.installPixels(info, addr, rowBytes);
+            SkAutoTUnref<SkData> src(
+                 SkImageEncoder::EncodeData(bitmap, SkImageEncoder::kPNG_Type, 100));
+            return SkImage::NewFromEncoded(src);
+        }
+    }
+    SkASSERT(false);
+    return nullptr;
+}
+
+static void set_pixels(SkPMColor pixels[], int count, SkPMColor color) {
+    sk_memset32(pixels, color, count);
+}
+static bool has_pixels(const SkPMColor pixels[], int count, SkPMColor expected) {
+    for (int i = 0; i < count; ++i) {
+        if (pixels[i] != expected) {
+            return false;
+        }
+    }
+    return true;
+}
+
+static void test_image_readpixels(skiatest::Reporter* reporter, SkImage* image,
+                                  SkPMColor expected) {
+    const SkPMColor notExpected = ~expected;
+
+    const int w = 2, h = 2;
+    const size_t rowBytes = w * sizeof(SkPMColor);
+    SkPMColor pixels[w*h];
+
+    SkImageInfo info;
+
+    info = SkImageInfo::MakeUnknown(w, h);
+    REPORTER_ASSERT(reporter, !image->readPixels(info, pixels, rowBytes, 0, 0));
+
+    // out-of-bounds should fail
+    info = SkImageInfo::MakeN32Premul(w, h);
+    REPORTER_ASSERT(reporter, !image->readPixels(info, pixels, rowBytes, -w, 0));
+    REPORTER_ASSERT(reporter, !image->readPixels(info, pixels, rowBytes, 0, -h));
+    REPORTER_ASSERT(reporter, !image->readPixels(info, pixels, rowBytes, image->width(), 0));
+    REPORTER_ASSERT(reporter, !image->readPixels(info, pixels, rowBytes, 0, image->height()));
+
+    // top-left should succeed
+    set_pixels(pixels, w*h, notExpected);
+    REPORTER_ASSERT(reporter, image->readPixels(info, pixels, rowBytes, 0, 0));
+    REPORTER_ASSERT(reporter, has_pixels(pixels, w*h, expected));
+
+    // bottom-right should succeed
+    set_pixels(pixels, w*h, notExpected);
+    REPORTER_ASSERT(reporter, image->readPixels(info, pixels, rowBytes,
+                                                image->width() - w, image->height() - h));
+    REPORTER_ASSERT(reporter, has_pixels(pixels, w*h, expected));
+
+    // partial top-left should succeed
+    set_pixels(pixels, w*h, notExpected);
+    REPORTER_ASSERT(reporter, image->readPixels(info, pixels, rowBytes, -1, -1));
+    REPORTER_ASSERT(reporter, pixels[3] == expected);
+    REPORTER_ASSERT(reporter, has_pixels(pixels, w*h - 1, notExpected));
+
+    // partial bottom-right should succeed
+    set_pixels(pixels, w*h, notExpected);
+    REPORTER_ASSERT(reporter, image->readPixels(info, pixels, rowBytes,
+                                                image->width() - 1, image->height() - 1));
+    REPORTER_ASSERT(reporter, pixels[0] == expected);
+    REPORTER_ASSERT(reporter, has_pixels(&pixels[1], w*h - 1, notExpected));
+}
+
+static void check_legacy_bitmap(skiatest::Reporter* reporter, const SkImage* image,
+                                const SkBitmap& bitmap, SkImage::LegacyBitmapMode mode) {
+    REPORTER_ASSERT(reporter, image->width() == bitmap.width());
+    REPORTER_ASSERT(reporter, image->height() == bitmap.height());
+    REPORTER_ASSERT(reporter, image->isOpaque() == bitmap.isOpaque());
+
+    if (SkImage::kRO_LegacyBitmapMode == mode) {
+        REPORTER_ASSERT(reporter, bitmap.isImmutable());
+    }
+
+    SkAutoLockPixels alp(bitmap);
+    REPORTER_ASSERT(reporter, bitmap.getPixels());
+
+    const SkImageInfo info = SkImageInfo::MakeN32(1, 1, bitmap.alphaType());
+    SkPMColor imageColor;
+    REPORTER_ASSERT(reporter, image->readPixels(info, &imageColor, sizeof(SkPMColor), 0, 0));
+    REPORTER_ASSERT(reporter, imageColor == *bitmap.getAddr32(0, 0));
+}
+
+static void test_legacy_bitmap(skiatest::Reporter* reporter, const SkImage* image) {
+    const SkImage::LegacyBitmapMode modes[] = {
+        SkImage::kRO_LegacyBitmapMode,
+        SkImage::kRW_LegacyBitmapMode,
+    };
+    for (size_t i = 0; i < SK_ARRAY_COUNT(modes); ++i) {
+        SkBitmap bitmap;
+        REPORTER_ASSERT(reporter, image->asLegacyBitmap(&bitmap, modes[i]));
+        check_legacy_bitmap(reporter, image, bitmap, modes[i]);
+
+        // Test subsetting to exercise the rowBytes logic.
+        SkBitmap tmp;
+        REPORTER_ASSERT(reporter, bitmap.extractSubset(&tmp, SkIRect::MakeWH(image->width() / 2,
+                                                                             image->height() / 2)));
+        SkAutoTUnref<SkImage> subsetImage(SkImage::NewFromBitmap(tmp));
+        REPORTER_ASSERT(reporter, subsetImage);
+
+        SkBitmap subsetBitmap;
+        REPORTER_ASSERT(reporter, subsetImage->asLegacyBitmap(&subsetBitmap, modes[i]));
+        check_legacy_bitmap(reporter, subsetImage, subsetBitmap, modes[i]);
+    }
+}
+
+static void test_imagepeek(skiatest::Reporter* reporter, GrContextFactory* factory) {
+    static const struct {
+        ImageType   fType;
+        bool        fPeekShouldSucceed;
+        const char* fName;
+    } gRec[] = {
+        { kRasterCopy_ImageType,    true,       "RasterCopy"    },
+        { kRasterData_ImageType,    true,       "RasterData"    },
+        { kRasterProc_ImageType,    true,       "RasterProc"    },
+        { kGpu_ImageType,           false,      "Gpu"           },
+        { kCodec_ImageType,         false,      "Codec"         },
+    };
+
+    const SkColor color = SK_ColorRED;
+    const SkPMColor pmcolor = SkPreMultiplyColor(color);
+
+    GrContext* ctx = nullptr;
+#if SK_SUPPORT_GPU
+    ctx = factory->get(GrContextFactory::kNative_GLContextType);
+    if (nullptr == ctx) {
+        return;
+    }
+#endif
+
+    ReleaseDataContext releaseCtx;
+    releaseCtx.fReporter = reporter;
+
+    for (size_t i = 0; i < SK_ARRAY_COUNT(gRec); ++i) {
+        SkImageInfo info;
+        size_t rowBytes;
+
+        releaseCtx.fData = nullptr;
+        SkAutoTUnref<SkImage> image(create_image(reporter, gRec[i].fType, ctx, color, &releaseCtx));
+        if (!image.get()) {
+            SkDebugf("failed to createImage[%d] %s\n", i, gRec[i].fName);
+            continue;   // gpu may not be enabled
+        }
+        if (kRasterProc_ImageType == gRec[i].fType) {
+            REPORTER_ASSERT(reporter, nullptr != releaseCtx.fData);  // we are tracking the data
+        } else {
+            REPORTER_ASSERT(reporter, nullptr == releaseCtx.fData);  // we ignored the context
+        }
+
+        test_legacy_bitmap(reporter, image);
+
+        const void* addr = image->peekPixels(&info, &rowBytes);
+        bool success = SkToBool(addr);
+        REPORTER_ASSERT(reporter, gRec[i].fPeekShouldSucceed == success);
+        if (success) {
+            REPORTER_ASSERT(reporter, 10 == info.width());
+            REPORTER_ASSERT(reporter, 10 == info.height());
+            REPORTER_ASSERT(reporter, kN32_SkColorType == info.colorType());
+            REPORTER_ASSERT(reporter, kPremul_SkAlphaType == info.alphaType() ||
+                            kOpaque_SkAlphaType == info.alphaType());
+            REPORTER_ASSERT(reporter, info.minRowBytes() <= rowBytes);
+            REPORTER_ASSERT(reporter, pmcolor == *(const SkPMColor*)addr);
+        }
+
+        test_image_readpixels(reporter, image, pmcolor);
+    }
+    REPORTER_ASSERT(reporter, nullptr == releaseCtx.fData);  // we released the data
+}
+#if SK_SUPPORT_GPU
+
+struct ReleaseTextureContext {
+    ReleaseTextureContext(skiatest::Reporter* reporter) {
+        fReporter = reporter;
+        fIsReleased = false;
+    }
+
+    skiatest::Reporter* fReporter;
+    bool                fIsReleased;
+
+    void doRelease() {
+        REPORTER_ASSERT(fReporter, false == fIsReleased);
+        fIsReleased = true;
+    }
+
+    static void ReleaseProc(void* context) {
+        ((ReleaseTextureContext*)context)->doRelease();
+    }
+};
+
+static SkImage* make_desc_image(GrContext* ctx, int w, int h, GrBackendObject texID,
+                                ReleaseTextureContext* releaseContext) {
+    GrBackendTextureDesc desc;
+    desc.fConfig = kSkia8888_GrPixelConfig;
+    // need to be a rendertarget for now...
+    desc.fFlags = kRenderTarget_GrBackendTextureFlag;
+    desc.fWidth = w;
+    desc.fHeight = h;
+    desc.fSampleCnt = 0;
+    desc.fTextureHandle = texID;
+    return releaseContext
+                ? SkImage::NewFromTexture(ctx, desc, kPremul_SkAlphaType,
+                                          ReleaseTextureContext::ReleaseProc, releaseContext)
+                : SkImage::NewFromTextureCopy(ctx, desc, kPremul_SkAlphaType);
+}
+
+static void test_image_color(skiatest::Reporter* reporter, SkImage* image, SkPMColor expected) {
+    const SkImageInfo info = SkImageInfo::MakeN32Premul(1, 1);
+    SkPMColor pixel;
+    REPORTER_ASSERT(reporter, image->readPixels(info, &pixel, sizeof(pixel), 0, 0));
+    REPORTER_ASSERT(reporter, pixel == expected);
+}
+
+DEF_GPUTEST(SkImage_NewFromTexture, reporter, factory) {
+    GrContext* ctx = factory->get(GrContextFactory::kNative_GLContextType);
+    if (!ctx) {
+        REPORTER_ASSERT(reporter, false);
+        return;
+    }
+    GrTextureProvider* provider = ctx->textureProvider();
+    
+    const int w = 10;
+    const int h = 10;
+    SkPMColor storage[w * h];
+    const SkPMColor expected0 = SkPreMultiplyColor(SK_ColorRED);
+    sk_memset32(storage, expected0, w * h);
+    
+    GrSurfaceDesc desc;
+    desc.fFlags = kRenderTarget_GrSurfaceFlag;  // needs to be a rendertarget for readpixels();
+    desc.fOrigin = kDefault_GrSurfaceOrigin;
+    desc.fWidth = w;
+    desc.fHeight = h;
+    desc.fConfig = kSkia8888_GrPixelConfig;
+    desc.fSampleCnt = 0;
+    
+    SkAutoTUnref<GrTexture> tex(provider->createTexture(desc, false, storage, w * 4));
+    if (!tex) {
+        REPORTER_ASSERT(reporter, false);
+        return;
+    }
+
+    GrBackendObject srcTex = tex->getTextureHandle();
+    ReleaseTextureContext releaseCtx(reporter);
+
+    SkAutoTUnref<SkImage> refImg(make_desc_image(ctx, w, h, srcTex, &releaseCtx));
+    SkAutoTUnref<SkImage> cpyImg(make_desc_image(ctx, w, h, srcTex, nullptr));
+
+    test_image_color(reporter, refImg, expected0);
+    test_image_color(reporter, cpyImg, expected0);
+
+    // Now lets jam new colors into our "external" texture, and see if the images notice
+    const SkPMColor expected1 = SkPreMultiplyColor(SK_ColorBLUE);
+    sk_memset32(storage, expected1, w * h);
+    tex->writePixels(0, 0, w, h, kSkia8888_GrPixelConfig, storage, GrContext::kFlushWrites_PixelOp);
+
+    // The cpy'd one should still see the old color
+#if 0
+    // There is no guarantee that refImg sees the new color. We are free to have made a copy. Our
+    // write pixels call violated the contract with refImg and refImg is now undefined.
+    test_image_color(reporter, refImg, expected1);
+#endif
+    test_image_color(reporter, cpyImg, expected0);
+
+    // Now exercise the release proc
+    REPORTER_ASSERT(reporter, !releaseCtx.fIsReleased);
+    refImg.reset(nullptr); // force a release of the image
+    REPORTER_ASSERT(reporter, releaseCtx.fIsReleased);
+}
+#endif
+DEF_GPUTEST(ImageTestsFromSurfaceTestsTODO, reporter, factory) {
+    test_image(reporter);
+    test_empty_image(reporter);
+    test_imagepeek(reporter, factory);
+}
diff --git a/tests/SurfaceTest.cpp b/tests/SurfaceTest.cpp
index a6739e3..7e07e17 100644
--- a/tests/SurfaceTest.cpp
+++ b/tests/SurfaceTest.cpp
@@ -65,30 +65,6 @@
     return nullptr;
 }
 
-enum ImageType {
-    kRasterCopy_ImageType,
-    kRasterData_ImageType,
-    kRasterProc_ImageType,
-    kGpu_ImageType,
-    kCodec_ImageType,
-};
-
-#include "SkImageGenerator.h"
-
-class EmptyGenerator : public SkImageGenerator {
-public:
-    EmptyGenerator() : SkImageGenerator(SkImageInfo::MakeN32Premul(0, 0)) {}
-};
-
-static void test_empty_image(skiatest::Reporter* reporter) {
-    const SkImageInfo info = SkImageInfo::Make(0, 0, kN32_SkColorType, kPremul_SkAlphaType);
-    
-    REPORTER_ASSERT(reporter, nullptr == SkImage::NewRasterCopy(info, nullptr, 0));
-    REPORTER_ASSERT(reporter, nullptr == SkImage::NewRasterData(info, nullptr, 0));
-    REPORTER_ASSERT(reporter, nullptr == SkImage::NewFromRaster(info, nullptr, 0, nullptr, nullptr));
-    REPORTER_ASSERT(reporter, nullptr == SkImage::NewFromGenerator(new EmptyGenerator));
-}
-
 static void test_empty_surface(skiatest::Reporter* reporter, GrContext* ctx) {
     const SkImageInfo info = SkImageInfo::Make(0, 0, kN32_SkColorType, kPremul_SkAlphaType);
     
@@ -175,304 +151,6 @@
 #endif
 
 
-static void test_image(skiatest::Reporter* reporter) {
-    SkImageInfo info = SkImageInfo::MakeN32Premul(1, 1);
-    size_t rowBytes = info.minRowBytes();
-    size_t size = info.getSafeSize(rowBytes);
-    SkData* data = SkData::NewUninitialized(size);
-
-    REPORTER_ASSERT(reporter, data->unique());
-    SkImage* image = SkImage::NewRasterData(info, data, rowBytes);
-    REPORTER_ASSERT(reporter, !data->unique());
-    image->unref();
-    REPORTER_ASSERT(reporter, data->unique());
-    data->unref();
-}
-
-// Want to ensure that our Release is called when the owning image is destroyed
-struct ReleaseDataContext {
-    skiatest::Reporter* fReporter;
-    SkData*             fData;
-
-    static void Release(const void* pixels, void* context) {
-        ReleaseDataContext* state = (ReleaseDataContext*)context;
-        REPORTER_ASSERT(state->fReporter, state->fData);
-        state->fData->unref();
-        state->fData = nullptr;
-    }
-};
-
-// May we (soon) eliminate the need to keep testing this, by hiding the bloody device!
-#include "SkDevice.h"
-static uint32_t get_legacy_gen_id(SkSurface* surf) {
-    SkBaseDevice* device = surf->getCanvas()->getDevice_just_for_deprecated_compatibility_testing();
-    return device->accessBitmap(false).getGenerationID();
-}
-
-/*
- *  Test legacy behavor of bumping the surface's device's bitmap's genID when we access its
- *  texture handle for writing.
- *
- *  Note: this needs to be tested separately from checking newImageSnapshot, as calling that
- *  can also incidentally bump the genID (when a new backing surface is created).
- */
-template <class F>
-static void test_texture_handle_genID(skiatest::Reporter* reporter, SkSurface* surf, F f) {
-    const uint32_t gen0 = get_legacy_gen_id(surf);
-    f(surf, SkSurface::kFlushRead_BackendHandleAccess);
-    const uint32_t gen1 = get_legacy_gen_id(surf);
-    REPORTER_ASSERT(reporter, gen0 == gen1);
-
-    f(surf, SkSurface::kFlushWrite_BackendHandleAccess);
-    const uint32_t gen2 = get_legacy_gen_id(surf);
-    REPORTER_ASSERT(reporter, gen0 != gen2);
-
-    f(surf, SkSurface::kDiscardWrite_BackendHandleAccess);
-    const uint32_t gen3 = get_legacy_gen_id(surf);
-    REPORTER_ASSERT(reporter, gen0 != gen3);
-    REPORTER_ASSERT(reporter, gen2 != gen3);
-}
-
-template <class F>
-static void test_backend_handle(skiatest::Reporter* reporter, SkSurface* surf, F f) {
-    SkAutoTUnref<SkImage> image0(surf->newImageSnapshot());
-    GrBackendObject obj = f(surf, SkSurface::kFlushRead_BackendHandleAccess);
-    REPORTER_ASSERT(reporter, obj != 0);
-    SkAutoTUnref<SkImage> image1(surf->newImageSnapshot());
-    // just read access should not affect the snapshot
-    REPORTER_ASSERT(reporter, image0->uniqueID() == image1->uniqueID());
-
-    obj = f(surf, SkSurface::kFlushWrite_BackendHandleAccess);
-    REPORTER_ASSERT(reporter, obj != 0);
-    SkAutoTUnref<SkImage> image2(surf->newImageSnapshot());
-    // expect a new image, since we claimed we would write
-    REPORTER_ASSERT(reporter, image0->uniqueID() != image2->uniqueID());
-
-    obj = f(surf, SkSurface::kDiscardWrite_BackendHandleAccess);
-    REPORTER_ASSERT(reporter, obj != 0);
-    SkAutoTUnref<SkImage> image3(surf->newImageSnapshot());
-    // expect a new(er) image, since we claimed we would write
-    REPORTER_ASSERT(reporter, image0->uniqueID() != image3->uniqueID());
-    REPORTER_ASSERT(reporter, image2->uniqueID() != image3->uniqueID());
-}
-
-static SkImage* create_image(skiatest::Reporter* reporter,
-                             ImageType imageType, GrContext* context, SkColor color,
-                             ReleaseDataContext* releaseContext) {
-    const SkPMColor pmcolor = SkPreMultiplyColor(color);
-    const SkImageInfo info = SkImageInfo::MakeN32Premul(10, 10);
-    const size_t rowBytes = info.minRowBytes();
-    const size_t size = rowBytes * info.height();
-
-    SkAutoTUnref<SkData> data(SkData::NewUninitialized(size));
-    void* addr = data->writable_data();
-    sk_memset32((SkPMColor*)addr, pmcolor, SkToInt(size >> 2));
-
-    switch (imageType) {
-        case kRasterCopy_ImageType:
-            return SkImage::NewRasterCopy(info, addr, rowBytes);
-        case kRasterData_ImageType:
-            return SkImage::NewRasterData(info, data, rowBytes);
-        case kRasterProc_ImageType:
-            SkASSERT(releaseContext);
-            releaseContext->fData = SkRef(data.get());
-            return SkImage::NewFromRaster(info, addr, rowBytes,
-                                          ReleaseDataContext::Release, releaseContext);
-        case kGpu_ImageType: {
-            SkAutoTUnref<SkSurface> surf(
-                SkSurface::NewRenderTarget(context, SkSurface::kNo_Budgeted, info, 0));
-            surf->getCanvas()->clear(color);
-            // test our backing texture / rendertarget while were here...
-            auto textureAccessorFunc =
-                    [](SkSurface* surf, SkSurface::BackendHandleAccess access) -> GrBackendObject {
-                        return surf->getTextureHandle(access); };
-            auto renderTargetAccessorFunc =
-                    [](SkSurface* surf, SkSurface::BackendHandleAccess access) -> GrBackendObject {
-                        GrBackendObject obj;
-                        SkAssertResult(surf->getRenderTargetHandle(&obj, access));
-                        return obj; };
-            test_backend_handle(reporter, surf, textureAccessorFunc);
-            test_backend_handle(reporter, surf, renderTargetAccessorFunc);
-            test_texture_handle_genID(reporter, surf, textureAccessorFunc);
-            test_texture_handle_genID(reporter, surf, renderTargetAccessorFunc);
-
-            // redraw so our returned image looks as expected.
-            surf->getCanvas()->clear(color);
-            return surf->newImageSnapshot();
-        }
-        case kCodec_ImageType: {
-            SkBitmap bitmap;
-            bitmap.installPixels(info, addr, rowBytes);
-            SkAutoTUnref<SkData> src(
-                 SkImageEncoder::EncodeData(bitmap, SkImageEncoder::kPNG_Type, 100));
-            return SkImage::NewFromEncoded(src);
-        }
-    }
-    SkASSERT(false);
-    return nullptr;
-}
-
-static void set_pixels(SkPMColor pixels[], int count, SkPMColor color) {
-    sk_memset32(pixels, color, count);
-}
-static bool has_pixels(const SkPMColor pixels[], int count, SkPMColor expected) {
-    for (int i = 0; i < count; ++i) {
-        if (pixels[i] != expected) {
-            return false;
-        }
-    }
-    return true;
-}
-
-static void test_image_readpixels(skiatest::Reporter* reporter, SkImage* image,
-                                  SkPMColor expected) {
-    const SkPMColor notExpected = ~expected;
-
-    const int w = 2, h = 2;
-    const size_t rowBytes = w * sizeof(SkPMColor);
-    SkPMColor pixels[w*h];
-
-    SkImageInfo info;
-
-    info = SkImageInfo::MakeUnknown(w, h);
-    REPORTER_ASSERT(reporter, !image->readPixels(info, pixels, rowBytes, 0, 0));
-
-    // out-of-bounds should fail
-    info = SkImageInfo::MakeN32Premul(w, h);
-    REPORTER_ASSERT(reporter, !image->readPixels(info, pixels, rowBytes, -w, 0));
-    REPORTER_ASSERT(reporter, !image->readPixels(info, pixels, rowBytes, 0, -h));
-    REPORTER_ASSERT(reporter, !image->readPixels(info, pixels, rowBytes, image->width(), 0));
-    REPORTER_ASSERT(reporter, !image->readPixels(info, pixels, rowBytes, 0, image->height()));
-
-    // top-left should succeed
-    set_pixels(pixels, w*h, notExpected);
-    REPORTER_ASSERT(reporter, image->readPixels(info, pixels, rowBytes, 0, 0));
-    REPORTER_ASSERT(reporter, has_pixels(pixels, w*h, expected));
-
-    // bottom-right should succeed
-    set_pixels(pixels, w*h, notExpected);
-    REPORTER_ASSERT(reporter, image->readPixels(info, pixels, rowBytes,
-                                                image->width() - w, image->height() - h));
-    REPORTER_ASSERT(reporter, has_pixels(pixels, w*h, expected));
-
-    // partial top-left should succeed
-    set_pixels(pixels, w*h, notExpected);
-    REPORTER_ASSERT(reporter, image->readPixels(info, pixels, rowBytes, -1, -1));
-    REPORTER_ASSERT(reporter, pixels[3] == expected);
-    REPORTER_ASSERT(reporter, has_pixels(pixels, w*h - 1, notExpected));
-
-    // partial bottom-right should succeed
-    set_pixels(pixels, w*h, notExpected);
-    REPORTER_ASSERT(reporter, image->readPixels(info, pixels, rowBytes,
-                                                image->width() - 1, image->height() - 1));
-    REPORTER_ASSERT(reporter, pixels[0] == expected);
-    REPORTER_ASSERT(reporter, has_pixels(&pixels[1], w*h - 1, notExpected));
-}
-
-static void check_legacy_bitmap(skiatest::Reporter* reporter, const SkImage* image,
-                                const SkBitmap& bitmap, SkImage::LegacyBitmapMode mode) {
-    REPORTER_ASSERT(reporter, image->width() == bitmap.width());
-    REPORTER_ASSERT(reporter, image->height() == bitmap.height());
-    REPORTER_ASSERT(reporter, image->isOpaque() == bitmap.isOpaque());
-
-    if (SkImage::kRO_LegacyBitmapMode == mode) {
-        REPORTER_ASSERT(reporter, bitmap.isImmutable());
-    }
-
-    SkAutoLockPixels alp(bitmap);
-    REPORTER_ASSERT(reporter, bitmap.getPixels());
-
-    const SkImageInfo info = SkImageInfo::MakeN32(1, 1, bitmap.alphaType());
-    SkPMColor imageColor;
-    REPORTER_ASSERT(reporter, image->readPixels(info, &imageColor, sizeof(SkPMColor), 0, 0));
-    REPORTER_ASSERT(reporter, imageColor == *bitmap.getAddr32(0, 0));
-}
-
-static void test_legacy_bitmap(skiatest::Reporter* reporter, const SkImage* image) {
-    const SkImage::LegacyBitmapMode modes[] = {
-        SkImage::kRO_LegacyBitmapMode,
-        SkImage::kRW_LegacyBitmapMode,
-    };
-    for (size_t i = 0; i < SK_ARRAY_COUNT(modes); ++i) {
-        SkBitmap bitmap;
-        REPORTER_ASSERT(reporter, image->asLegacyBitmap(&bitmap, modes[i]));
-        check_legacy_bitmap(reporter, image, bitmap, modes[i]);
-
-        // Test subsetting to exercise the rowBytes logic.
-        SkBitmap tmp;
-        REPORTER_ASSERT(reporter, bitmap.extractSubset(&tmp, SkIRect::MakeWH(image->width() / 2,
-                                                                             image->height() / 2)));
-        SkAutoTUnref<SkImage> subsetImage(SkImage::NewFromBitmap(tmp));
-        REPORTER_ASSERT(reporter, subsetImage);
-
-        SkBitmap subsetBitmap;
-        REPORTER_ASSERT(reporter, subsetImage->asLegacyBitmap(&subsetBitmap, modes[i]));
-        check_legacy_bitmap(reporter, subsetImage, subsetBitmap, modes[i]);
-    }
-}
-
-static void test_imagepeek(skiatest::Reporter* reporter, GrContextFactory* factory) {
-    static const struct {
-        ImageType   fType;
-        bool        fPeekShouldSucceed;
-        const char* fName;
-    } gRec[] = {
-        { kRasterCopy_ImageType,    true,       "RasterCopy"    },
-        { kRasterData_ImageType,    true,       "RasterData"    },
-        { kRasterProc_ImageType,    true,       "RasterProc"    },
-        { kGpu_ImageType,           false,      "Gpu"           },
-        { kCodec_ImageType,         false,      "Codec"         },
-    };
-
-    const SkColor color = SK_ColorRED;
-    const SkPMColor pmcolor = SkPreMultiplyColor(color);
-
-    GrContext* ctx = nullptr;
-#if SK_SUPPORT_GPU
-    ctx = factory->get(GrContextFactory::kNative_GLContextType);
-    if (nullptr == ctx) {
-        return;
-    }
-#endif
-
-    ReleaseDataContext releaseCtx;
-    releaseCtx.fReporter = reporter;
-
-    for (size_t i = 0; i < SK_ARRAY_COUNT(gRec); ++i) {
-        SkImageInfo info;
-        size_t rowBytes;
-
-        releaseCtx.fData = nullptr;
-        SkAutoTUnref<SkImage> image(create_image(reporter, gRec[i].fType, ctx, color, &releaseCtx));
-        if (!image.get()) {
-            SkDebugf("failed to createImage[%d] %s\n", i, gRec[i].fName);
-            continue;   // gpu may not be enabled
-        }
-        if (kRasterProc_ImageType == gRec[i].fType) {
-            REPORTER_ASSERT(reporter, nullptr != releaseCtx.fData);  // we are tracking the data
-        } else {
-            REPORTER_ASSERT(reporter, nullptr == releaseCtx.fData);  // we ignored the context
-        }
-
-        test_legacy_bitmap(reporter, image);
-
-        const void* addr = image->peekPixels(&info, &rowBytes);
-        bool success = SkToBool(addr);
-        REPORTER_ASSERT(reporter, gRec[i].fPeekShouldSucceed == success);
-        if (success) {
-            REPORTER_ASSERT(reporter, 10 == info.width());
-            REPORTER_ASSERT(reporter, 10 == info.height());
-            REPORTER_ASSERT(reporter, kN32_SkColorType == info.colorType());
-            REPORTER_ASSERT(reporter, kPremul_SkAlphaType == info.alphaType() ||
-                            kOpaque_SkAlphaType == info.alphaType());
-            REPORTER_ASSERT(reporter, info.minRowBytes() <= rowBytes);
-            REPORTER_ASSERT(reporter, pmcolor == *(const SkPMColor*)addr);
-        }
-
-        test_image_readpixels(reporter, image, pmcolor);
-    }
-    REPORTER_ASSERT(reporter, nullptr == releaseCtx.fData);  // we released the data
-}
 
 static void test_canvaspeek(skiatest::Reporter* reporter,
                             GrContextFactory* factory) {
@@ -883,17 +561,15 @@
 }
 
 DEF_GPUTEST(Surface, reporter, factory) {
-    test_image(reporter);
-
     TestSurfaceCopyOnWrite(reporter, kRaster_SurfaceType, nullptr);
     TestSurfaceWritableAfterSnapshotRelease(reporter, kRaster_SurfaceType, nullptr);
     TestSurfaceNoCanvas(reporter, kRaster_SurfaceType, nullptr, SkSurface::kDiscard_ContentChangeMode);
     TestSurfaceNoCanvas(reporter, kRaster_SurfaceType, nullptr, SkSurface::kRetain_ContentChangeMode);
 
-    test_empty_image(reporter);
+
     test_empty_surface(reporter, nullptr);
 
-    test_imagepeek(reporter, factory);
+
     test_canvaspeek(reporter, factory);
 
     test_accessPixels(reporter, factory);
@@ -931,103 +607,4 @@
 #endif
 }
 
-#if SK_SUPPORT_GPU
 
-struct ReleaseTextureContext {
-    ReleaseTextureContext(skiatest::Reporter* reporter) {
-        fReporter = reporter;
-        fIsReleased = false;
-    }
-
-    skiatest::Reporter* fReporter;
-    bool                fIsReleased;
-
-    void doRelease() {
-        REPORTER_ASSERT(fReporter, false == fIsReleased);
-        fIsReleased = true;
-    }
-
-    static void ReleaseProc(void* context) {
-        ((ReleaseTextureContext*)context)->doRelease();
-    }
-};
-
-static SkImage* make_desc_image(GrContext* ctx, int w, int h, GrBackendObject texID,
-                                ReleaseTextureContext* releaseContext) {
-    GrBackendTextureDesc desc;
-    desc.fConfig = kSkia8888_GrPixelConfig;
-    // need to be a rendertarget for now...
-    desc.fFlags = kRenderTarget_GrBackendTextureFlag;
-    desc.fWidth = w;
-    desc.fHeight = h;
-    desc.fSampleCnt = 0;
-    desc.fTextureHandle = texID;
-    return releaseContext
-                ? SkImage::NewFromTexture(ctx, desc, kPremul_SkAlphaType,
-                                          ReleaseTextureContext::ReleaseProc, releaseContext)
-                : SkImage::NewFromTextureCopy(ctx, desc, kPremul_SkAlphaType);
-}
-
-static void test_image_color(skiatest::Reporter* reporter, SkImage* image, SkPMColor expected) {
-    const SkImageInfo info = SkImageInfo::MakeN32Premul(1, 1);
-    SkPMColor pixel;
-    REPORTER_ASSERT(reporter, image->readPixels(info, &pixel, sizeof(pixel), 0, 0));
-    REPORTER_ASSERT(reporter, pixel == expected);
-}
-
-DEF_GPUTEST(SkImage_NewFromTexture, reporter, factory) {
-    GrContext* ctx = factory->get(GrContextFactory::kNative_GLContextType);
-    if (!ctx) {
-        REPORTER_ASSERT(reporter, false);
-        return;
-    }
-    GrTextureProvider* provider = ctx->textureProvider();
-    
-    const int w = 10;
-    const int h = 10;
-    SkPMColor storage[w * h];
-    const SkPMColor expected0 = SkPreMultiplyColor(SK_ColorRED);
-    sk_memset32(storage, expected0, w * h);
-    
-    GrSurfaceDesc desc;
-    desc.fFlags = kRenderTarget_GrSurfaceFlag;  // needs to be a rendertarget for readpixels();
-    desc.fOrigin = kDefault_GrSurfaceOrigin;
-    desc.fWidth = w;
-    desc.fHeight = h;
-    desc.fConfig = kSkia8888_GrPixelConfig;
-    desc.fSampleCnt = 0;
-    
-    SkAutoTUnref<GrTexture> tex(provider->createTexture(desc, false, storage, w * 4));
-    if (!tex) {
-        REPORTER_ASSERT(reporter, false);
-        return;
-    }
-
-    GrBackendObject srcTex = tex->getTextureHandle();
-    ReleaseTextureContext releaseCtx(reporter);
-
-    SkAutoTUnref<SkImage> refImg(make_desc_image(ctx, w, h, srcTex, &releaseCtx));
-    SkAutoTUnref<SkImage> cpyImg(make_desc_image(ctx, w, h, srcTex, nullptr));
-
-    test_image_color(reporter, refImg, expected0);
-    test_image_color(reporter, cpyImg, expected0);
-
-    // Now lets jam new colors into our "external" texture, and see if the images notice
-    const SkPMColor expected1 = SkPreMultiplyColor(SK_ColorBLUE);
-    sk_memset32(storage, expected1, w * h);
-    tex->writePixels(0, 0, w, h, kSkia8888_GrPixelConfig, storage, GrContext::kFlushWrites_PixelOp);
-
-    // The cpy'd one should still see the old color
-#if 0
-    // There is no guarantee that refImg sees the new color. We are free to have made a copy. Our
-    // write pixels call violated the contract with refImg and refImg is now undefined.
-    test_image_color(reporter, refImg, expected1);
-#endif
-    test_image_color(reporter, cpyImg, expected0);
-
-    // Now exercise the release proc
-    REPORTER_ASSERT(reporter, !releaseCtx.fIsReleased);
-    refImg.reset(nullptr); // force a release of the image
-    REPORTER_ASSERT(reporter, releaseCtx.fIsReleased);
-}
-#endif
