
/*
 * 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 "gl/GrGLInterface.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.
};

}  // anonymous namespace

////////////////////////////////////////////////////////////////////////////////

const GrGLInterface* GrGLCreateDebugInterface() { return new DebugInterface; }
