diff --git a/libs/hwui/Android.bp b/libs/hwui/Android.bp
index ebba4cb..9fe53d3 100644
--- a/libs/hwui/Android.bp
+++ b/libs/hwui/Android.bp
@@ -101,6 +101,7 @@
         "debug/GlesDriver.cpp",
         "debug/FatalBaseDriver.cpp",
         "debug/NullGlesDriver.cpp",
+        "debug/NullSkiaInterface.cpp",
     ],
     include_dirs: ["frameworks/native/opengl/libs/GLES2"],
 }
diff --git a/libs/hwui/debug/NullGlesDriver.cpp b/libs/hwui/debug/NullGlesDriver.cpp
index 212b242..f27adf0 100644
--- a/libs/hwui/debug/NullGlesDriver.cpp
+++ b/libs/hwui/debug/NullGlesDriver.cpp
@@ -20,8 +20,10 @@
 namespace uirenderer {
 namespace debug {
 
+extern const GrGLInterface* CreateNullSkiaInterface();
+
 sk_sp<const GrGLInterface> NullGlesDriver::getSkiaInterface() {
-    sk_sp<const GrGLInterface> skiaInterface(GrGLCreateNullInterface());
+    sk_sp<const GrGLInterface> skiaInterface(CreateNullSkiaInterface());
     return skiaInterface;
 }
 
diff --git a/libs/hwui/debug/NullSkiaInterface.cpp b/libs/hwui/debug/NullSkiaInterface.cpp
new file mode 100644
index 0000000..b5438cb
--- /dev/null
+++ b/libs/hwui/debug/NullSkiaInterface.cpp
@@ -0,0 +1,852 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// TODO: Remove this file. This has been temporarily copied from Skia (where this class is
+// deprecated). The NullGlesDriver should be constructing a GrGLInterface that calls *its*
+// GL functions!
+
+#include "gl/GrGLTestInterface.h"
+#include "GrNonAtomicRef.h"
+#include "SkMutex.h"
+#include "SkTDArray.h"
+#include "SkTo.h"
+#include "gl/GrGLInterface.h"
+
+#include <type_traits>
+
+// added to suppress 'no previous prototype' warning and because this code is duplicated in
+// SkNullGLContext.cpp
+namespace {
+
+class GLObject : public GrNonAtomicRef<GLObject> {
+public:
+    GLObject(GrGLuint id) : fID(id) {}
+    virtual ~GLObject() {}
+
+    GrGLuint id() const { return fID; }
+
+private:
+    GrGLuint fID;
+};
+
+// This class maintains a sparsely populated array of object pointers.
+template<typename T> class TGLObjectManager {
+   static_assert(std::is_convertible<T*, GLObject*>::value, "T must be a subclass of GLObject");
+
+public:
+    TGLObjectManager() : fFreeListHead(kFreeListEnd) {
+        *fGLObjects.append() = nullptr; // 0 is not a valid GL object id.
+    }
+
+    ~TGLObjectManager() {
+        // 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>(fGLObjects[SkToS32(curr)]);
+            fGLObjects[SkToS32(curr)] = nullptr;
+            curr = next;
+        }
+
+        fGLObjects.safeUnrefAll();
+    }
+
+    T* lookUp(GrGLuint id) {
+        T* object = fGLObjects[id];
+        SkASSERT(object && object->id() == id);
+        return object;
+    }
+
+    T* create() {
+        GrGLuint id;
+        T* object;
+
+        if (kFreeListEnd == fFreeListHead) {
+            // no free slots - create a new one
+            id = fGLObjects.count();
+            object = new T(id);
+            *fGLObjects.append() = object;
+        } 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>(fGLObjects[id]);
+
+            object = new T(id);
+            fGLObjects[id] = object;
+        }
+
+        return object;
+    }
+
+    void free(T* object) {
+        SkASSERT(object);
+        SkASSERT(fGLObjects.count() > 0);
+
+        GrGLuint id = object->id();
+        object->unref();
+
+        fGLObjects[id] = reinterpret_cast<T*>(fFreeListHead);
+        fFreeListHead = id;
+    }
+
+private:
+    static const intptr_t kFreeListEnd = -1;
+    // Index of the first entry of fGLObjects in the free list. Free slots in fGLObjects are indices
+    // to the next free slot. The last free slot has a value of kFreeListEnd.
+    intptr_t        fFreeListHead;
+    SkTDArray<T*>   fGLObjects;
+};
+
+class Buffer : public GLObject {
+public:
+    Buffer(GrGLuint id) : INHERITED(id), fDataPtr(nullptr), fSize(0), fMapped(false) {}
+    ~Buffer() { delete[] fDataPtr; }
+
+    void allocate(GrGLsizeiptr size, const GrGLchar* dataPtr) {
+        if (fDataPtr) {
+            SkASSERT(0 != fSize);
+            delete[] fDataPtr;
+        }
+
+        fSize = size;
+        fDataPtr = new char[size];
+    }
+
+    GrGLchar* dataPtr()          { return fDataPtr; }
+    GrGLsizeiptr size() const    { return fSize; }
+
+    void setMapped(bool mapped)  { fMapped = mapped; }
+    bool mapped() const          { return fMapped; }
+
+private:
+    GrGLchar*    fDataPtr;
+    GrGLsizeiptr fSize;         // size in bytes
+    bool         fMapped;
+
+    typedef GLObject INHERITED;
+};
+
+class FramebufferAttachment : public GLObject {
+public:
+    int numSamples() const { return fNumSamples; }
+
+protected:
+    FramebufferAttachment(int id) : INHERITED(id), fNumSamples(1) {}
+
+    int fNumSamples;
+
+    typedef GLObject INHERITED;
+};
+
+class Renderbuffer : public FramebufferAttachment {
+public:
+    Renderbuffer(int id) : INHERITED(id) {}
+    void setNumSamples(int numSamples) { fNumSamples = numSamples; }
+
+private:
+    typedef FramebufferAttachment INHERITED;
+};
+
+class Texture : public FramebufferAttachment {
+public:
+    Texture() : INHERITED(1) {}
+
+private:
+    typedef FramebufferAttachment INHERITED;
+};
+
+class Framebuffer : public GLObject {
+public:
+    Framebuffer(int id) : INHERITED(id) {}
+
+    void setAttachment(GrGLenum attachmentPoint, const FramebufferAttachment* attachment) {
+        switch (attachmentPoint) {
+            default:
+                SK_ABORT("Invalid framebuffer attachment.");
+                break;
+            case GR_GL_STENCIL_ATTACHMENT:
+                fAttachments[(int)AttachmentPoint::kStencil].reset(SkRef(attachment));
+                break;
+            case GR_GL_DEPTH_ATTACHMENT:
+                fAttachments[(int)AttachmentPoint::kDepth].reset(SkRef(attachment));
+                break;
+            case GR_GL_COLOR_ATTACHMENT0:
+                fAttachments[(int)AttachmentPoint::kColor].reset(SkRef(attachment));
+                break;
+        }
+    }
+
+    void notifyAttachmentDeleteWhileBound(const FramebufferAttachment* deleted) {
+        for (auto& attachment : fAttachments) {
+            if (attachment.get() == deleted) {
+                attachment.reset(nullptr);
+            }
+        }
+    }
+
+    int numSamples() const {
+        int numSamples = 0;
+        for (auto& attachment : fAttachments) {
+            if (!attachment) {
+                continue;
+            }
+            if (numSamples) {
+                GrAlwaysAssert(attachment->numSamples() == numSamples);
+                continue;
+            }
+            numSamples = attachment->numSamples();
+        }
+        GrAlwaysAssert(numSamples);
+        return numSamples;
+    }
+
+private:
+    enum AttachmentPoint {
+        kStencil,
+        kDepth,
+        kColor
+    };
+    constexpr int static kNumAttachmentPoints = 1 + (int)AttachmentPoint::kColor;
+
+    sk_sp<const FramebufferAttachment> fAttachments[kNumAttachmentPoints];
+
+    typedef GLObject INHERITED;
+};
+
+/** Null interface implementation */
+class NullInterface : public GrGLTestInterface {
+public:
+    NullInterface(bool enableNVPR)
+        : fCurrDrawFramebuffer(0)
+        , fCurrReadFramebuffer(0)
+        , fCurrRenderbuffer(0)
+        , fCurrProgramID(0)
+        , fCurrShaderID(0)
+        , fCurrGenericID(0)
+        , fCurrUniformLocation(0)
+        , fCurrPathID(0) {
+        memset(fBoundBuffers, 0, sizeof(fBoundBuffers));
+        fAdvertisedExtensions.push_back("GL_ARB_framebuffer_object");
+        fAdvertisedExtensions.push_back("GL_ARB_blend_func_extended");
+        fAdvertisedExtensions.push_back("GL_ARB_timer_query");
+        fAdvertisedExtensions.push_back("GL_ARB_draw_buffers");
+        fAdvertisedExtensions.push_back("GL_ARB_occlusion_query");
+        fAdvertisedExtensions.push_back("GL_EXT_stencil_wrap");
+        if (enableNVPR) {
+            fAdvertisedExtensions.push_back("GL_NV_path_rendering");
+            fAdvertisedExtensions.push_back("GL_ARB_program_interface_query");
+        }
+        fAdvertisedExtensions.push_back(nullptr);
+
+        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) {
+            Buffer* buffer = fBufferManager.create();
+            ids[i] = buffer->id();
+        }
+    }
+
+    GrGLvoid bufferData(GrGLenum target, GrGLsizeiptr size, const GrGLvoid* data,
+                        GrGLenum usage) override {
+        GrGLuint id = fBoundBuffers[GetBufferIndex(target)];
+        if (id > 0) {
+            Buffer* 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 {
+        fBoundBuffers[GetBufferIndex(target)] = buffer;
+    }
+
+   // 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 buffIdx = 0; buffIdx < kNumBufferTargets; ++buffIdx) {
+            if (!fBoundBuffers[buffIdx]) {
+                continue;
+            }
+            for (int i = 0; i < n; ++i) {
+                if (ids[i] == fBoundBuffers[buffIdx]) {
+                    fBoundBuffers[buffIdx] = 0;
+                    break;
+                }
+            }
+        }
+
+        // Then actually "delete" the buffers.
+        for (int i = 0; i < n; ++i) {
+            if (ids[i] > 0) {
+                Buffer* buffer = fBufferManager.lookUp(ids[i]);
+                fBufferManager.free(buffer);
+            }
+        }
+    }
+
+    GrGLvoid genFramebuffers(GrGLsizei n, GrGLuint *framebuffers) override {
+        for (int i = 0; i < n; ++i) {
+            Framebuffer* framebuffer = fFramebufferManager.create();
+            framebuffers[i] = framebuffer->id();
+        }
+    }
+
+    GrGLvoid bindFramebuffer(GrGLenum target, GrGLuint framebuffer) override {
+        SkASSERT(GR_GL_FRAMEBUFFER == target || GR_GL_DRAW_FRAMEBUFFER == target ||
+                 GR_GL_READ_FRAMEBUFFER == target);
+        if (GR_GL_READ_FRAMEBUFFER != target) {
+            fCurrDrawFramebuffer = framebuffer;
+        }
+        if (GR_GL_DRAW_FRAMEBUFFER != target) {
+            fCurrReadFramebuffer = framebuffer;
+        }
+    }
+
+    GrGLvoid deleteFramebuffers(GrGLsizei n, const GrGLuint* ids) override {
+        for (int i = 0; i < n; ++i) {
+            if (ids[i] == fCurrDrawFramebuffer) {
+                fCurrDrawFramebuffer = 0;
+            }
+            if (ids[i] == fCurrReadFramebuffer) {
+                fCurrReadFramebuffer = 0;
+            }
+
+            if (ids[i] > 0) {
+                Framebuffer* framebuffer = fFramebufferManager.lookUp(ids[i]);
+                fFramebufferManager.free(framebuffer);
+            }
+        }
+    }
+
+    GrGLvoid genQueries(GrGLsizei n, GrGLuint *ids) override { this->genGenericIds(n, ids); }
+
+    GrGLvoid genRenderbuffers(GrGLsizei n, GrGLuint *renderbuffers) override {
+        for (int i = 0; i < n; ++i) {
+            Renderbuffer* renderbuffer = fRenderbufferManager.create();
+            renderbuffers[i] = renderbuffer->id();
+        }
+    }
+
+    GrGLvoid bindRenderbuffer(GrGLenum target, GrGLuint renderbuffer) override {
+        SkASSERT(GR_GL_RENDERBUFFER == target);
+        fCurrRenderbuffer = renderbuffer;
+    }
+
+    GrGLvoid deleteRenderbuffers(GrGLsizei n, const GrGLuint* ids) override {
+        for (int i = 0; i < n; ++i) {
+            if (ids[i] <= 0) {
+                continue;
+            }
+            if (ids[i] == fCurrRenderbuffer) {
+                fCurrRenderbuffer = 0;
+            }
+            Renderbuffer* renderbuffer = fRenderbufferManager.lookUp(ids[i]);
+
+            if (fCurrDrawFramebuffer) {
+                Framebuffer* drawFramebuffer = fFramebufferManager.lookUp(fCurrDrawFramebuffer);
+                drawFramebuffer->notifyAttachmentDeleteWhileBound(renderbuffer);
+            }
+            if (fCurrReadFramebuffer) {
+                Framebuffer* readFramebuffer = fFramebufferManager.lookUp(fCurrReadFramebuffer);
+                readFramebuffer->notifyAttachmentDeleteWhileBound(renderbuffer);
+            }
+
+            fRenderbufferManager.free(renderbuffer);
+        }
+    }
+
+    GrGLvoid renderbufferStorage(GrGLenum target, GrGLenum internalformat, GrGLsizei width,
+                                 GrGLsizei height) override {
+        GrAlwaysAssert(GR_GL_RENDERBUFFER == target);
+        GrAlwaysAssert(fCurrRenderbuffer);
+        Renderbuffer* renderbuffer = fRenderbufferManager.lookUp(fCurrRenderbuffer);
+        renderbuffer->setNumSamples(1);
+    }
+
+    GrGLvoid renderbufferStorageMultisample(GrGLenum target, GrGLsizei samples,
+                                            GrGLenum internalformat, GrGLsizei width,
+                                            GrGLsizei height) override {
+        GrAlwaysAssert(GR_GL_RENDERBUFFER == target);
+        GrAlwaysAssert(samples > 0);
+        GrAlwaysAssert(fCurrRenderbuffer);
+        Renderbuffer* renderbuffer = fRenderbufferManager.lookUp(fCurrRenderbuffer);
+        renderbuffer->setNumSamples(samples);
+    }
+
+    GrGLvoid namedRenderbufferStorage(GrGLuint renderbuffer, GrGLenum GrGLinternalformat,
+                                      GrGLsizei width, GrGLsizei height) override {
+        SK_ABORT("Not implemented");
+    }
+
+    GrGLvoid namedRenderbufferStorageMultisample(GrGLuint renderbuffer, GrGLsizei samples,
+                                                 GrGLenum GrGLinternalformat, GrGLsizei width,
+                                                 GrGLsizei height) override {
+        SK_ABORT("Not implemented");
+    }
+
+    GrGLvoid framebufferRenderbuffer(GrGLenum target, GrGLenum attachment,
+                                     GrGLenum renderbuffertarget,
+                                     GrGLuint renderBufferID) override {
+        GrGLuint id = this->getBoundFramebufferID(target);
+        GrAlwaysAssert(id);
+        Framebuffer* framebuffer = fFramebufferManager.lookUp(id);
+
+        GrAlwaysAssert(GR_GL_RENDERBUFFER == renderbuffertarget);
+        if (!renderBufferID && !fCurrRenderbuffer) {
+           return;
+        }
+        GrAlwaysAssert(fCurrRenderbuffer);
+        Renderbuffer* renderbuffer = fRenderbufferManager.lookUp(fCurrRenderbuffer);
+
+        framebuffer->setAttachment(attachment, renderbuffer);
+    }
+
+    GrGLvoid namedFramebufferRenderbuffer(GrGLuint framebuffer, GrGLenum attachment,
+                                          GrGLenum renderbuffertarget,
+                                          GrGLuint renderbuffer) override {
+        SK_ABORT("Not implemented");
+    }
+
+    GrGLvoid genSamplers(GrGLsizei n, GrGLuint* samplers) override {
+        this->genGenericIds(n, samplers);
+    }
+
+    GrGLvoid genTextures(GrGLsizei n, GrGLuint *textures) override {
+        this->genGenericIds(n, textures);
+    }
+
+    GrGLvoid framebufferTexture2D(GrGLenum target, GrGLenum attachment, GrGLenum textarget,
+                                  GrGLuint textureID, GrGLint level) override {
+        GrGLuint id = this->getBoundFramebufferID(target);
+        GrAlwaysAssert(id);
+        Framebuffer* framebuffer = fFramebufferManager.lookUp(id);
+        framebuffer->setAttachment(attachment, this->getSingleTextureObject());
+    }
+
+    GrGLvoid framebufferTexture2DMultisample(GrGLenum target, GrGLenum attachment,
+                                             GrGLenum textarget, GrGLuint texture, GrGLint level,
+                                             GrGLsizei samples) override {
+        SK_ABORT("Not implemented");
+    }
+
+    GrGLvoid namedFramebufferTexture1D(GrGLuint framebuffer, GrGLenum attachment,
+                                       GrGLenum textarget, GrGLuint texture,
+                                       GrGLint level) override {
+        SK_ABORT("Not implemented");
+    }
+
+    GrGLvoid namedFramebufferTexture2D(GrGLuint framebuffer, GrGLenum attachment,
+                                       GrGLenum textarget, GrGLuint texture,
+                                       GrGLint level) override {
+        SK_ABORT("Not implemented");
+    }
+
+    GrGLvoid namedFramebufferTexture3D(GrGLuint framebuffer, GrGLenum attachment,
+                                       GrGLenum textarget, GrGLuint texture, GrGLint level,
+                                       GrGLint zoffset) override {
+        SK_ABORT("Not implemented");
+    }
+
+    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: {
+                GrAlwaysAssert(fCurrDrawFramebuffer);
+                Framebuffer* framebuffer = fFramebufferManager.lookUp(fCurrDrawFramebuffer);
+                *params = framebuffer->numSamples();
+                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 (fAdvertisedExtensions[i++]);
+                *params = i;
+                break;
+            }
+            default:
+                SK_ABORT("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:
+                SK_ABORT("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:
+                SK_ABORT("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*) fAdvertisedExtensions[i];
+                } else {
+                    return nullptr;
+                }
+            }
+            default:
+                SK_ABORT("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 = fBoundBuffers[GetBufferIndex(target)];
+        if (id > 0) {
+            // We just ignore the offset and length here.
+            Buffer* buffer = fBufferManager.lookUp(id);
+            SkASSERT(!buffer->mapped());
+            buffer->setMapped(true);
+            return buffer->dataPtr();
+        }
+        return nullptr;
+    }
+
+    GrGLvoid* mapBuffer(GrGLenum target, GrGLenum access) override {
+        GrGLuint id = fBoundBuffers[GetBufferIndex(target)];
+        if (id > 0) {
+            Buffer* 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 = fBoundBuffers[GetBufferIndex(target)];
+        if (id > 0) {
+            Buffer* 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 = fBoundBuffers[GetBufferIndex(target)];
+                if (id > 0) {
+                    Buffer* buffer = fBufferManager.lookUp(id);
+                    if (buffer->mapped()) {
+                        *params = GR_GL_TRUE;
+                    }
+                }
+                break; }
+            default:
+                SK_ABORT("Unexpected pname to GetBufferParamateriv");
+                break;
+        }
+    }
+
+    // NV_path_rendering
+    GrGLuint genPaths(GrGLsizei range) override {
+        return ++fCurrPathID;
+    }
+
+
+private:
+    inline int static GetBufferIndex(GrGLenum glTarget) {
+        switch (glTarget) {
+            default:                           SK_ABORT("Unexpected GL target to GetBufferIndex");
+            case GR_GL_ARRAY_BUFFER:           return 0;
+            case GR_GL_ELEMENT_ARRAY_BUFFER:   return 1;
+            case GR_GL_TEXTURE_BUFFER:         return 2;
+            case GR_GL_DRAW_INDIRECT_BUFFER:   return 3;
+            case GR_GL_PIXEL_PACK_BUFFER:      return 4;
+            case GR_GL_PIXEL_UNPACK_BUFFER:    return 5;
+        }
+    }
+    constexpr int static kNumBufferTargets = 6;
+
+    TGLObjectManager<Buffer>         fBufferManager;
+    GrGLuint                         fBoundBuffers[kNumBufferTargets];
+    TGLObjectManager<Framebuffer>    fFramebufferManager;
+    GrGLuint                         fCurrDrawFramebuffer;
+    GrGLuint                         fCurrReadFramebuffer;
+    TGLObjectManager<Renderbuffer>   fRenderbufferManager;
+    GrGLuint                         fCurrRenderbuffer;
+    GrGLuint                         fCurrProgramID;
+    GrGLuint                         fCurrShaderID;
+    GrGLuint                         fCurrGenericID;
+    GrGLuint                         fCurrUniformLocation;
+    GrGLuint                         fCurrPathID;
+    sk_sp<const Texture>             fSingleTextureObject;
+    SkTArray<const char*>            fAdvertisedExtensions;
+
+    // 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;
+
+    GrGLuint getBoundFramebufferID(GrGLenum target) {
+        switch (target) {
+            case GR_GL_FRAMEBUFFER:
+            case GR_GL_DRAW_FRAMEBUFFER:
+                return fCurrDrawFramebuffer;
+            case GR_GL_READ_FRAMEBUFFER:
+                return fCurrReadFramebuffer;
+            default:
+                SK_ABORT("Invalid framebuffer target.");
+                return 0;
+        }
+    }
+
+    const Texture* getSingleTextureObject() {
+        // We currently only use FramebufferAttachment objects for a sample count, and all textures
+        // in Skia have one sample, so there is no need as of yet to track individual textures. This
+        // also works around a bug in chromium's cc_unittests where they send us texture IDs that
+        // were generated by cc::TestGLES2Interface.
+        if (!fSingleTextureObject) {
+            fSingleTextureObject.reset(new Texture);
+        }
+        return fSingleTextureObject.get();
+    }
+
+    const GrGLubyte* CombinedExtensionString() {
+        static SkString gExtString;
+        static SkMutex gMutex;
+        gMutex.acquire();
+        if (0 == gExtString.size()) {
+            int i = 0;
+            while (fAdvertisedExtensions[i]) {
+                if (i > 0) {
+                    gExtString.append(" ");
+                }
+                gExtString.append(fAdvertisedExtensions[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: // fallthru
+            case GL_PROGRAM_BINARY_LENGTH:
+                *params = 0;
+                break;
+                // we don't expect any other pnames
+            default:
+                SK_ABORT("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:
+                SK_ABORT("Unexpected pname passed to GetQueryObject.");
+                break;
+        }
+    }
+
+    typedef GrGLTestInterface INHERITED;
+};
+
+}  // anonymous namespace
+
+namespace android {
+namespace uirenderer {
+namespace debug {
+
+const GrGLInterface* CreateNullSkiaInterface() { return new NullInterface(false); }
+
+}  // namespace debug
+}  // namespace uirenderer
+}  // namespace android
