
/*
 * 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;
}
}
