/*
 * 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 "GrNonAtomicRef.h"
#include "gl/GrGLInterface.h"
#include "GrGLTestInterface.h"
#include "SkMutex.h"
#include "SkTDArray.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);
        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 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:
                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*) fAdvertisedExtensions[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 = 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:
                SkFAIL("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:                           SkFAIL("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:
                *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;
};

}  // anonymous namespace

const GrGLInterface* GrGLCreateNullInterface(bool enableNVPR) { return new NullInterface(enableNVPR); }
