diff --git a/tools/VisualBench/VisualBench.h b/tools/VisualBench/VisualBench.h
index 1920a52..e9fbdfb 100644
--- a/tools/VisualBench/VisualBench.h
+++ b/tools/VisualBench/VisualBench.h
@@ -16,7 +16,7 @@
 #include "SkSurface.h"
 #include "VisualFlags.h"
 #include "VisualModule.h"
-#include "gl/SkGLContext.h"
+#include "gl/GLContext.h"
 
 class GrContext;
 struct GrGLInterface;
diff --git a/tools/flags/SkCommonFlagsConfig.cpp b/tools/flags/SkCommonFlagsConfig.cpp
index 9e0fd60..1ee3130 100644
--- a/tools/flags/SkCommonFlagsConfig.cpp
+++ b/tools/flags/SkCommonFlagsConfig.cpp
@@ -9,6 +9,10 @@
 
 #include <stdlib.h>
 
+#if SK_SUPPORT_GPU
+using sk_gpu_test::GrContextFactory;
+#endif
+
 static const char defaultConfigs[] =
     "565 8888 gpu nonrendering"
 #if SK_ANGLE
diff --git a/tools/flags/SkCommonFlagsConfig.h b/tools/flags/SkCommonFlagsConfig.h
index 39f1f97..abf5946 100644
--- a/tools/flags/SkCommonFlagsConfig.h
+++ b/tools/flags/SkCommonFlagsConfig.h
@@ -50,7 +50,7 @@
 // * backends that represent a shorthand of above (such as "msaa16" representing "gpu(samples=16)")
 class SkCommandLineConfigGpu : public SkCommandLineConfig {
   public:
-    typedef GrContextFactory::GLContextType ContextType;
+    typedef sk_gpu_test::GrContextFactory::GLContextType ContextType;
     SkCommandLineConfigGpu(const SkString& tag, const SkTArray<SkString>& viaParts,
                            ContextType contextType, bool useNVPR, bool useDIText, int samples,
                            SkColorType colorType, SkColorProfileType profileType);
diff --git a/tools/gpu/GrContextFactory.cpp b/tools/gpu/GrContextFactory.cpp
new file mode 100755
index 0000000..cb23014
--- /dev/null
+++ b/tools/gpu/GrContextFactory.cpp
@@ -0,0 +1,162 @@
+
+/*
+ * Copyright 2014 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "GrContextFactory.h"
+#include "gl/GLContext.h"
+
+#if SK_ANGLE
+    #include "gl/angle/GLContext_angle.h"
+#endif
+#if SK_COMMAND_BUFFER
+    #include "gl/command_buffer/GLContext_command_buffer.h"
+#endif
+#include "gl/debug/DebugGLContext.h"
+#if SK_MESA
+    #include "gl/mesa/GLContext_mesa.h"
+#endif
+#include "gl/null/NullGLContext.h"
+#include "gl/GrGLGpu.h"
+#include "GrCaps.h"
+
+namespace sk_gpu_test {
+GrContextFactory::GrContextFactory() { }
+
+GrContextFactory::GrContextFactory(const GrContextOptions& opts)
+    : fGlobalOptions(opts) {
+}
+
+GrContextFactory::~GrContextFactory() {
+    this->destroyContexts();
+}
+
+void GrContextFactory::destroyContexts() {
+    for (Context& context : fContexts) {
+        if (context.fGLContext) {
+            context.fGLContext->makeCurrent();
+        }
+        if (!context.fGrContext->unique()) {
+            context.fGrContext->abandonContext();
+        }
+        context.fGrContext->unref();
+        delete(context.fGLContext);
+    }
+    fContexts.reset();
+}
+
+void GrContextFactory::abandonContexts() {
+    for (Context& context : fContexts) {
+        if (context.fGLContext) {
+            context.fGLContext->makeCurrent();
+            context.fGLContext->testAbandon();
+            delete(context.fGLContext);
+            context.fGLContext = nullptr;
+        }
+        context.fGrContext->abandonContext();
+    }
+}
+
+GrContextFactory::ContextInfo GrContextFactory::getContextInfo(GLContextType type,
+                                                               GLContextOptions options) {
+    for (int i = 0; i < fContexts.count(); ++i) {
+        Context& context = fContexts[i];
+        if (!context.fGLContext) {
+            continue;
+        }
+        if (context.fType == type &&
+            context.fOptions == options) {
+            context.fGLContext->makeCurrent();
+            return ContextInfo(context.fGrContext, context.fGLContext);
+        }
+    }
+    SkAutoTDelete<GLContext> glCtx;
+    SkAutoTUnref<GrContext> grCtx;
+    switch (type) {
+        case kNative_GLContextType:
+            glCtx.reset(CreatePlatformGLContext(kNone_GrGLStandard));
+            break;
+        case kGL_GLContextType:
+            glCtx.reset(CreatePlatformGLContext(kGL_GrGLStandard));
+            break;
+        case kGLES_GLContextType:
+            glCtx.reset(CreatePlatformGLContext(kGLES_GrGLStandard));
+            break;
+#if SK_ANGLE
+#ifdef SK_BUILD_FOR_WIN
+        case kANGLE_GLContextType:
+            glCtx.reset(CreateANGLEDirect3DGLContext());
+            break;
+#endif
+        case kANGLE_GL_GLContextType:
+            glCtx.reset(CreateANGLEOpenGLGLContext());
+            break;
+#endif
+#if SK_COMMAND_BUFFER
+        case kCommandBuffer_GLContextType:
+            glCtx.reset(CommandBufferGLContext::Create());
+            break;
+#endif
+#if SK_MESA
+        case kMESA_GLContextType:
+            glCtx.reset(CreateMesaGLContext());
+            break;
+#endif
+        case kNull_GLContextType:
+            glCtx.reset(CreateNullGLContext());
+            break;
+        case kDebug_GLContextType:
+            glCtx.reset(CreateDebugGLContext());
+            break;
+    }
+    if (nullptr == glCtx.get()) {
+        return ContextInfo();
+    }
+
+    SkASSERT(glCtx->isValid());
+
+    // Block NVPR from non-NVPR types.
+    SkAutoTUnref<const GrGLInterface> glInterface(SkRef(glCtx->gl()));
+    if (!(kEnableNVPR_GLContextOptions & options)) {
+        glInterface.reset(GrGLInterfaceRemoveNVPR(glInterface));
+        if (!glInterface) {
+            return ContextInfo();
+        }
+    }
+
+    glCtx->makeCurrent();
+    GrBackendContext p3dctx = reinterpret_cast<GrBackendContext>(glInterface.get());
+#ifdef SK_VULKAN
+    if (kEnableNVPR_GLContextOptions & options) {
+        return ContextInfo();
+    } else {
+        grCtx.reset(GrContext::Create(kVulkan_GrBackend, p3dctx, fGlobalOptions));
+    }
+#else
+    grCtx.reset(GrContext::Create(kOpenGL_GrBackend, p3dctx, fGlobalOptions));
+#endif
+    if (!grCtx.get()) {
+        return ContextInfo();
+    }
+    if (kEnableNVPR_GLContextOptions & options) {
+        if (!grCtx->caps()->shaderCaps()->pathRenderingSupport()) {
+            return ContextInfo();
+        }
+    }
+    if (kRequireSRGBSupport_GLContextOptions & options) {
+        if (!grCtx->caps()->srgbSupport()) {
+            return ContextInfo();
+        }
+    }
+
+    Context& context = fContexts.push_back();
+    context.fGLContext = glCtx.release();
+    context.fGrContext = SkRef(grCtx.get());
+    context.fType = type;
+    context.fOptions = options;
+    return ContextInfo(context.fGrContext, context.fGLContext);
+}
+}  // namespace sk_gpu_test
diff --git a/tools/gpu/GrContextFactory.h b/tools/gpu/GrContextFactory.h
new file mode 100644
index 0000000..b174608
--- /dev/null
+++ b/tools/gpu/GrContextFactory.h
@@ -0,0 +1,146 @@
+/*
+ * Copyright 2012 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef GrContextFactory_DEFINED
+#define GrContextFactory_DEFINED
+
+#include "GrContext.h"
+#include "GrContextOptions.h"
+
+#include "gl/GLContext.h"
+#include "SkTArray.h"
+
+namespace sk_gpu_test {
+/**
+ * This is a simple class that is useful in test apps that use different
+ * GrContexts backed by different types of GL contexts. It manages creating the
+ * GL context and a GrContext that uses it. The GL/Gr contexts persist until the
+ * factory is destroyed (though the caller can always grab a ref on the returned
+ * Gr and GL contexts to make them outlive the factory).
+ */
+class GrContextFactory : SkNoncopyable {
+public:
+    enum GLContextType {
+        kNative_GLContextType,  //! OpenGL or OpenGL ES context.
+        kGL_GLContextType,      //! OpenGL context.
+        kGLES_GLContextType,    //! OpenGL ES context.
+#if SK_ANGLE
+#ifdef SK_BUILD_FOR_WIN
+        kANGLE_GLContextType,    //! ANGLE on DirectX OpenGL ES context.
+#endif
+        kANGLE_GL_GLContextType, //! ANGLE on OpenGL OpenGL ES context.
+#endif
+#if SK_COMMAND_BUFFER
+        kCommandBuffer_GLContextType, //! Chromium command buffer OpenGL ES context.
+#endif
+#if SK_MESA
+        kMESA_GLContextType,  //! MESA OpenGL context
+#endif
+        kNull_GLContextType,  //! Non-rendering OpenGL mock context.
+        kDebug_GLContextType, //! Non-rendering, state verifying OpenGL context.
+        kLastGLContextType = kDebug_GLContextType
+    };
+
+    static const int kGLContextTypeCnt = kLastGLContextType + 1;
+
+    /**
+     * Options for GL context creation. For historical and testing reasons the options will default
+     * to not using GL_NV_path_rendering extension  even when the driver supports it.
+     */
+    enum GLContextOptions {
+        kNone_GLContextOptions = 0,
+        kEnableNVPR_GLContextOptions = 0x1,
+        kRequireSRGBSupport_GLContextOptions = 0x2,
+    };
+
+    static bool IsRenderingGLContext(GLContextType type) {
+        switch (type) {
+            case kNull_GLContextType:
+            case kDebug_GLContextType:
+                return false;
+            default:
+                return true;
+        }
+    }
+
+    static const char* GLContextTypeName(GLContextType type) {
+        switch (type) {
+            case kNative_GLContextType:
+                return "native";
+            case kGL_GLContextType:
+                return "gl";
+            case kGLES_GLContextType:
+                return "gles";
+#if SK_ANGLE
+#ifdef SK_BUILD_FOR_WIN
+            case kANGLE_GLContextType:
+                return "angle";
+#endif
+            case kANGLE_GL_GLContextType:
+                return "angle-gl";
+#endif
+#if SK_COMMAND_BUFFER
+            case kCommandBuffer_GLContextType:
+                return "commandbuffer";
+#endif
+#if SK_MESA
+            case kMESA_GLContextType:
+                return "mesa";
+#endif
+            case kNull_GLContextType:
+                return "null";
+            case kDebug_GLContextType:
+                return "debug";
+            default:
+                SkFAIL("Unknown GL Context type.");
+        }
+    }
+
+    explicit GrContextFactory(const GrContextOptions& opts);
+    GrContextFactory();
+
+    ~GrContextFactory();
+
+    void destroyContexts();
+    void abandonContexts();
+
+    struct ContextInfo {
+        ContextInfo()
+            : fGrContext(nullptr), fGLContext(nullptr) { }
+        ContextInfo(GrContext* grContext, GLContext* glContext)
+            : fGrContext(grContext), fGLContext(glContext) { }
+        GrContext* fGrContext;
+        GLContext* fGLContext; //! Valid until the factory destroys it via abandonContexts() or
+                               //! destroyContexts().
+    };
+
+    /**
+     * Get a context initialized with a type of GL context. It also makes the GL context current.
+     */
+    ContextInfo getContextInfo(GLContextType type,
+                               GLContextOptions options = kNone_GLContextOptions);
+    /**
+     * Get a GrContext initialized with a type of GL context. It also makes the GL context current.
+     */
+    GrContext* get(GLContextType type,
+                   GLContextOptions options = kNone_GLContextOptions) {
+        return this->getContextInfo(type, options).fGrContext;
+    }
+    const GrContextOptions& getGlobalOptions() const { return fGlobalOptions; }
+
+private:
+    struct Context {
+        GLContextType       fType;
+        GLContextOptions    fOptions;
+        GLContext*          fGLContext;
+        GrContext*          fGrContext;
+    };
+    SkTArray<Context, true> fContexts;
+    const GrContextOptions  fGlobalOptions;
+};
+}  // namespace sk_gpu_test
+#endif
diff --git a/tools/gpu/GrTest.cpp b/tools/gpu/GrTest.cpp
new file mode 100644
index 0000000..2b6463d
--- /dev/null
+++ b/tools/gpu/GrTest.cpp
@@ -0,0 +1,419 @@
+/*
+ * Copyright 2013 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "GrTest.h"
+
+#include "GrBatchAtlas.h"
+#include "GrContextOptions.h"
+#include "GrDrawContextPriv.h"
+#include "GrDrawingManager.h"
+#include "GrGpuResourceCacheAccess.h"
+#include "GrResourceCache.h"
+
+#include "SkGpuDevice.h"
+#include "SkGrPriv.h"
+#include "SkString.h"
+
+#include "text/GrBatchFontCache.h"
+#include "text/GrTextBlobCache.h"
+
+namespace GrTest {
+void SetupAlwaysEvictAtlas(GrContext* context) {
+    // These sizes were selected because they allow each atlas to hold a single plot and will thus
+    // stress the atlas
+    int dim = GrBatchAtlas::kGlyphMaxDim;
+    GrBatchAtlasConfig configs[3];
+    configs[kA8_GrMaskFormat].fWidth = dim;
+    configs[kA8_GrMaskFormat].fHeight = dim;
+    configs[kA8_GrMaskFormat].fLog2Width = SkNextLog2(dim);
+    configs[kA8_GrMaskFormat].fLog2Height = SkNextLog2(dim);
+    configs[kA8_GrMaskFormat].fPlotWidth = dim;
+    configs[kA8_GrMaskFormat].fPlotHeight = dim;
+
+    configs[kA565_GrMaskFormat].fWidth = dim;
+    configs[kA565_GrMaskFormat].fHeight = dim;
+    configs[kA565_GrMaskFormat].fLog2Width = SkNextLog2(dim);
+    configs[kA565_GrMaskFormat].fLog2Height = SkNextLog2(dim);
+    configs[kA565_GrMaskFormat].fPlotWidth = dim;
+    configs[kA565_GrMaskFormat].fPlotHeight = dim;
+
+    configs[kARGB_GrMaskFormat].fWidth = dim;
+    configs[kARGB_GrMaskFormat].fHeight = dim;
+    configs[kARGB_GrMaskFormat].fLog2Width = SkNextLog2(dim);
+    configs[kARGB_GrMaskFormat].fLog2Height = SkNextLog2(dim);
+    configs[kARGB_GrMaskFormat].fPlotWidth = dim;
+    configs[kARGB_GrMaskFormat].fPlotHeight = dim;
+
+    context->setTextContextAtlasSizes_ForTesting(configs);
+}
+};
+
+void GrTestTarget::init(GrContext* ctx, GrDrawTarget* target, GrRenderTarget* rt) {
+    SkASSERT(!fContext);
+
+    fContext.reset(SkRef(ctx));
+    fDrawTarget.reset(SkRef(target));
+    fRenderTarget.reset(SkRef(rt));
+}
+
+void GrContext::getTestTarget(GrTestTarget* tar, GrRenderTarget* rt) {
+    this->flush();
+    // We could create a proxy GrDrawTarget that passes through to fGpu until ~GrTextTarget() and
+    // then disconnects. This would help prevent test writers from mixing using the returned
+    // GrDrawTarget and regular drawing. We could also assert or fail in GrContext drawing methods
+    // until ~GrTestTarget().
+    if (!rt) {
+        GrSurfaceDesc desc;
+        desc.fFlags = kRenderTarget_GrSurfaceFlag;
+        desc.fWidth = 32;
+        desc.fHeight = 32;
+        desc.fConfig = kRGBA_8888_GrPixelConfig;
+        desc.fSampleCnt = 0;
+
+        SkAutoTUnref<GrTexture> texture(this->textureProvider()->createTexture(
+            desc, SkBudgeted::kNo, nullptr, 0));
+        if (nullptr == texture) {
+            return;
+        }
+        SkASSERT(nullptr != texture->asRenderTarget());
+        rt = texture->asRenderTarget();
+    }
+
+    SkAutoTUnref<GrDrawTarget> dt(fDrawingManager->newDrawTarget(rt));
+    tar->init(this, dt, rt);
+}
+
+void GrContext::setTextBlobCacheLimit_ForTesting(size_t bytes) {
+    fTextBlobCache->setBudget(bytes);
+}
+
+void GrContext::setTextContextAtlasSizes_ForTesting(const GrBatchAtlasConfig* configs) {
+    fBatchFontCache->setAtlasSizes_ForTesting(configs);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+void GrContext::purgeAllUnlockedResources() {
+    fResourceCache->purgeAllUnlocked();
+}
+
+void GrContext::resetGpuStats() const {
+#if GR_GPU_STATS
+    fGpu->stats()->reset();
+#endif
+}
+
+void GrContext::dumpCacheStats(SkString* out) const {
+#if GR_CACHE_STATS
+    fResourceCache->dumpStats(out);
+#endif
+}
+
+void GrContext::dumpCacheStatsKeyValuePairs(SkTArray<SkString>* keys,
+                                            SkTArray<double>* values) const {
+#if GR_CACHE_STATS
+    fResourceCache->dumpStatsKeyValuePairs(keys, values);
+#endif
+}
+
+void GrContext::printCacheStats() const {
+    SkString out;
+    this->dumpCacheStats(&out);
+    SkDebugf("%s", out.c_str());
+}
+
+void GrContext::dumpGpuStats(SkString* out) const {
+#if GR_GPU_STATS
+    return fGpu->stats()->dump(out);
+#endif
+}
+
+void GrContext::dumpGpuStatsKeyValuePairs(SkTArray<SkString>* keys,
+                                          SkTArray<double>* values) const {
+#if GR_GPU_STATS
+    return fGpu->stats()->dumpKeyValuePairs(keys, values);
+#endif
+}
+
+void GrContext::printGpuStats() const {
+    SkString out;
+    this->dumpGpuStats(&out);
+    SkDebugf("%s", out.c_str());
+}
+
+GrTexture* GrContext::getFontAtlasTexture(GrMaskFormat format) {
+    GrBatchFontCache* cache = this->getBatchFontCache();
+
+    return cache->getTexture(format);
+}
+
+void SkGpuDevice::drawTexture(GrTexture* tex, const SkRect& dst, const SkPaint& paint) {
+    GrPaint grPaint;
+    SkMatrix mat;
+    mat.reset();
+    if (!SkPaintToGrPaint(this->context(), paint, mat, &grPaint)) {
+        return;
+    }
+    SkMatrix textureMat;
+    textureMat.reset();
+    textureMat[SkMatrix::kMScaleX] = 1.0f/dst.width();
+    textureMat[SkMatrix::kMScaleY] = 1.0f/dst.height();
+    textureMat[SkMatrix::kMTransX] = -dst.fLeft/dst.width();
+    textureMat[SkMatrix::kMTransY] = -dst.fTop/dst.height();
+
+    grPaint.addColorTextureProcessor(tex, textureMat);
+
+    GrClip clip;
+    fDrawContext->drawRect(clip, grPaint, mat, dst);
+}
+
+
+#if GR_GPU_STATS
+void GrGpu::Stats::dump(SkString* out) {
+    out->appendf("Render Target Binds: %d\n", fRenderTargetBinds);
+    out->appendf("Shader Compilations: %d\n", fShaderCompilations);
+    out->appendf("Textures Created: %d\n", fTextureCreates);
+    out->appendf("Texture Uploads: %d\n", fTextureUploads);
+    out->appendf("Transfers to Texture: %d\n", fTransfersToTexture);
+    out->appendf("Stencil Buffer Creates: %d\n", fStencilAttachmentCreates);
+    out->appendf("Number of draws: %d\n", fNumDraws);
+}
+
+void GrGpu::Stats::dumpKeyValuePairs(SkTArray<SkString>* keys, SkTArray<double>* values) {
+    keys->push_back(SkString("render_target_binds")); values->push_back(fRenderTargetBinds);
+    keys->push_back(SkString("shader_compilations")); values->push_back(fShaderCompilations);
+    keys->push_back(SkString("texture_uploads")); values->push_back(fTextureUploads);
+    keys->push_back(SkString("number_of_draws")); values->push_back(fNumDraws);
+    keys->push_back(SkString("number_of_failed_draws")); values->push_back(fNumFailedDraws);
+}
+
+#endif
+
+#if GR_CACHE_STATS
+void GrResourceCache::getStats(Stats* stats) const {
+    stats->reset();
+
+    stats->fTotal = this->getResourceCount();
+    stats->fNumNonPurgeable = fNonpurgeableResources.count();
+    stats->fNumPurgeable = fPurgeableQueue.count();
+
+    for (int i = 0; i < fNonpurgeableResources.count(); ++i) {
+        stats->update(fNonpurgeableResources[i]);
+    }
+    for (int i = 0; i < fPurgeableQueue.count(); ++i) {
+        stats->update(fPurgeableQueue.at(i));
+    }
+}
+
+void GrResourceCache::dumpStats(SkString* out) const {
+    this->validate();
+
+    Stats stats;
+
+    this->getStats(&stats);
+
+    float countUtilization = (100.f * fBudgetedCount) / fMaxCount;
+    float byteUtilization = (100.f * fBudgetedBytes) / fMaxBytes;
+
+    out->appendf("Budget: %d items %d bytes\n", fMaxCount, (int)fMaxBytes);
+    out->appendf("\t\tEntry Count: current %d"
+                 " (%d budgeted, %d external(%d borrowed, %d adopted), %d locked, %d scratch %.2g%% full), high %d\n",
+                 stats.fTotal, fBudgetedCount, stats.fExternal, stats.fBorrowed,
+                 stats.fAdopted, stats.fNumNonPurgeable, stats.fScratch, countUtilization,
+                 fHighWaterCount);
+    out->appendf("\t\tEntry Bytes: current %d (budgeted %d, %.2g%% full, %d unbudgeted) high %d\n",
+                 SkToInt(fBytes), SkToInt(fBudgetedBytes), byteUtilization,
+                 SkToInt(stats.fUnbudgetedSize), SkToInt(fHighWaterBytes));
+}
+
+void GrResourceCache::dumpStatsKeyValuePairs(SkTArray<SkString>* keys,
+                                             SkTArray<double>* values) const {
+    this->validate();
+
+    Stats stats;
+    this->getStats(&stats);
+
+    keys->push_back(SkString("gpu_cache_purgable_entries")); values->push_back(stats.fNumPurgeable);
+}
+
+#endif
+
+///////////////////////////////////////////////////////////////////////////////
+
+void GrResourceCache::changeTimestamp(uint32_t newTimestamp) { fTimestamp = newTimestamp; }
+
+///////////////////////////////////////////////////////////////////////////////
+
+#define ASSERT_SINGLE_OWNER \
+    SkDEBUGCODE(GrSingleOwner::AutoEnforce debug_SingleOwner(fDrawContext->fSingleOwner);)
+#define RETURN_IF_ABANDONED        if (fDrawContext->fDrawingManager->abandoned()) { return; }
+
+void GrDrawContextPriv::testingOnly_drawBatch(const GrPipelineBuilder& pipelineBuilder,
+                                              GrDrawBatch* batch) {
+    ASSERT_SINGLE_OWNER
+    RETURN_IF_ABANDONED
+    SkDEBUGCODE(fDrawContext->validate();)
+    GR_AUDIT_TRAIL_AUTO_FRAME(fDrawContext->fAuditTrail, "GrDrawContext::testingOnly_drawBatch");
+
+    fDrawContext->getDrawTarget()->drawBatch(pipelineBuilder, batch);
+}
+
+#undef ASSERT_SINGLE_OWNER
+#undef RETURN_IF_ABANDONED
+
+///////////////////////////////////////////////////////////////////////////////
+// Code for the mock context. It's built on a mock GrGpu class that does nothing.
+////
+
+#include "GrGpu.h"
+
+class GrPipeline;
+
+class MockCaps : public GrCaps {
+public:
+    explicit MockCaps(const GrContextOptions& options) : INHERITED(options) {}
+    bool isConfigTexturable(GrPixelConfig config) const override { return false; }
+    bool isConfigRenderable(GrPixelConfig config, bool withMSAA) const override { return false; }
+private:
+    typedef GrCaps INHERITED;
+};
+
+class MockGpu : public GrGpu {
+public:
+    MockGpu(GrContext* context, const GrContextOptions& options) : INHERITED(context) {
+        fCaps.reset(new MockCaps(options));
+    }
+    ~MockGpu() override {}
+
+    bool onGetReadPixelsInfo(GrSurface* srcSurface, int readWidth, int readHeight, size_t rowBytes,
+                             GrPixelConfig readConfig, DrawPreference*,
+                             ReadPixelTempDrawInfo*) override { return false; }
+
+    bool onGetWritePixelsInfo(GrSurface* dstSurface, int width, int height,
+                              GrPixelConfig srcConfig, DrawPreference*,
+                              WritePixelTempDrawInfo*) override { return false; }
+
+    void discard(GrRenderTarget*) override {}
+
+    bool onCopySurface(GrSurface* dst,
+                       GrSurface* src,
+                       const SkIRect& srcRect,
+                       const SkIPoint& dstPoint) override { return false; };
+
+    void onGetMultisampleSpecs(GrRenderTarget* rt,
+                               const GrStencilSettings&,
+                               int* effectiveSampleCnt,
+                               SkAutoTDeleteArray<SkPoint>*) override {
+        *effectiveSampleCnt = rt->desc().fSampleCnt;
+    }
+
+    bool initCopySurfaceDstDesc(const GrSurface* src, GrSurfaceDesc* desc) const override {
+        return false;
+    }
+
+    void drawDebugWireRect(GrRenderTarget*, const SkIRect&, GrColor) override {};
+
+private:
+    void onResetContext(uint32_t resetBits) override {}
+
+    void xferBarrier(GrRenderTarget*, GrXferBarrierType) override {}
+
+    GrTexture* onCreateTexture(const GrSurfaceDesc& desc, GrGpuResource::LifeCycle lifeCycle,
+                               const SkTArray<GrMipLevel>& texels) override {
+        return nullptr;
+    }
+
+    GrTexture* onCreateCompressedTexture(const GrSurfaceDesc& desc, GrGpuResource::LifeCycle,
+                                         const SkTArray<GrMipLevel>& texels) override {
+        return nullptr;
+    }
+
+    GrTexture* onWrapBackendTexture(const GrBackendTextureDesc&,
+                                    GrWrapOwnership) override { return nullptr; }
+
+    GrRenderTarget* onWrapBackendRenderTarget(const GrBackendRenderTargetDesc&,
+                                              GrWrapOwnership) override {
+        return nullptr;
+    }
+
+    GrRenderTarget* onWrapBackendTextureAsRenderTarget(const GrBackendTextureDesc&,
+                                                       GrWrapOwnership) override {
+        return nullptr;
+    }
+
+    GrBuffer* onCreateBuffer(GrBufferType, size_t, GrAccessPattern) override { return nullptr; }
+
+    void onClear(GrRenderTarget*, const SkIRect& rect, GrColor color) override {}
+
+    void onClearStencilClip(GrRenderTarget*, const SkIRect& rect, bool insideClip) override {}
+
+    void onDraw(const GrPipeline&,
+                const GrPrimitiveProcessor&,
+                const GrMesh*,
+                int meshCount) override {}
+
+    bool onReadPixels(GrSurface* surface,
+                      int left, int top, int width, int height,
+                      GrPixelConfig,
+                      void* buffer,
+                      size_t rowBytes) override {
+        return false;
+    }
+
+    bool onWritePixels(GrSurface* surface,
+                       int left, int top, int width, int height,
+                       GrPixelConfig config, const SkTArray<GrMipLevel>& texels) override {
+        return false;
+    }
+
+    bool onTransferPixels(GrSurface* surface,
+                          int left, int top, int width, int height,
+                          GrPixelConfig config, GrBuffer* transferBuffer,
+                          size_t offset, size_t rowBytes) override {
+        return false;
+    }
+
+    void onResolveRenderTarget(GrRenderTarget* target) override { return; }
+
+    GrStencilAttachment* createStencilAttachmentForRenderTarget(const GrRenderTarget*,
+                                                                int width,
+                                                                int height) override {
+        return nullptr;
+    }
+
+    void clearStencil(GrRenderTarget* target) override  {}
+
+    GrBackendObject createTestingOnlyBackendTexture(void* pixels, int w, int h,
+                                                    GrPixelConfig config) override {
+        return 0;
+    }
+    bool isTestingOnlyBackendTexture(GrBackendObject ) const override { return false; }
+    void deleteTestingOnlyBackendTexture(GrBackendObject, bool abandonTexture) override {}
+
+    typedef GrGpu INHERITED;
+};
+
+GrContext* GrContext::CreateMockContext() {
+    GrContext* context = new GrContext;
+
+    context->initMockContext();
+    return context;
+}
+
+void GrContext::initMockContext() {
+    GrContextOptions options;
+    options.fBufferMapThreshold = 0;
+    SkASSERT(nullptr == fGpu);
+    fGpu = new MockGpu(this, options);
+    SkASSERT(fGpu);
+    this->initCommon(options);
+
+    // We delete these because we want to test the cache starting with zero resources. Also, none of
+    // these objects are required for any of tests that use this context. TODO: make stop allocating
+    // resources in the buffer pools.
+    fDrawingManager->abandon();
+}
diff --git a/tools/gpu/GrTest.h b/tools/gpu/GrTest.h
new file mode 100644
index 0000000..53aaac3
--- /dev/null
+++ b/tools/gpu/GrTest.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2013 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef GrTest_DEFINED
+#define GrTest_DEFINED
+
+#include "GrContext.h"
+#include "GrDrawTarget.h"
+#include "gl/GrGLContext.h"
+
+namespace GrTest {
+    /**
+     * Forces the GrContext to use a small atlas which only has room for one plot and will thus
+     * constantly be evicting entries
+     */
+    void SetupAlwaysEvictAtlas(GrContext*);
+};
+
+/** TODO Please do not use this if you can avoid it.  We are in the process of deleting it.
+    Allows a test to temporarily draw to a GrDrawTarget owned by a GrContext. Tests that use this
+    should be careful not to mix using the GrDrawTarget directly and drawing via SkCanvas or
+    GrContext. In the future this object may provide some guards to prevent this. */
+class GrTestTarget {
+public:
+    GrTestTarget() {};
+
+    void init(GrContext*, GrDrawTarget*, GrRenderTarget*);
+
+    GrDrawTarget* target() { return fDrawTarget.get(); }
+    GrResourceProvider* resourceProvider() { return fContext->resourceProvider(); }
+
+private:
+    SkAutoTUnref<GrContext>                 fContext;
+    SkAutoTUnref<GrDrawTarget>              fDrawTarget;
+    SkAutoTUnref<GrRenderTarget>            fRenderTarget;
+};
+
+#endif
diff --git a/tools/gpu/gl/GLContext.cpp b/tools/gpu/gl/GLContext.cpp
new file mode 100644
index 0000000..ac0e310
--- /dev/null
+++ b/tools/gpu/gl/GLContext.cpp
@@ -0,0 +1,188 @@
+
+/*
+ * Copyright 2013 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+#include "GLContext.h"
+#include "gl/GrGLUtil.h"
+#include "SkGpuFenceSync.h"
+
+namespace sk_gpu_test {
+class GLContext::GLFenceSync : public SkGpuFenceSync {
+public:
+    static GLFenceSync* CreateIfSupported(const GLContext*);
+
+    SkPlatformGpuFence SK_WARN_UNUSED_RESULT insertFence() const override;
+    bool waitFence(SkPlatformGpuFence fence, bool flush) const override;
+    void deleteFence(SkPlatformGpuFence fence) const override;
+
+private:
+    GLFenceSync() {}
+
+    static const GrGLenum GL_SYNC_GPU_COMMANDS_COMPLETE  = 0x9117;
+    static const GrGLenum GL_WAIT_FAILED                 = 0x911d;
+    static const GrGLbitfield GL_SYNC_FLUSH_COMMANDS_BIT = 0x00000001;
+
+    typedef struct __GLsync *GLsync;
+
+    typedef GLsync (GR_GL_FUNCTION_TYPE* GLFenceSyncProc) (GrGLenum, GrGLbitfield);
+    typedef GrGLenum (GR_GL_FUNCTION_TYPE* GLClientWaitSyncProc) (GLsync, GrGLbitfield, GrGLuint64);
+    typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GLDeleteSyncProc) (GLsync);
+
+    GLFenceSyncProc        fGLFenceSync;
+    GLClientWaitSyncProc   fGLClientWaitSync;
+    GLDeleteSyncProc       fGLDeleteSync;
+
+    typedef SkGpuFenceSync INHERITED;
+};
+
+GLContext::GLContext()
+    : fCurrentFenceIdx(0) {
+    memset(fFrameFences, 0, sizeof(fFrameFences));
+}
+
+GLContext::~GLContext() {
+    // Subclass should call teardown.
+#ifdef SK_DEBUG
+    for (size_t i = 0; i < SK_ARRAY_COUNT(fFrameFences); i++) {
+        SkASSERT(0 == fFrameFences[i]);
+    }
+#endif
+    SkASSERT(nullptr == fGL.get());
+    SkASSERT(nullptr == fFenceSync.get());
+}
+
+void GLContext::init(const GrGLInterface* gl, SkGpuFenceSync* fenceSync) {
+    SkASSERT(!fGL.get());
+    fGL.reset(gl);
+    fFenceSync.reset(fenceSync ? fenceSync : GLFenceSync::CreateIfSupported(this));
+}
+
+void GLContext::teardown() {
+    if (fFenceSync) {
+        for (size_t i = 0; i < SK_ARRAY_COUNT(fFrameFences); i++) {
+            if (fFrameFences[i]) {
+                fFenceSync->deleteFence(fFrameFences[i]);
+                fFrameFences[i] = 0;
+            }
+        }
+        fFenceSync.reset(nullptr);
+    }
+
+    fGL.reset(nullptr);
+}
+
+void GLContext::makeCurrent() const {
+    this->onPlatformMakeCurrent();
+}
+
+void GLContext::swapBuffers() {
+    this->onPlatformSwapBuffers();
+}
+
+void GLContext::waitOnSyncOrSwap() {
+    if (!fFenceSync) {
+        // Fallback on the platform SwapBuffers method for synchronization. This may have no effect.
+        this->swapBuffers();
+        return;
+    }
+
+    if (fFrameFences[fCurrentFenceIdx]) {
+        if (!fFenceSync->waitFence(fFrameFences[fCurrentFenceIdx], true)) {
+            SkDebugf("WARNING: Wait failed for fence sync. Timings might not be accurate.\n");
+        }
+        fFenceSync->deleteFence(fFrameFences[fCurrentFenceIdx]);
+    }
+
+    fFrameFences[fCurrentFenceIdx] = fFenceSync->insertFence();
+    fCurrentFenceIdx = (fCurrentFenceIdx + 1) % SK_ARRAY_COUNT(fFrameFences);
+}
+
+void GLContext::testAbandon() {
+    if (fGL) {
+        fGL->abandon();
+    }
+    if (fFenceSync) {
+        memset(fFrameFences, 0, sizeof(fFrameFences));
+    }
+}
+
+GLContext::GLFenceSync* GLContext::GLFenceSync::CreateIfSupported(const GLContext* ctx) {
+    SkAutoTDelete<GLFenceSync> ret(new GLFenceSync);
+
+    if (kGL_GrGLStandard == ctx->gl()->fStandard) {
+        const GrGLubyte* versionStr;
+        GR_GL_CALL_RET(ctx->gl(), versionStr, GetString(GR_GL_VERSION));
+        GrGLVersion version = GrGLGetVersionFromString(reinterpret_cast<const char*>(versionStr));
+        if (version < GR_GL_VER(3,2) && !ctx->gl()->hasExtension("GL_ARB_sync")) {
+            return nullptr;
+        }
+        ret->fGLFenceSync = reinterpret_cast<GLFenceSyncProc>(
+            ctx->onPlatformGetProcAddress("glFenceSync"));
+        ret->fGLClientWaitSync = reinterpret_cast<GLClientWaitSyncProc>(
+            ctx->onPlatformGetProcAddress("glClientWaitSync"));
+        ret->fGLDeleteSync = reinterpret_cast<GLDeleteSyncProc>(
+            ctx->onPlatformGetProcAddress("glDeleteSync"));
+    } else {
+        if (!ctx->gl()->hasExtension("GL_APPLE_sync")) {
+            return nullptr;
+        }
+        ret->fGLFenceSync = reinterpret_cast<GLFenceSyncProc>(
+            ctx->onPlatformGetProcAddress("glFenceSyncAPPLE"));
+        ret->fGLClientWaitSync = reinterpret_cast<GLClientWaitSyncProc>(
+            ctx->onPlatformGetProcAddress("glClientWaitSyncAPPLE"));
+        ret->fGLDeleteSync = reinterpret_cast<GLDeleteSyncProc>(
+            ctx->onPlatformGetProcAddress("glDeleteSyncAPPLE"));
+    }
+
+    if (!ret->fGLFenceSync || !ret->fGLClientWaitSync || !ret->fGLDeleteSync) {
+        return nullptr;
+    }
+
+    return ret.release();
+}
+
+SkPlatformGpuFence GLContext::GLFenceSync::insertFence() const {
+    return fGLFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
+}
+
+bool GLContext::GLFenceSync::waitFence(SkPlatformGpuFence fence, bool flush) const {
+    GLsync glsync = static_cast<GLsync>(fence);
+    return GL_WAIT_FAILED != fGLClientWaitSync(glsync, flush ? GL_SYNC_FLUSH_COMMANDS_BIT : 0, -1);
+}
+
+void GLContext::GLFenceSync::deleteFence(SkPlatformGpuFence fence) const {
+    GLsync glsync = static_cast<GLsync>(fence);
+    fGLDeleteSync(glsync);
+}
+
+GrGLint GLContext::createTextureRectangle(int width, int height, GrGLenum internalFormat,
+                                          GrGLenum externalFormat, GrGLenum externalType,
+                                          GrGLvoid* data) {
+    if (!(kGL_GrGLStandard == fGL->fStandard && GrGLGetVersion(fGL) >= GR_GL_VER(3, 1)) &&
+        !fGL->fExtensions.has("GL_ARB_texture_rectangle")) {
+        return 0;
+    }
+
+    if  (GrGLGetGLSLVersion(fGL) < GR_GLSL_VER(1, 40)) {
+        return 0;
+    }
+
+    GrGLuint id;
+    GR_GL_CALL(fGL, GenTextures(1, &id));
+    GR_GL_CALL(fGL, BindTexture(GR_GL_TEXTURE_RECTANGLE, id));
+    GR_GL_CALL(fGL, TexParameteri(GR_GL_TEXTURE_RECTANGLE, GR_GL_TEXTURE_MAG_FILTER,
+                                  GR_GL_NEAREST));
+    GR_GL_CALL(fGL, TexParameteri(GR_GL_TEXTURE_RECTANGLE, GR_GL_TEXTURE_MIN_FILTER,
+                                  GR_GL_NEAREST));
+    GR_GL_CALL(fGL, TexParameteri(GR_GL_TEXTURE_RECTANGLE, GR_GL_TEXTURE_WRAP_S,
+                                  GR_GL_CLAMP_TO_EDGE));    
+    GR_GL_CALL(fGL, TexParameteri(GR_GL_TEXTURE_RECTANGLE, GR_GL_TEXTURE_WRAP_T,
+                                  GR_GL_CLAMP_TO_EDGE));
+    GR_GL_CALL(fGL, TexImage2D(GR_GL_TEXTURE_RECTANGLE, 0, internalFormat, width, height, 0,
+                               externalFormat, externalType, data));
+    return id;
+}
+}  // namespace sk_gpu_test
diff --git a/tools/gpu/gl/GLContext.h b/tools/gpu/gl/GLContext.h
new file mode 100644
index 0000000..3f47613
--- /dev/null
+++ b/tools/gpu/gl/GLContext.h
@@ -0,0 +1,141 @@
+
+/*
+ * Copyright 2013 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+#ifndef GLContext_DEFINED
+#define GLContext_DEFINED
+
+#include "gl/GrGLInterface.h"
+#include "../private/SkGpuFenceSync.h"
+
+
+namespace sk_gpu_test {
+/**
+ * Create an offscreen Oppengl context. Provides a GrGLInterface struct of function pointers for
+ * the context. This class is intended for Skia's internal testing needs and not for general use.
+ */
+class GLContext : public SkNoncopyable {
+public:
+    virtual ~GLContext();
+
+    bool isValid() const { return NULL != gl(); }
+
+    const GrGLInterface *gl() const { return fGL.get(); }
+
+    bool fenceSyncSupport() const { return fFenceSync != nullptr; }
+
+    bool getMaxGpuFrameLag(int *maxFrameLag) const {
+        if (!fFenceSync) {
+            return false;
+        }
+        *maxFrameLag = kMaxFrameLag;
+        return true;
+    }
+
+    void makeCurrent() const;
+
+    /** Used for testing EGLImage integration. Take a GL_TEXTURE_2D and wraps it in an EGL Image */
+    virtual GrEGLImage texture2DToEGLImage(GrGLuint /*texID*/) const { return 0; }
+
+    virtual void destroyEGLImage(GrEGLImage) const { }
+
+    /** Used for testing GL_TEXTURE_RECTANGLE integration. */
+    GrGLint createTextureRectangle(int width, int height, GrGLenum internalFormat,
+                                   GrGLenum externalFormat, GrGLenum externalType,
+                                   GrGLvoid *data);
+
+    /**
+     * Used for testing EGLImage integration. Takes a EGLImage and wraps it in a
+     * GL_TEXTURE_EXTERNAL_OES.
+     */
+    virtual GrGLuint eglImageToExternalTexture(GrEGLImage) const { return 0; }
+
+    void swapBuffers();
+
+    /**
+     * The only purpose of this function it to provide a means of scheduling
+     * work on the GPU (since all of the subclasses create primary buffers for
+     * testing that are small and not meant to be rendered to the screen).
+     *
+     * If the platform supports fence sync (OpenGL 3.2+ or EGL_KHR_fence_sync),
+     * this will not swap any buffers, but rather emulate triple buffer
+     * synchronization using fences.
+     *
+     * Otherwise it will call the platform SwapBuffers method. This may or may
+     * not perform some sort of synchronization, depending on whether the
+     * drawing surface provided by the platform is double buffered.
+     */
+    void waitOnSyncOrSwap();
+
+    /**
+     * This notifies the context that we are deliberately testing abandoning
+     * the context. It is useful for debugging contexts that would otherwise
+     * test that GPU resources are properly deleted. It also allows a debugging
+     * context to test that further GL calls are not made by Skia GPU code.
+     */
+    void testAbandon();
+
+    /**
+     * Creates a new GL context of the same type and makes the returned context current
+     * (if not null).
+     */
+    virtual GLContext *createNew() const { return nullptr; }
+
+    class GLFenceSync;  // SkGpuFenceSync implementation that uses the OpenGL functionality.
+
+    /*
+     * returns the fencesync object owned by this GLContext
+     */
+    SkGpuFenceSync *fenceSync() { return fFenceSync.get(); }
+
+protected:
+    GLContext();
+
+    /*
+     * Methods that sublcasses must call from their constructors and destructors.
+     */
+    void init(const GrGLInterface *, SkGpuFenceSync * = NULL);
+
+    void teardown();
+
+    /*
+     * Operations that have a platform-dependent implementation.
+     */
+    virtual void onPlatformMakeCurrent() const = 0;
+
+    virtual void onPlatformSwapBuffers() const = 0;
+
+    virtual GrGLFuncPtr onPlatformGetProcAddress(const char *) const = 0;
+
+private:
+    enum {
+        kMaxFrameLag = 3
+    };
+
+    SkAutoTDelete <SkGpuFenceSync> fFenceSync;
+    SkPlatformGpuFence fFrameFences[kMaxFrameLag - 1];
+    int fCurrentFenceIdx;
+
+    /** Subclass provides the gl interface object if construction was
+     *  successful. */
+    SkAutoTUnref<const GrGLInterface> fGL;
+
+    friend class GLFenceSync;  // For onPlatformGetProcAddress.
+};
+
+
+/** Creates platform-dependent GL context object.  The shareContext parameter is in an optional
+ * context with which to share display lists. This should be a pointer to an GLContext created
+ * with SkCreatePlatformGLContext.  NULL indicates that no sharing is to take place. Returns a valid
+ * gl context object or NULL if such can not be created.
+ * Note: If Skia embedder needs a custom GL context that sets up the GL interface, this function
+ * should be implemented by the embedder. Otherwise, the default implementation for the platform
+ * should be compiled in the library.
+ */
+GLContext* CreatePlatformGLContext(GrGLStandard forcedGpuAPI, GLContext *shareContext = nullptr);
+
+}  // namespace sk_gpu_test
+#endif
diff --git a/tools/gpu/gl/angle/GLContext_angle.cpp b/tools/gpu/gl/angle/GLContext_angle.cpp
new file mode 100644
index 0000000..f1e8aad
--- /dev/null
+++ b/tools/gpu/gl/angle/GLContext_angle.cpp
@@ -0,0 +1,320 @@
+
+/*
+ * Copyright 2012 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "GLContext_angle.h"
+
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
+
+#include "gl/GrGLDefines.h"
+#include "gl/GrGLUtil.h"
+
+#include "gl/GrGLInterface.h"
+#include "gl/GrGLAssembleInterface.h"
+#include "../ports/SkOSLibrary.h"
+
+#include <EGL/egl.h>
+
+#define EGL_PLATFORM_ANGLE_ANGLE                0x3202
+#define EGL_PLATFORM_ANGLE_TYPE_ANGLE           0x3203
+#define EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE      0x3207
+#define EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE     0x3208
+#define EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE    0x320D
+
+namespace {
+struct Libs {
+    void* fGLLib;
+    void* fEGLLib;
+};
+
+static GrGLFuncPtr angle_get_gl_proc(void* ctx, const char name[]) {
+    const Libs* libs = reinterpret_cast<const Libs*>(ctx);
+    GrGLFuncPtr proc = (GrGLFuncPtr) GetProcedureAddress(libs->fGLLib, name);
+    if (proc) {
+        return proc;
+    }
+    proc = (GrGLFuncPtr) GetProcedureAddress(libs->fEGLLib, name);
+    if (proc) {
+        return proc;
+    }
+    return eglGetProcAddress(name);
+}
+
+void* get_angle_egl_display(void* nativeDisplay, bool useGLBackend) {
+    PFNEGLGETPLATFORMDISPLAYEXTPROC eglGetPlatformDisplayEXT;
+    eglGetPlatformDisplayEXT =
+        (PFNEGLGETPLATFORMDISPLAYEXTPROC)eglGetProcAddress("eglGetPlatformDisplayEXT");
+
+    // We expect ANGLE to support this extension
+    if (!eglGetPlatformDisplayEXT) {
+        return EGL_NO_DISPLAY;
+    }
+
+    EGLDisplay display = EGL_NO_DISPLAY;
+    if (useGLBackend) {
+        EGLint attribs[3] = {
+            EGL_PLATFORM_ANGLE_TYPE_ANGLE,
+            EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE,
+            EGL_NONE
+        };
+        display = eglGetPlatformDisplayEXT(EGL_PLATFORM_ANGLE_ANGLE, nativeDisplay, attribs);
+    } else {
+        // Try for an ANGLE D3D11 context, fall back to D3D9.
+        EGLint attribs[3][3] = {
+            {
+                EGL_PLATFORM_ANGLE_TYPE_ANGLE,
+                EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE,
+                EGL_NONE
+            },
+            {
+                EGL_PLATFORM_ANGLE_TYPE_ANGLE,
+                EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE,
+                EGL_NONE
+            },
+        };
+        for (int i = 0; i < 3 && display == EGL_NO_DISPLAY; ++i) {
+            display = eglGetPlatformDisplayEXT(EGL_PLATFORM_ANGLE_ANGLE,nativeDisplay, attribs[i]);
+        }
+    }
+    return display;
+}
+
+class ANGLEGLContext : public sk_gpu_test::GLContext {
+public:
+    ANGLEGLContext(bool preferGLBackend);
+    ~ANGLEGLContext() override;
+
+    GrEGLImage texture2DToEGLImage(GrGLuint texID) const override;
+    void destroyEGLImage(GrEGLImage) const override;
+    GrGLuint eglImageToExternalTexture(GrEGLImage) const override;
+    sk_gpu_test::GLContext* createNew() const override;
+
+private:
+    void destroyGLContext();
+
+    void onPlatformMakeCurrent() const override;
+    void onPlatformSwapBuffers() const override;
+    GrGLFuncPtr onPlatformGetProcAddress(const char* name) const override;
+
+    void* fContext;
+    void* fDisplay;
+    void* fSurface;
+    bool  fIsGLBackend;
+};
+
+ANGLEGLContext::ANGLEGLContext(bool useGLBackend)
+    : fContext(EGL_NO_CONTEXT)
+    , fDisplay(EGL_NO_DISPLAY)
+    , fSurface(EGL_NO_SURFACE) {
+
+    EGLint numConfigs;
+    static const EGLint configAttribs[] = {
+        EGL_SURFACE_TYPE, EGL_PBUFFER_BIT,
+        EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
+        EGL_RED_SIZE, 8,
+        EGL_GREEN_SIZE, 8,
+        EGL_BLUE_SIZE, 8,
+        EGL_ALPHA_SIZE, 8,
+        EGL_NONE
+    };
+
+    fIsGLBackend = useGLBackend;
+    fDisplay = get_angle_egl_display(EGL_DEFAULT_DISPLAY, useGLBackend);
+    if (EGL_NO_DISPLAY == fDisplay) {
+        SkDebugf("Could not create EGL display!");
+        return;
+    }
+
+    EGLint majorVersion;
+    EGLint minorVersion;
+    eglInitialize(fDisplay, &majorVersion, &minorVersion);
+
+    EGLConfig surfaceConfig;
+    eglChooseConfig(fDisplay, configAttribs, &surfaceConfig, 1, &numConfigs);
+
+    static const EGLint contextAttribs[] = {
+        EGL_CONTEXT_CLIENT_VERSION, 2,
+        EGL_NONE
+    };
+    fContext = eglCreateContext(fDisplay, surfaceConfig, nullptr, contextAttribs);
+
+
+    static const EGLint surfaceAttribs[] = {
+        EGL_WIDTH, 1,
+        EGL_HEIGHT, 1,
+        EGL_NONE
+    };
+
+    fSurface = eglCreatePbufferSurface(fDisplay, surfaceConfig, surfaceAttribs);
+
+    eglMakeCurrent(fDisplay, fSurface, fSurface, fContext);
+
+    SkAutoTUnref<const GrGLInterface> gl(sk_gpu_test::CreateANGLEGLInterface());
+    if (nullptr == gl.get()) {
+        SkDebugf("Could not create ANGLE GL interface!\n");
+        this->destroyGLContext();
+        return;
+    }
+    if (!gl->validate()) {
+        SkDebugf("Could not validate ANGLE GL interface!\n");
+        this->destroyGLContext();
+        return;
+    }
+
+    this->init(gl.release());
+}
+
+ANGLEGLContext::~ANGLEGLContext() {
+    this->teardown();
+    this->destroyGLContext();
+}
+
+GrEGLImage ANGLEGLContext::texture2DToEGLImage(GrGLuint texID) const {
+    if (!this->gl()->hasExtension("EGL_KHR_gl_texture_2D_image")) {
+        return GR_EGL_NO_IMAGE;
+    }
+    GrEGLImage img;
+    GrEGLint attribs[] = { GR_EGL_GL_TEXTURE_LEVEL, 0,
+                           GR_EGL_IMAGE_PRESERVED, GR_EGL_TRUE,
+                           GR_EGL_NONE };
+    // 64 bit cast is to shut Visual C++ up about casting 32 bit value to a pointer.
+    GrEGLClientBuffer clientBuffer = reinterpret_cast<GrEGLClientBuffer>((uint64_t)texID);
+    GR_GL_CALL_RET(this->gl(), img,
+                   EGLCreateImage(fDisplay, fContext, GR_EGL_GL_TEXTURE_2D, clientBuffer,
+                                  attribs));
+    return img;
+}
+
+void ANGLEGLContext::destroyEGLImage(GrEGLImage image) const {
+    GR_GL_CALL(this->gl(), EGLDestroyImage(fDisplay, image));
+}
+
+GrGLuint ANGLEGLContext::eglImageToExternalTexture(GrEGLImage image) const {
+    GrGLClearErr(this->gl());
+    if (!this->gl()->hasExtension("GL_OES_EGL_image_external")) {
+        return 0;
+    }
+    typedef GrGLvoid (*EGLImageTargetTexture2DProc)(GrGLenum, GrGLeglImage);
+    EGLImageTargetTexture2DProc glEGLImageTargetTexture2D =
+        (EGLImageTargetTexture2DProc)eglGetProcAddress("glEGLImageTargetTexture2DOES");
+    if (!glEGLImageTargetTexture2D) {
+        return 0;
+    }
+    GrGLuint texID;
+    GR_GL_CALL(this->gl(), GenTextures(1, &texID));
+    if (!texID) {
+        return 0;
+    }
+    GR_GL_CALL(this->gl(), BindTexture(GR_GL_TEXTURE_EXTERNAL, texID));
+    if (GR_GL_GET_ERROR(this->gl()) != GR_GL_NO_ERROR) {
+        GR_GL_CALL(this->gl(), DeleteTextures(1, &texID));
+        return 0;
+    }
+    glEGLImageTargetTexture2D(GR_GL_TEXTURE_EXTERNAL, image);
+    if (GR_GL_GET_ERROR(this->gl()) != GR_GL_NO_ERROR) {
+        GR_GL_CALL(this->gl(), DeleteTextures(1, &texID));
+        return 0;
+    }
+    return texID;
+}
+
+sk_gpu_test::GLContext* ANGLEGLContext::createNew() const {
+#ifdef SK_BUILD_FOR_WIN
+    sk_gpu_test::GLContext* ctx = fIsGLBackend ? sk_gpu_test::CreateANGLEOpenGLGLContext()
+                                               : sk_gpu_test::CreateANGLEDirect3DGLContext();
+#else
+    sk_gpu_test::GLContext* ctx = sk_gpu_test::CreateANGLEOpenGLGLContext();
+#endif
+    if (ctx) {
+        ctx->makeCurrent();
+    }
+    return ctx;
+}
+
+void ANGLEGLContext::destroyGLContext() {
+    if (fDisplay) {
+        eglMakeCurrent(fDisplay, 0, 0, 0);
+
+        if (fContext) {
+            eglDestroyContext(fDisplay, fContext);
+            fContext = EGL_NO_CONTEXT;
+        }
+
+        if (fSurface) {
+            eglDestroySurface(fDisplay, fSurface);
+            fSurface = EGL_NO_SURFACE;
+        }
+
+        //TODO should we close the display?
+        fDisplay = EGL_NO_DISPLAY;
+    }
+}
+
+void ANGLEGLContext::onPlatformMakeCurrent() const {
+    if (!eglMakeCurrent(fDisplay, fSurface, fSurface, fContext)) {
+        SkDebugf("Could not set the context.\n");
+    }
+}
+
+void ANGLEGLContext::onPlatformSwapBuffers() const {
+    if (!eglSwapBuffers(fDisplay, fSurface)) {
+        SkDebugf("Could not complete eglSwapBuffers.\n");
+    }
+}
+
+GrGLFuncPtr ANGLEGLContext::onPlatformGetProcAddress(const char* name) const {
+    return eglGetProcAddress(name);
+}
+}  // anonymous namespace
+
+namespace sk_gpu_test {
+const GrGLInterface* CreateANGLEGLInterface() {
+    static Libs gLibs = { nullptr, nullptr };
+
+    if (nullptr == gLibs.fGLLib) {
+        // We load the ANGLE library and never let it go
+#if defined _WIN32
+        gLibs.fGLLib = DynamicLoadLibrary("libGLESv2.dll");
+        gLibs.fEGLLib = DynamicLoadLibrary("libEGL.dll");
+#elif defined SK_BUILD_FOR_MAC
+        gLibs.fGLLib = DynamicLoadLibrary("libGLESv2.dylib");
+        gLibs.fEGLLib = DynamicLoadLibrary("libEGL.dylib");
+#else
+        gLibs.fGLLib = DynamicLoadLibrary("libGLESv2.so");
+        gLibs.fEGLLib = DynamicLoadLibrary("libEGL.so");
+#endif
+    }
+
+    if (nullptr == gLibs.fGLLib || nullptr == gLibs.fEGLLib) {
+        // We can't setup the interface correctly w/o the so
+        return nullptr;
+    }
+
+    return GrGLAssembleGLESInterface(&gLibs, angle_get_gl_proc);
+}
+
+#ifdef SK_BUILD_FOR_WIN
+GLContext* CreateANGLEDirect3DGLContext() {
+        ANGLEGLContext* ctx = new ANGLEGLContext(false);
+        if (!ctx->isValid()) {
+            delete ctx;
+            return NULL;
+        }
+        return ctx;
+    }
+#endif
+
+GLContext* CreateANGLEOpenGLGLContext() {
+    ANGLEGLContext* ctx = new ANGLEGLContext(true);
+    if (!ctx->isValid()) {
+        delete ctx;
+        return NULL;
+    }
+    return ctx;
+}
+}  // namespace sk_gpu_test
diff --git a/tools/gpu/gl/angle/GLContext_angle.h b/tools/gpu/gl/angle/GLContext_angle.h
new file mode 100644
index 0000000..519ea6b
--- /dev/null
+++ b/tools/gpu/gl/angle/GLContext_angle.h
@@ -0,0 +1,30 @@
+
+/*
+ * Copyright 2012 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+#ifndef GLContext_angle_DEFINED
+#define GLContext_angle_DEFINED
+
+#include "gl/GLContext.h"
+
+namespace sk_gpu_test {
+
+/**
+ * Creates a GrGLInterface for the currently ANGLE GL context currently bound in ANGLE's EGL
+ * implementation.
+ */
+const GrGLInterface* CreateANGLEGLInterface();
+
+#ifdef SK_BUILD_FOR_WIN
+/** Creates a GLContext backed by ANGLE's Direct3D backend. */
+GLContext* CreateANGLEDirect3DGLContext();
+#endif
+
+/** Creates a GLContext backed by ANGLE's OpenGL backend. */
+GLContext* CreateANGLEOpenGLGLContext();
+
+}  // namespace sk_gpu_test
+#endif
diff --git a/tools/gpu/gl/command_buffer/GLContext_command_buffer.cpp b/tools/gpu/gl/command_buffer/GLContext_command_buffer.cpp
new file mode 100644
index 0000000..b878cb4
--- /dev/null
+++ b/tools/gpu/gl/command_buffer/GLContext_command_buffer.cpp
@@ -0,0 +1,345 @@
+
+/*
+ * Copyright 2015 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "SkOnce.h"
+#include "gl/GrGLInterface.h"
+#include "gl/GrGLAssembleInterface.h"
+#include "gl/command_buffer/GLContext_command_buffer.h"
+#include "../ports/SkOSEnvironment.h"
+#include "../ports/SkOSLibrary.h"
+
+#if defined SK_BUILD_FOR_MAC
+
+// EGL doesn't exist on the mac, so expose what we need to get the command buffer's EGL running.
+typedef void *EGLDisplay;
+typedef unsigned int EGLBoolean;
+typedef void *EGLConfig;
+typedef void *EGLSurface;
+typedef void *EGLContext;
+typedef int32_t EGLint;
+typedef void* EGLNativeDisplayType;
+typedef void* EGLNativeWindowType;
+typedef void (*__eglMustCastToProperFunctionPointerType)(void);
+#define EGL_FALSE 0
+#define EGL_OPENGL_ES2_BIT 0x0004
+#define EGL_CONTEXT_CLIENT_VERSION 0x3098
+#define EGL_NO_SURFACE ((EGLSurface)0)
+#define EGL_NO_DISPLAY ((EGLDisplay)0)
+#define EGL_NO_CONTEXT ((EGLContext)0)
+#define EGL_DEFAULT_DISPLAY ((EGLNativeDisplayType)0)
+#define EGL_SURFACE_TYPE 0x3033
+#define EGL_PBUFFER_BIT 0x0001
+#define EGL_RENDERABLE_TYPE 0x3040
+#define EGL_RED_SIZE 0x3024
+#define EGL_GREEN_SIZE 0x3023
+#define EGL_BLUE_SIZE 0x3022
+#define EGL_ALPHA_SIZE 0x3021
+#define EGL_DEPTH_SIZE 0x3025
+#define EGL_STENCIL_SIZE 0x3025
+#define EGL_SAMPLES 0x3031
+#define EGL_SAMPLE_BUFFERS 0x3032
+#define EGL_NONE 0x3038
+#define EGL_WIDTH 0x3057
+#define EGL_HEIGHT 0x3056
+
+#else
+
+#include <EGL/egl.h>
+
+#endif
+
+typedef EGLDisplay (*GetDisplayProc)(EGLNativeDisplayType display_id);
+typedef EGLBoolean (*InitializeProc)(EGLDisplay dpy, EGLint *major, EGLint *minor);
+typedef EGLBoolean (*TerminateProc)(EGLDisplay dpy);
+typedef EGLBoolean (*ChooseConfigProc)(EGLDisplay dpy, const EGLint* attrib_list, EGLConfig* configs, EGLint config_size, EGLint* num_config);
+typedef EGLBoolean (*GetConfigAttrib)(EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint* value);
+typedef EGLSurface (*CreateWindowSurfaceProc)(EGLDisplay dpy, EGLConfig config, EGLNativeWindowType win, const EGLint* attrib_list);
+typedef EGLSurface (*CreatePbufferSurfaceProc)(EGLDisplay dpy, EGLConfig config, const EGLint* attrib_list);
+typedef EGLBoolean (*DestroySurfaceProc)(EGLDisplay dpy, EGLSurface surface);
+typedef EGLContext (*CreateContextProc)(EGLDisplay dpy, EGLConfig config, EGLContext share_context, const EGLint* attrib_list);
+typedef EGLBoolean (*DestroyContextProc)(EGLDisplay dpy, EGLContext ctx);
+typedef EGLBoolean (*MakeCurrentProc)(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx);
+typedef EGLBoolean (*SwapBuffersProc)(EGLDisplay dpy, EGLSurface surface);
+typedef __eglMustCastToProperFunctionPointerType (*GetProcAddressProc)(const char* procname);
+
+static GetDisplayProc gfGetDisplay = nullptr;
+static InitializeProc gfInitialize = nullptr;
+static TerminateProc gfTerminate = nullptr;
+static ChooseConfigProc gfChooseConfig = nullptr;
+static GetConfigAttrib gfGetConfigAttrib = nullptr;
+static CreateWindowSurfaceProc gfCreateWindowSurface = nullptr;
+static CreatePbufferSurfaceProc gfCreatePbufferSurface = nullptr;
+static DestroySurfaceProc gfDestroySurface = nullptr;
+static CreateContextProc gfCreateContext = nullptr;
+static DestroyContextProc gfDestroyContext = nullptr;
+static MakeCurrentProc gfMakeCurrent = nullptr;
+static SwapBuffersProc gfSwapBuffers = nullptr;
+static GetProcAddressProc gfGetProcAddress = nullptr;
+
+static void* gLibrary = nullptr;
+static bool gfFunctionsLoadedSuccessfully = false;
+
+namespace {
+static void load_command_buffer_functions() {
+    if (!gLibrary) {
+#if defined _WIN32
+        gLibrary = DynamicLoadLibrary("command_buffer_gles2.dll");
+#elif defined SK_BUILD_FOR_MAC
+        gLibrary = DynamicLoadLibrary("libcommand_buffer_gles2.dylib");
+#else
+        gLibrary = DynamicLoadLibrary("libcommand_buffer_gles2.so");
+#endif // defined _WIN32
+        if (gLibrary) {
+            gfGetDisplay = (GetDisplayProc)GetProcedureAddress(gLibrary, "eglGetDisplay");
+            gfInitialize = (InitializeProc)GetProcedureAddress(gLibrary, "eglInitialize");
+            gfTerminate = (TerminateProc)GetProcedureAddress(gLibrary, "eglTerminate");
+            gfChooseConfig = (ChooseConfigProc)GetProcedureAddress(gLibrary, "eglChooseConfig");
+            gfGetConfigAttrib = (GetConfigAttrib)GetProcedureAddress(gLibrary, "eglGetConfigAttrib");
+            gfCreateWindowSurface = (CreateWindowSurfaceProc)GetProcedureAddress(gLibrary, "eglCreateWindowSurface");
+            gfCreatePbufferSurface = (CreatePbufferSurfaceProc)GetProcedureAddress(gLibrary, "eglCreatePbufferSurface");
+            gfDestroySurface = (DestroySurfaceProc)GetProcedureAddress(gLibrary, "eglDestroySurface");
+            gfCreateContext = (CreateContextProc)GetProcedureAddress(gLibrary, "eglCreateContext");
+            gfDestroyContext = (DestroyContextProc)GetProcedureAddress(gLibrary, "eglDestroyContext");
+            gfMakeCurrent = (MakeCurrentProc)GetProcedureAddress(gLibrary, "eglMakeCurrent");
+            gfSwapBuffers = (SwapBuffersProc)GetProcedureAddress(gLibrary, "eglSwapBuffers");
+            gfGetProcAddress = (GetProcAddressProc)GetProcedureAddress(gLibrary, "eglGetProcAddress");
+
+            gfFunctionsLoadedSuccessfully = gfGetDisplay && gfInitialize && gfTerminate &&
+                                            gfChooseConfig && gfCreateWindowSurface &&
+                                            gfCreatePbufferSurface && gfDestroySurface &&
+                                            gfCreateContext && gfDestroyContext && gfMakeCurrent &&
+                                            gfSwapBuffers && gfGetProcAddress;
+
+        }
+    }
+}
+
+static GrGLFuncPtr command_buffer_get_gl_proc(void* ctx, const char name[]) {
+    if (!gfFunctionsLoadedSuccessfully) {
+        return nullptr;
+    }
+    return gfGetProcAddress(name);
+}
+
+SK_DECLARE_STATIC_ONCE(loadCommandBufferOnce);
+static void load_command_buffer_once() {
+    SkOnce(&loadCommandBufferOnce, load_command_buffer_functions);
+}
+
+static const GrGLInterface* create_command_buffer_interface() {
+    load_command_buffer_once();
+    if (!gfFunctionsLoadedSuccessfully) {
+        return nullptr;
+    }
+    return GrGLAssembleGLESInterface(gLibrary, command_buffer_get_gl_proc);
+}
+
+}  // anonymous namespace
+
+namespace sk_gpu_test {
+
+CommandBufferGLContext::CommandBufferGLContext()
+    : fContext(EGL_NO_CONTEXT), fDisplay(EGL_NO_DISPLAY), fSurface(EGL_NO_SURFACE) {
+
+    static const EGLint configAttribs[] = {
+        EGL_SURFACE_TYPE, EGL_PBUFFER_BIT,
+        EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
+        EGL_RED_SIZE, 8,
+        EGL_GREEN_SIZE, 8,
+        EGL_BLUE_SIZE, 8,
+        EGL_ALPHA_SIZE, 8,
+        EGL_NONE
+    };
+
+    static const EGLint surfaceAttribs[] = {
+        EGL_WIDTH, 1,
+        EGL_HEIGHT, 1,
+        EGL_NONE
+    };
+
+    initializeGLContext(nullptr, configAttribs, surfaceAttribs);
+}
+
+CommandBufferGLContext::CommandBufferGLContext(void *nativeWindow, int msaaSampleCount) {
+    static const EGLint surfaceAttribs[] = {EGL_NONE};
+
+    EGLint configAttribs[] = {
+        EGL_RED_SIZE, 8,
+        EGL_GREEN_SIZE, 8,
+        EGL_BLUE_SIZE, 8,
+        EGL_ALPHA_SIZE, 8,
+        EGL_DEPTH_SIZE, 8,
+        EGL_STENCIL_SIZE, 8,
+        EGL_SAMPLE_BUFFERS, 1,
+        EGL_SAMPLES, msaaSampleCount,
+        EGL_NONE
+    };
+    if (msaaSampleCount == 0) {
+        configAttribs[12] = EGL_NONE;
+    }
+
+    initializeGLContext(nativeWindow, configAttribs, surfaceAttribs);
+}
+
+void CommandBufferGLContext::initializeGLContext(void *nativeWindow, const int *configAttribs,
+                                                 const int *surfaceAttribs) {
+    load_command_buffer_once();
+    if (!gfFunctionsLoadedSuccessfully) {
+        SkDebugf("Command Buffer: Could not load EGL functions.\n");
+        return;
+    }
+
+    // Make sure CHROMIUM_path_rendering is enabled for NVPR support.
+    sk_setenv("CHROME_COMMAND_BUFFER_GLES2_ARGS", "--enable-gl-path-rendering");
+    fDisplay = gfGetDisplay(EGL_DEFAULT_DISPLAY);
+    if (EGL_NO_DISPLAY == fDisplay) {
+        SkDebugf("Command Buffer: Could not create EGL display.\n");
+        return;
+    }
+
+    EGLint majorVersion;
+    EGLint minorVersion;
+    if (!gfInitialize(fDisplay, &majorVersion, &minorVersion)) {
+        SkDebugf("Command Buffer: Could not initialize EGL display.\n");
+        this->destroyGLContext();
+        return;
+    }
+
+    EGLint numConfigs;
+    if (!gfChooseConfig(fDisplay, configAttribs, static_cast<EGLConfig *>(&fConfig), 1,
+                        &numConfigs) || numConfigs != 1) {
+        SkDebugf("Command Buffer: Could not choose EGL config.\n");
+        this->destroyGLContext();
+        return;
+    }
+
+    if (nativeWindow) {
+        fSurface = gfCreateWindowSurface(fDisplay,
+                                         static_cast<EGLConfig>(fConfig),
+                                         (EGLNativeWindowType) nativeWindow,
+                                         surfaceAttribs);
+    } else {
+        fSurface = gfCreatePbufferSurface(fDisplay,
+                                          static_cast<EGLConfig>(fConfig),
+                                          surfaceAttribs);
+    }
+    if (EGL_NO_SURFACE == fSurface) {
+        SkDebugf("Command Buffer: Could not create EGL surface.\n");
+        this->destroyGLContext();
+        return;
+    }
+
+    static const EGLint contextAttribs[] = {
+        EGL_CONTEXT_CLIENT_VERSION, 2,
+        EGL_NONE
+    };
+    fContext = gfCreateContext(fDisplay, static_cast<EGLConfig>(fConfig), nullptr, contextAttribs);
+    if (EGL_NO_CONTEXT == fContext) {
+        SkDebugf("Command Buffer: Could not create EGL context.\n");
+        this->destroyGLContext();
+        return;
+    }
+
+    if (!gfMakeCurrent(fDisplay, fSurface, fSurface, fContext)) {
+        SkDebugf("Command Buffer: Could not make EGL context current.\n");
+        this->destroyGLContext();
+        return;
+    }
+
+    SkAutoTUnref<const GrGLInterface> gl(create_command_buffer_interface());
+    if (nullptr == gl.get()) {
+        SkDebugf("Command Buffer: Could not create CommandBuffer GL interface.\n");
+        this->destroyGLContext();
+        return;
+    }
+    if (!gl->validate()) {
+        SkDebugf("Command Buffer: Could not validate CommandBuffer GL interface.\n");
+        this->destroyGLContext();
+        return;
+    }
+
+    this->init(gl.release());
+}
+
+CommandBufferGLContext::~CommandBufferGLContext() {
+    this->teardown();
+    this->destroyGLContext();
+}
+
+void CommandBufferGLContext::destroyGLContext() {
+    if (!gfFunctionsLoadedSuccessfully) {
+        return;
+    }
+    if (fDisplay) {
+        gfMakeCurrent(fDisplay, 0, 0, 0);
+
+        if (fContext) {
+            gfDestroyContext(fDisplay, fContext);
+            fContext = EGL_NO_CONTEXT;
+        }
+
+        if (fSurface) {
+            gfDestroySurface(fDisplay, fSurface);
+            fSurface = EGL_NO_SURFACE;
+        }
+
+        gfTerminate(fDisplay);
+        fDisplay = EGL_NO_DISPLAY;
+    }
+}
+
+void CommandBufferGLContext::onPlatformMakeCurrent() const {
+    if (!gfFunctionsLoadedSuccessfully) {
+        return;
+    }
+    if (!gfMakeCurrent(fDisplay, fSurface, fSurface, fContext)) {
+        SkDebugf("Command Buffer: Could not make EGL context current.\n");
+    }
+}
+
+void CommandBufferGLContext::onPlatformSwapBuffers() const {
+    if (!gfFunctionsLoadedSuccessfully) {
+        return;
+    }
+    if (!gfSwapBuffers(fDisplay, fSurface)) {
+        SkDebugf("Command Buffer: Could not complete gfSwapBuffers.\n");
+    }
+}
+
+GrGLFuncPtr CommandBufferGLContext::onPlatformGetProcAddress(const char *name) const {
+    if (!gfFunctionsLoadedSuccessfully) {
+        return nullptr;
+    }
+    return gfGetProcAddress(name);
+}
+
+void CommandBufferGLContext::presentCommandBuffer() {
+    if (this->gl()) {
+        this->gl()->fFunctions.fFlush();
+    }
+
+    this->onPlatformSwapBuffers();
+}
+
+bool CommandBufferGLContext::makeCurrent() {
+    return gfMakeCurrent(fDisplay, fSurface, fSurface, fContext) != EGL_FALSE;
+}
+
+int CommandBufferGLContext::getStencilBits() {
+    EGLint result = 0;
+    gfGetConfigAttrib(fDisplay, static_cast<EGLConfig>(fConfig), EGL_STENCIL_SIZE, &result);
+    return result;
+}
+
+int CommandBufferGLContext::getSampleCount() {
+    EGLint result = 0;
+    gfGetConfigAttrib(fDisplay, static_cast<EGLConfig>(fConfig), EGL_SAMPLES, &result);
+    return result;
+}
+
+}  // namespace sk_gpu_test
diff --git a/tools/gpu/gl/command_buffer/GLContext_command_buffer.h b/tools/gpu/gl/command_buffer/GLContext_command_buffer.h
new file mode 100644
index 0000000..73f02e2
--- /dev/null
+++ b/tools/gpu/gl/command_buffer/GLContext_command_buffer.h
@@ -0,0 +1,68 @@
+
+/*
+ * Copyright 2015 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef GLContext_command_buffer_DEFINED
+#define GLContext_command_buffer_DEFINED
+
+#include "gl/GLContext.h"
+
+namespace sk_gpu_test {
+class CommandBufferGLContext : public GLContext {
+public:
+    ~CommandBufferGLContext() override;
+
+    static CommandBufferGLContext *Create() {
+        CommandBufferGLContext *ctx = new CommandBufferGLContext;
+        if (!ctx->isValid()) {
+            delete ctx;
+            return nullptr;
+        }
+        return ctx;
+    }
+
+    static CommandBufferGLContext *Create(void *nativeWindow, int msaaSampleCount) {
+        CommandBufferGLContext *ctx = new CommandBufferGLContext(nativeWindow, msaaSampleCount);
+        if (!ctx->isValid()) {
+            delete ctx;
+            return nullptr;
+        }
+        return ctx;
+    }
+
+    void presentCommandBuffer();
+
+    bool makeCurrent();
+
+    int getStencilBits();
+
+    int getSampleCount();
+
+private:
+    CommandBufferGLContext();
+
+    CommandBufferGLContext(void *nativeWindow, int msaaSampleCount);
+
+    void initializeGLContext(void *nativeWindow, const int *configAttribs,
+                             const int *surfaceAttribs);
+
+    void destroyGLContext();
+
+    void onPlatformMakeCurrent() const override;
+
+    void onPlatformSwapBuffers() const override;
+
+    GrGLFuncPtr onPlatformGetProcAddress(const char *name) const override;
+
+    void *fContext;
+    void *fDisplay;
+    void *fSurface;
+    void *fConfig;
+};
+}   // namespace sk_gpu_test
+
+#endif
diff --git a/tools/gpu/gl/debug/DebugGLContext.cpp b/tools/gpu/gl/debug/DebugGLContext.cpp
new file mode 100644
index 0000000..f4cbbea
--- /dev/null
+++ b/tools/gpu/gl/debug/DebugGLContext.cpp
@@ -0,0 +1,1256 @@
+
+/*
+ * Copyright 2012 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "DebugGLContext.h"
+
+#include "GrBufferObj.h"
+#include "GrFrameBufferObj.h"
+#include "GrProgramObj.h"
+#include "GrRenderBufferObj.h"
+#include "GrShaderObj.h"
+#include "GrTextureObj.h"
+#include "GrTextureUnitObj.h"
+#include "GrVertexArrayObj.h"
+#include "gl/GrGLTestInterface.h"
+
+#include "SkMutex.h"
+
+namespace {
+
+// Helper macro to make creating an object (where you need to get back a derived type) easier
+#define CREATE(className, classEnum)                     \
+    reinterpret_cast<className *>(this->createObj(classEnum))
+
+// Helper macro to make creating an object (where you need to get back a derived type) easier
+#define FIND(id, className, classEnum)                   \
+    reinterpret_cast<className *>(this->findObject(id, classEnum))
+
+class DebugInterface : public GrGLTestInterface {
+public:
+    DebugInterface()
+        : fCurrGenericID(0)
+        , fCurrTextureUnit(0)
+        , fArrayBuffer(nullptr)
+        , fElementArrayBuffer(nullptr)
+        , fVertexArray(nullptr)
+        , fPackRowLength(0)
+        , fUnpackRowLength(0)
+        , fPackAlignment(4)
+        , fFrameBuffer(nullptr)
+        , fRenderBuffer(nullptr)
+        , fProgram(nullptr)
+        , fAbandoned(false) {
+        for (int i = 0; i < kDefaultMaxTextureUnits; ++i) {
+            fTextureUnits[i] =
+                reinterpret_cast<GrTextureUnitObj*>(this->createObj(kTextureUnit_ObjTypes));
+            fTextureUnits[i]->ref();
+            fTextureUnits[i]->setNumber(i);
+        }
+        this->init(kGL_GrGLStandard);
+    }
+
+    ~DebugInterface() override {
+        // unref & delete the texture units first so they don't show up on the leak report
+        for (int i = 0; i < kDefaultMaxTextureUnits; ++i) {
+            fTextureUnits[i]->unref();
+            fTextureUnits[i]->deleteAction();
+        }
+        for (int i = 0; i < fObjects.count(); ++i) {
+            delete fObjects[i];
+        }
+        fObjects.reset();
+
+        fArrayBuffer = nullptr;
+        fElementArrayBuffer = nullptr;
+        fVertexArray = nullptr;
+
+        this->report();
+    }
+
+    void abandon() const override { fAbandoned = true; }
+
+    GrGLvoid activeTexture(GrGLenum texture) override {
+        // Ganesh offsets the texture unit indices
+        texture -= GR_GL_TEXTURE0;
+        GrAlwaysAssert(texture < kDefaultMaxTextureUnits);
+        fCurrTextureUnit = texture;
+    }
+
+    GrGLvoid attachShader(GrGLuint programID, GrGLuint shaderID) override {
+
+        GrProgramObj *program = FIND(programID, GrProgramObj, kProgram_ObjTypes);
+        GrAlwaysAssert(program);
+
+        GrShaderObj *shader = FIND(shaderID, GrShaderObj, kShader_ObjTypes);
+        GrAlwaysAssert(shader);
+
+        program->AttachShader(shader);
+    }
+
+    ////////////////////////////////////////////////////////////////////////////////
+    GrGLvoid bindTexture(GrGLenum target, GrGLuint textureID) override {
+        GrAlwaysAssert(target == GR_GL_TEXTURE_2D ||
+                       target == GR_GL_TEXTURE_RECTANGLE ||
+                       target == GR_GL_TEXTURE_EXTERNAL);
+
+        // a textureID of 0 is acceptable - it binds to the default texture target
+        GrTextureObj *texture = FIND(textureID, GrTextureObj, kTexture_ObjTypes);
+
+        this->setTexture(texture);
+    }
+
+    ////////////////////////////////////////////////////////////////////////////////
+    GrGLvoid bufferData(GrGLenum target, GrGLsizeiptr size, const GrGLvoid* data,
+                        GrGLenum usage) override {
+        GrAlwaysAssert(GR_GL_ARRAY_BUFFER == target ||
+                       GR_GL_ELEMENT_ARRAY_BUFFER == target);
+        GrAlwaysAssert(size >= 0);
+        GrAlwaysAssert(GR_GL_STREAM_DRAW == usage ||
+                       GR_GL_STATIC_DRAW == usage ||
+                       GR_GL_DYNAMIC_DRAW == usage);
+
+        GrBufferObj *buffer = nullptr;
+        switch (target) {
+            case GR_GL_ARRAY_BUFFER:
+                buffer = this->getArrayBuffer();
+                break;
+            case GR_GL_ELEMENT_ARRAY_BUFFER:
+                buffer = this->getElementArrayBuffer();
+                break;
+            default:
+                SkFAIL("Unexpected target to glBufferData");
+                break;
+        }
+
+        GrAlwaysAssert(buffer);
+        GrAlwaysAssert(buffer->getBound());
+
+        buffer->allocate(size, reinterpret_cast<const GrGLchar *>(data));
+        buffer->setUsage(usage);
+    }
+
+
+    GrGLvoid pixelStorei(GrGLenum pname, GrGLint param) override {
+
+        switch (pname) {
+            case GR_GL_UNPACK_ROW_LENGTH:
+                fUnpackRowLength = param;
+                break;
+            case GR_GL_PACK_ROW_LENGTH:
+                fPackRowLength = param;
+                break;
+            case GR_GL_UNPACK_ALIGNMENT:
+                break;
+            case GR_GL_PACK_ALIGNMENT:
+                fPackAlignment = param;
+                break;
+            default:
+                GrAlwaysAssert(false);
+                break;
+        }
+    }
+
+    GrGLvoid readPixels(GrGLint x,
+                        GrGLint y,
+                        GrGLsizei width,
+                        GrGLsizei height,
+                        GrGLenum format,
+                        GrGLenum type,
+                        GrGLvoid* pixels) override {
+
+        GrGLint pixelsInRow = width;
+        if (fPackRowLength > 0) {
+            pixelsInRow = fPackRowLength;
+        }
+
+        GrGLint componentsPerPixel = 0;
+
+        switch (format) {
+            case GR_GL_RGBA:
+                // fallthrough
+            case GR_GL_BGRA:
+                componentsPerPixel = 4;
+                break;
+            case GR_GL_RGB:
+                componentsPerPixel = 3;
+                break;
+            case GR_GL_RED:
+                componentsPerPixel = 1;
+                break;
+            default:
+                GrAlwaysAssert(false);
+                break;
+        }
+
+        GrGLint alignment = fPackAlignment;
+
+        GrGLint componentSize = 0;  // size (in bytes) of a single component
+
+        switch (type) {
+            case GR_GL_UNSIGNED_BYTE:
+                componentSize = 1;
+                break;
+            default:
+                GrAlwaysAssert(false);
+                break;
+        }
+
+        GrGLint rowStride = 0;  // number of components (not bytes) to skip
+        if (componentSize >= alignment) {
+            rowStride = componentsPerPixel * pixelsInRow;
+        } else {
+            float fTemp =
+                sk_float_ceil(componentSize * componentsPerPixel * pixelsInRow /
+                              static_cast<float>(alignment));
+            rowStride = static_cast<GrGLint>(alignment * fTemp / componentSize);
+        }
+
+        GrGLchar *scanline = static_cast<GrGLchar *>(pixels);
+        for (int y = 0; y < height; ++y) {
+            memset(scanline, 0, componentsPerPixel * componentSize * width);
+            scanline += rowStride;
+        }
+    }
+
+    GrGLvoid useProgram(GrGLuint programID) override {
+
+        // A programID of 0 is legal
+        GrProgramObj *program = FIND(programID, GrProgramObj, kProgram_ObjTypes);
+
+        this->useProgram(program);
+    }
+
+    GrGLvoid bindFramebuffer(GrGLenum target, GrGLuint frameBufferID) override {
+
+        GrAlwaysAssert(GR_GL_FRAMEBUFFER == target ||
+                       GR_GL_READ_FRAMEBUFFER == target ||
+                       GR_GL_DRAW_FRAMEBUFFER);
+
+        // a frameBufferID of 0 is acceptable - it binds to the default
+        // frame buffer
+        GrFrameBufferObj *frameBuffer = FIND(frameBufferID, GrFrameBufferObj,
+                                             kFrameBuffer_ObjTypes);
+
+        this->setFrameBuffer(frameBuffer);
+    }
+
+    GrGLvoid bindRenderbuffer(GrGLenum target, GrGLuint renderBufferID) override {
+
+        GrAlwaysAssert(GR_GL_RENDERBUFFER == target);
+
+        // a renderBufferID of 0 is acceptable - it unbinds the bound render buffer
+        GrRenderBufferObj *renderBuffer = FIND(renderBufferID, GrRenderBufferObj,
+                                               kRenderBuffer_ObjTypes);
+
+        this->setRenderBuffer(renderBuffer);
+    }
+
+    GrGLvoid deleteTextures(GrGLsizei n, const GrGLuint* textures) override {
+        // first potentially unbind the texture
+        for (unsigned int i = 0; i < kDefaultMaxTextureUnits; ++i) {
+            GrTextureUnitObj *pTU = this->getTextureUnit(i);
+
+            if (pTU->getTexture()) {
+                for (int j = 0; j < n; ++j) {
+
+                    if (textures[j] == pTU->getTexture()->getID()) {
+                        // this ID is the current texture - revert the binding to 0
+                        pTU->setTexture(nullptr);
+                    }
+                }
+            }
+        }
+
+        // TODO: fuse the following block with DeleteRenderBuffers?
+        // Open GL will remove a deleted render buffer from the active
+        // frame buffer but not from any other frame buffer
+        if (this->getFrameBuffer()) {
+
+            GrFrameBufferObj *frameBuffer = this->getFrameBuffer();
+
+            for (int i = 0; i < n; ++i) {
+
+                if (frameBuffer->getColor() &&
+                    textures[i] == frameBuffer->getColor()->getID()) {
+                    frameBuffer->setColor(nullptr);
+                }
+                if (frameBuffer->getDepth() &&
+                    textures[i] == frameBuffer->getDepth()->getID()) {
+                    frameBuffer->setDepth(nullptr);
+                }
+                if (frameBuffer->getStencil() &&
+                    textures[i] == frameBuffer->getStencil()->getID()) {
+                    frameBuffer->setStencil(nullptr);
+                }
+            }
+        }
+
+        // then actually "delete" the buffers
+        for (int i = 0; i < n; ++i) {
+            GrTextureObj *buffer = FIND(textures[i], GrTextureObj, kTexture_ObjTypes);
+            GrAlwaysAssert(buffer);
+
+            // OpenGL gives no guarantees if a texture is deleted while attached to
+            // something other than the currently bound frame buffer
+            GrAlwaysAssert(!buffer->getBound());
+
+            GrAlwaysAssert(!buffer->getDeleted());
+            buffer->deleteAction();
+        }
+
+    }
+
+    GrGLvoid deleteFramebuffers(GrGLsizei n, const GrGLuint *frameBuffers) override {
+
+        // first potentially unbind the buffers
+        if (this->getFrameBuffer()) {
+            for (int i = 0; i < n; ++i) {
+
+                if (frameBuffers[i] ==
+                    this->getFrameBuffer()->getID()) {
+                    // this ID is the current frame buffer - rebind to the default
+                    this->setFrameBuffer(nullptr);
+                }
+            }
+        }
+
+        // then actually "delete" the buffers
+        for (int i = 0; i < n; ++i) {
+            GrFrameBufferObj *buffer = FIND(frameBuffers[i], GrFrameBufferObj,
+                                            kFrameBuffer_ObjTypes);
+            GrAlwaysAssert(buffer);
+
+            GrAlwaysAssert(!buffer->getDeleted());
+            buffer->deleteAction();
+        }
+    }
+
+    GrGLvoid deleteRenderbuffers(GrGLsizei n,const GrGLuint *renderBuffers) override {
+
+        // first potentially unbind the buffers
+        if (this->getRenderBuffer()) {
+            for (int i = 0; i < n; ++i) {
+
+                if (renderBuffers[i] ==
+                    this->getRenderBuffer()->getID()) {
+                    // this ID is the current render buffer - make no
+                    // render buffer be bound
+                    this->setRenderBuffer(nullptr);
+                }
+            }
+        }
+
+        // TODO: fuse the following block with DeleteTextures?
+        // Open GL will remove a deleted render buffer from the active frame
+        // buffer but not from any other frame buffer
+        if (this->getFrameBuffer()) {
+
+            GrFrameBufferObj *frameBuffer = this->getFrameBuffer();
+
+            for (int i = 0; i < n; ++i) {
+
+                if (frameBuffer->getColor() &&
+                    renderBuffers[i] == frameBuffer->getColor()->getID()) {
+                    frameBuffer->setColor(nullptr);
+                }
+                if (frameBuffer->getDepth() &&
+                    renderBuffers[i] == frameBuffer->getDepth()->getID()) {
+                    frameBuffer->setDepth(nullptr);
+                }
+                if (frameBuffer->getStencil() &&
+                    renderBuffers[i] == frameBuffer->getStencil()->getID()) {
+                    frameBuffer->setStencil(nullptr);
+                }
+            }
+        }
+
+        // then actually "delete" the buffers
+        for (int i = 0; i < n; ++i) {
+            GrRenderBufferObj *buffer = FIND(renderBuffers[i], GrRenderBufferObj,
+                                             kRenderBuffer_ObjTypes);
+            GrAlwaysAssert(buffer);
+
+            // OpenGL gives no guarantees if a render buffer is deleted
+            // while attached to something other than the currently
+            // bound frame buffer
+            GrAlwaysAssert(!buffer->getColorBound());
+            GrAlwaysAssert(!buffer->getDepthBound());
+            // However, at GrContext destroy time we release all GrRsources and so stencil buffers
+            // may get deleted before FBOs that refer to them.
+            //GrAlwaysAssert(!buffer->getStencilBound());
+
+            GrAlwaysAssert(!buffer->getDeleted());
+            buffer->deleteAction();
+        }
+    }
+
+    GrGLvoid framebufferRenderbuffer(GrGLenum target,
+                                     GrGLenum attachment,
+                                     GrGLenum renderbuffertarget,
+                                     GrGLuint renderBufferID) override {
+
+        GrAlwaysAssert(GR_GL_FRAMEBUFFER == target);
+        GrAlwaysAssert(GR_GL_COLOR_ATTACHMENT0 == attachment ||
+                       GR_GL_DEPTH_ATTACHMENT == attachment ||
+                       GR_GL_STENCIL_ATTACHMENT == attachment);
+        GrAlwaysAssert(GR_GL_RENDERBUFFER == renderbuffertarget);
+
+        GrFrameBufferObj *framebuffer = this->getFrameBuffer();
+        // A render buffer cannot be attached to the default framebuffer
+        GrAlwaysAssert(framebuffer);
+
+        // a renderBufferID of 0 is acceptable - it unbinds the current
+        // render buffer
+        GrRenderBufferObj *renderbuffer = FIND(renderBufferID, GrRenderBufferObj,
+                                               kRenderBuffer_ObjTypes);
+
+        switch (attachment) {
+            case GR_GL_COLOR_ATTACHMENT0:
+                framebuffer->setColor(renderbuffer);
+                break;
+            case GR_GL_DEPTH_ATTACHMENT:
+                framebuffer->setDepth(renderbuffer);
+                break;
+            case GR_GL_STENCIL_ATTACHMENT:
+                framebuffer->setStencil(renderbuffer);
+                break;
+            default:
+                GrAlwaysAssert(false);
+                break;
+        };
+
+    }
+
+    ////////////////////////////////////////////////////////////////////////////////
+    GrGLvoid framebufferTexture2D(GrGLenum target, GrGLenum attachment, GrGLenum textarget,
+                                  GrGLuint textureID, GrGLint level) override {
+
+        GrAlwaysAssert(GR_GL_FRAMEBUFFER == target);
+        GrAlwaysAssert(GR_GL_COLOR_ATTACHMENT0 == attachment ||
+                       GR_GL_DEPTH_ATTACHMENT == attachment ||
+                       GR_GL_STENCIL_ATTACHMENT == attachment);
+        GrAlwaysAssert(GR_GL_TEXTURE_2D == textarget);
+
+        GrFrameBufferObj *framebuffer = this->getFrameBuffer();
+        // A texture cannot be attached to the default framebuffer
+        GrAlwaysAssert(framebuffer);
+
+        // A textureID of 0 is allowed - it unbinds the currently bound texture
+        GrTextureObj *texture = FIND(textureID, GrTextureObj, kTexture_ObjTypes);
+        if (texture) {
+            // The texture shouldn't be bound to a texture unit - this
+            // could lead to a feedback loop
+            GrAlwaysAssert(!texture->getBound());
+        }
+
+        GrAlwaysAssert(0 == level);
+
+        switch (attachment) {
+            case GR_GL_COLOR_ATTACHMENT0:
+                framebuffer->setColor(texture);
+                break;
+            case GR_GL_DEPTH_ATTACHMENT:
+                framebuffer->setDepth(texture);
+                break;
+            case GR_GL_STENCIL_ATTACHMENT:
+                framebuffer->setStencil(texture);
+                break;
+            default:
+                GrAlwaysAssert(false);
+                break;
+        };
+    }
+
+    GrGLuint createProgram() override {
+
+        GrProgramObj *program = CREATE(GrProgramObj, kProgram_ObjTypes);
+
+        return program->getID();
+    }
+
+    GrGLuint createShader(GrGLenum type) override {
+
+        GrAlwaysAssert(GR_GL_VERTEX_SHADER == type ||
+                       GR_GL_FRAGMENT_SHADER == type);
+
+        GrShaderObj *shader = CREATE(GrShaderObj, kShader_ObjTypes);
+        shader->setType(type);
+
+        return shader->getID();
+    }
+
+    GrGLenum checkFramebufferStatus(GrGLenum target) override { return GR_GL_FRAMEBUFFER_COMPLETE; }
+
+    GrGLvoid deleteProgram(GrGLuint programID) override {
+
+        GrProgramObj *program = FIND(programID, GrProgramObj, kProgram_ObjTypes);
+        GrAlwaysAssert(program);
+
+        if (program->getRefCount()) {
+            // someone is still using this program so we can't delete it here
+            program->setMarkedForDeletion();
+        } else {
+            program->deleteAction();
+        }
+    }
+
+    GrGLvoid deleteShader(GrGLuint shaderID) override {
+
+        GrShaderObj *shader = FIND(shaderID, GrShaderObj, kShader_ObjTypes);
+        GrAlwaysAssert(shader);
+
+        if (shader->getRefCount()) {
+            // someone is still using this shader so we can't delete it here
+            shader->setMarkedForDeletion();
+        } else {
+            shader->deleteAction();
+        }
+    }
+
+    GrGLvoid genBuffers(GrGLsizei n, GrGLuint* ids) override {
+        this->genObjs(kBuffer_ObjTypes, n, ids);
+    }
+
+    GrGLvoid genFramebuffers(GrGLsizei n, GrGLuint* ids) override {
+        this->genObjs(kFrameBuffer_ObjTypes, n, ids);
+    }
+
+    GrGLvoid genRenderbuffers(GrGLsizei n, GrGLuint* ids) override {
+        this->genObjs(kRenderBuffer_ObjTypes, n, ids);
+    }
+
+    GrGLvoid genTextures(GrGLsizei n, GrGLuint* ids) override {
+        this->genObjs(kTexture_ObjTypes, n, ids);
+    }
+
+    GrGLvoid genVertexArrays(GrGLsizei n, GrGLuint* ids) override {
+        this->genObjs(kVertexArray_ObjTypes, n, ids);
+    }
+
+    GrGLvoid genQueries(GrGLsizei n, GrGLuint *ids) override { this->genGenericIds(n, ids); }
+
+    GrGLenum getError() override { return GR_GL_NO_ERROR; }
+
+    GrGLvoid getIntegerv(GrGLenum pname, GrGLint* params) override {
+        // TODO: remove from Ganesh the #defines for gets we don't use.
+        // We would like to minimize gets overall due to performance issues
+        switch (pname) {
+            case GR_GL_CONTEXT_PROFILE_MASK:
+                *params = GR_GL_CONTEXT_COMPATIBILITY_PROFILE_BIT;
+                break;
+            case GR_GL_STENCIL_BITS:
+                *params = 8;
+                break;
+            case GR_GL_SAMPLES:
+                *params = 1;
+                break;
+            case GR_GL_FRAMEBUFFER_BINDING:
+                *params = 0;
+                break;
+            case GR_GL_VIEWPORT:
+                params[0] = 0;
+                params[1] = 0;
+                params[2] = 800;
+                params[3] = 600;
+                break;
+            case GR_GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:
+            case GR_GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS:
+            case GR_GL_MAX_TEXTURE_IMAGE_UNITS:
+            case GR_GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS:
+                *params = 8;
+                break;
+            case GR_GL_MAX_TEXTURE_COORDS:
+                *params = 8;
+                break;
+            case GR_GL_MAX_VERTEX_UNIFORM_VECTORS:
+                *params = kDefaultMaxVertexUniformVectors;
+                break;
+            case GR_GL_MAX_FRAGMENT_UNIFORM_VECTORS:
+                *params = kDefaultMaxFragmentUniformVectors;
+                break;
+            case GR_GL_MAX_FRAGMENT_UNIFORM_COMPONENTS:
+                *params = 16 * 4;
+                break;
+            case GR_GL_NUM_COMPRESSED_TEXTURE_FORMATS:
+                *params = 0;
+                break;
+            case GR_GL_COMPRESSED_TEXTURE_FORMATS:
+                break;
+            case GR_GL_MAX_TEXTURE_SIZE:
+                *params = 8192;
+                break;
+            case GR_GL_MAX_RENDERBUFFER_SIZE:
+                *params = 8192;
+                break;
+            case GR_GL_MAX_SAMPLES:
+                *params = 32;
+                break;
+            case GR_GL_MAX_VERTEX_ATTRIBS:
+                *params = kDefaultMaxVertexAttribs;
+                break;
+            case GR_GL_MAX_VARYING_VECTORS:
+                *params = kDefaultMaxVaryingVectors;
+                break;
+            case GR_GL_NUM_EXTENSIONS: {
+                GrGLint i = 0;
+                while (kExtensions[i++]);
+                *params = i;
+                break;
+            }
+            default:
+                SkFAIL("Unexpected pname to GetIntegerv");
+        }
+    }
+
+    GrGLvoid getMultisamplefv(GrGLenum pname, GrGLuint index, GrGLfloat* val) override {
+        val[0] = val[1] = 0.5f;
+    }
+
+    GrGLvoid getProgramiv(GrGLuint program, GrGLenum pname, GrGLint* params) override {
+        this->getShaderOrProgramiv(program, pname, params);
+    }
+
+    GrGLvoid getProgramInfoLog(GrGLuint program, GrGLsizei bufsize, GrGLsizei* length,
+                               char* infolog) override {
+        this->getInfoLog(program, bufsize, length, infolog);
+    }
+
+    GrGLvoid getQueryiv(GrGLenum GLtarget, GrGLenum pname, GrGLint *params) override {
+        switch (pname) {
+            case GR_GL_CURRENT_QUERY:
+                *params = 0;
+                break;
+            case GR_GL_QUERY_COUNTER_BITS:
+                *params = 32;
+                break;
+            default:
+                SkFAIL("Unexpected pname passed GetQueryiv.");
+        }
+    }
+
+    GrGLvoid getQueryObjecti64v(GrGLuint id, GrGLenum pname, GrGLint64 *params) override {
+        this->queryResult(id, pname, params);
+    }
+
+    GrGLvoid getQueryObjectiv(GrGLuint id, GrGLenum pname, GrGLint *params) override {
+        this->queryResult(id, pname, params);
+    }
+
+    GrGLvoid getQueryObjectui64v(GrGLuint id, GrGLenum pname, GrGLuint64 *params) override {
+        this->queryResult(id, pname, params);
+    }
+
+    GrGLvoid getQueryObjectuiv(GrGLuint id, GrGLenum pname, GrGLuint *params) override {
+        this->queryResult(id, pname, params);
+    }
+
+    GrGLvoid getShaderiv(GrGLuint shader, GrGLenum pname, GrGLint* params) override {
+        this->getShaderOrProgramiv(shader, pname, params);
+    }
+
+    GrGLvoid getShaderInfoLog(GrGLuint shader, GrGLsizei bufsize, GrGLsizei* length,
+                              char* infolog) override {
+        this->getInfoLog(shader, bufsize, length, infolog);
+    }
+
+    const GrGLubyte* getString(GrGLenum name) override {
+        switch (name) {
+            case GR_GL_EXTENSIONS:
+                return CombinedExtensionString();
+            case GR_GL_VERSION:
+                return (const GrGLubyte*)"4.0 Debug GL";
+            case GR_GL_SHADING_LANGUAGE_VERSION:
+                return (const GrGLubyte*)"4.20.8 Debug GLSL";
+            case GR_GL_VENDOR:
+                return (const GrGLubyte*)"Debug Vendor";
+            case GR_GL_RENDERER:
+                return (const GrGLubyte*)"The Debug (Non-)Renderer";
+            default:
+                SkFAIL("Unexpected name passed to GetString");
+                return nullptr;
+        }
+    }
+
+    const GrGLubyte* getStringi(GrGLenum name, GrGLuint i) override {
+        switch (name) {
+            case GR_GL_EXTENSIONS: {
+                GrGLint count;
+                this->getIntegerv(GR_GL_NUM_EXTENSIONS, &count);
+                if ((GrGLint)i <= count) {
+                    return (const GrGLubyte*) kExtensions[i];
+                } else {
+                    return nullptr;
+                }
+            }
+            default:
+                SkFAIL("Unexpected name passed to GetStringi");
+                return nullptr;
+        }
+    }
+
+    GrGLvoid getTexLevelParameteriv(GrGLenum target, GrGLint level, GrGLenum pname,
+                                    GrGLint* params) override {
+        // we used to use this to query stuff about externally created textures,
+        // now we just require clients to tell us everything about the texture.
+        SkFAIL("Should never query texture parameters.");
+    }
+
+    GrGLvoid deleteVertexArrays(GrGLsizei n, const GrGLuint* ids) override {
+        for (GrGLsizei i = 0; i < n; ++i) {
+            GrVertexArrayObj* array = FIND(ids[i], GrVertexArrayObj, kVertexArray_ObjTypes);
+            GrAlwaysAssert(array);
+
+            // Deleting the current vertex array binds object 0
+            if (this->getVertexArray() == array) {
+                this->setVertexArray(nullptr);
+            }
+
+            if (array->getRefCount()) {
+                // someone is still using this vertex array so we can't delete it here
+                array->setMarkedForDeletion();
+            } else {
+                array->deleteAction();
+            }
+        }
+    }
+
+    GrGLvoid bindVertexArray(GrGLuint id) override {
+        GrVertexArrayObj* array = FIND(id, GrVertexArrayObj, kVertexArray_ObjTypes);
+        GrAlwaysAssert((0 == id) || array);
+        this->setVertexArray(array);
+    }
+
+    GrGLvoid bindBuffer(GrGLenum target, GrGLuint bufferID) override {
+        GrAlwaysAssert(GR_GL_ARRAY_BUFFER == target || GR_GL_ELEMENT_ARRAY_BUFFER == target);
+
+        GrBufferObj *buffer = FIND(bufferID, GrBufferObj, kBuffer_ObjTypes);
+        // 0 is a permissible bufferID - it unbinds the current buffer
+
+        switch (target) {
+            case GR_GL_ARRAY_BUFFER:
+                this->setArrayBuffer(buffer);
+                break;
+            case GR_GL_ELEMENT_ARRAY_BUFFER:
+                this->setElementArrayBuffer(buffer);
+                break;
+            default:
+                SkFAIL("Unexpected target to glBindBuffer");
+                break;
+        }
+    }
+
+    // deleting a bound buffer has the side effect of binding 0
+    GrGLvoid deleteBuffers(GrGLsizei n, const GrGLuint* ids) override {
+        // first potentially unbind the buffers
+        for (int i = 0; i < n; ++i) {
+
+            if (this->getArrayBuffer() &&
+                ids[i] == this->getArrayBuffer()->getID()) {
+                // this ID is the current array buffer
+                this->setArrayBuffer(nullptr);
+            }
+            if (this->getElementArrayBuffer() &&
+                ids[i] == this->getElementArrayBuffer()->getID()) {
+                // this ID is the current element array buffer
+                this->setElementArrayBuffer(nullptr);
+            }
+        }
+
+        // then actually "delete" the buffers
+        for (int i = 0; i < n; ++i) {
+            GrBufferObj *buffer = FIND(ids[i], GrBufferObj, kBuffer_ObjTypes);
+            GrAlwaysAssert(buffer);
+
+            GrAlwaysAssert(!buffer->getDeleted());
+            buffer->deleteAction();
+        }
+    }
+
+    // map a buffer to the caller's address space
+    GrGLvoid* mapBufferRange(GrGLenum target, GrGLintptr offset, GrGLsizeiptr length,
+                             GrGLbitfield access) override {
+        GrAlwaysAssert(GR_GL_ARRAY_BUFFER == target ||
+                       GR_GL_ELEMENT_ARRAY_BUFFER == target);
+
+        // We only expect read access and we expect that the buffer or range is always invalidated.
+        GrAlwaysAssert(!SkToBool(GR_GL_MAP_READ_BIT & access));
+        GrAlwaysAssert((GR_GL_MAP_INVALIDATE_BUFFER_BIT | GR_GL_MAP_INVALIDATE_RANGE_BIT) & access);
+
+        GrBufferObj *buffer = nullptr;
+        switch (target) {
+            case GR_GL_ARRAY_BUFFER:
+                buffer = this->getArrayBuffer();
+                break;
+            case GR_GL_ELEMENT_ARRAY_BUFFER:
+                buffer = this->getElementArrayBuffer();
+                break;
+            default:
+                SkFAIL("Unexpected target to glMapBufferRange");
+                break;
+        }
+
+        if (buffer) {
+            GrAlwaysAssert(offset >= 0 && offset + length <= buffer->getSize());
+            GrAlwaysAssert(!buffer->getMapped());
+            buffer->setMapped(offset, length);
+            return buffer->getDataPtr() + offset;
+        }
+
+        GrAlwaysAssert(false);
+        return nullptr;        // no buffer bound to the target
+    }
+
+    GrGLvoid* mapBuffer(GrGLenum target, GrGLenum access) override {
+        GrAlwaysAssert(GR_GL_WRITE_ONLY == access);
+
+        GrBufferObj *buffer = nullptr;
+        switch (target) {
+            case GR_GL_ARRAY_BUFFER:
+                buffer = this->getArrayBuffer();
+                break;
+            case GR_GL_ELEMENT_ARRAY_BUFFER:
+                buffer = this->getElementArrayBuffer();
+                break;
+            default:
+                SkFAIL("Unexpected target to glMapBuffer");
+                break;
+        }
+
+        return this->mapBufferRange(target, 0, buffer->getSize(),
+                                    GR_GL_MAP_WRITE_BIT | GR_GL_MAP_INVALIDATE_BUFFER_BIT);
+    }
+
+    // remove a buffer from the caller's address space
+    // TODO: check if the "access" method from "glMapBuffer" was honored
+    GrGLboolean unmapBuffer(GrGLenum target) override {
+        GrAlwaysAssert(GR_GL_ARRAY_BUFFER == target ||
+                       GR_GL_ELEMENT_ARRAY_BUFFER == target);
+
+        GrBufferObj *buffer = nullptr;
+        switch (target) {
+            case GR_GL_ARRAY_BUFFER:
+                buffer = this->getArrayBuffer();
+                break;
+            case GR_GL_ELEMENT_ARRAY_BUFFER:
+                buffer = this->getElementArrayBuffer();
+                break;
+            default:
+                SkFAIL("Unexpected target to glUnmapBuffer");
+                break;
+        }
+
+        if (buffer) {
+            GrAlwaysAssert(buffer->getMapped());
+            buffer->resetMapped();
+            return GR_GL_TRUE;
+        }
+
+        GrAlwaysAssert(false);
+        return GR_GL_FALSE; // GR_GL_INVALID_OPERATION;
+    }
+
+    GrGLvoid flushMappedBufferRange(GrGLenum target, GrGLintptr offset,
+                                    GrGLsizeiptr length) override {
+        GrAlwaysAssert(GR_GL_ARRAY_BUFFER == target ||
+                       GR_GL_ELEMENT_ARRAY_BUFFER == target);
+
+        GrBufferObj *buffer = nullptr;
+        switch (target) {
+            case GR_GL_ARRAY_BUFFER:
+                buffer = this->getArrayBuffer();
+                break;
+            case GR_GL_ELEMENT_ARRAY_BUFFER:
+                buffer = this->getElementArrayBuffer();
+                break;
+            default:
+                SkFAIL("Unexpected target to glUnmapBuffer");
+                break;
+        }
+
+        if (buffer) {
+            GrAlwaysAssert(buffer->getMapped());
+            GrAlwaysAssert(offset >= 0 && (offset + length) <= buffer->getMappedLength());
+        } else {
+            GrAlwaysAssert(false);
+        }
+    }
+
+    GrGLvoid getBufferParameteriv(GrGLenum target, GrGLenum value, GrGLint* params) override {
+
+        GrAlwaysAssert(GR_GL_ARRAY_BUFFER == target ||
+                       GR_GL_ELEMENT_ARRAY_BUFFER == target);
+        GrAlwaysAssert(GR_GL_BUFFER_SIZE == value ||
+                       GR_GL_BUFFER_USAGE == value);
+
+        GrBufferObj *buffer = nullptr;
+        switch (target) {
+            case GR_GL_ARRAY_BUFFER:
+                buffer = this->getArrayBuffer();
+                break;
+            case GR_GL_ELEMENT_ARRAY_BUFFER:
+                buffer = this->getElementArrayBuffer();
+                break;
+        }
+
+        GrAlwaysAssert(buffer);
+
+        switch (value) {
+            case GR_GL_BUFFER_MAPPED:
+                *params = GR_GL_FALSE;
+                if (buffer)
+                    *params = buffer->getMapped() ? GR_GL_TRUE : GR_GL_FALSE;
+                break;
+            case GR_GL_BUFFER_SIZE:
+                *params = 0;
+                if (buffer)
+                    *params = SkToInt(buffer->getSize());
+                break;
+            case GR_GL_BUFFER_USAGE:
+                *params = GR_GL_STATIC_DRAW;
+                if (buffer)
+                    *params = buffer->getUsage();
+                break;
+            default:
+                SkFAIL("Unexpected value to glGetBufferParamateriv");
+                break;
+        }
+    }
+
+private:
+    // the OpenGLES 2.0 spec says this must be >= 128
+    static const GrGLint kDefaultMaxVertexUniformVectors = 128;
+
+    // the OpenGLES 2.0 spec says this must be >=16
+    static const GrGLint kDefaultMaxFragmentUniformVectors = 16;
+
+    // the OpenGLES 2.0 spec says this must be >= 8
+    static const GrGLint kDefaultMaxVertexAttribs = 8;
+
+    // the OpenGLES 2.0 spec says this must be >= 8
+    static const GrGLint kDefaultMaxVaryingVectors = 8;
+
+    // the OpenGLES 2.0 spec says this must be >= 2
+    static const GrGLint kDefaultMaxTextureUnits = 8;
+
+    static const char* kExtensions[];
+
+    GrGLuint                    fCurrGenericID;
+    GrGLuint                    fCurrTextureUnit;
+    GrTextureUnitObj*           fTextureUnits[kDefaultMaxTextureUnits];
+    GrBufferObj*                fArrayBuffer;
+    GrBufferObj*                fElementArrayBuffer;
+    GrVertexArrayObj*           fVertexArray;
+    GrGLint                     fPackRowLength;
+    GrGLint                     fUnpackRowLength;
+    GrGLint                     fPackAlignment;
+    GrFrameBufferObj*           fFrameBuffer;
+    GrRenderBufferObj*          fRenderBuffer;
+    GrProgramObj*               fProgram;
+    mutable bool                fAbandoned;
+    // global store of all objects
+    SkTArray<GrFakeRefObj *>    fObjects;
+
+    static const GrGLubyte* CombinedExtensionString() {
+        static SkString gExtString;
+        static SkMutex gMutex;
+        gMutex.acquire();
+        if (0 == gExtString.size()) {
+            int i = 0;
+            while (kExtensions[i]) {
+                if (i > 0) {
+                    gExtString.append(" ");
+                }
+                gExtString.append(kExtensions[i]);
+                ++i;
+            }
+        }
+        gMutex.release();
+        return (const GrGLubyte*) gExtString.c_str();
+    }
+
+    GrGLvoid genGenericIds(GrGLsizei n, GrGLuint* ids) {
+        for (int i = 0; i < n; ++i) {
+            ids[i] = ++fCurrGenericID;
+        }
+    }
+
+    GrGLvoid getInfoLog(GrGLuint object, GrGLsizei bufsize, GrGLsizei* length,
+                        char* infolog) {
+        if (length) {
+            *length = 0;
+        }
+        if (bufsize > 0) {
+            *infolog = 0;
+        }
+    }
+
+    GrGLvoid getShaderOrProgramiv(GrGLuint object,  GrGLenum pname, GrGLint* params) {
+        switch (pname) {
+            case GR_GL_LINK_STATUS:  // fallthru
+            case GR_GL_COMPILE_STATUS:
+                *params = GR_GL_TRUE;
+                break;
+            case GR_GL_INFO_LOG_LENGTH:
+                *params = 0;
+                break;
+                // we don't expect any other pnames
+            default:
+                SkFAIL("Unexpected pname to GetProgramiv");
+                break;
+        }
+    }
+
+    template <typename T>
+    void queryResult(GrGLenum GLtarget, GrGLenum pname, T *params) {
+        switch (pname) {
+            case GR_GL_QUERY_RESULT_AVAILABLE:
+                *params = GR_GL_TRUE;
+                break;
+            case GR_GL_QUERY_RESULT:
+                *params = 0;
+                break;
+            default:
+                SkFAIL("Unexpected pname passed to GetQueryObject.");
+                break;
+        }
+    }
+
+    enum ObjTypes {
+        kTexture_ObjTypes = 0,
+        kBuffer_ObjTypes,
+        kRenderBuffer_ObjTypes,
+        kFrameBuffer_ObjTypes,
+        kShader_ObjTypes,
+        kProgram_ObjTypes,
+        kTextureUnit_ObjTypes,
+        kVertexArray_ObjTypes,
+        kObjTypeCount
+    };
+
+    typedef GrFakeRefObj *(*Create)();
+
+    static Create gFactoryFunc[kObjTypeCount];
+
+    GrGLvoid genObjs(ObjTypes type, GrGLsizei n, GrGLuint* ids) {
+        for (int i = 0; i < n; ++i) {
+            GrAlwaysAssert(ids[i] == 0);
+            GrFakeRefObj *obj = this->createObj(type);
+            GrAlwaysAssert(obj);
+            ids[i] = obj->getID();
+        }
+    }
+
+    GrFakeRefObj* createObj(ObjTypes type) {
+        GrFakeRefObj *temp = (*gFactoryFunc[type])();
+
+        fObjects.push_back(temp);
+
+        return temp;
+    }
+
+    GrFakeRefObj* findObject(GrGLuint ID, ObjTypes type) {
+        for (int i = 0; i < fObjects.count(); ++i) {
+            if (fObjects[i]->getID() == ID) { // && fObjects[i]->getType() == type) {
+                // The application shouldn't be accessing objects
+                // that (as far as OpenGL knows) were already deleted
+                GrAlwaysAssert(!fObjects[i]->getDeleted());
+                GrAlwaysAssert(!fObjects[i]->getMarkedForDeletion());
+                return fObjects[i];
+            }
+        }
+        return nullptr;
+    }
+
+    GrTextureUnitObj* getTextureUnit(int unit) {
+        GrAlwaysAssert(0 <= unit && kDefaultMaxTextureUnits > unit);
+
+        return fTextureUnits[unit];
+    }
+
+    void setArrayBuffer(GrBufferObj *arrayBuffer) {
+        if (fArrayBuffer) {
+            // automatically break the binding of the old buffer
+            GrAlwaysAssert(fArrayBuffer->getBound());
+            fArrayBuffer->resetBound();
+
+            GrAlwaysAssert(!fArrayBuffer->getDeleted());
+            fArrayBuffer->unref();
+        }
+
+        fArrayBuffer = arrayBuffer;
+
+        if (fArrayBuffer) {
+            GrAlwaysAssert(!fArrayBuffer->getDeleted());
+            fArrayBuffer->ref();
+
+            GrAlwaysAssert(!fArrayBuffer->getBound());
+            fArrayBuffer->setBound();
+        }
+    }
+
+    GrBufferObj* getArrayBuffer() { return fArrayBuffer; }
+    void setElementArrayBuffer(GrBufferObj *elementArrayBuffer) {
+        if (fElementArrayBuffer) {
+            // automatically break the binding of the old buffer
+            GrAlwaysAssert(fElementArrayBuffer->getBound());
+            fElementArrayBuffer->resetBound();
+
+            GrAlwaysAssert(!fElementArrayBuffer->getDeleted());
+            fElementArrayBuffer->unref();
+        }
+
+        fElementArrayBuffer = elementArrayBuffer;
+
+        if (fElementArrayBuffer) {
+            GrAlwaysAssert(!fElementArrayBuffer->getDeleted());
+            fElementArrayBuffer->ref();
+
+            GrAlwaysAssert(!fElementArrayBuffer->getBound());
+            fElementArrayBuffer->setBound();
+        }
+    }
+
+    GrBufferObj *getElementArrayBuffer() { return fElementArrayBuffer; }
+
+    void setVertexArray(GrVertexArrayObj* vertexArray) {
+        if (vertexArray) {
+            SkASSERT(!vertexArray->getDeleted());
+        }
+        SkRefCnt_SafeAssign(fVertexArray, vertexArray);
+    }
+
+    GrVertexArrayObj* getVertexArray() { return fVertexArray; }
+
+    void setTexture(GrTextureObj *texture) {
+        fTextureUnits[fCurrTextureUnit]->setTexture(texture);
+    }
+
+    void setFrameBuffer(GrFrameBufferObj *frameBuffer) {
+        if (fFrameBuffer) {
+            GrAlwaysAssert(fFrameBuffer->getBound());
+            fFrameBuffer->resetBound();
+
+            GrAlwaysAssert(!fFrameBuffer->getDeleted());
+            fFrameBuffer->unref();
+        }
+
+        fFrameBuffer = frameBuffer;
+
+        if (fFrameBuffer) {
+            GrAlwaysAssert(!fFrameBuffer->getDeleted());
+            fFrameBuffer->ref();
+
+            GrAlwaysAssert(!fFrameBuffer->getBound());
+            fFrameBuffer->setBound();
+        }
+    }
+
+    GrFrameBufferObj *getFrameBuffer() { return fFrameBuffer; }
+
+    void setRenderBuffer(GrRenderBufferObj *renderBuffer) {
+        if (fRenderBuffer) {
+            GrAlwaysAssert(fRenderBuffer->getBound());
+            fRenderBuffer->resetBound();
+
+            GrAlwaysAssert(!fRenderBuffer->getDeleted());
+            fRenderBuffer->unref();
+        }
+
+        fRenderBuffer = renderBuffer;
+
+        if (fRenderBuffer) {
+            GrAlwaysAssert(!fRenderBuffer->getDeleted());
+            fRenderBuffer->ref();
+
+            GrAlwaysAssert(!fRenderBuffer->getBound());
+            fRenderBuffer->setBound();
+        }
+    }
+    GrRenderBufferObj *getRenderBuffer() { return fRenderBuffer; }
+
+    void useProgram(GrProgramObj *program) {
+        if (fProgram) {
+            GrAlwaysAssert(fProgram->getInUse());
+            fProgram->resetInUse();
+
+            GrAlwaysAssert(!fProgram->getDeleted());
+            fProgram->unref();
+        }
+
+        fProgram = program;
+
+        if (fProgram) {
+            GrAlwaysAssert(!fProgram->getDeleted());
+            fProgram->ref();
+
+            GrAlwaysAssert(!fProgram->getInUse());
+            fProgram->setInUse();
+        }
+    }
+
+    void report() const {
+        for (int i = 0; i < fObjects.count(); ++i) {
+            if (!fAbandoned) {
+                GrAlwaysAssert(0 == fObjects[i]->getRefCount());
+                GrAlwaysAssert(fObjects[i]->getDeleted());
+            }
+        }
+    }
+
+    typedef GrGLTestInterface INHERITED;
+};
+
+#undef CREATE
+#undef FIND
+
+DebugInterface::Create DebugInterface::gFactoryFunc[kObjTypeCount] = {
+    GrTextureObj::createGrTextureObj,
+    GrBufferObj::createGrBufferObj,
+    GrRenderBufferObj::createGrRenderBufferObj,
+    GrFrameBufferObj::createGrFrameBufferObj,
+    GrShaderObj::createGrShaderObj,
+    GrProgramObj::createGrProgramObj,
+    GrTextureUnitObj::createGrTextureUnitObj,
+    GrVertexArrayObj::createGrVertexArrayObj,
+};
+
+const char* DebugInterface::kExtensions[] = {
+    "GL_ARB_framebuffer_object",
+    "GL_ARB_blend_func_extended",
+    "GL_ARB_timer_query",
+    "GL_ARB_draw_buffers",
+    "GL_ARB_occlusion_query",
+    "GL_EXT_stencil_wrap",
+    nullptr, // signifies the end of the array.
+};
+
+class DebugGLContext : public sk_gpu_test::GLContext {
+public:
+   DebugGLContext() {
+       this->init(new DebugInterface());
+   }
+
+   ~DebugGLContext() override { this->teardown(); }
+
+private:
+    void onPlatformMakeCurrent() const override {}
+    void onPlatformSwapBuffers() const override {}
+    GrGLFuncPtr onPlatformGetProcAddress(const char*) const override { return nullptr; }
+};
+}  // anonymous namespace
+
+namespace sk_gpu_test {
+GLContext* CreateDebugGLContext() {
+    GLContext* ctx = new DebugGLContext();
+    if (ctx->isValid()) {
+        return ctx;
+    }
+    delete ctx;
+    return nullptr;
+}
+}
diff --git a/tools/gpu/gl/debug/DebugGLContext.h b/tools/gpu/gl/debug/DebugGLContext.h
new file mode 100644
index 0000000..0ac505b
--- /dev/null
+++ b/tools/gpu/gl/debug/DebugGLContext.h
@@ -0,0 +1,17 @@
+
+/*
+ * Copyright 2012 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+#ifndef DebugGLContext_DEFINED
+#define DebugGLContext_DEFINED
+
+#include "gl/GLContext.h"
+
+namespace sk_gpu_test {
+GLContext* CreateDebugGLContext();
+}  // namespace sk_gpu_test
+
+#endif
diff --git a/tools/gpu/gl/debug/GrBufferObj.cpp b/tools/gpu/gl/debug/GrBufferObj.cpp
new file mode 100644
index 0000000..37d4438
--- /dev/null
+++ b/tools/gpu/gl/debug/GrBufferObj.cpp
@@ -0,0 +1,31 @@
+
+/*
+ * Copyright 2012 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "GrBufferObj.h"
+
+void GrBufferObj::allocate(GrGLsizeiptr size, const GrGLchar *dataPtr) {
+    GrAlwaysAssert(size >= 0);
+
+    // delete pre-existing data
+    delete[] fDataPtr;
+
+    fSize = size;
+    fDataPtr = new GrGLchar[size];
+    if (dataPtr) {
+        memcpy(fDataPtr, dataPtr, fSize);
+    }
+    // TODO: w/ no dataPtr the data is unitialized - this could be tracked
+}
+
+void GrBufferObj::deleteAction() {
+
+    // buffers are automatically unmapped when deleted
+    this->resetMapped();
+
+    this->INHERITED::deleteAction();
+}
diff --git a/tools/gpu/gl/debug/GrBufferObj.h b/tools/gpu/gl/debug/GrBufferObj.h
new file mode 100644
index 0000000..96aef6e
--- /dev/null
+++ b/tools/gpu/gl/debug/GrBufferObj.h
@@ -0,0 +1,76 @@
+
+/*
+ * Copyright 2012 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef GrBufferObj_DEFINED
+#define GrBufferObj_DEFINED
+
+#include "GrFakeRefObj.h"
+#include "gl/GrGLDefines.h"
+
+////////////////////////////////////////////////////////////////////////////////
+class GrBufferObj : public GrFakeRefObj {
+    GR_DEFINE_CREATOR(GrBufferObj);
+
+public:
+    GrBufferObj()
+        : GrFakeRefObj()
+        , fDataPtr(nullptr)
+        , fMapped(false)
+        , fBound(false)
+        , fSize(0)
+        , fUsage(GR_GL_STATIC_DRAW) {
+    }
+    virtual ~GrBufferObj() {
+        delete[] fDataPtr;
+    }
+
+    void access() {
+        // cannot access the buffer if it is currently mapped
+        GrAlwaysAssert(!fMapped);
+    }
+
+    void setMapped(GrGLintptr offset, GrGLsizeiptr length) {
+        fMapped = true;
+        fMappedOffset = offset;
+        fMappedLength = length;
+    }
+    void resetMapped()           { fMapped = false; }
+    bool getMapped() const       { return fMapped; }
+    GrGLintptr getMappedOffset() const { return fMappedOffset; }
+    GrGLsizeiptr getMappedLength() const { return fMappedLength; }
+
+    void setBound()              { fBound = true; }
+    void resetBound()            { fBound = false; }
+    bool getBound() const        { return fBound; }
+
+    void allocate(GrGLsizeiptr size, const GrGLchar *dataPtr);
+    GrGLsizeiptr getSize() const { return fSize; }
+    GrGLchar *getDataPtr()       { return fDataPtr; }
+
+    void setUsage(GrGLint usage) { fUsage = usage; }
+    GrGLint getUsage() const     { return fUsage; }
+
+    void deleteAction() override;
+
+protected:
+private:
+
+    GrGLchar*    fDataPtr;
+    bool         fMapped;       // is the buffer object mapped via "glMapBuffer[Range]"?
+    GrGLintptr   fMappedOffset; // the offset of the buffer range that is mapped
+    GrGLsizeiptr fMappedLength; // the size of the buffer range that is mapped
+    bool         fBound;        // is the buffer object bound via "glBindBuffer"?
+    GrGLsizeiptr fSize;         // size in bytes
+    GrGLint      fUsage;        // one of: GL_STREAM_DRAW,
+                                //         GL_STATIC_DRAW,
+                                //         GL_DYNAMIC_DRAW
+
+    typedef GrFakeRefObj INHERITED;
+};
+
+#endif // GrBufferObj_DEFINED
diff --git a/tools/gpu/gl/debug/GrFBBindableObj.h b/tools/gpu/gl/debug/GrFBBindableObj.h
new file mode 100644
index 0000000..e2b43a6
--- /dev/null
+++ b/tools/gpu/gl/debug/GrFBBindableObj.h
@@ -0,0 +1,88 @@
+
+/*
+ * Copyright 2012 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef GrFBBindableObj_DEFINED
+#define GrFBBindableObj_DEFINED
+
+#include "SkTDArray.h"
+#include "GrFakeRefObj.h"
+
+////////////////////////////////////////////////////////////////////////////////
+// A common base class for render buffers and textures
+class GrFBBindableObj : public GrFakeRefObj {
+
+public:
+    GrFBBindableObj()
+        : GrFakeRefObj() {
+    }
+
+    virtual ~GrFBBindableObj() {
+        GrAlwaysAssert(0 == fColorReferees.count());
+        GrAlwaysAssert(0 == fDepthReferees.count());
+        GrAlwaysAssert(0 == fStencilReferees.count());
+    }
+
+    void setColorBound(GrFakeRefObj *referee) {
+        fColorReferees.append(1, &referee);
+    }
+    void resetColorBound(GrFakeRefObj *referee) {
+        int index = fColorReferees.find(referee);
+        GrAlwaysAssert(0 <= index);
+        fColorReferees.removeShuffle(index);
+    }
+    bool getColorBound(GrFakeRefObj *referee) const {
+        int index = fColorReferees.find(referee);
+        return 0 <= index;
+    }
+    bool getColorBound() const {
+        return 0 != fColorReferees.count();
+    }
+
+    void setDepthBound(GrFakeRefObj *referee) {
+        fDepthReferees.append(1, &referee);
+    }
+    void resetDepthBound(GrFakeRefObj *referee) {
+        int index = fDepthReferees.find(referee);
+        GrAlwaysAssert(0 <= index);
+        fDepthReferees.removeShuffle(index);
+    }
+    bool getDepthBound(GrFakeRefObj *referee) const {
+        int index = fDepthReferees.find(referee);
+        return 0 <= index;
+    }
+    bool getDepthBound() const {
+        return 0 != fDepthReferees.count();
+    }
+
+    void setStencilBound(GrFakeRefObj *referee) {
+        fStencilReferees.append(1, &referee);
+    }
+    void resetStencilBound(GrFakeRefObj *referee) {
+        int index = fStencilReferees.find(referee);
+        GrAlwaysAssert(0 <= index);
+        fStencilReferees.removeShuffle(index);
+    }
+    bool getStencilBound(GrFakeRefObj *referee) const {
+        int index = fStencilReferees.find(referee);
+        return 0 <= index;
+    }
+    bool getStencilBound() const {
+        return 0 != fStencilReferees.count();
+    }
+
+
+protected:
+private:
+    SkTDArray<GrFakeRefObj *> fColorReferees;   // frame buffers that use this as a color buffer (via "glFramebufferRenderbuffer" or "glFramebufferTexture2D")
+    SkTDArray<GrFakeRefObj *> fDepthReferees;   // frame buffers that use this as a depth buffer (via "glFramebufferRenderbuffer" or "glFramebufferTexture2D")
+    SkTDArray<GrFakeRefObj *> fStencilReferees; // frame buffers that use this as a stencil buffer (via "glFramebufferRenderbuffer" or "glFramebufferTexture2D")
+
+    typedef GrFakeRefObj INHERITED;
+};
+
+#endif // GrFBBindableObj_DEFINED
diff --git a/tools/gpu/gl/debug/GrFakeRefObj.h b/tools/gpu/gl/debug/GrFakeRefObj.h
new file mode 100644
index 0000000..3058051
--- /dev/null
+++ b/tools/gpu/gl/debug/GrFakeRefObj.h
@@ -0,0 +1,86 @@
+/*
+ * Copyright 2012 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef GrFakeRefObj_DEFINED
+#define GrFakeRefObj_DEFINED
+
+#include "SkTypes.h"
+#include "gl/GrGLInterface.h"
+
+////////////////////////////////////////////////////////////////////////////////
+// This object is used to track the OpenGL objects. We don't use real
+// reference counting (i.e., we don't free the objects when their ref count
+// goes to 0) so that we can detect invalid memory accesses. The refs we
+// are tracking in this class are actually OpenGL's references to the objects
+// not "ours"
+// Each object also gets a unique globally identifying ID
+class GrFakeRefObj : SkNoncopyable {
+public:
+    GrFakeRefObj()
+        : fRef(0)
+        , fMarkedForDeletion(false)
+        , fDeleted(false) {
+
+        // source for globally unique IDs - 0 is reserved!
+        static int fNextID = 0;
+
+        fID = ++fNextID;
+    }
+    virtual ~GrFakeRefObj() {};
+
+    void ref() {
+        fRef++;
+    }
+    void unref() {
+        fRef--;
+        GrAlwaysAssert(fRef >= 0);
+
+        // often in OpenGL a given object may still be in use when the
+        // delete call is made. In these cases the object is marked
+        // for deletion and then freed when it is no longer in use
+        if (0 == fRef && fMarkedForDeletion) {
+            this->deleteAction();
+        }
+    }
+    int getRefCount() const             { return fRef; }
+
+    GrGLuint getID() const              { return fID; }
+
+    void setMarkedForDeletion()         { fMarkedForDeletion = true; }
+    bool getMarkedForDeletion() const   { return fMarkedForDeletion; }
+
+    bool getDeleted() const             { return fDeleted; }
+
+    // The deleteAction fires if the object has been marked for deletion but
+    // couldn't be deleted earlier due to refs
+    virtual void deleteAction() {
+        this->setDeleted();
+    }
+
+protected:
+private:
+    int         fRef;               // ref count
+    GrGLuint    fID;                // globally unique ID
+    bool        fMarkedForDeletion;
+    // The deleted flag is only set when OpenGL thinks the object is deleted
+    // It is obviously still allocated w/in this framework
+    bool        fDeleted;
+
+    // setDeleted should only ever appear in the deleteAction method!
+    void setDeleted()                   { fDeleted = true; }
+};
+
+////////////////////////////////////////////////////////////////////////////////
+// Each class derived from GrFakeRefObj should use this macro to add a
+// factory creation entry point. This entry point is used by the GrGLDebug
+// object to instantiate the various objects
+// all globally unique IDs
+#define GR_DEFINE_CREATOR(className) \
+public:                              \
+    static GrFakeRefObj *create##className() { return new className; }
+
+#endif // GrFakeRefObj_DEFINED
diff --git a/tools/gpu/gl/debug/GrFrameBufferObj.cpp b/tools/gpu/gl/debug/GrFrameBufferObj.cpp
new file mode 100644
index 0000000..7dc12ac
--- /dev/null
+++ b/tools/gpu/gl/debug/GrFrameBufferObj.cpp
@@ -0,0 +1,67 @@
+
+/*
+ * Copyright 2012 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "GrFrameBufferObj.h"
+#include "GrFBBindableObj.h"
+
+void GrFrameBufferObj::setColor(GrFBBindableObj *buffer) {
+    if (fColorBuffer) {
+        // automatically break the binding of the old buffer
+        GrAlwaysAssert(fColorBuffer->getColorBound(this));
+        fColorBuffer->resetColorBound(this);
+
+        GrAlwaysAssert(!fColorBuffer->getDeleted());
+        fColorBuffer->unref();
+    }
+    fColorBuffer = buffer;
+    if (fColorBuffer) {
+        GrAlwaysAssert(!fColorBuffer->getDeleted());
+        fColorBuffer->ref();
+
+        GrAlwaysAssert(!fColorBuffer->getColorBound(this));
+        fColorBuffer->setColorBound(this);
+    }
+}
+
+void GrFrameBufferObj::setDepth(GrFBBindableObj *buffer) {
+    if (fDepthBuffer) {
+        // automatically break the binding of the old buffer
+        GrAlwaysAssert(fDepthBuffer->getDepthBound(this));
+        fDepthBuffer->resetDepthBound(this);
+
+        GrAlwaysAssert(!fDepthBuffer->getDeleted());
+        fDepthBuffer->unref();
+    }
+    fDepthBuffer = buffer;
+    if (fDepthBuffer) {
+        GrAlwaysAssert(!fDepthBuffer->getDeleted());
+        fDepthBuffer->ref();
+
+        GrAlwaysAssert(!fDepthBuffer->getDepthBound(this));
+        fDepthBuffer->setDepthBound(this);
+    }
+}
+
+void GrFrameBufferObj::setStencil(GrFBBindableObj *buffer) {
+    if (fStencilBuffer) {
+        // automatically break the binding of the old buffer
+        GrAlwaysAssert(fStencilBuffer->getStencilBound(this));
+        fStencilBuffer->resetStencilBound(this);
+
+        //GrAlwaysAssert(!fStencilBuffer->getDeleted());
+        fStencilBuffer->unref();
+    }
+    fStencilBuffer = buffer;
+    if (fStencilBuffer) {
+        GrAlwaysAssert(!fStencilBuffer->getDeleted());
+        fStencilBuffer->ref();
+
+        GrAlwaysAssert(!fStencilBuffer->getStencilBound(this));
+        fStencilBuffer->setStencilBound(this);
+    }
+}
diff --git a/tools/gpu/gl/debug/GrFrameBufferObj.h b/tools/gpu/gl/debug/GrFrameBufferObj.h
new file mode 100644
index 0000000..42a0eff
--- /dev/null
+++ b/tools/gpu/gl/debug/GrFrameBufferObj.h
@@ -0,0 +1,68 @@
+
+/*
+ * Copyright 2012 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef GrFrameBufferObj_DEFINED
+#define GrFrameBufferObj_DEFINED
+
+#include "GrFakeRefObj.h"
+class GrFBBindableObj;
+
+////////////////////////////////////////////////////////////////////////////////
+// TODO: when a framebuffer obj is bound the GL_SAMPLES query must return 0
+// TODO: GL_STENCIL_BITS must also be redirected to the framebuffer
+class GrFrameBufferObj : public GrFakeRefObj {
+    GR_DEFINE_CREATOR(GrFrameBufferObj);
+
+public:
+    GrFrameBufferObj()
+        : GrFakeRefObj()
+        , fBound(false)
+        , fColorBuffer(nullptr)
+        , fDepthBuffer(nullptr)
+        , fStencilBuffer(nullptr) {
+    }
+
+    virtual ~GrFrameBufferObj() {
+        fColorBuffer = nullptr;
+        fDepthBuffer = nullptr;
+        fStencilBuffer = nullptr;
+    }
+
+    void setBound()         { fBound = true; }
+    void resetBound()       { fBound = false; }
+    bool getBound() const   { return fBound; }
+
+    void setColor(GrFBBindableObj *buffer);
+    GrFBBindableObj *getColor()       { return fColorBuffer; }
+
+    void setDepth(GrFBBindableObj *buffer);
+    GrFBBindableObj *getDepth()       { return fDepthBuffer; }
+
+    void setStencil(GrFBBindableObj *buffer);
+    GrFBBindableObj *getStencil()     { return fStencilBuffer; }
+
+    void deleteAction() override {
+
+        setColor(nullptr);
+        setDepth(nullptr);
+        setStencil(nullptr);
+
+        this->INHERITED::deleteAction();
+    }
+
+protected:
+private:
+    bool fBound;        // is this frame buffer currently bound via "glBindFramebuffer"?
+    GrFBBindableObj * fColorBuffer;
+    GrFBBindableObj * fDepthBuffer;
+    GrFBBindableObj * fStencilBuffer;
+
+    typedef GrFakeRefObj INHERITED;
+};
+
+#endif // GrFrameBufferObj_DEFINED
diff --git a/tools/gpu/gl/debug/GrProgramObj.cpp b/tools/gpu/gl/debug/GrProgramObj.cpp
new file mode 100644
index 0000000..d6cc36b
--- /dev/null
+++ b/tools/gpu/gl/debug/GrProgramObj.cpp
@@ -0,0 +1,27 @@
+
+/*
+ * Copyright 2012 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "GrProgramObj.h"
+#include "GrShaderObj.h"
+
+void GrProgramObj::AttachShader(GrShaderObj *shader) {
+    shader->ref();
+    fShaders.push_back(shader);
+}
+
+void GrProgramObj::deleteAction() {
+
+    // shaders are automatically detached from a deleted program. They will only be
+    // deleted if they were marked for deletion by a prior call to glDeleteShader
+    for (int i = 0; i < fShaders.count(); ++i) {
+        fShaders[i]->unref();
+    }
+    fShaders.reset();
+
+    this->INHERITED::deleteAction();
+}
diff --git a/tools/gpu/gl/debug/GrProgramObj.h b/tools/gpu/gl/debug/GrProgramObj.h
new file mode 100644
index 0000000..a25341a
--- /dev/null
+++ b/tools/gpu/gl/debug/GrProgramObj.h
@@ -0,0 +1,43 @@
+
+/*
+ * Copyright 2012 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef GrProgramObj_DEFINED
+#define GrProgramObj_DEFINED
+
+#include "SkTArray.h"
+#include "GrFakeRefObj.h"
+class GrShaderObj;
+
+////////////////////////////////////////////////////////////////////////////////
+class GrProgramObj : public GrFakeRefObj {
+    GR_DEFINE_CREATOR(GrProgramObj);
+
+public:
+    GrProgramObj()
+        : GrFakeRefObj()
+        , fInUse(false) {}
+
+    void AttachShader(GrShaderObj *shader);
+
+    void deleteAction() override;
+
+    // TODO: this flag system won't work w/ multiple contexts!
+    void setInUse()         { fInUse = true; }
+    void resetInUse()       { fInUse = false; }
+    bool getInUse() const   { return fInUse; }
+
+protected:
+
+private:
+    SkTArray<GrShaderObj *> fShaders;
+    bool fInUse;            // has this program been activated by a glUseProgram call?
+
+    typedef GrFakeRefObj INHERITED;
+};
+
+#endif // GrProgramObj_DEFINED
diff --git a/tools/gpu/gl/debug/GrRenderBufferObj.h b/tools/gpu/gl/debug/GrRenderBufferObj.h
new file mode 100644
index 0000000..8231ef5
--- /dev/null
+++ b/tools/gpu/gl/debug/GrRenderBufferObj.h
@@ -0,0 +1,40 @@
+
+/*
+ * Copyright 2012 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef GrRenderBufferObj_DEFINED
+#define GrRenderBufferObj_DEFINED
+
+#include "GrFBBindableObj.h"
+
+////////////////////////////////////////////////////////////////////////////////
+class GrRenderBufferObj : public GrFBBindableObj {
+    GR_DEFINE_CREATOR(GrRenderBufferObj);
+
+public:
+    GrRenderBufferObj()
+        : GrFBBindableObj()
+        , fBound(false) {
+    }
+
+    void setBound()         { fBound = true; }
+    void resetBound()       { fBound = false; }
+    bool getBound() const   { return fBound; }
+
+    void deleteAction() override {
+
+        this->INHERITED::deleteAction();
+    }
+
+protected:
+private:
+    bool fBound;           // is this render buffer currently bound via "glBindRenderbuffer"?
+
+    typedef GrFBBindableObj INHERITED;
+};
+
+#endif // GrRenderBufferObj_DEFINED
diff --git a/tools/gpu/gl/debug/GrShaderObj.cpp b/tools/gpu/gl/debug/GrShaderObj.cpp
new file mode 100644
index 0000000..8d3caa1
--- /dev/null
+++ b/tools/gpu/gl/debug/GrShaderObj.cpp
@@ -0,0 +1,14 @@
+
+/*
+ * Copyright 2012 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "GrShaderObj.h"
+
+void GrShaderObj::deleteAction() {
+
+    this->INHERITED::deleteAction();
+}
diff --git a/tools/gpu/gl/debug/GrShaderObj.h b/tools/gpu/gl/debug/GrShaderObj.h
new file mode 100644
index 0000000..327bd7f
--- /dev/null
+++ b/tools/gpu/gl/debug/GrShaderObj.h
@@ -0,0 +1,36 @@
+
+/*
+ * Copyright 2012 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef GrShaderObj_DEFINED
+#define GrShaderObj_DEFINED
+
+#include "GrFakeRefObj.h"
+#include "gl/GrGLDefines.h"
+
+////////////////////////////////////////////////////////////////////////////////
+class GrShaderObj : public GrFakeRefObj {
+    GR_DEFINE_CREATOR(GrShaderObj);
+
+public:
+    GrShaderObj()
+        : GrFakeRefObj()
+        , fType(GR_GL_VERTEX_SHADER)    {}
+
+    void setType(GrGLenum type)         { fType = type; }
+    GrGLenum getType()                  { return fType; }
+
+    void deleteAction() override;
+
+protected:
+private:
+    GrGLenum fType;  // either GR_GL_VERTEX_SHADER or GR_GL_FRAGMENT_SHADER
+
+    typedef GrFakeRefObj INHERITED;
+};
+
+#endif // GrShaderObj_DEFINED
diff --git a/tools/gpu/gl/debug/GrTextureObj.cpp b/tools/gpu/gl/debug/GrTextureObj.cpp
new file mode 100644
index 0000000..86063fb
--- /dev/null
+++ b/tools/gpu/gl/debug/GrTextureObj.cpp
@@ -0,0 +1,14 @@
+
+/*
+ * Copyright 2012 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "GrTextureObj.h"
+
+void GrTextureObj::deleteAction() {
+
+    this->INHERITED::deleteAction();
+}
diff --git a/tools/gpu/gl/debug/GrTextureObj.h b/tools/gpu/gl/debug/GrTextureObj.h
new file mode 100644
index 0000000..fcf851d
--- /dev/null
+++ b/tools/gpu/gl/debug/GrTextureObj.h
@@ -0,0 +1,57 @@
+
+/*
+ * Copyright 2012 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef GrTextureObj_DEFINED
+#define GrTextureObj_DEFINED
+
+#include "GrFBBindableObj.h"
+
+class GrTextureUnitObj;
+
+////////////////////////////////////////////////////////////////////////////////
+class GrTextureObj : public GrFBBindableObj {
+    GR_DEFINE_CREATOR(GrTextureObj);
+
+public:
+    GrTextureObj()
+        : GrFBBindableObj() {
+    }
+
+    virtual ~GrTextureObj() {
+        GrAlwaysAssert(0 == fTextureUnitReferees.count());
+    }
+
+    void setBound(GrTextureUnitObj *referee) {
+        fTextureUnitReferees.append(1, &referee);
+    }
+
+    void resetBound(GrTextureUnitObj *referee) {
+        int index = fTextureUnitReferees.find(referee);
+        GrAlwaysAssert(0 <= index);
+        fTextureUnitReferees.removeShuffle(index);
+    }
+    bool getBound(GrTextureUnitObj *referee) const {
+        int index = fTextureUnitReferees.find(referee);
+        return 0 <= index;
+    }
+    bool getBound() const {
+        return 0 != fTextureUnitReferees.count();
+    }
+
+    void deleteAction() override;
+
+protected:
+
+private:
+    // texture units that bind this texture (via "glBindTexture")
+    SkTDArray<GrTextureUnitObj *> fTextureUnitReferees;
+
+    typedef GrFBBindableObj INHERITED;
+};
+
+#endif // GrTextureObj_DEFINED
diff --git a/tools/gpu/gl/debug/GrTextureUnitObj.cpp b/tools/gpu/gl/debug/GrTextureUnitObj.cpp
new file mode 100644
index 0000000..316dcec
--- /dev/null
+++ b/tools/gpu/gl/debug/GrTextureUnitObj.cpp
@@ -0,0 +1,31 @@
+
+/*
+ * Copyright 2012 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "GrTextureUnitObj.h"
+#include "GrTextureObj.h"
+
+void GrTextureUnitObj::setTexture(GrTextureObj *texture)  {
+
+    if (fTexture) {
+        GrAlwaysAssert(fTexture->getBound(this));
+        fTexture->resetBound(this);
+
+        GrAlwaysAssert(!fTexture->getDeleted());
+        fTexture->unref();
+    }
+
+    fTexture = texture;
+
+    if (fTexture) {
+        GrAlwaysAssert(!fTexture->getDeleted());
+        fTexture->ref();
+
+        GrAlwaysAssert(!fTexture->getBound(this));
+        fTexture->setBound(this);
+    }
+}
diff --git a/tools/gpu/gl/debug/GrTextureUnitObj.h b/tools/gpu/gl/debug/GrTextureUnitObj.h
new file mode 100644
index 0000000..5c7a039
--- /dev/null
+++ b/tools/gpu/gl/debug/GrTextureUnitObj.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2012 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef GrTextureUnitObj_DEFINED
+#define GrTextureUnitObj_DEFINED
+
+#include "GrFakeRefObj.h"
+class GrTextureObj;
+
+////////////////////////////////////////////////////////////////////////////////
+// Although texture unit objects are allocated & deallocated like the other
+// GL emulation objects they are derived from GrFakeRefObj to provide some
+// uniformity in how the debug interface class manages resources
+class GrTextureUnitObj : public GrFakeRefObj {
+    GR_DEFINE_CREATOR(GrTextureUnitObj);
+
+public:
+    GrTextureUnitObj()
+        : GrFakeRefObj()
+        , fNumber(0)
+        , fTexture(nullptr) {
+    }
+
+    void setNumber(GrGLenum number) {
+        fNumber = number;
+    }
+    GrGLenum getNumber() const { return fNumber; }
+
+    void setTexture(GrTextureObj *texture);
+    GrTextureObj *getTexture()                  { return fTexture; }
+
+protected:
+private:
+    GrGLenum fNumber;
+    GrTextureObj *fTexture;
+
+    typedef GrFakeRefObj INHERITED;
+};
+
+#endif // GrTextureUnitObj_DEFINED
diff --git a/tools/gpu/gl/debug/GrVertexArrayObj.h b/tools/gpu/gl/debug/GrVertexArrayObj.h
new file mode 100644
index 0000000..989c610
--- /dev/null
+++ b/tools/gpu/gl/debug/GrVertexArrayObj.h
@@ -0,0 +1,21 @@
+/*
+ * Copyright 2013 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef GrVertexArrayObj_DEFINED
+#define GrVertexArrayObj_DEFINED
+
+#include "GrFakeRefObj.h"
+
+class GrVertexArrayObj : public GrFakeRefObj {
+    GR_DEFINE_CREATOR(GrVertexArrayObj);
+
+public:
+    GrVertexArrayObj() : GrFakeRefObj() {}
+
+    typedef GrFakeRefObj INHERITED;
+};
+#endif
diff --git a/tools/gpu/gl/egl/CreatePlatformGLContext_egl.cpp b/tools/gpu/gl/egl/CreatePlatformGLContext_egl.cpp
new file mode 100644
index 0000000..ac2e7ca
--- /dev/null
+++ b/tools/gpu/gl/egl/CreatePlatformGLContext_egl.cpp
@@ -0,0 +1,337 @@
+
+/*
+ * Copyright 2011 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+#include "gl/GLContext.h"
+
+#include <GLES2/gl2.h>
+
+#define EGL_EGLEXT_PROTOTYPES
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
+
+#include "gl/GrGLDefines.h"
+#include "gl/GrGLUtil.h"
+
+namespace {
+
+// TODO: Share this class with ANGLE if/when it gets support for EGL_KHR_fence_sync.
+class SkEGLFenceSync : public SkGpuFenceSync {
+public:
+    static SkEGLFenceSync* CreateIfSupported(EGLDisplay);
+
+    SkPlatformGpuFence SK_WARN_UNUSED_RESULT insertFence() const override;
+    bool waitFence(SkPlatformGpuFence fence, bool flush) const override;
+    void deleteFence(SkPlatformGpuFence fence) const override;
+
+private:
+    SkEGLFenceSync(EGLDisplay display) : fDisplay(display) {}
+
+    EGLDisplay                    fDisplay;
+
+    typedef SkGpuFenceSync INHERITED;
+};
+
+class EGLGLContext : public sk_gpu_test::GLContext {
+public:
+    EGLGLContext(GrGLStandard forcedGpuAPI);
+    ~EGLGLContext() override;
+
+    GrEGLImage texture2DToEGLImage(GrGLuint texID) const override;
+    void destroyEGLImage(GrEGLImage) const override;
+    GrGLuint eglImageToExternalTexture(GrEGLImage) const override;
+    sk_gpu_test::GLContext* createNew() const override;
+
+private:
+    void destroyGLContext();
+
+    void onPlatformMakeCurrent() const override;
+    void onPlatformSwapBuffers() const override;
+    GrGLFuncPtr onPlatformGetProcAddress(const char*) const override;
+
+    EGLContext fContext;
+    EGLDisplay fDisplay;
+    EGLSurface fSurface;
+};
+
+EGLGLContext::EGLGLContext(GrGLStandard forcedGpuAPI)
+    : fContext(EGL_NO_CONTEXT)
+    , fDisplay(EGL_NO_DISPLAY)
+    , fSurface(EGL_NO_SURFACE) {
+    static const EGLint kEGLContextAttribsForOpenGL[] = {
+        EGL_NONE
+    };
+
+    static const EGLint kEGLContextAttribsForOpenGLES[] = {
+        EGL_CONTEXT_CLIENT_VERSION, 2,
+        EGL_NONE
+    };
+
+    static const struct {
+        const EGLint* fContextAttribs;
+        EGLenum fAPI;
+        EGLint  fRenderableTypeBit;
+        GrGLStandard fStandard;
+    } kAPIs[] = {
+        {   // OpenGL
+            kEGLContextAttribsForOpenGL,
+            EGL_OPENGL_API,
+            EGL_OPENGL_BIT,
+            kGL_GrGLStandard
+        },
+        {   // OpenGL ES. This seems to work for both ES2 and 3 (when available).
+            kEGLContextAttribsForOpenGLES,
+            EGL_OPENGL_ES_API,
+            EGL_OPENGL_ES2_BIT,
+            kGLES_GrGLStandard
+        },
+    };
+
+    size_t apiLimit = SK_ARRAY_COUNT(kAPIs);
+    size_t api = 0;
+    if (forcedGpuAPI == kGL_GrGLStandard) {
+        apiLimit = 1;
+    } else if (forcedGpuAPI == kGLES_GrGLStandard) {
+        api = 1;
+    }
+    SkASSERT(forcedGpuAPI == kNone_GrGLStandard || kAPIs[api].fStandard == forcedGpuAPI);
+
+    SkAutoTUnref<const GrGLInterface> gl;
+
+    for (; nullptr == gl.get() && api < apiLimit; ++api) {
+        fDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
+
+        EGLint majorVersion;
+        EGLint minorVersion;
+        eglInitialize(fDisplay, &majorVersion, &minorVersion);
+
+#if 0
+        SkDebugf("VENDOR: %s\n", eglQueryString(fDisplay, EGL_VENDOR));
+        SkDebugf("APIS: %s\n", eglQueryString(fDisplay, EGL_CLIENT_APIS));
+        SkDebugf("VERSION: %s\n", eglQueryString(fDisplay, EGL_VERSION));
+        SkDebugf("EXTENSIONS %s\n", eglQueryString(fDisplay, EGL_EXTENSIONS));
+#endif
+
+        if (!eglBindAPI(kAPIs[api].fAPI)) {
+            continue;
+        }
+
+        EGLint numConfigs = 0;
+        const EGLint configAttribs[] = {
+            EGL_SURFACE_TYPE, EGL_PBUFFER_BIT,
+            EGL_RENDERABLE_TYPE, kAPIs[api].fRenderableTypeBit,
+            EGL_RED_SIZE, 8,
+            EGL_GREEN_SIZE, 8,
+            EGL_BLUE_SIZE, 8,
+            EGL_ALPHA_SIZE, 8,
+            EGL_NONE
+        };
+
+        EGLConfig surfaceConfig;
+        if (!eglChooseConfig(fDisplay, configAttribs, &surfaceConfig, 1, &numConfigs)) {
+            SkDebugf("eglChooseConfig failed. EGL Error: 0x%08x\n", eglGetError());
+            continue;
+        }
+
+        if (0 == numConfigs) {
+            SkDebugf("No suitable EGL config found.\n");
+            continue;
+        }
+
+        fContext = eglCreateContext(fDisplay, surfaceConfig, nullptr, kAPIs[api].fContextAttribs);
+        if (EGL_NO_CONTEXT == fContext) {
+            SkDebugf("eglCreateContext failed.  EGL Error: 0x%08x\n", eglGetError());
+            continue;
+        }
+
+        static const EGLint kSurfaceAttribs[] = {
+            EGL_WIDTH, 1,
+            EGL_HEIGHT, 1,
+            EGL_NONE
+        };
+
+        fSurface = eglCreatePbufferSurface(fDisplay, surfaceConfig, kSurfaceAttribs);
+        if (EGL_NO_SURFACE == fSurface) {
+            SkDebugf("eglCreatePbufferSurface failed. EGL Error: 0x%08x\n", eglGetError());
+            this->destroyGLContext();
+            continue;
+        }
+
+        if (!eglMakeCurrent(fDisplay, fSurface, fSurface, fContext)) {
+            SkDebugf("eglMakeCurrent failed.  EGL Error: 0x%08x\n", eglGetError());
+            this->destroyGLContext();
+            continue;
+        }
+
+        gl.reset(GrGLCreateNativeInterface());
+        if (nullptr == gl.get()) {
+            SkDebugf("Failed to create gl interface.\n");
+            this->destroyGLContext();
+            continue;
+        }
+
+        if (!gl->validate()) {
+            SkDebugf("Failed to validate gl interface.\n");
+            this->destroyGLContext();
+            continue;
+        }
+
+        this->init(gl.release(), SkEGLFenceSync::CreateIfSupported(fDisplay));
+        break;
+    }
+}
+
+EGLGLContext::~EGLGLContext() {
+    this->teardown();
+    this->destroyGLContext();
+}
+
+void EGLGLContext::destroyGLContext() {
+    if (fDisplay) {
+        eglMakeCurrent(fDisplay, 0, 0, 0);
+
+        if (fContext) {
+            eglDestroyContext(fDisplay, fContext);
+            fContext = EGL_NO_CONTEXT;
+        }
+
+        if (fSurface) {
+            eglDestroySurface(fDisplay, fSurface);
+            fSurface = EGL_NO_SURFACE;
+        }
+
+        //TODO should we close the display?
+        fDisplay = EGL_NO_DISPLAY;
+    }
+}
+
+GrEGLImage EGLGLContext::texture2DToEGLImage(GrGLuint texID) const {
+    if (!this->gl()->hasExtension("EGL_KHR_gl_texture_2D_image")) {
+        return GR_EGL_NO_IMAGE;
+    }
+    GrEGLImage img;
+    GrEGLint attribs[] = { GR_EGL_GL_TEXTURE_LEVEL, 0, GR_EGL_NONE };
+    GrEGLClientBuffer clientBuffer = reinterpret_cast<GrEGLClientBuffer>(texID);
+    GR_GL_CALL_RET(this->gl(), img,
+                   EGLCreateImage(fDisplay, fContext, GR_EGL_GL_TEXTURE_2D, clientBuffer, attribs));
+    return img;
+}
+
+void EGLGLContext::destroyEGLImage(GrEGLImage image) const {
+    GR_GL_CALL(this->gl(), EGLDestroyImage(fDisplay, image));
+}
+
+GrGLuint EGLGLContext::eglImageToExternalTexture(GrEGLImage image) const {
+    GrGLClearErr(this->gl());
+    if (!this->gl()->hasExtension("GL_OES_EGL_image_external")) {
+        return 0;
+    }
+    typedef GrGLvoid (*EGLImageTargetTexture2DProc)(GrGLenum, GrGLeglImage);
+
+    EGLImageTargetTexture2DProc glEGLImageTargetTexture2D =
+        (EGLImageTargetTexture2DProc) eglGetProcAddress("glEGLImageTargetTexture2DOES");
+    if (!glEGLImageTargetTexture2D) {
+        return 0;
+    }
+    GrGLuint texID;
+    glGenTextures(1, &texID);
+    if (!texID) {
+        return 0;
+    }
+    glBindTexture(GR_GL_TEXTURE_EXTERNAL, texID);
+    if (glGetError() != GR_GL_NO_ERROR) {
+        glDeleteTextures(1, &texID);
+        return 0;
+    }
+    glEGLImageTargetTexture2D(GR_GL_TEXTURE_EXTERNAL, image);
+    if (glGetError() != GR_GL_NO_ERROR) {
+        glDeleteTextures(1, &texID);
+        return 0;
+    }
+    return texID;
+}
+
+sk_gpu_test::GLContext* EGLGLContext::createNew() const {
+    sk_gpu_test::GLContext* ctx = new EGLGLContext(this->gl()->fStandard);
+    if (ctx) {
+        ctx->makeCurrent();
+    }
+    return ctx;
+}
+
+void EGLGLContext::onPlatformMakeCurrent() const {
+    if (!eglMakeCurrent(fDisplay, fSurface, fSurface, fContext)) {
+        SkDebugf("Could not set the context.\n");
+    }
+}
+
+void EGLGLContext::onPlatformSwapBuffers() const {
+    if (!eglSwapBuffers(fDisplay, fSurface)) {
+        SkDebugf("Could not complete eglSwapBuffers.\n");
+    }
+}
+
+GrGLFuncPtr EGLGLContext::onPlatformGetProcAddress(const char* procName) const {
+    return eglGetProcAddress(procName);
+}
+
+static bool supports_egl_extension(EGLDisplay display, const char* extension) {
+    size_t extensionLength = strlen(extension);
+    const char* extensionsStr = eglQueryString(display, EGL_EXTENSIONS);
+    while (const char* match = strstr(extensionsStr, extension)) {
+        // Ensure the string we found is its own extension, not a substring of a larger extension
+        // (e.g. GL_ARB_occlusion_query / GL_ARB_occlusion_query2).
+        if ((match == extensionsStr || match[-1] == ' ') &&
+            (match[extensionLength] == ' ' || match[extensionLength] == '\0')) {
+            return true;
+        }
+        extensionsStr = match + extensionLength;
+    }
+    return false;
+}
+
+SkEGLFenceSync* SkEGLFenceSync::CreateIfSupported(EGLDisplay display) {
+    if (!display || !supports_egl_extension(display, "EGL_KHR_fence_sync")) {
+        return nullptr;
+    }
+    return new SkEGLFenceSync(display);
+}
+
+SkPlatformGpuFence SkEGLFenceSync::insertFence() const {
+    return eglCreateSyncKHR(fDisplay, EGL_SYNC_FENCE_KHR, nullptr);
+}
+
+bool SkEGLFenceSync::waitFence(SkPlatformGpuFence platformFence, bool flush) const {
+    EGLSyncKHR eglsync = static_cast<EGLSyncKHR>(platformFence);
+    return EGL_CONDITION_SATISFIED_KHR ==
+            eglClientWaitSyncKHR(fDisplay,
+                                 eglsync,
+                                 flush ? EGL_SYNC_FLUSH_COMMANDS_BIT_KHR : 0,
+                                 EGL_FOREVER_KHR);
+}
+
+void SkEGLFenceSync::deleteFence(SkPlatformGpuFence platformFence) const {
+    EGLSyncKHR eglsync = static_cast<EGLSyncKHR>(platformFence);
+    eglDestroySyncKHR(fDisplay, eglsync);
+}
+
+}  // anonymous namespace
+
+namespace sk_gpu_test {
+GLContext *CreatePlatformGLContext(GrGLStandard forcedGpuAPI, GLContext *shareContext) {
+    SkASSERT(!shareContext);
+    if (shareContext) {
+        return nullptr;
+    }
+    EGLGLContext *ctx = new EGLGLContext(forcedGpuAPI);
+    if (!ctx->isValid()) {
+        delete ctx;
+        return nullptr;
+    }
+    return ctx;
+}
+}  // namespace sk_gpu_test
+
diff --git a/tools/gpu/gl/glx/CreatePlatformGLContext_glx.cpp b/tools/gpu/gl/glx/CreatePlatformGLContext_glx.cpp
new file mode 100644
index 0000000..b2168e3
--- /dev/null
+++ b/tools/gpu/gl/glx/CreatePlatformGLContext_glx.cpp
@@ -0,0 +1,346 @@
+
+/*
+ * Copyright 2011 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+#include "gl/GLContext.h"
+
+#include <X11/Xlib.h>
+#include <GL/glx.h>
+#include <GL/glu.h>
+
+namespace {
+
+/* Note: Skia requires glx 1.3 or newer */
+
+/* This struct is taken from a mesa demo.  Please update as required */
+static const struct { int major, minor; } gl_versions[] = {
+   {1, 0},
+   {1, 1},
+   {1, 2},
+   {1, 3},
+   {1, 4},
+   {1, 5},
+   {2, 0},
+   {2, 1},
+   {3, 0},
+   {3, 1},
+   {3, 2},
+   {3, 3},
+   {4, 0},
+   {4, 1},
+   {4, 2},
+   {4, 3},
+   {4, 4},
+   {0, 0} /* end of list */
+};
+#define NUM_GL_VERSIONS SK_ARRAY_COUNT(gl_versions)
+
+static bool ctxErrorOccurred = false;
+static int ctxErrorHandler(Display *dpy, XErrorEvent *ev) {
+    ctxErrorOccurred = true;
+    return 0;
+}
+
+class GLXGLContext : public sk_gpu_test::GLContext {
+public:
+    GLXGLContext(GrGLStandard forcedGpuAPI, GLXGLContext* shareList);
+    ~GLXGLContext() override;
+
+private:
+    void destroyGLContext();
+
+    void onPlatformMakeCurrent() const override;
+    void onPlatformSwapBuffers() const override;
+    GrGLFuncPtr onPlatformGetProcAddress(const char*) const override;
+
+    GLXContext fContext;
+    Display* fDisplay;
+    Pixmap fPixmap;
+    GLXPixmap fGlxPixmap;
+};
+
+GLXGLContext::GLXGLContext(GrGLStandard forcedGpuAPI, GLXGLContext* shareContext)
+    : fContext(nullptr)
+    , fDisplay(nullptr)
+    , fPixmap(0)
+    , fGlxPixmap(0) {
+    fDisplay = XOpenDisplay(0);
+
+    GLXContext glxShareContext = shareContext ? shareContext->fContext : nullptr;
+
+    if (!fDisplay) {
+        SkDebugf("Failed to open X display.\n");
+        this->destroyGLContext();
+        return;
+    }
+
+    // Get a matching FB config
+    static int visual_attribs[] = {
+        GLX_X_RENDERABLE    , True,
+        GLX_DRAWABLE_TYPE   , GLX_PIXMAP_BIT,
+        None
+    };
+
+    int glx_major, glx_minor;
+
+    // FBConfigs were added in GLX version 1.3.
+    if (!glXQueryVersion(fDisplay, &glx_major, &glx_minor) ||
+            ((glx_major == 1) && (glx_minor < 3)) || (glx_major < 1)) {
+        SkDebugf("GLX version 1.3 or higher required.\n");
+        this->destroyGLContext();
+        return;
+    }
+
+    //SkDebugf("Getting matching framebuffer configs.\n");
+    int fbcount;
+    GLXFBConfig *fbc = glXChooseFBConfig(fDisplay, DefaultScreen(fDisplay),
+                                          visual_attribs, &fbcount);
+    if (!fbc) {
+        SkDebugf("Failed to retrieve a framebuffer config.\n");
+        this->destroyGLContext();
+        return;
+    }
+    //SkDebugf("Found %d matching FB configs.\n", fbcount);
+
+    // Pick the FB config/visual with the most samples per pixel
+    //SkDebugf("Getting XVisualInfos.\n");
+    int best_fbc = -1, best_num_samp = -1;
+
+    int i;
+    for (i = 0; i < fbcount; ++i) {
+        XVisualInfo *vi = glXGetVisualFromFBConfig(fDisplay, fbc[i]);
+        if (vi) {
+            int samp_buf, samples;
+            glXGetFBConfigAttrib(fDisplay, fbc[i], GLX_SAMPLE_BUFFERS, &samp_buf);
+            glXGetFBConfigAttrib(fDisplay, fbc[i], GLX_SAMPLES, &samples);
+
+            //SkDebugf("  Matching fbconfig %d, visual ID 0x%2x: SAMPLE_BUFFERS = %d,"
+            //       " SAMPLES = %d\n",
+            //        i, (unsigned int)vi->visualid, samp_buf, samples);
+
+            if (best_fbc < 0 || (samp_buf && samples > best_num_samp))
+                best_fbc = i, best_num_samp = samples;
+        }
+        XFree(vi);
+    }
+
+    GLXFBConfig bestFbc = fbc[best_fbc];
+
+    // Be sure to free the FBConfig list allocated by glXChooseFBConfig()
+    XFree(fbc);
+
+    // Get a visual
+    XVisualInfo *vi = glXGetVisualFromFBConfig(fDisplay, bestFbc);
+    //SkDebugf("Chosen visual ID = 0x%x\n", (unsigned int)vi->visualid);
+
+    fPixmap = XCreatePixmap(fDisplay, RootWindow(fDisplay, vi->screen), 10, 10, vi->depth);
+
+    if (!fPixmap) {
+        SkDebugf("Failed to create pixmap.\n");
+        this->destroyGLContext();
+        return;
+    }
+
+    fGlxPixmap = glXCreateGLXPixmap(fDisplay, vi, fPixmap);
+
+    // Done with the visual info data
+    XFree(vi);
+
+    // Create the context
+
+    // Install an X error handler so the application won't exit if GL 3.0
+    // context allocation fails.
+    //
+    // Note this error handler is global.
+    // All display connections in all threads of a process use the same
+    // error handler, so be sure to guard against other threads issuing
+    // X commands while this code is running.
+    ctxErrorOccurred = false;
+    int (*oldHandler)(Display*, XErrorEvent*) =
+        XSetErrorHandler(&ctxErrorHandler);
+
+    // Get the default screen's GLX extension list
+    const char *glxExts = glXQueryExtensionsString(
+        fDisplay, DefaultScreen(fDisplay)
+    );
+
+
+    // Check for the GLX_ARB_create_context extension string and the function.
+    // If either is not present, use GLX 1.3 context creation method.
+    if (!gluCheckExtension(reinterpret_cast<const GLubyte*>("GLX_ARB_create_context"),
+                           reinterpret_cast<const GLubyte*>(glxExts))) {
+        if (kGLES_GrGLStandard != forcedGpuAPI) {
+            fContext = glXCreateNewContext(fDisplay, bestFbc, GLX_RGBA_TYPE, 0, True);
+        }
+    } else {
+        //SkDebugf("Creating context.\n");
+        PFNGLXCREATECONTEXTATTRIBSARBPROC glXCreateContextAttribsARB =
+            (PFNGLXCREATECONTEXTATTRIBSARBPROC) glXGetProcAddressARB((GrGLubyte*)"glXCreateContextAttribsARB");
+
+        if (kGLES_GrGLStandard == forcedGpuAPI) {
+            if (gluCheckExtension(
+                    reinterpret_cast<const GLubyte*>("GLX_EXT_create_context_es2_profile"),
+                    reinterpret_cast<const GLubyte*>(glxExts))) {
+                static const int context_attribs_gles[] = {
+                    GLX_CONTEXT_MAJOR_VERSION_ARB, 3,
+                    GLX_CONTEXT_MINOR_VERSION_ARB, 0,
+                    GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_ES2_PROFILE_BIT_EXT,
+                    None
+                };
+                fContext = glXCreateContextAttribsARB(fDisplay, bestFbc, glxShareContext, True,
+                                                      context_attribs_gles);
+            }
+        } else {
+            // Well, unfortunately GLX will not just give us the highest context so instead we have
+            // to do this nastiness
+            for (i = NUM_GL_VERSIONS - 2; i > 0 ; i--) {
+                /* don't bother below GL 3.0 */
+                if (gl_versions[i].major == 3 && gl_versions[i].minor == 0) {
+                    break;
+                }
+                // On Nvidia GPUs, to use Nv Path rendering we need a compatibility profile for the
+                // time being.
+                // TODO when Nvidia implements NVPR on Core profiles, we should start requesting
+                // core here
+                static const int context_attribs_gl[] = {
+                      GLX_CONTEXT_MAJOR_VERSION_ARB, gl_versions[i].major,
+                      GLX_CONTEXT_MINOR_VERSION_ARB, gl_versions[i].minor,
+                      GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB,
+                      None
+                };
+                fContext =
+                        glXCreateContextAttribsARB(fDisplay, bestFbc, glxShareContext, True,
+                                                   context_attribs_gl);
+
+                // Sync to ensure any errors generated are processed.
+                XSync(fDisplay, False);
+
+                if (!ctxErrorOccurred && fContext) {
+                    break;
+                }
+                // try again
+                ctxErrorOccurred = false;
+            }
+
+            // Couldn't create GL 3.0 context.
+            // Fall back to old-style 2.x context.
+            // When a context version below 3.0 is requested,
+            // implementations will return the newest context version
+            // compatible with OpenGL versions less than version 3.0.
+            if (ctxErrorOccurred || !fContext) {
+                static const int context_attribs_gl_fallback[] = {
+                    GLX_CONTEXT_MAJOR_VERSION_ARB, 1,
+                    GLX_CONTEXT_MINOR_VERSION_ARB, 0,
+                    None
+                };
+
+                ctxErrorOccurred = false;
+
+                fContext = glXCreateContextAttribsARB(fDisplay, bestFbc, glxShareContext, True,
+                                                      context_attribs_gl_fallback);
+            }
+        }
+    }
+
+    // Sync to ensure any errors generated are processed.
+    XSync(fDisplay, False);
+
+    // Restore the original error handler
+    XSetErrorHandler(oldHandler);
+
+    if (ctxErrorOccurred || !fContext) {
+        SkDebugf("Failed to create an OpenGL context.\n");
+        this->destroyGLContext();
+        return;
+    }
+
+    // Verify that context is a direct context
+    if (!glXIsDirect(fDisplay, fContext)) {
+        //SkDebugf("Indirect GLX rendering context obtained.\n");
+    } else {
+        //SkDebugf("Direct GLX rendering context obtained.\n");
+    }
+
+    //SkDebugf("Making context current.\n");
+    if (!glXMakeCurrent(fDisplay, fGlxPixmap, fContext)) {
+      SkDebugf("Could not set the context.\n");
+        this->destroyGLContext();
+        return;
+    }
+
+    SkAutoTUnref<const GrGLInterface> gl(GrGLCreateNativeInterface());
+    if (nullptr == gl.get()) {
+        SkDebugf("Failed to create gl interface");
+        this->destroyGLContext();
+        return;
+    }
+
+    if (!gl->validate()) {
+        SkDebugf("Failed to validate gl interface");
+        this->destroyGLContext();
+        return;
+    }
+
+    this->init(gl.release());
+}
+
+
+GLXGLContext::~GLXGLContext() {
+    this->teardown();
+    this->destroyGLContext();
+}
+
+void GLXGLContext::destroyGLContext() {
+    if (fDisplay) {
+        glXMakeCurrent(fDisplay, 0, 0);
+
+        if (fContext) {
+            glXDestroyContext(fDisplay, fContext);
+            fContext = nullptr;
+        }
+
+        if (fGlxPixmap) {
+            glXDestroyGLXPixmap(fDisplay, fGlxPixmap);
+            fGlxPixmap = 0;
+        }
+
+        if (fPixmap) {
+            XFreePixmap(fDisplay, fPixmap);
+            fPixmap = 0;
+        }
+
+        XCloseDisplay(fDisplay);
+        fDisplay = nullptr;
+    }
+}
+
+void GLXGLContext::onPlatformMakeCurrent() const {
+    if (!glXMakeCurrent(fDisplay, fGlxPixmap, fContext)) {
+        SkDebugf("Could not set the context.\n");
+    }
+}
+
+void GLXGLContext::onPlatformSwapBuffers() const {
+    glXSwapBuffers(fDisplay, fGlxPixmap);
+}
+
+GrGLFuncPtr GLXGLContext::onPlatformGetProcAddress(const char* procName) const {
+    return glXGetProcAddress(reinterpret_cast<const GLubyte*>(procName));
+}
+
+}  // anonymous namespace
+
+namespace sk_gpu_test {
+GLContext *CreatePlatformGLContext(GrGLStandard forcedGpuAPI, GLContext *shareContext) {
+    GLXGLContext *glxShareContext = reinterpret_cast<GLXGLContext *>(shareContext);
+    GLXGLContext *ctx = new GLXGLContext(forcedGpuAPI, glxShareContext);
+    if (!ctx->isValid()) {
+        delete ctx;
+        return nullptr;
+    }
+    return ctx;
+}
+}  // namespace sk_gpu_test
diff --git a/tools/gpu/gl/iOS/CreatePlatformGLContext_iOS.mm b/tools/gpu/gl/iOS/CreatePlatformGLContext_iOS.mm
new file mode 100644
index 0000000..d6507f2
--- /dev/null
+++ b/tools/gpu/gl/iOS/CreatePlatformGLContext_iOS.mm
@@ -0,0 +1,108 @@
+
+/*
+ * Copyright 2012 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "GLContext.h"
+#import <OpenGLES/EAGL.h>
+#include <dlfcn.h>
+
+#define EAGLCTX ((EAGLContext*)(fEAGLContext))
+
+namespace {
+
+class IOSGLContext : public sk_gpu_test::GLContext {
+public:
+    IOSGLContext();
+    ~IOSGLContext() override;
+
+private:
+    void destroyGLContext();
+
+    void onPlatformMakeCurrent() const override;
+    void onPlatformSwapBuffers() const override;
+    GrGLFuncPtr onPlatformGetProcAddress(const char*) const override;
+
+    void* fEAGLContext;
+    void* fGLLibrary;
+};
+
+IOSGLContext::IOSGLContext()
+    : fEAGLContext(NULL)
+    , fGLLibrary(RTLD_DEFAULT) {
+
+    fEAGLContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
+    [EAGLContext setCurrentContext:EAGLCTX];
+
+    SkAutoTUnref<const GrGLInterface> gl(GrGLCreateNativeInterface());
+    if (NULL == gl.get()) {
+        SkDebugf("Failed to create gl interface");
+        this->destroyGLContext();
+        return;
+    }
+    if (!gl->validate()) {
+        SkDebugf("Failed to validate gl interface");
+        this->destroyGLContext();
+        return;
+    }
+
+    fGLLibrary = dlopen(
+        "/System/Library/Frameworks/OpenGL.framework/Versions/A/Libraries/libGL.dylib",
+        RTLD_LAZY);
+
+    this->init(gl.release());
+}
+
+IOSGLContext::~IOSGLContext() {
+    this->teardown();
+    this->destroyGLContext();
+}
+
+void IOSGLContext::destroyGLContext() {
+    if (fEAGLContext) {
+        if ([EAGLContext currentContext] == EAGLCTX) {
+            [EAGLContext setCurrentContext:nil];
+        }
+        [EAGLCTX release];
+        fEAGLContext = NULL;
+    }
+    if (RTLD_DEFAULT != fGLLibrary) {
+        dlclose(fGLLibrary);
+    }
+}
+
+
+void IOSGLContext::onPlatformMakeCurrent() const {
+    if (![EAGLContext setCurrentContext:EAGLCTX]) {
+        SkDebugf("Could not set the context.\n");
+    }
+}
+
+void IOSGLContext::onPlatformSwapBuffers() const { }
+
+GrGLFuncPtr IOSGLContext::onPlatformGetProcAddress(const char* procName) const {
+    return reinterpret_cast<GrGLFuncPtr>(dlsym(fGLLibrary, procName));
+}
+
+}  // anonymous namespace
+
+namespace sk_gpu_test {
+GLContext *CreatePlatformGLContext(GrGLStandard forcedGpuAPI, GLContext *shareContext) {
+    SkASSERT(!shareContext);
+    if (shareContext) {
+        return NULL;
+    }
+    if (kGL_GrGLStandard == forcedGpuAPI) {
+        return NULL;
+    }
+    IOSGLContext *ctx = new IOSGLContext;
+    if (!ctx->isValid()) {
+        delete ctx;
+        return NULL;
+    }
+    return ctx;
+}
+}
diff --git a/tools/gpu/gl/mac/CreatePlatformGLContext_mac.cpp b/tools/gpu/gl/mac/CreatePlatformGLContext_mac.cpp
new file mode 100644
index 0000000..7da99d7
--- /dev/null
+++ b/tools/gpu/gl/mac/CreatePlatformGLContext_mac.cpp
@@ -0,0 +1,128 @@
+
+/*
+ * Copyright 2011 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+#include "SkTypes.h"
+
+#include "gl/GLContext.h"
+#include "AvailabilityMacros.h"
+
+#include <OpenGL/OpenGL.h>
+#include <dlfcn.h>
+
+namespace {
+class MacGLContext : public sk_gpu_test::GLContext {
+public:
+    MacGLContext();
+    ~MacGLContext() override;
+
+private:
+    void destroyGLContext();
+
+    void onPlatformMakeCurrent() const override;
+    void onPlatformSwapBuffers() const override;
+    GrGLFuncPtr onPlatformGetProcAddress(const char*) const override;
+
+    CGLContextObj fContext;
+    void* fGLLibrary;
+};
+
+MacGLContext::MacGLContext()
+    : fContext(nullptr)
+    , fGLLibrary(RTLD_DEFAULT) {
+    CGLPixelFormatAttribute attributes[] = {
+#if MAC_OS_X_VERSION_10_7
+        kCGLPFAOpenGLProfile, (CGLPixelFormatAttribute) kCGLOGLPVersion_3_2_Core,
+#endif
+        kCGLPFADoubleBuffer,
+        (CGLPixelFormatAttribute)0
+    };
+    CGLPixelFormatObj pixFormat;
+    GLint npix;
+
+    CGLChoosePixelFormat(attributes, &pixFormat, &npix);
+
+    if (nullptr == pixFormat) {
+        SkDebugf("CGLChoosePixelFormat failed.");
+        return;
+    }
+
+    CGLCreateContext(pixFormat, nullptr, &fContext);
+    CGLReleasePixelFormat(pixFormat);
+
+    if (nullptr == fContext) {
+        SkDebugf("CGLCreateContext failed.");
+        return;
+    }
+
+    CGLSetCurrentContext(fContext);
+
+    SkAutoTUnref<const GrGLInterface> gl(GrGLCreateNativeInterface());
+    if (nullptr == gl.get()) {
+        SkDebugf("Context could not create GL interface.\n");
+        this->destroyGLContext();
+        return;
+    }
+    if (!gl->validate()) {
+        SkDebugf("Context could not validate GL interface.\n");
+        this->destroyGLContext();
+        return;
+    }
+
+    fGLLibrary = dlopen(
+        "/System/Library/Frameworks/OpenGL.framework/Versions/A/Libraries/libGL.dylib",
+        RTLD_LAZY);
+
+    this->init(gl.release());
+}
+
+MacGLContext::~MacGLContext() {
+    this->teardown();
+    this->destroyGLContext();
+}
+
+void MacGLContext::destroyGLContext() {
+    if (fContext) {
+        CGLReleaseContext(fContext);
+        fContext = nullptr;
+    }
+    if (RTLD_DEFAULT != fGLLibrary) {
+        dlclose(fGLLibrary);
+    }
+}
+
+void MacGLContext::onPlatformMakeCurrent() const {
+    CGLSetCurrentContext(fContext);
+}
+
+void MacGLContext::onPlatformSwapBuffers() const {
+    CGLFlushDrawable(fContext);
+}
+
+GrGLFuncPtr MacGLContext::onPlatformGetProcAddress(const char* procName) const {
+    return reinterpret_cast<GrGLFuncPtr>(dlsym(fGLLibrary, procName));
+}
+
+}  // anonymous namespace
+
+namespace sk_gpu_test {
+GLContext* CreatePlatformGLContext(GrGLStandard forcedGpuAPI, GLContext* shareContext) {
+    SkASSERT(!shareContext);
+    if (shareContext) {
+        return nullptr;
+    }
+
+    if (kGLES_GrGLStandard == forcedGpuAPI) {
+        return nullptr;
+    }
+    MacGLContext* ctx = new MacGLContext;
+    if (!ctx->isValid()) {
+        delete ctx;
+        return nullptr;
+    }
+    return ctx;
+}
+}  // namespace sk_gpu_test
diff --git a/tools/gpu/gl/mesa/GLContext_mesa.cpp b/tools/gpu/gl/mesa/GLContext_mesa.cpp
new file mode 100644
index 0000000..e6cc7c7
--- /dev/null
+++ b/tools/gpu/gl/mesa/GLContext_mesa.cpp
@@ -0,0 +1,151 @@
+
+/*
+ * Copyright 2011 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include <GL/osmesa.h>
+
+#include "gl/mesa/GLContext_mesa.h"
+#include "gl/GrGLDefines.h"
+
+#include "gl/GrGLAssembleInterface.h"
+#include "gl/GrGLUtil.h"
+#include "osmesa_wrapper.h"
+
+namespace {
+
+static GrGLFuncPtr osmesa_get(void* ctx, const char name[]) {
+    SkASSERT(nullptr == ctx);
+    SkASSERT(OSMesaGetCurrentContext());
+    return OSMesaGetProcAddress(name);
+}
+
+static const GrGLInterface* create_mesa_interface() {
+    if (nullptr == OSMesaGetCurrentContext()) {
+        return nullptr;
+    }
+    return GrGLAssembleInterface(nullptr, osmesa_get);
+}
+
+static const GrGLint gBOGUS_SIZE = 16;
+
+class MesaGLContext : public sk_gpu_test::GLContext {
+private:
+    typedef intptr_t Context;
+
+public:
+    MesaGLContext();
+    ~MesaGLContext() override;
+
+private:
+    void destroyGLContext();
+
+    void onPlatformMakeCurrent() const override;
+
+    void onPlatformSwapBuffers() const override;
+
+    GrGLFuncPtr onPlatformGetProcAddress(const char *) const override;
+
+    Context fContext;
+    GrGLubyte *fImage;
+};
+
+MesaGLContext::MesaGLContext() : fContext(static_cast<Context>(0)), fImage(nullptr) {
+    GR_STATIC_ASSERT(sizeof(Context) == sizeof(OSMesaContext));
+
+    /* Create an RGBA-mode context */
+#if OSMESA_MAJOR_VERSION * 100 + OSMESA_MINOR_VERSION >= 305
+    /* specify Z, stencil, accum sizes */
+    fContext = (Context)OSMesaCreateContextExt(OSMESA_BGRA, 0, 0, 0, nullptr);
+#else
+    fContext = (Context) OSMesaCreateContext(OSMESA_BGRA, nullptr);
+#endif
+    if (!fContext) {
+        SkDebugf("OSMesaCreateContext failed!\n");
+        this->destroyGLContext();
+        return;
+    }
+    // Allocate the image buffer
+    fImage = (GrGLubyte *) sk_malloc_throw(gBOGUS_SIZE * gBOGUS_SIZE *
+                                           4 * sizeof(GrGLubyte));
+    if (!fImage) {
+        SkDebugf("Alloc image buffer failed!\n");
+        this->destroyGLContext();
+        return;
+    }
+
+    // Bind the buffer to the context and make it current
+    if (!OSMesaMakeCurrent((OSMesaContext) fContext,
+                           fImage,
+                           GR_GL_UNSIGNED_BYTE,
+                           gBOGUS_SIZE,
+                           gBOGUS_SIZE)) {
+        SkDebugf("OSMesaMakeCurrent failed!\n");
+        this->destroyGLContext();
+        return;
+    }
+
+    SkAutoTUnref<const GrGLInterface> gl(create_mesa_interface());
+    if (nullptr == gl.get()) {
+        SkDebugf("Could not create GL interface!\n");
+        this->destroyGLContext();
+        return;
+    }
+
+    if (!gl->validate()) {
+        SkDebugf("Could not validate GL interface!\n");
+        this->destroyGLContext();
+        return;
+    }
+
+    this->init(gl.release());
+}
+
+MesaGLContext::~MesaGLContext() {
+    this->teardown();
+    this->destroyGLContext();
+}
+
+void MesaGLContext::destroyGLContext() {
+    if (fImage) {
+        sk_free(fImage);
+        fImage = nullptr;
+    }
+
+    if (fContext) {
+        OSMesaDestroyContext((OSMesaContext) fContext);
+        fContext = static_cast<Context>(0);
+    }
+}
+
+
+void MesaGLContext::onPlatformMakeCurrent() const {
+    if (fContext) {
+        if (!OSMesaMakeCurrent((OSMesaContext) fContext, fImage,
+                               GR_GL_UNSIGNED_BYTE, gBOGUS_SIZE, gBOGUS_SIZE)) {
+            SkDebugf("Could not make MESA context current.");
+        }
+    }
+}
+
+void MesaGLContext::onPlatformSwapBuffers() const { }
+
+GrGLFuncPtr MesaGLContext::onPlatformGetProcAddress(const char *procName) const {
+    return OSMesaGetProcAddress(procName);
+}
+}  // anonymous namespace
+
+
+namespace sk_gpu_test {
+GLContext *CreateMesaGLContext() {
+    MesaGLContext *ctx = new MesaGLContext;
+    if (!ctx->isValid()) {
+        delete ctx;
+        return nullptr;
+    }
+    return ctx;
+}
+}  // sk_gpu_test
diff --git a/tools/gpu/gl/mesa/GLContext_mesa.h b/tools/gpu/gl/mesa/GLContext_mesa.h
new file mode 100644
index 0000000..0d6ee4d
--- /dev/null
+++ b/tools/gpu/gl/mesa/GLContext_mesa.h
@@ -0,0 +1,17 @@
+
+/*
+ * Copyright 2011 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+#ifndef GLContext_mesa_DEFINED
+#define GLContext_mesa_DEFINED
+
+#include "gl/GLContext.h"
+
+namespace sk_gpu_test {
+GLContext* CreateMesaGLContext();
+}  // namespace sk_gpu_test
+
+#endif
diff --git a/tools/gpu/gl/mesa/osmesa_wrapper.h b/tools/gpu/gl/mesa/osmesa_wrapper.h
new file mode 100644
index 0000000..70de993
--- /dev/null
+++ b/tools/gpu/gl/mesa/osmesa_wrapper.h
@@ -0,0 +1,16 @@
+
+/*
+ * Copyright 2013 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+// Older versions of XQuartz have a bug where a header included by osmesa.h
+// defines GL_GLEXT_PROTOTYPES. This will cause a redefinition warning if
+// the file that includes osmesa.h already defined it. XCode 3 uses a version
+// of gcc (4.2.1) that does not support the diagnostic pragma to disable a
+// warning (added in 4.2.4). So we use the system_header pragma to shut GCC
+// up about warnings in osmesa.h
+#pragma GCC system_header
+#include <GL/osmesa.h>
diff --git a/tools/gpu/gl/null/NullGLContext.cpp b/tools/gpu/gl/null/NullGLContext.cpp
new file mode 100644
index 0000000..4781c90
--- /dev/null
+++ b/tools/gpu/gl/null/NullGLContext.cpp
@@ -0,0 +1,630 @@
+
+/*
+ * Copyright 2011 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "NullGLContext.h"
+#include "gl/GrGLTestInterface.h"
+#include "gl/GrGLDefines.h"
+#include "gl/GrGLInterface.h"
+#include "gl/GrGLTypes.h"
+#include "SkMutex.h"
+#include "SkTDArray.h"
+
+namespace {
+
+class BufferObj {
+public:
+    BufferObj(GrGLuint id) : fID(id), fDataPtr(nullptr), fSize(0), fMapped(false) {}
+    ~BufferObj() { delete[] fDataPtr; }
+
+    void allocate(GrGLsizeiptr size, const GrGLchar* dataPtr) {
+        if (fDataPtr) {
+            SkASSERT(0 != fSize);
+            delete[] fDataPtr;
+        }
+
+        fSize = size;
+        fDataPtr = new char[size];
+    }
+
+    GrGLuint id() const          { return fID; }
+    GrGLchar* dataPtr()          { return fDataPtr; }
+    GrGLsizeiptr size() const    { return fSize; }
+
+    void setMapped(bool mapped)  { fMapped = mapped; }
+    bool mapped() const          { return fMapped; }
+
+private:
+    GrGLuint     fID;
+    GrGLchar*    fDataPtr;
+    GrGLsizeiptr fSize;         // size in bytes
+    bool         fMapped;
+};
+
+// This class maintains a sparsely populated array of buffer pointers.
+class BufferManager {
+public:
+    BufferManager() : fFreeListHead(kFreeListEnd) {}
+
+    ~BufferManager() {
+        // nullptr out the entries that are really free list links rather than ptrs before deleting.
+        intptr_t curr = fFreeListHead;
+        while (kFreeListEnd != curr) {
+            intptr_t next = reinterpret_cast<intptr_t>(fBuffers[SkToS32(curr)]);
+            fBuffers[SkToS32(curr)] = nullptr;
+            curr = next;
+        }
+
+        fBuffers.deleteAll();
+    }
+
+    BufferObj* lookUp(GrGLuint id) {
+        BufferObj* buffer = fBuffers[id];
+        SkASSERT(buffer && buffer->id() == id);
+        return buffer;
+    }
+
+    BufferObj* create() {
+        GrGLuint id;
+        BufferObj* buffer;
+
+        if (kFreeListEnd == fFreeListHead) {
+            // no free slots - create a new one
+            id = fBuffers.count();
+            buffer = new BufferObj(id);
+            *fBuffers.append() = buffer;
+        } else {
+            // grab the head of the free list and advance the head to the next free slot.
+            id = static_cast<GrGLuint>(fFreeListHead);
+            fFreeListHead = reinterpret_cast<intptr_t>(fBuffers[id]);
+
+            buffer = new BufferObj(id);
+            fBuffers[id] = buffer;
+        }
+
+        return buffer;
+    }
+
+    void free(BufferObj* buffer) {
+        SkASSERT(fBuffers.count() > 0);
+
+        GrGLuint id = buffer->id();
+        delete buffer;
+
+        fBuffers[id] = reinterpret_cast<BufferObj*>(fFreeListHead);
+        fFreeListHead = id;
+    }
+
+private:
+    static const intptr_t kFreeListEnd = -1;
+    // Index of the first entry of fBuffers in the free list. Free slots in fBuffers are indices to
+    // the next free slot. The last free slot has a value of kFreeListEnd.
+    intptr_t                fFreeListHead;
+    SkTDArray<BufferObj*>   fBuffers;
+};
+
+/** Null interface implementation */
+class NullInterface : public GrGLTestInterface {
+public:
+    NullInterface()
+        : fCurrArrayBuffer(0)
+        , fCurrElementArrayBuffer(0)
+        , fCurrPixelPackBuffer(0)
+        , fCurrPixelUnpackBuffer(0)
+        , fCurrShaderID(0)
+        , fCurrGenericID(0)
+        , fCurrUniformLocation(0) {
+        this->init(kGL_GrGLStandard);
+    }
+
+    GrGLenum checkFramebufferStatus(GrGLenum target) override {
+        return GR_GL_FRAMEBUFFER_COMPLETE;
+    }
+
+    GrGLvoid genBuffers(GrGLsizei n, GrGLuint* ids) override {
+        for (int i = 0; i < n; ++i) {
+            BufferObj* buffer = fBufferManager.create();
+            ids[i] = buffer->id();
+        }
+    }
+
+    GrGLvoid bufferData(GrGLenum target, GrGLsizeiptr size, const GrGLvoid* data,
+                        GrGLenum usage) override {
+        GrGLuint id = 0;
+
+        switch (target) {
+            case GR_GL_ARRAY_BUFFER:
+                id = fCurrArrayBuffer;
+                break;
+            case GR_GL_ELEMENT_ARRAY_BUFFER:
+                id = fCurrElementArrayBuffer;
+                break;
+            case GR_GL_PIXEL_PACK_BUFFER:
+                id = fCurrPixelPackBuffer;
+                break;
+            case GR_GL_PIXEL_UNPACK_BUFFER:
+                id = fCurrPixelUnpackBuffer;
+                break;
+            default:
+                SkFAIL("Unexpected target to nullGLBufferData");
+                break;
+        }
+
+        if (id > 0) {
+            BufferObj* buffer = fBufferManager.lookUp(id);
+            buffer->allocate(size, (const GrGLchar*) data);
+        }
+    }
+
+    GrGLuint createProgram() override {
+        return ++fCurrProgramID;
+    }
+
+    GrGLuint createShader(GrGLenum type) override {
+        return ++fCurrShaderID;
+    }
+
+    GrGLvoid bindBuffer(GrGLenum target, GrGLuint buffer) override {
+        switch (target) {
+            case GR_GL_ARRAY_BUFFER:
+                fCurrArrayBuffer = buffer;
+                break;
+            case GR_GL_ELEMENT_ARRAY_BUFFER:
+                fCurrElementArrayBuffer = buffer;
+                break;
+            case GR_GL_PIXEL_PACK_BUFFER:
+                fCurrPixelPackBuffer = buffer;
+                break;
+            case GR_GL_PIXEL_UNPACK_BUFFER:
+                fCurrPixelUnpackBuffer = buffer;
+                break;
+        }
+    }
+
+    // deleting a bound buffer has the side effect of binding 0
+    GrGLvoid deleteBuffers(GrGLsizei n, const GrGLuint* ids) override {
+        for (int i = 0; i < n; ++i) {
+            if (ids[i] == fCurrArrayBuffer) {
+                fCurrArrayBuffer = 0;
+            }
+            if (ids[i] == fCurrElementArrayBuffer) {
+                fCurrElementArrayBuffer = 0;
+            }
+            if (ids[i] == fCurrPixelPackBuffer) {
+                fCurrPixelPackBuffer = 0;
+            }
+            if (ids[i] == fCurrPixelUnpackBuffer) {
+                fCurrPixelUnpackBuffer = 0;
+            }
+
+            BufferObj* buffer = fBufferManager.lookUp(ids[i]);
+            fBufferManager.free(buffer);
+        }
+    }
+
+    GrGLvoid genFramebuffers(GrGLsizei n, GrGLuint *framebuffers) override {
+        this->genGenericIds(n, framebuffers);
+    }
+
+    GrGLvoid genQueries(GrGLsizei n, GrGLuint *ids) override { this->genGenericIds(n, ids); }
+
+    GrGLvoid genRenderbuffers(GrGLsizei n, GrGLuint *renderbuffers) override {
+        this->genGenericIds(n, renderbuffers);
+    }
+
+    GrGLvoid genTextures(GrGLsizei n, GrGLuint *textures) override {
+        this->genGenericIds(n, textures);
+    }
+
+    GrGLvoid genVertexArrays(GrGLsizei n, GrGLuint *arrays) override {
+        this->genGenericIds(n, arrays);
+    }
+
+    GrGLenum getError() override { return GR_GL_NO_ERROR; }
+
+    GrGLvoid getIntegerv(GrGLenum pname, GrGLint* params) override {
+        // TODO: remove from Ganesh the #defines for gets we don't use.
+        // We would like to minimize gets overall due to performance issues
+        switch (pname) {
+            case GR_GL_CONTEXT_PROFILE_MASK:
+                *params = GR_GL_CONTEXT_COMPATIBILITY_PROFILE_BIT;
+                break;
+            case GR_GL_STENCIL_BITS:
+                *params = 8;
+                break;
+            case GR_GL_SAMPLES:
+                *params = 1;
+                break;
+            case GR_GL_FRAMEBUFFER_BINDING:
+                *params = 0;
+                break;
+            case GR_GL_VIEWPORT:
+                params[0] = 0;
+                params[1] = 0;
+                params[2] = 800;
+                params[3] = 600;
+                break;
+            case GR_GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:
+            case GR_GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS:
+            case GR_GL_MAX_TEXTURE_IMAGE_UNITS:
+            case GR_GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS:
+                *params = 8;
+                break;
+            case GR_GL_MAX_TEXTURE_COORDS:
+                *params = 8;
+                break;
+            case GR_GL_MAX_VERTEX_UNIFORM_VECTORS:
+                *params = kDefaultMaxVertexUniformVectors;
+                break;
+            case GR_GL_MAX_FRAGMENT_UNIFORM_VECTORS:
+                *params = kDefaultMaxFragmentUniformVectors;
+                break;
+            case GR_GL_MAX_FRAGMENT_UNIFORM_COMPONENTS:
+                *params = 16 * 4;
+                break;
+            case GR_GL_NUM_COMPRESSED_TEXTURE_FORMATS:
+                *params = 0;
+                break;
+            case GR_GL_COMPRESSED_TEXTURE_FORMATS:
+                break;
+            case GR_GL_MAX_TEXTURE_SIZE:
+                *params = 8192;
+                break;
+            case GR_GL_MAX_RENDERBUFFER_SIZE:
+                *params = 8192;
+                break;
+            case GR_GL_MAX_SAMPLES:
+                *params = 32;
+                break;
+            case GR_GL_MAX_VERTEX_ATTRIBS:
+                *params = kDefaultMaxVertexAttribs;
+                break;
+            case GR_GL_MAX_VARYING_VECTORS:
+                *params = kDefaultMaxVaryingVectors;
+                break;
+            case GR_GL_NUM_EXTENSIONS: {
+                GrGLint i = 0;
+                while (kExtensions[i++]);
+                *params = i;
+                break;
+            }
+            default:
+                SkFAIL("Unexpected pname to GetIntegerv");
+        }
+    }
+
+    GrGLvoid getProgramiv(GrGLuint program, GrGLenum pname, GrGLint* params) override {
+        this->getShaderOrProgramiv(program, pname, params);
+    }
+
+    GrGLvoid getProgramInfoLog(GrGLuint program, GrGLsizei bufsize, GrGLsizei* length,
+                               char* infolog) override {
+        this->getInfoLog(program, bufsize, length, infolog);
+    }
+
+    GrGLvoid getMultisamplefv(GrGLenum pname, GrGLuint index, GrGLfloat* val) override {
+        val[0] = val[1] = 0.5f;
+    }
+
+    GrGLvoid getQueryiv(GrGLenum GLtarget, GrGLenum pname, GrGLint *params) override {
+        switch (pname) {
+            case GR_GL_CURRENT_QUERY:
+                *params = 0;
+                break;
+            case GR_GL_QUERY_COUNTER_BITS:
+                *params = 32;
+                break;
+            default:
+                SkFAIL("Unexpected pname passed GetQueryiv.");
+        }
+    }
+
+    GrGLvoid getQueryObjecti64v(GrGLuint id, GrGLenum pname, GrGLint64 *params) override {
+        this->queryResult(id, pname, params);
+    }
+
+    GrGLvoid getQueryObjectiv(GrGLuint id, GrGLenum pname, GrGLint *params) override {
+        this->queryResult(id, pname, params);
+    }
+
+    GrGLvoid getQueryObjectui64v(GrGLuint id, GrGLenum pname, GrGLuint64 *params) override {
+        this->queryResult(id, pname, params);
+    }
+
+    GrGLvoid getQueryObjectuiv(GrGLuint id, GrGLenum pname, GrGLuint *params) override {
+        this->queryResult(id, pname, params);
+    }
+
+    GrGLvoid getShaderiv(GrGLuint shader, GrGLenum pname, GrGLint* params) override {
+        this->getShaderOrProgramiv(shader, pname, params);
+    }
+
+    GrGLvoid getShaderInfoLog(GrGLuint shader, GrGLsizei bufsize, GrGLsizei* length,
+                              char* infolog) override {
+        this->getInfoLog(shader, bufsize, length, infolog);
+    }
+
+    const GrGLubyte* getString(GrGLenum name) override {
+        switch (name) {
+            case GR_GL_EXTENSIONS:
+                return CombinedExtensionString();
+            case GR_GL_VERSION:
+                return (const GrGLubyte*)"4.0 Null GL";
+            case GR_GL_SHADING_LANGUAGE_VERSION:
+                return (const GrGLubyte*)"4.20.8 Null GLSL";
+            case GR_GL_VENDOR:
+                return (const GrGLubyte*)"Null Vendor";
+            case GR_GL_RENDERER:
+                return (const GrGLubyte*)"The Null (Non-)Renderer";
+            default:
+                SkFAIL("Unexpected name passed to GetString");
+                return nullptr;
+        }
+    }
+
+    const GrGLubyte* getStringi(GrGLenum name, GrGLuint i) override {
+        switch (name) {
+            case GR_GL_EXTENSIONS: {
+                GrGLint count;
+                this->getIntegerv(GR_GL_NUM_EXTENSIONS, &count);
+                if ((GrGLint)i <= count) {
+                    return (const GrGLubyte*) kExtensions[i];
+                } else {
+                    return nullptr;
+                }
+            }
+            default:
+                SkFAIL("Unexpected name passed to GetStringi");
+                return nullptr;
+        }
+    }
+
+    GrGLint getUniformLocation(GrGLuint program, const char* name) override {
+        return ++fCurrUniformLocation;
+    }
+
+    GrGLvoid* mapBufferRange(GrGLenum target, GrGLintptr offset, GrGLsizeiptr length,
+                             GrGLbitfield access) override {
+        GrGLuint id = 0;
+        switch (target) {
+            case GR_GL_ARRAY_BUFFER:
+                id = fCurrArrayBuffer;
+                break;
+            case GR_GL_ELEMENT_ARRAY_BUFFER:
+                id = fCurrElementArrayBuffer;
+                break;
+            case GR_GL_PIXEL_PACK_BUFFER:
+                id = fCurrPixelPackBuffer;
+                break;
+            case GR_GL_PIXEL_UNPACK_BUFFER:
+                id = fCurrPixelUnpackBuffer;
+                break;
+        }
+
+        if (id > 0) {
+            // We just ignore the offset and length here.
+            BufferObj* buffer = fBufferManager.lookUp(id);
+            SkASSERT(!buffer->mapped());
+            buffer->setMapped(true);
+            return buffer->dataPtr();
+        }
+        return nullptr;
+    }
+
+    GrGLvoid* mapBuffer(GrGLenum target, GrGLenum access) override {
+        GrGLuint id = 0;
+        switch (target) {
+            case GR_GL_ARRAY_BUFFER:
+                id = fCurrArrayBuffer;
+                break;
+            case GR_GL_ELEMENT_ARRAY_BUFFER:
+                id = fCurrElementArrayBuffer;
+                break;
+            case GR_GL_PIXEL_PACK_BUFFER:
+                id = fCurrPixelPackBuffer;
+                break;
+            case GR_GL_PIXEL_UNPACK_BUFFER:
+                id = fCurrPixelUnpackBuffer;
+                break;
+        }
+
+        if (id > 0) {
+            BufferObj* buffer = fBufferManager.lookUp(id);
+            SkASSERT(!buffer->mapped());
+            buffer->setMapped(true);
+            return buffer->dataPtr();
+        }
+
+        SkASSERT(false);
+        return nullptr;            // no buffer bound to target
+    }
+
+    GrGLboolean unmapBuffer(GrGLenum target) override {
+        GrGLuint id = 0;
+        switch (target) {
+            case GR_GL_ARRAY_BUFFER:
+                id = fCurrArrayBuffer;
+                break;
+            case GR_GL_ELEMENT_ARRAY_BUFFER:
+                id = fCurrElementArrayBuffer;
+                break;
+            case GR_GL_PIXEL_PACK_BUFFER:
+                id = fCurrPixelPackBuffer;
+                break;
+            case GR_GL_PIXEL_UNPACK_BUFFER:
+                id = fCurrPixelUnpackBuffer;
+                break;
+        }
+        if (id > 0) {
+            BufferObj* buffer = fBufferManager.lookUp(id);
+            SkASSERT(buffer->mapped());
+            buffer->setMapped(false);
+            return GR_GL_TRUE;
+        }
+
+        GrAlwaysAssert(false);
+        return GR_GL_FALSE; // GR_GL_INVALID_OPERATION;
+    }
+
+    GrGLvoid getBufferParameteriv(GrGLenum target, GrGLenum pname, GrGLint* params) override {
+        switch (pname) {
+            case GR_GL_BUFFER_MAPPED: {
+                *params = GR_GL_FALSE;
+                GrGLuint id = 0;
+                switch (target) {
+                    case GR_GL_ARRAY_BUFFER:
+                        id = fCurrArrayBuffer;
+                        break;
+                    case GR_GL_ELEMENT_ARRAY_BUFFER:
+                        id = fCurrElementArrayBuffer;
+                        break;
+                    case GR_GL_PIXEL_PACK_BUFFER:
+                        id = fCurrPixelPackBuffer;
+                        break;
+                    case GR_GL_PIXEL_UNPACK_BUFFER:
+                        id = fCurrPixelUnpackBuffer;
+                        break;
+                }
+                if (id > 0) {
+                    BufferObj* buffer = fBufferManager.lookUp(id);
+                    if (buffer->mapped()) {
+                        *params = GR_GL_TRUE;
+                    }
+                }
+                break; }
+            default:
+                SkFAIL("Unexpected pname to GetBufferParamateriv");
+                break;
+        }
+    };
+
+private:
+    BufferManager   fBufferManager;
+    GrGLuint        fCurrArrayBuffer;
+    GrGLuint        fCurrElementArrayBuffer;
+    GrGLuint        fCurrPixelPackBuffer;
+    GrGLuint        fCurrPixelUnpackBuffer;
+    GrGLuint        fCurrProgramID;
+    GrGLuint        fCurrShaderID;
+    GrGLuint        fCurrGenericID;
+    GrGLuint        fCurrUniformLocation;
+
+    // the OpenGLES 2.0 spec says this must be >= 128
+    static const GrGLint kDefaultMaxVertexUniformVectors = 128;
+
+    // the OpenGLES 2.0 spec says this must be >=16
+    static const GrGLint kDefaultMaxFragmentUniformVectors = 16;
+
+    // the OpenGLES 2.0 spec says this must be >= 8
+    static const GrGLint kDefaultMaxVertexAttribs = 8;
+
+    // the OpenGLES 2.0 spec says this must be >= 8
+    static const GrGLint kDefaultMaxVaryingVectors = 8;
+
+    static const char* kExtensions[];
+
+    static const GrGLubyte* CombinedExtensionString() {
+        static SkString gExtString;
+        static SkMutex gMutex;
+        gMutex.acquire();
+        if (0 == gExtString.size()) {
+            int i = 0;
+            while (kExtensions[i]) {
+                if (i > 0) {
+                    gExtString.append(" ");
+                }
+                gExtString.append(kExtensions[i]);
+                ++i;
+            }
+        }
+        gMutex.release();
+        return (const GrGLubyte*) gExtString.c_str();
+    }
+
+    GrGLvoid genGenericIds(GrGLsizei n, GrGLuint* ids) {
+        for (int i = 0; i < n; ++i) {
+            ids[i] = ++fCurrGenericID;
+        }
+    }
+
+    GrGLvoid getInfoLog(GrGLuint object, GrGLsizei bufsize, GrGLsizei* length,
+                        char* infolog) {
+        if (length) {
+            *length = 0;
+        }
+        if (bufsize > 0) {
+            *infolog = 0;
+        }
+    }
+
+    GrGLvoid getShaderOrProgramiv(GrGLuint object,  GrGLenum pname, GrGLint* params) {
+        switch (pname) {
+            case GR_GL_LINK_STATUS:  // fallthru
+            case GR_GL_COMPILE_STATUS:
+                *params = GR_GL_TRUE;
+                break;
+            case GR_GL_INFO_LOG_LENGTH:
+                *params = 0;
+                break;
+                // we don't expect any other pnames
+            default:
+                SkFAIL("Unexpected pname to GetProgramiv");
+                break;
+        }
+    }
+
+    template <typename T>
+    void queryResult(GrGLenum GLtarget, GrGLenum pname, T *params) {
+        switch (pname) {
+            case GR_GL_QUERY_RESULT_AVAILABLE:
+                *params = GR_GL_TRUE;
+                break;
+            case GR_GL_QUERY_RESULT:
+                *params = 0;
+                break;
+            default:
+                SkFAIL("Unexpected pname passed to GetQueryObject.");
+                break;
+        }
+    }
+
+    typedef GrGLTestInterface INHERITED;
+};
+
+const char* NullInterface::kExtensions[] = {
+    "GL_ARB_framebuffer_object",
+    "GL_ARB_blend_func_extended",
+    "GL_ARB_timer_query",
+    "GL_ARB_draw_buffers",
+    "GL_ARB_occlusion_query",
+    "GL_EXT_stencil_wrap",
+    nullptr, // signifies the end of the array.
+};
+
+class NullGLContext : public sk_gpu_test::GLContext {
+public:
+    NullGLContext() { this->init(new NullInterface); }
+   ~NullGLContext() override { this->teardown(); }
+
+private:    
+    void onPlatformMakeCurrent() const override {};
+    void onPlatformSwapBuffers() const override {}
+    GrGLFuncPtr onPlatformGetProcAddress(const char*) const override { return nullptr; }
+};
+}  // anonymous namespace
+
+namespace sk_gpu_test {
+GLContext* CreateNullGLContext() {
+    GLContext* ctx = new NullGLContext();
+    if (ctx->isValid()) {
+        return ctx;
+    }
+    delete ctx;
+    return nullptr;
+}
+}  // namespace sk_gpu_test
+
diff --git a/tools/gpu/gl/null/NullGLContext.h b/tools/gpu/gl/null/NullGLContext.h
new file mode 100644
index 0000000..16fb9fd
--- /dev/null
+++ b/tools/gpu/gl/null/NullGLContext.h
@@ -0,0 +1,17 @@
+
+/*
+ * Copyright 2011 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+#ifndef NullGLContext_DEFINED
+#define NullGLContext_DEFINED
+
+#include "gl/GLContext.h"
+
+namespace sk_gpu_test {
+GLContext* CreateNullGLContext();
+}  // namespace sk_gpu_test
+
+#endif
diff --git a/tools/gpu/gl/win/CreatePlatformGLContext_win.cpp b/tools/gpu/gl/win/CreatePlatformGLContext_win.cpp
new file mode 100644
index 0000000..efee28b
--- /dev/null
+++ b/tools/gpu/gl/win/CreatePlatformGLContext_win.cpp
@@ -0,0 +1,204 @@
+
+/*
+ * Copyright 2011 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "gl/GLContext.h"
+
+#include <windows.h>
+#include <GL/GL.h>
+#include "win/SkWGL.h"
+
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+
+namespace {
+
+class WinGLContext : public sk_gpu_test::GLContext {
+public:
+    WinGLContext(GrGLStandard forcedGpuAPI);
+	~WinGLContext() override;
+
+private:
+    void destroyGLContext();
+
+    void onPlatformMakeCurrent() const override;
+    void onPlatformSwapBuffers() const override;
+    GrGLFuncPtr onPlatformGetProcAddress(const char* name) const override;
+
+    HWND fWindow;
+    HDC fDeviceContext;
+    HGLRC fGlRenderContext;
+    static ATOM gWC;
+    SkWGLPbufferContext* fPbufferContext;
+};
+
+ATOM WinGLContext::gWC = 0;
+
+WinGLContext::WinGLContext(GrGLStandard forcedGpuAPI)
+    : fWindow(nullptr)
+    , fDeviceContext(nullptr)
+    , fGlRenderContext(0)
+    , fPbufferContext(nullptr) {
+    HINSTANCE hInstance = (HINSTANCE)GetModuleHandle(nullptr);
+
+    if (!gWC) {
+        WNDCLASS wc;
+        wc.cbClsExtra = 0;
+        wc.cbWndExtra = 0;
+        wc.hbrBackground = nullptr;
+        wc.hCursor = LoadCursor(nullptr, IDC_ARROW);
+        wc.hIcon = LoadIcon(nullptr, IDI_APPLICATION);
+        wc.hInstance = hInstance;
+        wc.lpfnWndProc = (WNDPROC) DefWindowProc;
+        wc.lpszClassName = TEXT("Griffin");
+        wc.lpszMenuName = nullptr;
+        wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
+
+        gWC = RegisterClass(&wc);
+        if (!gWC) {
+            SkDebugf("Could not register window class.\n");
+            return;
+        }
+    }
+
+    if (!(fWindow = CreateWindow(TEXT("Griffin"),
+                                 TEXT("The Invisible Man"),
+                                 WS_OVERLAPPEDWINDOW,
+                                 0, 0, 1, 1,
+                                 nullptr, nullptr,
+                                 hInstance, nullptr))) {
+        SkDebugf("Could not create window.\n");
+        return;
+    }
+
+    if (!(fDeviceContext = GetDC(fWindow))) {
+        SkDebugf("Could not get device context.\n");
+        this->destroyGLContext();
+        return;
+    }
+    // Requesting a Core profile would bar us from using NVPR. So we request
+    // compatibility profile or GL ES.
+    SkWGLContextRequest contextType =
+        kGLES_GrGLStandard == forcedGpuAPI ?
+        kGLES_SkWGLContextRequest : kGLPreferCompatibilityProfile_SkWGLContextRequest;
+
+    fPbufferContext = SkWGLPbufferContext::Create(fDeviceContext, 0, contextType);
+
+    HDC dc;
+    HGLRC glrc;
+
+    if (nullptr == fPbufferContext) {
+        if (!(fGlRenderContext = SkCreateWGLContext(fDeviceContext, 0, contextType))) {
+            SkDebugf("Could not create rendering context.\n");
+            this->destroyGLContext();
+            return;
+        }
+        dc = fDeviceContext;
+        glrc = fGlRenderContext;
+    } else {
+        ReleaseDC(fWindow, fDeviceContext);
+        fDeviceContext = 0;
+        DestroyWindow(fWindow);
+        fWindow = 0;
+
+        dc = fPbufferContext->getDC();
+        glrc = fPbufferContext->getGLRC();
+    }
+
+    if (!(wglMakeCurrent(dc, glrc))) {
+        SkDebugf("Could not set the context.\n");
+        this->destroyGLContext();
+        return;
+    }
+
+    SkAutoTUnref<const GrGLInterface> gl(GrGLCreateNativeInterface());
+    if (nullptr == gl.get()) {
+        SkDebugf("Could not create GL interface.\n");
+        this->destroyGLContext();
+        return;
+    }
+    if (!gl->validate()) {
+        SkDebugf("Could not validate GL interface.\n");
+        this->destroyGLContext();
+        return;
+    }
+
+    this->init(gl.release());
+}
+
+WinGLContext::~WinGLContext() {
+    this->teardown();
+    this->destroyGLContext();
+}
+
+void WinGLContext::destroyGLContext() {
+    SkSafeSetNull(fPbufferContext);
+    if (fGlRenderContext) {
+        wglDeleteContext(fGlRenderContext);
+        fGlRenderContext = 0;
+    }
+    if (fWindow && fDeviceContext) {
+        ReleaseDC(fWindow, fDeviceContext);
+        fDeviceContext = 0;
+    }
+    if (fWindow) {
+        DestroyWindow(fWindow);
+        fWindow = 0;
+    }
+}
+
+void WinGLContext::onPlatformMakeCurrent() const {
+    HDC dc;
+    HGLRC glrc;
+
+    if (nullptr == fPbufferContext) {
+        dc = fDeviceContext;
+        glrc = fGlRenderContext;
+    } else {
+        dc = fPbufferContext->getDC();
+        glrc = fPbufferContext->getGLRC();
+    }
+
+    if (!wglMakeCurrent(dc, glrc)) {
+        SkDebugf("Could not create rendering context.\n");
+    }
+}
+
+void WinGLContext::onPlatformSwapBuffers() const {
+    HDC dc;
+
+    if (nullptr == fPbufferContext) {
+        dc = fDeviceContext;
+    } else {
+        dc = fPbufferContext->getDC();
+    }
+    if (!SwapBuffers(dc)) {
+        SkDebugf("Could not complete SwapBuffers.\n");
+    }
+}
+
+GrGLFuncPtr WinGLContext::onPlatformGetProcAddress(const char* name) const {
+    return reinterpret_cast<GrGLFuncPtr>(wglGetProcAddress(name));
+}
+
+} // anonymous namespace
+
+namespace sk_gpu_test {
+GLContext* CreatePlatformGLContext(GrGLStandard forcedGpuAPI, GLContext *shareContext) {
+    SkASSERT(!shareContext);
+    if (shareContext) {
+        return nullptr;
+    }
+    WinGLContext *ctx = new WinGLContext(forcedGpuAPI);
+    if (!ctx->isValid()) {
+        delete ctx;
+        return nullptr;
+    }
+    return ctx;
+}
+}  // namespace sk_gpu_test
+
diff --git a/tools/kilobench/kilobench.cpp b/tools/kilobench/kilobench.cpp
index c0422d8..8123835 100644
--- a/tools/kilobench/kilobench.cpp
+++ b/tools/kilobench/kilobench.cpp
@@ -20,6 +20,7 @@
 #include "Timer.h"
 #include "VisualSKPBench.h"
 #include "gl/GrGLDefines.h"
+#include "gl/GrGLUtil.h"
 #include "../private/SkMutex.h"
 #include "../private/SkSemaphore.h"
 #include "../private/SkGpuFenceSync.h"
@@ -29,6 +30,8 @@
 #include <sys/types.h>
 #include <sys/wait.h>
 
+using namespace sk_gpu_test;
+
 /*
  * This is an experimental GPU only benchmarking program.  The initial implementation will only
  * support SKPs.
@@ -144,14 +147,14 @@
     void setup() {
         fGL->makeCurrent();
         // Make sure we're done with whatever came before.
-        SK_GL(*fGL, Finish());
+        GR_GL_CALL(fGL->gl(), Finish());
     }
 
     SkCanvas* beginTiming(SkCanvas* canvas) { return canvas; }
 
     void endTiming(bool usePlatformSwapBuffers) {
         if (fGL) {
-            SK_GL(*fGL, Flush());
+            GR_GL_CALL(fGL->gl(), Flush());
             if (usePlatformSwapBuffers) {
                 fGL->swapBuffers();
             } else {
@@ -160,7 +163,7 @@
         }
     }
     void finish() {
-        SK_GL(*fGL, Finish());
+        GR_GL_CALL(fGL->gl(), Finish());
     }
 
     bool needsFrameTiming(int* maxFrameLag) const {
@@ -215,10 +218,10 @@
         return true;
     }
 
-    SkGLContext* gl() { return fGL; }
+    GLContext* gl() { return fGL; }
 
 private:
-    SkGLContext* fGL;
+    GLContext* fGL;
     SkAutoTDelete<SkSurface> fSurface;
 };
 
@@ -279,7 +282,7 @@
 static double now_ms() { return SkTime::GetNSecs() * 1e-6; }
 
 struct TimingThread {
-    TimingThread(SkGLContext* mainContext)
+    TimingThread(GLContext* mainContext)
         : fFenceSync(mainContext->fenceSync())
         ,  fMainContext(mainContext)
         ,  fDone(false) {}
@@ -305,8 +308,8 @@
 
     void timingLoop() {
         // Create a context which shares display lists with the main thread
-        SkAutoTDelete<SkGLContext> glContext(SkCreatePlatformGLContext(kNone_GrGLStandard,
-                                                                       fMainContext));
+        SkAutoTDelete<GLContext> glContext(CreatePlatformGLContext(kNone_GrGLStandard,
+                                                                   fMainContext));
         glContext->makeCurrent();
 
         // Basic timing methodology is:
@@ -402,7 +405,7 @@
     SyncQueue fFrameEndSyncs;
     SkTArray<double> fTimings;
     SkMutex fDoneMutex;
-    SkGLContext* fMainContext;
+    GLContext* fMainContext;
     bool fDone;
 };
 
diff --git a/tools/skiaserve/Request.cpp b/tools/skiaserve/Request.cpp
index 1d946ab..d9e1bda 100644
--- a/tools/skiaserve/Request.cpp
+++ b/tools/skiaserve/Request.cpp
@@ -10,6 +10,8 @@
 #include "SkPictureRecorder.h"
 #include "SkPixelSerializer.h"
 
+using namespace sk_gpu_test;
+
 static int kDefaultWidth = 1920;
 static int kDefaultHeight = 1080;
 
@@ -63,8 +65,8 @@
 SkCanvas* Request::getCanvas() {
 #if SK_SUPPORT_GPU
     GrContextFactory* factory = fContextFactory;
-    SkGLContext* gl = factory->getContextInfo(GrContextFactory::kNative_GLContextType,
-                                              GrContextFactory::kNone_GLContextOptions).fGLContext;
+    GLContext* gl = factory->getContextInfo(GrContextFactory::kNative_GLContextType,
+                                            GrContextFactory::kNone_GLContextOptions).fGLContext;
     gl->makeCurrent();
 #endif
     SkASSERT(fDebugCanvas);
diff --git a/tools/skiaserve/Request.h b/tools/skiaserve/Request.h
index e3bc373..d19c2ba 100644
--- a/tools/skiaserve/Request.h
+++ b/tools/skiaserve/Request.h
@@ -19,7 +19,9 @@
 
 #include "UrlDataManager.h"
 
+namespace sk_gpu_test {
 class GrContextFactory;
+}
 struct MHD_Connection;
 struct MHD_PostProcessor;
 
@@ -69,7 +71,7 @@
     GrContext* getContext();
 
     sk_sp<SkPicture> fPicture;
-    GrContextFactory* fContextFactory;
+    sk_gpu_test::GrContextFactory* fContextFactory;
     SkAutoTUnref<SkSurface> fSurface;
     bool fGPUEnabled;
 };
