/*
 * Copyright 2011 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */


#include "gl/GrGLInterface.h"
#include "GrGLTestInterface.h"
#include "SkMutex.h"
#include "SkTDArray.h"

// added to suppress 'no previous prototype' warning and because this code is duplicated in
// SkNullGLContext.cpp
namespace {

class BufferObj {
public:
    BufferObj(GrGLuint id) : fID(id), fDataPtr(nullptr), fSize(0), fMapped(false) {}
    ~BufferObj() { delete[] fDataPtr; }

    void allocate(GrGLsizeiptr size, const GrGLchar* dataPtr) {
        if (fDataPtr) {
            SkASSERT(0 != fSize);
            delete[] fDataPtr;
        }

        fSize = size;
        fDataPtr = new char[size];
    }

    GrGLuint id() const          { return fID; }
    GrGLchar* dataPtr()          { return fDataPtr; }
    GrGLsizeiptr size() const    { return fSize; }

    void setMapped(bool mapped)  { fMapped = mapped; }
    bool mapped() const          { return fMapped; }

private:
    GrGLuint     fID;
    GrGLchar*    fDataPtr;
    GrGLsizeiptr fSize;         // size in bytes
    bool         fMapped;
};

// This class maintains a sparsely populated array of buffer pointers.
class BufferManager {
public:
    BufferManager() : fFreeListHead(kFreeListEnd) {
        *fBuffers.append() = nullptr; // 0 is not a valid GL buffer id.
    }

    ~BufferManager() {
        // nullptr out the entries that are really free list links rather than ptrs before deleting.
        intptr_t curr = fFreeListHead;
        while (kFreeListEnd != curr) {
            intptr_t next = reinterpret_cast<intptr_t>(fBuffers[SkToS32(curr)]);
            fBuffers[SkToS32(curr)] = nullptr;
            curr = next;
        }

        fBuffers.deleteAll();
    }

    BufferObj* lookUp(GrGLuint id) {
        BufferObj* buffer = fBuffers[id];
        SkASSERT(buffer && buffer->id() == id);
        return buffer;
    }

    BufferObj* create() {
        GrGLuint id;
        BufferObj* buffer;

        if (kFreeListEnd == fFreeListHead) {
            // no free slots - create a new one
            id = fBuffers.count();
            buffer = new BufferObj(id);
            *fBuffers.append() = buffer;
        } else {
            // grab the head of the free list and advance the head to the next free slot.
            id = static_cast<GrGLuint>(fFreeListHead);
            fFreeListHead = reinterpret_cast<intptr_t>(fBuffers[id]);

            buffer = new BufferObj(id);
            fBuffers[id] = buffer;
        }

        return buffer;
    }

    void free(BufferObj* buffer) {
        SkASSERT(buffer);
        SkASSERT(fBuffers.count() > 0);

        GrGLuint id = buffer->id();
        delete buffer;

        fBuffers[id] = reinterpret_cast<BufferObj*>(fFreeListHead);
        fFreeListHead = id;
    }

private:
    static const intptr_t kFreeListEnd = -1;
    // Index of the first entry of fBuffers in the free list. Free slots in fBuffers are indices to
    // the next free slot. The last free slot has a value of kFreeListEnd.
    intptr_t                fFreeListHead;
    SkTDArray<BufferObj*>   fBuffers;
};

/** Null interface implementation */
class NullInterface : public GrGLTestInterface {
public:
    NullInterface(bool enableNVPR)
        : fCurrArrayBuffer(0)
        , fCurrElementArrayBuffer(0)
        , fCurrPixelPackBuffer(0)
        , fCurrPixelUnpackBuffer(0)
        , fCurrProgramID(0)
        , fCurrShaderID(0)
        , fCurrGenericID(0)
        , fCurrUniformLocation(0)
        , fCurrPathID(0) {
        fExtensions.push_back("GL_ARB_framebuffer_object");
        fExtensions.push_back("GL_ARB_blend_func_extended");
        fExtensions.push_back("GL_ARB_timer_query");
        fExtensions.push_back("GL_ARB_draw_buffers");
        fExtensions.push_back("GL_ARB_occlusion_query");
        fExtensions.push_back("GL_EXT_stencil_wrap");
        if (enableNVPR) {
            fExtensions.push_back("GL_NV_path_rendering");
            fExtensions.push_back("GL_ARB_program_interface_query");
        }
        fExtensions.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) {
            BufferObj* buffer = fBufferManager.create();
            ids[i] = buffer->id();
        }
    }

    GrGLvoid bufferData(GrGLenum target, GrGLsizeiptr size, const GrGLvoid* data,
                        GrGLenum usage) override {
        GrGLuint id = 0;

        switch (target) {
            case GR_GL_ARRAY_BUFFER:
                id = fCurrArrayBuffer;
                break;
            case GR_GL_ELEMENT_ARRAY_BUFFER:
                id = fCurrElementArrayBuffer;
                break;
            case GR_GL_PIXEL_PACK_BUFFER:
                id = fCurrPixelPackBuffer;
                break;
            case GR_GL_PIXEL_UNPACK_BUFFER:
                id = fCurrPixelUnpackBuffer;
                break;
            default:
                SkFAIL("Unexpected target to nullGLBufferData");
                break;
        }

        if (id > 0) {
            BufferObj* buffer = fBufferManager.lookUp(id);
            buffer->allocate(size, (const GrGLchar*) data);
        }
    }

    GrGLuint createProgram() override {
        return ++fCurrProgramID;
    }

    GrGLuint createShader(GrGLenum type) override {
        return ++fCurrShaderID;
    }

    GrGLvoid bindBuffer(GrGLenum target, GrGLuint buffer) override {
        switch (target) {
            case GR_GL_ARRAY_BUFFER:
                fCurrArrayBuffer = buffer;
                break;
            case GR_GL_ELEMENT_ARRAY_BUFFER:
                fCurrElementArrayBuffer = buffer;
                break;
            case GR_GL_PIXEL_PACK_BUFFER:
                fCurrPixelPackBuffer = buffer;
                break;
            case GR_GL_PIXEL_UNPACK_BUFFER:
                fCurrPixelUnpackBuffer = buffer;
                break;
        }
    }

   // deleting a bound buffer has the side effect of binding 0
    GrGLvoid deleteBuffers(GrGLsizei n, const GrGLuint* ids) override {
        for (int i = 0; i < n; ++i) {
            if (ids[i] == fCurrArrayBuffer) {
                fCurrArrayBuffer = 0;
            }
            if (ids[i] == fCurrElementArrayBuffer) {
                fCurrElementArrayBuffer = 0;
            }
            if (ids[i] == fCurrPixelPackBuffer) {
                fCurrPixelPackBuffer = 0;
            }
            if (ids[i] == fCurrPixelUnpackBuffer) {
                fCurrPixelUnpackBuffer = 0;
            }

            if (ids[i] > 0) {
                BufferObj* buffer = fBufferManager.lookUp(ids[i]);
                fBufferManager.free(buffer);
            }
        }
    }

    GrGLvoid genFramebuffers(GrGLsizei n, GrGLuint *framebuffers) override {
        this->genGenericIds(n, framebuffers);
    }

    GrGLvoid genQueries(GrGLsizei n, GrGLuint *ids) override { this->genGenericIds(n, ids); }

    GrGLvoid genRenderbuffers(GrGLsizei n, GrGLuint *renderbuffers) override {
        this->genGenericIds(n, renderbuffers);
    }

    GrGLvoid genTextures(GrGLsizei n, GrGLuint *textures) override {
        this->genGenericIds(n, textures);
    }

    GrGLvoid genVertexArrays(GrGLsizei n, GrGLuint *arrays) override {
        this->genGenericIds(n, arrays);
    }

    GrGLenum getError() override { return GR_GL_NO_ERROR; }

    GrGLvoid getIntegerv(GrGLenum pname, GrGLint* params) override {
        // TODO: remove from Ganesh the #defines for gets we don't use.
        // We would like to minimize gets overall due to performance issues
        switch (pname) {
            case GR_GL_CONTEXT_PROFILE_MASK:
                *params = GR_GL_CONTEXT_COMPATIBILITY_PROFILE_BIT;
                break;
            case GR_GL_STENCIL_BITS:
                *params = 8;
                break;
            case GR_GL_SAMPLES:
                *params = 1;
                break;
            case GR_GL_FRAMEBUFFER_BINDING:
                *params = 0;
                break;
            case GR_GL_VIEWPORT:
                params[0] = 0;
                params[1] = 0;
                params[2] = 800;
                params[3] = 600;
                break;
            case GR_GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:
            case GR_GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS:
            case GR_GL_MAX_TEXTURE_IMAGE_UNITS:
            case GR_GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS:
                *params = 8;
                break;
            case GR_GL_MAX_TEXTURE_COORDS:
                *params = 8;
                break;
            case GR_GL_MAX_VERTEX_UNIFORM_VECTORS:
                *params = kDefaultMaxVertexUniformVectors;
                break;
            case GR_GL_MAX_FRAGMENT_UNIFORM_VECTORS:
                *params = kDefaultMaxFragmentUniformVectors;
                break;
            case GR_GL_MAX_FRAGMENT_UNIFORM_COMPONENTS:
                *params = 16 * 4;
                break;
            case GR_GL_NUM_COMPRESSED_TEXTURE_FORMATS:
                *params = 0;
                break;
            case GR_GL_COMPRESSED_TEXTURE_FORMATS:
                break;
            case GR_GL_MAX_TEXTURE_SIZE:
                *params = 8192;
                break;
            case GR_GL_MAX_RENDERBUFFER_SIZE:
                *params = 8192;
                break;
            case GR_GL_MAX_SAMPLES:
                *params = 32;
                break;
            case GR_GL_MAX_VERTEX_ATTRIBS:
                *params = kDefaultMaxVertexAttribs;
                break;
            case GR_GL_MAX_VARYING_VECTORS:
                *params = kDefaultMaxVaryingVectors;
                break;
            case GR_GL_NUM_EXTENSIONS: {
                GrGLint i = 0;
                while (fExtensions[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*) fExtensions[i];
                } else {
                    return nullptr;
                }
            }
            default:
                SkFAIL("Unexpected name passed to GetStringi");
                return nullptr;
        }
    }

    GrGLint getUniformLocation(GrGLuint program, const char* name) override {
        return ++fCurrUniformLocation;
    }

    GrGLvoid* mapBufferRange(GrGLenum target, GrGLintptr offset, GrGLsizeiptr length,
                             GrGLbitfield access) override {
        GrGLuint id = 0;
        switch (target) {
            case GR_GL_ARRAY_BUFFER:
                id = fCurrArrayBuffer;
                break;
            case GR_GL_ELEMENT_ARRAY_BUFFER:
                id = fCurrElementArrayBuffer;
                break;
            case GR_GL_PIXEL_PACK_BUFFER:
                id = fCurrPixelPackBuffer;
                break;
            case GR_GL_PIXEL_UNPACK_BUFFER:
                id = fCurrPixelUnpackBuffer;
                break;
        }

        if (id > 0) {
            // We just ignore the offset and length here.
            BufferObj* buffer = fBufferManager.lookUp(id);
            SkASSERT(!buffer->mapped());
            buffer->setMapped(true);
            return buffer->dataPtr();
        }
        return nullptr;
    }

    GrGLvoid* mapBuffer(GrGLenum target, GrGLenum access) override {
        GrGLuint id = 0;
        switch (target) {
            case GR_GL_ARRAY_BUFFER:
                id = fCurrArrayBuffer;
                break;
            case GR_GL_ELEMENT_ARRAY_BUFFER:
                id = fCurrElementArrayBuffer;
                break;
            case GR_GL_PIXEL_PACK_BUFFER:
                id = fCurrPixelPackBuffer;
                break;
            case GR_GL_PIXEL_UNPACK_BUFFER:
                id = fCurrPixelUnpackBuffer;
                break;
        }

        if (id > 0) {
            BufferObj* buffer = fBufferManager.lookUp(id);
            SkASSERT(!buffer->mapped());
            buffer->setMapped(true);
            return buffer->dataPtr();
        }

        SkASSERT(false);
        return nullptr;            // no buffer bound to target
    }

    GrGLboolean unmapBuffer(GrGLenum target) override {
        GrGLuint id = 0;
        switch (target) {
            case GR_GL_ARRAY_BUFFER:
                id = fCurrArrayBuffer;
                break;
            case GR_GL_ELEMENT_ARRAY_BUFFER:
                id = fCurrElementArrayBuffer;
                break;
            case GR_GL_PIXEL_PACK_BUFFER:
                id = fCurrPixelPackBuffer;
                break;
            case GR_GL_PIXEL_UNPACK_BUFFER:
                id = fCurrPixelUnpackBuffer;
                break;
        }
        if (id > 0) {
            BufferObj* buffer = fBufferManager.lookUp(id);
            SkASSERT(buffer->mapped());
            buffer->setMapped(false);
            return GR_GL_TRUE;
        }

        GrAlwaysAssert(false);
        return GR_GL_FALSE; // GR_GL_INVALID_OPERATION;
    }

    GrGLvoid getBufferParameteriv(GrGLenum target, GrGLenum pname, GrGLint* params) override {
        switch (pname) {
            case GR_GL_BUFFER_MAPPED: {
                *params = GR_GL_FALSE;
                GrGLuint id = 0;
                switch (target) {
                    case GR_GL_ARRAY_BUFFER:
                        id = fCurrArrayBuffer;
                        break;
                    case GR_GL_ELEMENT_ARRAY_BUFFER:
                        id = fCurrElementArrayBuffer;
                        break;
                    case GR_GL_PIXEL_PACK_BUFFER:
                        id = fCurrPixelPackBuffer;
                        break;
                    case GR_GL_PIXEL_UNPACK_BUFFER:
                        id = fCurrPixelUnpackBuffer;
                        break;
                }
                if (id > 0) {
                    BufferObj* buffer = fBufferManager.lookUp(id);
                    if (buffer->mapped()) {
                        *params = GR_GL_TRUE;
                    }
                }
                break; }
            default:
                SkFAIL("Unexpected pname to GetBufferParamateriv");
                break;
        }
    };

    // NV_path_rendering
    GrGLuint genPaths(GrGLsizei range) override {
        return ++fCurrPathID;
    }


private:
    BufferManager          fBufferManager;
    GrGLuint               fCurrArrayBuffer;
    GrGLuint               fCurrElementArrayBuffer;
    GrGLuint               fCurrPixelPackBuffer;
    GrGLuint               fCurrPixelUnpackBuffer;
    GrGLuint               fCurrProgramID;
    GrGLuint               fCurrShaderID;
    GrGLuint               fCurrGenericID;
    GrGLuint               fCurrUniformLocation;
    GrGLuint               fCurrPathID;
    SkTArray<const char*>  fExtensions;

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

    const GrGLubyte* CombinedExtensionString() {
        static SkString gExtString;
        static SkMutex gMutex;
        gMutex.acquire();
        if (0 == gExtString.size()) {
            int i = 0;
            while (fExtensions[i]) {
                if (i > 0) {
                    gExtString.append(" ");
                }
                gExtString.append(fExtensions[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); }
