/*
* Copyright (C) 2011 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License")
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#ifdef _WIN32
#undef  GL_APICALL
#define GL_API __declspec(dllexport)
#define GL_APICALL __declspec(dllexport)
#endif

#define GL_GLEXT_PROTOTYPES
#include <GLES2/gl2.h>
#include <GLES2/gl2ext.h>
#include <GLES3/gl3.h>

#include <OpenglCodecCommon/ErrorLog.h>
#include <GLcommon/TranslatorIfaces.h>
#include "GLESv2Context.h"
#include "GLESv2Validate.h"
#include "ShaderParser.h"
#include "ProgramData.h"
#include <GLcommon/TextureUtils.h>
#include <GLcommon/FramebufferData.h>

#include "ANGLEShaderParser.h"

#include <stdio.h>

#include <unordered_map>

extern "C" {

//decleration
static void initGLESx();
static void initContext(GLEScontext* ctx,ShareGroupPtr grp);
static void deleteGLESContext(GLEScontext* ctx);
static void setShareGroup(GLEScontext* ctx,ShareGroupPtr grp);
static GLEScontext* createGLESContext();
static __translatorMustCastToProperFunctionPointerType getProcAddress(const char* procName);

}

/************************************** GLES EXTENSIONS *********************************************************/
typedef std::unordered_map<std::string, __translatorMustCastToProperFunctionPointerType> ProcTableMap;
ProcTableMap *s_glesExtensions = NULL;
/****************************************************************************************************************/

static EGLiface*  s_eglIface = NULL;
static GLESiface  s_glesIface = {
    .initGLESx         = initGLESx,
    .createGLESContext = createGLESContext,
    .initContext       = initContext,
    .deleteGLESContext = deleteGLESContext,
    .flush             = (FUNCPTR_NO_ARGS_RET_VOID)glFlush,
    .finish            = (FUNCPTR_NO_ARGS_RET_VOID)glFinish,
    .setShareGroup     = setShareGroup,
    .getProcAddress    = getProcAddress,
    .fenceSync         = (FUNCPTR_FENCE_SYNC)glFenceSync,
    .clientWaitSync    = (FUNCPTR_CLIENT_WAIT_SYNC)glClientWaitSync,
    .deleteSync        = (FUNCPTR_DELETE_SYNC)glDeleteSync,
};

#include <GLcommon/GLESmacros.h>

extern "C" {

static void initGLESx() {
    ANGLEShaderParser::globalInitialize();
}

static void initContext(GLEScontext* ctx,ShareGroupPtr grp) {
    if (!ctx->isInitialized()) {
        ctx->setShareGroup(grp);
        ctx->init(s_eglIface->eglGetGlLibrary());
        glBindTexture(GL_TEXTURE_2D,0);
        glBindTexture(GL_TEXTURE_CUBE_MAP,0);
    }
}
static GLEScontext* createGLESContext() {
    return new GLESv2Context();
}

static void deleteGLESContext(GLEScontext* ctx) {
    delete ctx;
}

static void setShareGroup(GLEScontext* ctx,ShareGroupPtr grp) {
    if(ctx) {
        ctx->setShareGroup(grp);
    }
}

static __translatorMustCastToProperFunctionPointerType getProcAddress(const char* procName) {
    GET_CTX_RET(NULL)
    ctx->getGlobalLock();
    static bool proc_table_initialized = false;
    if (!proc_table_initialized) {
        proc_table_initialized = true;
        if (!s_glesExtensions)
            s_glesExtensions = new ProcTableMap();
        else
            s_glesExtensions->clear();
        (*s_glesExtensions)["glEGLImageTargetTexture2DOES"] = (__translatorMustCastToProperFunctionPointerType)glEGLImageTargetTexture2DOES;
        (*s_glesExtensions)["glEGLImageTargetRenderbufferStorageOES"]=(__translatorMustCastToProperFunctionPointerType)glEGLImageTargetRenderbufferStorageOES;
    }
    __translatorMustCastToProperFunctionPointerType ret=NULL;
    ProcTableMap::iterator val = s_glesExtensions->find(procName);
    if (val!=s_glesExtensions->end())
        ret = val->second;
    ctx->releaseGlobalLock();

    return ret;
}

GL_APICALL GLESiface* GL_APIENTRY __translator_getIfaces(EGLiface* eglIface);

GLESiface* __translator_getIfaces(EGLiface* eglIface) {
    s_eglIface = eglIface;
    return & s_glesIface;
}

}  // extern "C"

static void s_attachShader(GLEScontext* ctx, GLuint program, GLuint shader,
                           ShaderParser* shaderParser) {
    if (ctx && program && shader && shaderParser) {
        shaderParser->attachProgram(program);
    }
}

static void s_detachShader(GLEScontext* ctx, GLuint program, GLuint shader) {
    if (ctx && shader && ctx->shareGroup().get()) {
        auto shaderData = ctx->shareGroup()->getObjectData(
                NamedObjectType::SHADER_OR_PROGRAM, shader);
        if (!shaderData) return;
        ShaderParser* shaderParser = (ShaderParser*)shaderData;
        shaderParser->detachProgram(program);
        if (shaderParser->getDeleteStatus()
                && !shaderParser->hasAttachedPrograms()) {
            ctx->shareGroup()->deleteName(NamedObjectType::SHADER_OR_PROGRAM, shader);
        }
    }
}

static ObjectLocalName TextureLocalName(GLenum target,unsigned int tex) {
    GET_CTX_RET(0);
    return (tex!=0? tex : ctx->getDefaultTextureName(target));
}

static TextureData* getTextureData(ObjectLocalName tex) {
    GET_CTX_RET(NULL);
    TextureData *texData = NULL;
    auto objData =
            ctx->shareGroup()->getObjectData(NamedObjectType::TEXTURE, tex);
    if(!objData){
        texData = new TextureData();
        ctx->shareGroup()->setObjectData(NamedObjectType::TEXTURE, tex,
                                         ObjectDataPtr(texData));
    } else {
        texData = (TextureData*)objData;
    }
    return texData;
}

static TextureData* getTextureTargetData(GLenum target){
    GET_CTX_RET(NULL);
    unsigned int tex = ctx->getBindedTexture(target);
    return getTextureData(TextureLocalName(target,tex));
}

GL_APICALL void  GL_APIENTRY glActiveTexture(GLenum texture){
    GET_CTX_V2();
    SET_ERROR_IF (!GLESv2Validate::textureEnum(texture,ctx->getMaxCombinedTexUnits()),GL_INVALID_ENUM);
    ctx->setActiveTexture(texture);
    ctx->dispatcher().glActiveTexture(texture);
}

GL_APICALL void  GL_APIENTRY glAttachShader(GLuint program, GLuint shader){
    GET_CTX();
    if(ctx->shareGroup().get()) {
        const GLuint globalProgramName = ctx->shareGroup()->getGlobalName(
                NamedObjectType::SHADER_OR_PROGRAM, program);
        SET_ERROR_IF(globalProgramName==0, GL_INVALID_VALUE);
        const GLuint globalShaderName = ctx->shareGroup()->getGlobalName(
                NamedObjectType::SHADER_OR_PROGRAM, shader);
        SET_ERROR_IF(globalShaderName==0, GL_INVALID_VALUE);

        auto programData = ctx->shareGroup()->getObjectData(
                NamedObjectType::SHADER_OR_PROGRAM, program);
        auto shaderData = ctx->shareGroup()->getObjectData(
                NamedObjectType::SHADER_OR_PROGRAM, shader);
        SET_ERROR_IF(!shaderData || !programData ,GL_INVALID_OPERATION);
        SET_ERROR_IF(!(shaderData->getDataType() ==SHADER_DATA) ||
                     !(programData->getDataType()==PROGRAM_DATA) ,GL_INVALID_OPERATION);

        GLenum shaderType = ((ShaderParser*)shaderData)->getType();
        ProgramData* pData = (ProgramData*)programData;
        SET_ERROR_IF((pData->getAttachedShader(shaderType)!=0), GL_INVALID_OPERATION);
        pData->attachShader(shader,shaderType);
        s_attachShader(ctx, program, shader, (ShaderParser*)shaderData);
        ctx->dispatcher().glAttachShader(globalProgramName,globalShaderName);
    }
}

GL_APICALL void  GL_APIENTRY glBindAttribLocation(GLuint program, GLuint index, const GLchar* name){
    GET_CTX();
    SET_ERROR_IF(!GLESv2Validate::attribName(name),GL_INVALID_OPERATION);
    SET_ERROR_IF(!GLESv2Validate::attribIndex(index),GL_INVALID_VALUE);
    if(ctx->shareGroup().get()) {
        const GLuint globalProgramName = ctx->shareGroup()->getGlobalName(
                NamedObjectType::SHADER_OR_PROGRAM, program);
        SET_ERROR_IF(globalProgramName==0, GL_INVALID_VALUE);
        auto objData = ctx->shareGroup()->getObjectData(
                NamedObjectType::SHADER_OR_PROGRAM, program);
        SET_ERROR_IF(objData->getDataType()!=PROGRAM_DATA,GL_INVALID_OPERATION);

        ctx->dispatcher().glBindAttribLocation(globalProgramName,index,name);
    }
}

GL_APICALL void  GL_APIENTRY glBindBuffer(GLenum target, GLuint buffer){
    GET_CTX();
    SET_ERROR_IF(!GLESv2Validate::bufferTarget(target),GL_INVALID_ENUM);
    //if buffer wasn't generated before,generate one
    if (buffer && ctx->shareGroup().get() &&
        !ctx->shareGroup()->isObject(NamedObjectType::VERTEXBUFFER, buffer)) {
        ctx->shareGroup()->genName(NamedObjectType::VERTEXBUFFER, buffer);
        ctx->shareGroup()->setObjectData(NamedObjectType::VERTEXBUFFER, buffer,
                                         ObjectDataPtr(new GLESbuffer()));
    }
    ctx->bindBuffer(target,buffer);
    if (buffer) {
        GLESbuffer* vbo =
                (GLESbuffer*)ctx->shareGroup()
                        ->getObjectData(NamedObjectType::VERTEXBUFFER, buffer);
        vbo->setBinded();
    }
}

GL_APICALL void  GL_APIENTRY glBindFramebuffer(GLenum target, GLuint framebuffer){
    GET_CTX();
    SET_ERROR_IF(!GLESv2Validate::framebufferTarget(target),GL_INVALID_ENUM);

    GLuint globalFrameBufferName = framebuffer;
    if(framebuffer && ctx->shareGroup().get()){
        globalFrameBufferName = ctx->shareGroup()->getGlobalName(
                NamedObjectType::FRAMEBUFFER, framebuffer);
        //if framebuffer wasn't generated before,generate one
        if(!globalFrameBufferName){
            ctx->shareGroup()->genName(NamedObjectType::FRAMEBUFFER,
                                       framebuffer);
            ctx->shareGroup()->setObjectData(
                    NamedObjectType::FRAMEBUFFER, framebuffer,
                    ObjectDataPtr(new FramebufferData(framebuffer)));
            globalFrameBufferName = ctx->shareGroup()->getGlobalName(
                    NamedObjectType::FRAMEBUFFER, framebuffer);
        }
    }
    ctx->dispatcher().glBindFramebufferEXT(target,globalFrameBufferName);

    // update framebuffer binding state
    ctx->setFramebufferBinding(framebuffer);
}

GL_APICALL void  GL_APIENTRY glBindRenderbuffer(GLenum target, GLuint renderbuffer){
    GET_CTX();
    SET_ERROR_IF(!GLESv2Validate::renderbufferTarget(target),GL_INVALID_ENUM);

    GLuint globalRenderBufferName = renderbuffer;
    if(renderbuffer && ctx->shareGroup().get()){
        globalRenderBufferName = ctx->shareGroup()->getGlobalName(
                NamedObjectType::RENDERBUFFER, renderbuffer);
        //if renderbuffer wasn't generated before,generate one
        if(!globalRenderBufferName){
            ctx->shareGroup()->genName(NamedObjectType::RENDERBUFFER,
                                       renderbuffer);
            ctx->shareGroup()->setObjectData(
                    NamedObjectType::RENDERBUFFER, renderbuffer,
                    ObjectDataPtr(new RenderbufferData()));
            globalRenderBufferName = ctx->shareGroup()->getGlobalName(
                    NamedObjectType::RENDERBUFFER, renderbuffer);
        }
    }
    ctx->dispatcher().glBindRenderbufferEXT(target,globalRenderBufferName);

    // update renderbuffer binding state
    ctx->setRenderbufferBinding(renderbuffer);
}

GL_APICALL void  GL_APIENTRY glBindTexture(GLenum target, GLuint texture){
    GET_CTX();
    SET_ERROR_IF(!GLESv2Validate::textureTarget(target),GL_INVALID_ENUM)

    //for handling default texture (0)
    ObjectLocalName localTexName = TextureLocalName(target,texture);
    GLuint globalTextureName = localTexName;
    if(ctx->shareGroup().get()){
        globalTextureName = ctx->shareGroup()->getGlobalName(
                NamedObjectType::TEXTURE, localTexName);
        //if texture wasn't generated before,generate one
        if(!globalTextureName){
            ctx->shareGroup()->genName(NamedObjectType::TEXTURE, localTexName);
            globalTextureName = ctx->shareGroup()->getGlobalName(
                    NamedObjectType::TEXTURE, localTexName);
        }

        TextureData* texData = getTextureData(localTexName);
        if (texData->target==0)
            texData->target = target;
        //if texture was already bound to another target
        SET_ERROR_IF(ctx->GLTextureTargetToLocal(texData->target) != ctx->GLTextureTargetToLocal(target), GL_INVALID_OPERATION);
        texData->wasBound = true;
    }

    ctx->setBindedTexture(target,texture);
    ctx->dispatcher().glBindTexture(target,globalTextureName);
}

GL_APICALL void  GL_APIENTRY glBlendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha){
    GET_CTX();
    ctx->dispatcher().glBlendColor(red,green,blue,alpha);
}

GL_APICALL void  GL_APIENTRY glBlendEquation( GLenum mode ){
    GET_CTX();
    SET_ERROR_IF(!GLESv2Validate::blendEquationMode(mode),GL_INVALID_ENUM)
    ctx->dispatcher().glBlendEquation(mode);
}

GL_APICALL void  GL_APIENTRY glBlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha){
    GET_CTX();
    SET_ERROR_IF(!(GLESv2Validate::blendEquationMode(modeRGB) && GLESv2Validate::blendEquationMode(modeAlpha)),GL_INVALID_ENUM);
    ctx->dispatcher().glBlendEquationSeparate(modeRGB,modeAlpha);
}

GL_APICALL void  GL_APIENTRY glBlendFunc(GLenum sfactor, GLenum dfactor){
    GET_CTX();
    SET_ERROR_IF(!GLESv2Validate::blendSrc(sfactor) || !GLESv2Validate::blendDst(dfactor),GL_INVALID_ENUM)
    ctx->dispatcher().glBlendFunc(sfactor,dfactor);
}

GL_APICALL void  GL_APIENTRY glBlendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha){
    GET_CTX();
    SET_ERROR_IF(
!(GLESv2Validate::blendSrc(srcRGB) && GLESv2Validate::blendDst(dstRGB) && GLESv2Validate::blendSrc(srcAlpha) && GLESv2Validate::blendDst(dstAlpha)),GL_INVALID_ENUM);
    ctx->dispatcher().glBlendFuncSeparate(srcRGB,dstRGB,srcAlpha,dstAlpha);
}

GL_APICALL void  GL_APIENTRY glBufferData(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage){
    GET_CTX();
    SET_ERROR_IF(!GLESv2Validate::bufferTarget(target),GL_INVALID_ENUM);
    SET_ERROR_IF(!GLESv2Validate::bufferUsage(usage),GL_INVALID_ENUM);
    SET_ERROR_IF(!ctx->isBindedBuffer(target),GL_INVALID_OPERATION);
    ctx->setBufferData(target,size,data,usage);
}

GL_APICALL void  GL_APIENTRY glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data){
    GET_CTX();
    SET_ERROR_IF(!ctx->isBindedBuffer(target),GL_INVALID_OPERATION);
    SET_ERROR_IF(!GLESv2Validate::bufferTarget(target),GL_INVALID_ENUM);
    SET_ERROR_IF(!ctx->setBufferSubData(target,offset,size,data),GL_INVALID_VALUE);
}


GL_APICALL GLenum GL_APIENTRY glCheckFramebufferStatus(GLenum target){
    GET_CTX_RET(GL_FRAMEBUFFER_COMPLETE);
    RET_AND_SET_ERROR_IF(!GLESv2Validate::framebufferTarget(target),GL_INVALID_ENUM,GL_FRAMEBUFFER_COMPLETE);
    ctx->drawValidate();
    return ctx->dispatcher().glCheckFramebufferStatusEXT(target);
}

GL_APICALL void  GL_APIENTRY glClear(GLbitfield mask){
    GET_CTX();
    GLbitfield allowed_bits = GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT;
    GLbitfield has_disallowed_bits = (mask & ~allowed_bits);
    SET_ERROR_IF(has_disallowed_bits, GL_INVALID_VALUE);
    ctx->drawValidate();

    ctx->dispatcher().glClear(mask);
}
GL_APICALL void  GL_APIENTRY glClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha){
    GET_CTX();
    ctx->dispatcher().glClearColor(red,green,blue,alpha);
}
GL_APICALL void  GL_APIENTRY glClearDepthf(GLclampf depth){
    GET_CTX();
    ctx->dispatcher().glClearDepth(depth);
}
GL_APICALL void  GL_APIENTRY glClearStencil(GLint s){
    GET_CTX();
    ctx->dispatcher().glClearStencil(s);
}
GL_APICALL void  GL_APIENTRY glColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha){
    GET_CTX();
    ctx->dispatcher().glColorMask(red,green,blue,alpha);
}

GL_APICALL void  GL_APIENTRY glCompileShader(GLuint shader){
    GET_CTX();
    if(ctx->shareGroup().get()) {
        const GLuint globalShaderName = ctx->shareGroup()->getGlobalName(
                NamedObjectType::SHADER_OR_PROGRAM, shader);
        SET_ERROR_IF(globalShaderName==0, GL_INVALID_VALUE);
        auto objData = ctx->shareGroup()->getObjectData(
                NamedObjectType::SHADER_OR_PROGRAM, shader);
        SET_ERROR_IF(objData->getDataType()!= SHADER_DATA,GL_INVALID_OPERATION);
        ShaderParser* sp = (ShaderParser*)objData;
        SET_ERROR_IF(sp->getDeleteStatus(), GL_INVALID_VALUE);
        if (sp->validShader()) {
            ctx->dispatcher().glCompileShader(globalShaderName);

            GLsizei infoLogLength=0;
            GLchar* infoLog;
            ctx->dispatcher().glGetShaderiv(globalShaderName,GL_INFO_LOG_LENGTH,&infoLogLength);
            infoLog = new GLchar[infoLogLength+1];
            ctx->dispatcher().glGetShaderInfoLog(globalShaderName,infoLogLength,NULL,infoLog);
            if (infoLogLength == 0) {
                infoLog[0] = 0;
            }
            sp->setInfoLog(infoLog);
        }
    }
}

GL_APICALL void  GL_APIENTRY glCompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid* data)
{
    GET_CTX();
    SET_ERROR_IF(!GLESv2Validate::textureTargetEx(target),GL_INVALID_ENUM);
    SET_ERROR_IF(level < 0 || imageSize < 0, GL_INVALID_VALUE);

    doCompressedTexImage2D(ctx, target, level, internalformat,
                                width, height, border,
                                imageSize, data, (void*)glTexImage2D);
}

GL_APICALL void  GL_APIENTRY glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid* data){
    GET_CTX();
    SET_ERROR_IF(!GLESv2Validate::textureTargetEx(target),GL_INVALID_ENUM);
    SET_ERROR_IF(!data,GL_INVALID_OPERATION);
    ctx->dispatcher().glCompressedTexSubImage2D(target,level,xoffset,yoffset,width,height,format,imageSize,data);
}

void s_glInitTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border){
    GET_CTX();

    if (ctx->shareGroup().get() && level == 0){
        TextureData *texData = getTextureTargetData(target);
        if(texData) {
            texData->width = width;
            texData->height = height;
            texData->border = border;
            texData->internalFormat = internalformat;
            texData->target = target;

            if (texData->sourceEGLImage != 0) {
                //
                // This texture was a target of EGLImage,
                // but now it is re-defined so we need to
                // re-generate global texture name for it.
                //
                unsigned int tex = ctx->getBindedTexture(target);
                ctx->shareGroup()->genName(NamedObjectType::TEXTURE, tex,
                                           false);
                unsigned int globalTextureName =
                        ctx->shareGroup()->getGlobalName(
                                NamedObjectType::TEXTURE, tex);
                ctx->dispatcher().glBindTexture(GL_TEXTURE_2D,
                                                globalTextureName);
                texData->sourceEGLImage = 0;
            }
        }
    }
}

GL_APICALL void  GL_APIENTRY glCopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border){
    GET_CTX();
    SET_ERROR_IF(!(GLESv2Validate::pixelFrmt(ctx,internalformat) && GLESv2Validate::textureTargetEx(target)),GL_INVALID_ENUM);
    SET_ERROR_IF((GLESv2Validate::textureIsCubeMap(target) && width != height), GL_INVALID_VALUE);
    SET_ERROR_IF(border != 0,GL_INVALID_VALUE);
    s_glInitTexImage2D(target,level,internalformat,width,height,border);
    ctx->dispatcher().glCopyTexImage2D(target,level,internalformat,x,y,width,height,border);
}

GL_APICALL void  GL_APIENTRY glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height){
    GET_CTX();
    SET_ERROR_IF(!GLESv2Validate::textureTargetEx(target),GL_INVALID_ENUM);
    ctx->dispatcher().glCopyTexSubImage2D(target,level,xoffset,yoffset,x,y,width,height);
}

GL_APICALL GLuint GL_APIENTRY glCreateProgram(void){
    GET_CTX_RET(0);
    if(ctx->shareGroup().get()) {
        ProgramData* programInfo = new ProgramData();
        const GLuint localProgramName =
                ctx->shareGroup()->genName(ShaderProgramType::PROGRAM, 0, true);
        ctx->shareGroup()->setObjectData(NamedObjectType::SHADER_OR_PROGRAM,
                                         localProgramName,
                                         ObjectDataPtr(programInfo));
        return localProgramName;
    }
    return 0;
}

GL_APICALL GLuint GL_APIENTRY glCreateShader(GLenum type){
    GET_CTX_V2_RET(0);
    RET_AND_SET_ERROR_IF(!GLESv2Validate::shaderType(type),GL_INVALID_ENUM,0);
    if(ctx->shareGroup().get()) {
        ShaderProgramType shaderProgramType;
        if (type == GL_VERTEX_SHADER) {
            shaderProgramType = ShaderProgramType::VERTEX_SHADER;
        } else {
            shaderProgramType = ShaderProgramType::FRAGMENT_SHADER;
        }
        const GLuint localShaderName = ctx->shareGroup()->genName(
                                                shaderProgramType, 0, true);
        ShaderParser* sp = new ShaderParser(type);
        ctx->shareGroup()->setObjectData(NamedObjectType::SHADER_OR_PROGRAM,
                                         localShaderName, ObjectDataPtr(sp));
        return localShaderName;
    }
    return 0;
}

GL_APICALL void  GL_APIENTRY glCullFace(GLenum mode){
    GET_CTX();
    ctx->dispatcher().glCullFace(mode);
}

GL_APICALL void  GL_APIENTRY glDeleteBuffers(GLsizei n, const GLuint* buffers){
    GET_CTX();
    SET_ERROR_IF(n<0,GL_INVALID_VALUE);
    if(ctx->shareGroup().get()) {
        for(int i=0; i < n; i++){
            ctx->shareGroup()->deleteName(NamedObjectType::VERTEXBUFFER,
                                          buffers[i]);
            ctx->unbindBuffer(buffers[i]);
        }
    }
}

GL_APICALL void  GL_APIENTRY glDeleteFramebuffers(GLsizei n, const GLuint* framebuffers){
    GET_CTX();
    SET_ERROR_IF(n < 0, GL_INVALID_VALUE);
    if (ctx->shareGroup().get()) {
        for (int i = 0; i < n; i++) {
            ctx->shareGroup()->deleteName(NamedObjectType::FRAMEBUFFER,
                                          framebuffers[i]);
        }
    }
}

static void s_detachFromFramebuffer(NamedObjectType bufferType,
                                    GLuint texture) {
    GET_CTX();
    GLuint fbName = ctx->getFramebufferBinding();
    if (!fbName) return;
    auto fbObj = ctx->shareGroup()->getObjectData(
            NamedObjectType::FRAMEBUFFER, fbName);
    if (fbObj == NULL) return;
    FramebufferData *fbData = (FramebufferData *)fbObj;
    GLenum target;
    const GLenum kAttachments[] = {GL_COLOR_ATTACHMENT0, GL_DEPTH_ATTACHMENT, GL_STENCIL_ATTACHMENT};
    const size_t sizen = sizeof(kAttachments)/sizeof(GLenum);
    for (size_t i = 0; i < sizen; ++i ) {
        GLuint name = fbData->getAttachment(kAttachments[i], &target, NULL);
        if (name != texture) continue;
        if (NamedObjectType::TEXTURE == bufferType &&
            GLESv2Validate::textureTargetEx(target)) {
            glFramebufferTexture2D(GL_FRAMEBUFFER, kAttachments[i], target, 0, 0);
        } else if (NamedObjectType::RENDERBUFFER == bufferType &&
                   GLESv2Validate::renderbufferTarget(target)) {
            glFramebufferRenderbuffer(GL_FRAMEBUFFER, kAttachments[i], target, 0);
        }
    }
}

GL_APICALL void  GL_APIENTRY glDeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers){
    GET_CTX();
    SET_ERROR_IF(n<0,GL_INVALID_VALUE);
    if(ctx->shareGroup().get()) {
        for(int i=0; i < n; i++){
            ctx->shareGroup()->deleteName(NamedObjectType::RENDERBUFFER,
                                          renderbuffers[i]);
            s_detachFromFramebuffer(NamedObjectType::RENDERBUFFER,
                                    renderbuffers[i]);
        }
    }
}

GL_APICALL void  GL_APIENTRY glDeleteTextures(GLsizei n, const GLuint* textures){
    GET_CTX();
    SET_ERROR_IF(n<0,GL_INVALID_VALUE);
    if(ctx->shareGroup().get()) {
        for(int i=0; i < n; i++){
            if (textures[i]!=0) {
                if (ctx->getBindedTexture(GL_TEXTURE_2D) == textures[i])
                    ctx->setBindedTexture(GL_TEXTURE_2D,0);
                if (ctx->getBindedTexture(GL_TEXTURE_CUBE_MAP) == textures[i])
                    ctx->setBindedTexture(GL_TEXTURE_CUBE_MAP,0);
                s_detachFromFramebuffer(NamedObjectType::TEXTURE, textures[i]);
                ctx->shareGroup()->deleteName(NamedObjectType::TEXTURE,
                                              textures[i]);
            }
        }
    }
}

GL_APICALL void  GL_APIENTRY glDeleteProgram(GLuint program){
    GET_CTX();
    if(program && ctx->shareGroup().get()) {
        const GLuint globalProgramName = ctx->shareGroup()->getGlobalName(
                NamedObjectType::SHADER_OR_PROGRAM, program);
        SET_ERROR_IF(!globalProgramName, GL_INVALID_VALUE);

        auto programData = ctx->shareGroup()->getObjectData(
                NamedObjectType::SHADER_OR_PROGRAM, program);
        SET_ERROR_IF(!(programData->getDataType()==PROGRAM_DATA),
                GL_INVALID_OPERATION);
        ProgramData* pData = (ProgramData*)programData;
        if (pData && pData->isInUse()) {
            pData->setDeleteStatus(true);
            return;
        }
        s_detachShader(ctx, program, pData->getAttachedVertexShader());
        s_detachShader(ctx, program, pData->getAttachedFragmentShader());

        ctx->shareGroup()->deleteName(NamedObjectType::SHADER_OR_PROGRAM, program);
    }
}

GL_APICALL void  GL_APIENTRY glDeleteShader(GLuint shader){
    GET_CTX();
    if(shader && ctx->shareGroup().get()) {
        const GLuint globalShaderName = ctx->shareGroup()->getGlobalName(
                NamedObjectType::SHADER_OR_PROGRAM, shader);
        SET_ERROR_IF(!globalShaderName, GL_INVALID_VALUE);
        auto objData = ctx->shareGroup()->getObjectData(
                NamedObjectType::SHADER_OR_PROGRAM, shader);
        SET_ERROR_IF(!objData ,GL_INVALID_OPERATION);
        SET_ERROR_IF(objData->getDataType()!=SHADER_DATA,GL_INVALID_OPERATION);
        ShaderParser* sp = (ShaderParser*)objData;
        SET_ERROR_IF(sp->getDeleteStatus(), GL_INVALID_VALUE);
        if (sp->hasAttachedPrograms()) {
            sp->setDeleteStatus(true);
        } else {
            ctx->shareGroup()->deleteName(NamedObjectType::SHADER_OR_PROGRAM, shader);
        }
    }
}

GL_APICALL void  GL_APIENTRY glDepthFunc(GLenum func){
    GET_CTX();
    ctx->dispatcher().glDepthFunc(func);
}
GL_APICALL void  GL_APIENTRY glDepthMask(GLboolean flag){
    GET_CTX();
    ctx->dispatcher().glDepthMask(flag);
}
GL_APICALL void  GL_APIENTRY glDepthRangef(GLclampf zNear, GLclampf zFar){
    GET_CTX();
    ctx->dispatcher().glDepthRange(zNear,zFar);
}

GL_APICALL void  GL_APIENTRY glDetachShader(GLuint program, GLuint shader){
    GET_CTX();
    if(ctx->shareGroup().get()) {
        const GLuint globalProgramName = ctx->shareGroup()->getGlobalName(
                NamedObjectType::SHADER_OR_PROGRAM, program);
        SET_ERROR_IF(globalProgramName==0, GL_INVALID_VALUE);
        const GLuint globalShaderName = ctx->shareGroup()->getGlobalName(
                NamedObjectType::SHADER_OR_PROGRAM, shader);
        SET_ERROR_IF(globalShaderName==0, GL_INVALID_VALUE);

        auto objData = ctx->shareGroup()->getObjectData(
                NamedObjectType::SHADER_OR_PROGRAM, program);
        SET_ERROR_IF(!objData,GL_INVALID_OPERATION);
        SET_ERROR_IF(!(objData->getDataType()==PROGRAM_DATA) ,GL_INVALID_OPERATION);

        ProgramData* programData = (ProgramData*)objData;
        SET_ERROR_IF(!programData->isAttached(shader),GL_INVALID_OPERATION);
        programData->detachShader(shader);

        s_detachShader(ctx, program, shader);

        ctx->dispatcher().glDetachShader(globalProgramName,globalShaderName);
    }
}

GL_APICALL void  GL_APIENTRY glDisable(GLenum cap){
    GET_CTX();
    ctx->dispatcher().glDisable(cap);
}

GL_APICALL void  GL_APIENTRY glDisableVertexAttribArray(GLuint index){
    GET_CTX();
    SET_ERROR_IF((!GLESv2Validate::arrayIndex(ctx,index)),GL_INVALID_VALUE);
    ctx->enableArr(index,false);
    ctx->dispatcher().glDisableVertexAttribArray(index);
}

GL_APICALL void  GL_APIENTRY glDrawArrays(GLenum mode, GLint first, GLsizei count){
    GET_CTX_V2();
    SET_ERROR_IF(count < 0,GL_INVALID_VALUE)
    SET_ERROR_IF(!GLESv2Validate::drawMode(mode),GL_INVALID_ENUM);

    ctx->drawValidate();

    GLESConversionArrays tmpArrs;
    ctx->setupArraysPointers(tmpArrs,first,count,0,NULL,true);

    if (ctx->needAtt0PreDrawValidation()) {
        ctx->validateAtt0PreDraw(count);
    }

    //Enable texture generation for GL_POINTS and gl_PointSize shader variable
    //GLES2 assumes this is enabled by default, we need to set this state for GL
    if (mode==GL_POINTS) {
        ctx->dispatcher().glEnable(GL_POINT_SPRITE);
        ctx->dispatcher().glEnable(GL_VERTEX_PROGRAM_POINT_SIZE);
    }

    ctx->dispatcher().glDrawArrays(mode,first,count);

    if (mode==GL_POINTS) {
        ctx->dispatcher().glDisable(GL_VERTEX_PROGRAM_POINT_SIZE);
        ctx->dispatcher().glDisable(GL_POINT_SPRITE);
    }

    ctx->validateAtt0PostDraw();
}

GL_APICALL void  GL_APIENTRY glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid* elementsIndices){
    GET_CTX_V2();
    SET_ERROR_IF(count < 0,GL_INVALID_VALUE)
    SET_ERROR_IF(!(GLESv2Validate::drawMode(mode) && GLESv2Validate::drawType(type)),GL_INVALID_ENUM);

    ctx->drawValidate();

    const GLvoid* indices = elementsIndices;
    if(ctx->isBindedBuffer(GL_ELEMENT_ARRAY_BUFFER)) { // if vbo is binded take the indices from the vbo
        const unsigned char* buf = static_cast<unsigned char *>(ctx->getBindedBuffer(GL_ELEMENT_ARRAY_BUFFER));
        indices = buf + SafeUIntFromPointer(elementsIndices);
    }

    GLESConversionArrays tmpArrs;
    ctx->setupArraysPointers(tmpArrs,0,count,type,indices,false);

    if (ctx->needAtt0PreDrawValidation()) {
        const unsigned int maxIndex = ctx->findMaxIndex(count, type, indices);
        ctx->validateAtt0PreDraw(maxIndex);
    }
    
    //See glDrawArrays
    if (mode==GL_POINTS) {
        ctx->dispatcher().glEnable(GL_POINT_SPRITE);
        ctx->dispatcher().glEnable(GL_VERTEX_PROGRAM_POINT_SIZE);
    }

    ctx->dispatcher().glDrawElements(mode,count,type,indices);

    if (mode==GL_POINTS) {
        ctx->dispatcher().glDisable(GL_VERTEX_PROGRAM_POINT_SIZE);
        ctx->dispatcher().glDisable(GL_POINT_SPRITE);
    }

    ctx->validateAtt0PostDraw();
}

GL_APICALL void  GL_APIENTRY glEnable(GLenum cap){
    GET_CTX();
    ctx->dispatcher().glEnable(cap);
}

GL_APICALL void  GL_APIENTRY glEnableVertexAttribArray(GLuint index){
    GET_CTX();
    SET_ERROR_IF(!(GLESv2Validate::arrayIndex(ctx,index)),GL_INVALID_VALUE);
    ctx->enableArr(index,true);
    ctx->dispatcher().glEnableVertexAttribArray(index);
}

GL_APICALL void  GL_APIENTRY glFinish(void){
    GET_CTX();
    ctx->dispatcher().glFinish();
}
GL_APICALL void  GL_APIENTRY glFlush(void){
    GET_CTX();
    ctx->dispatcher().glFlush();
}


GL_APICALL void  GL_APIENTRY glFramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer){
    GET_CTX();
    SET_ERROR_IF(!(GLESv2Validate::framebufferTarget(target)              &&
                   GLESv2Validate::renderbufferTarget(renderbuffertarget) &&
                   GLESv2Validate::framebufferAttachment(attachment)),GL_INVALID_ENUM);
    SET_ERROR_IF(!ctx->shareGroup().get(), GL_INVALID_OPERATION);

    GLuint globalRenderbufferName = 0;
    ObjectDataPtr obj;

    // generate the renderbuffer object if not yet exist
    if(renderbuffer) {
        if (!ctx->shareGroup()->isObject(NamedObjectType::RENDERBUFFER,
                                         renderbuffer)) {
            ctx->shareGroup()->genName(NamedObjectType::RENDERBUFFER,
                                       renderbuffer);
            obj = ObjectDataPtr(new RenderbufferData());
            ctx->shareGroup()->setObjectData(NamedObjectType::RENDERBUFFER,
                                             renderbuffer, obj);
        }
        else {
            obj = ctx->shareGroup()->getObjectDataPtr(
                    NamedObjectType::RENDERBUFFER, renderbuffer);
        }

        globalRenderbufferName = ctx->shareGroup()->getGlobalName(
                NamedObjectType::RENDERBUFFER, renderbuffer);
    }

    // Update the the current framebuffer object attachment state
    GLuint fbName = ctx->getFramebufferBinding();
    auto fbObj = ctx->shareGroup()->getObjectData(
            NamedObjectType::FRAMEBUFFER, fbName);
    if (fbObj != NULL) {
        FramebufferData *fbData = (FramebufferData *)fbObj;
        fbData->setAttachment(attachment, renderbuffertarget, renderbuffer, obj);
    }

    if (renderbuffer && obj.get() != NULL) {
        RenderbufferData *rbData = (RenderbufferData *)obj.get();
        if (rbData->eglImageGlobalTexObject) {
            //
            // This renderbuffer object is an eglImage target
            // attach the eglimage's texture instead the renderbuffer.
            //
            ctx->dispatcher().glFramebufferTexture2DEXT(target,
                                    attachment,
                                    GL_TEXTURE_2D,
                                    rbData->eglImageGlobalTexObject->getGlobalName(),
                                    0);
            return;
        }
    }

    ctx->dispatcher().glFramebufferRenderbufferEXT(target,attachment,renderbuffertarget,globalRenderbufferName);
}

GL_APICALL void  GL_APIENTRY glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level){
    GET_CTX();
    SET_ERROR_IF(!(GLESv2Validate::framebufferTarget(target) &&
                   GLESv2Validate::textureTargetEx(textarget)  &&
                   GLESv2Validate::framebufferAttachment(attachment)),GL_INVALID_ENUM);
    SET_ERROR_IF(level != 0, GL_INVALID_VALUE);
    SET_ERROR_IF(!ctx->shareGroup().get(), GL_INVALID_OPERATION);

    GLuint globalTextureName = 0;

    if(texture) {
        if (!ctx->shareGroup()->isObject(NamedObjectType::TEXTURE, texture)) {
            ctx->shareGroup()->genName(NamedObjectType::TEXTURE, texture);
        }
        ObjectLocalName texname = TextureLocalName(textarget,texture);
        globalTextureName = ctx->shareGroup()->getGlobalName(
                NamedObjectType::TEXTURE, texname);
    }

    ctx->dispatcher().glFramebufferTexture2DEXT(target,attachment,textarget,globalTextureName,level);

    // Update the the current framebuffer object attachment state
    GLuint fbName = ctx->getFramebufferBinding();
    auto fbObj = ctx->shareGroup()->getObjectData(
            NamedObjectType::FRAMEBUFFER, fbName);
    if (fbObj) {
        FramebufferData *fbData = (FramebufferData *)fbObj;
        fbData->setAttachment(attachment, textarget, 
                              texture, ObjectDataPtr());
    }
}


GL_APICALL void  GL_APIENTRY glFrontFace(GLenum mode){
    GET_CTX();
    ctx->dispatcher().glFrontFace(mode);
}

GL_APICALL void  GL_APIENTRY glGenBuffers(GLsizei n, GLuint* buffers){
    GET_CTX();
    SET_ERROR_IF(n<0,GL_INVALID_VALUE);
    if(ctx->shareGroup().get()) {
        for(int i=0; i<n ;i++) {
            buffers[i] = ctx->shareGroup()->genName(
                    NamedObjectType::VERTEXBUFFER, 0, true);
            //generating vbo object related to this buffer name
            ctx->shareGroup()->setObjectData(NamedObjectType::VERTEXBUFFER,
                                             buffers[i],
                                             ObjectDataPtr(new GLESbuffer()));
        }
    }
}

GL_APICALL void  GL_APIENTRY glGenerateMipmap(GLenum target){
    GET_CTX();
    SET_ERROR_IF(!GLESvalidate::textureTarget(target), GL_INVALID_ENUM);
    if (ctx->shareGroup().get()) {
        TextureData *texData = getTextureTargetData(target);
        if (texData) {
            unsigned int width = texData->width;
            unsigned int height = texData->height;
            // set error code if either the width or height is not a power of two.
            SET_ERROR_IF(width == 0 || height == 0 ||
                         (width & (width - 1)) != 0 || (height & (height - 1)) != 0,
                         GL_INVALID_OPERATION);
        }
    }
    ctx->dispatcher().glGenerateMipmapEXT(target);
}

GL_APICALL void  GL_APIENTRY glGenFramebuffers(GLsizei n, GLuint* framebuffers){
    GET_CTX();
    SET_ERROR_IF(n<0,GL_INVALID_VALUE);
    if(ctx->shareGroup().get()) {
        for(int i=0; i<n ;i++) {
            framebuffers[i] = ctx->shareGroup()->genName(
                    NamedObjectType::FRAMEBUFFER, 0, true);
            ctx->shareGroup()->setObjectData(
                    NamedObjectType::FRAMEBUFFER, framebuffers[i],
                    ObjectDataPtr(new FramebufferData(framebuffers[i])));
        }
    }
}

GL_APICALL void  GL_APIENTRY glGenRenderbuffers(GLsizei n, GLuint* renderbuffers){
    GET_CTX();
    SET_ERROR_IF(n<0,GL_INVALID_VALUE);
    if(ctx->shareGroup().get()) {
        for(int i=0; i<n ;i++) {
            renderbuffers[i] = ctx->shareGroup()->genName(
                    NamedObjectType::RENDERBUFFER, 0, true);
            ctx->shareGroup()->setObjectData(
                    NamedObjectType::RENDERBUFFER, renderbuffers[i],
                    ObjectDataPtr(new RenderbufferData()));
        }
    }
}

GL_APICALL void  GL_APIENTRY glGenTextures(GLsizei n, GLuint* textures){
    GET_CTX();
    SET_ERROR_IF(n<0,GL_INVALID_VALUE);
    if(ctx->shareGroup().get()) {
        for(int i=0; i<n ;i++) {
            textures[i] = ctx->shareGroup()->genName(NamedObjectType::TEXTURE,
                                                     0, true);
        }
    }
}

GL_APICALL void  GL_APIENTRY glGetActiveAttrib(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name){
    GET_CTX();
    if(ctx->shareGroup().get()) {
        const GLuint globalProgramName = ctx->shareGroup()->getGlobalName(
                NamedObjectType::SHADER_OR_PROGRAM, program);
        SET_ERROR_IF(globalProgramName==0, GL_INVALID_VALUE);
        auto objData = ctx->shareGroup()->getObjectData(
                NamedObjectType::SHADER_OR_PROGRAM, program);
        SET_ERROR_IF(objData->getDataType()!=PROGRAM_DATA,GL_INVALID_OPERATION);
        ctx->dispatcher().glGetActiveAttrib(globalProgramName,index,bufsize,length,size,type,name);
    }
}

GL_APICALL void  GL_APIENTRY glGetActiveUniform(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name){
    GET_CTX();
    if(ctx->shareGroup().get()) {
        const GLuint globalProgramName = ctx->shareGroup()->getGlobalName(
                NamedObjectType::SHADER_OR_PROGRAM, program);
        SET_ERROR_IF(globalProgramName==0, GL_INVALID_VALUE);
        auto objData = ctx->shareGroup()->getObjectData(
                NamedObjectType::SHADER_OR_PROGRAM, program);
        SET_ERROR_IF(objData->getDataType()!=PROGRAM_DATA,GL_INVALID_OPERATION);
        ctx->dispatcher().glGetActiveUniform(globalProgramName,index,bufsize,length,size,type,name);
    }
}

GL_APICALL void  GL_APIENTRY glGetAttachedShaders(GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders){
    GET_CTX();
    if(ctx->shareGroup().get()) {
        const GLuint globalProgramName = ctx->shareGroup()->getGlobalName(
                NamedObjectType::SHADER_OR_PROGRAM, program);
        SET_ERROR_IF(globalProgramName==0, GL_INVALID_VALUE);
        ctx->dispatcher().glGetAttachedShaders(globalProgramName,maxcount,count,shaders);
        auto objData = ctx->shareGroup()->getObjectData(
                NamedObjectType::SHADER_OR_PROGRAM, program);
        SET_ERROR_IF(objData->getDataType()!=PROGRAM_DATA,GL_INVALID_OPERATION);
        GLint numShaders=0;
        ctx->dispatcher().glGetProgramiv(globalProgramName,GL_ATTACHED_SHADERS,&numShaders);
        for(int i=0 ; i < maxcount && i<numShaders ;i++){
            shaders[i] = ctx->shareGroup()->getLocalName(
                    NamedObjectType::SHADER_OR_PROGRAM, shaders[i]);
        }
    }
}

GL_APICALL int GL_APIENTRY glGetAttribLocation(GLuint program, const GLchar* name){
     GET_CTX_RET(-1);
     if(ctx->shareGroup().get()) {
         const GLuint globalProgramName = ctx->shareGroup()->getGlobalName(
                 NamedObjectType::SHADER_OR_PROGRAM, program);
         RET_AND_SET_ERROR_IF(globalProgramName == 0, GL_INVALID_VALUE, -1);
         auto objData = ctx->shareGroup()->getObjectData(
                 NamedObjectType::SHADER_OR_PROGRAM, program);
         RET_AND_SET_ERROR_IF(objData->getDataType() != PROGRAM_DATA,
                              GL_INVALID_OPERATION, -1);
         ProgramData* pData = (ProgramData*)objData;
         RET_AND_SET_ERROR_IF(pData->getLinkStatus() != GL_TRUE,
                              GL_INVALID_OPERATION, -1);
         return ctx->dispatcher().glGetAttribLocation(globalProgramName, name);
     }
     return -1;
}

GL_APICALL void  GL_APIENTRY glGetBooleanv(GLenum pname, GLboolean* params){
    GET_CTX();

    if (ctx->glGetBooleanv(pname,params))
    {
        return;
    }

    switch(pname)
    {
        case GL_SHADER_COMPILER:
        case GL_SHADER_BINARY_FORMATS:
        case GL_NUM_SHADER_BINARY_FORMATS:
        case GL_MAX_VERTEX_UNIFORM_VECTORS:
        case GL_MAX_VARYING_VECTORS:
        case GL_MAX_FRAGMENT_UNIFORM_VECTORS:
            if(ctx->getCaps()->GL_ARB_ES2_COMPATIBILITY)
                ctx->dispatcher().glGetBooleanv(pname,params);
            else
            {
                GLint iparam;
                glGetIntegerv(pname,&iparam);
                *params = (iparam != 0);
            }
            break;

        default:
            ctx->dispatcher().glGetBooleanv(pname,params);
    }
}

GL_APICALL void  GL_APIENTRY glGetBufferParameteriv(GLenum target, GLenum pname, GLint* params){
    GET_CTX();
    SET_ERROR_IF(!(GLESv2Validate::bufferTarget(target) && GLESv2Validate::bufferParam(pname)),GL_INVALID_ENUM);
    SET_ERROR_IF(!ctx->isBindedBuffer(target),GL_INVALID_OPERATION);
    switch(pname) {
    case GL_BUFFER_SIZE:
        ctx->getBufferSize(target,params);
        break;
    case GL_BUFFER_USAGE:
        ctx->getBufferUsage(target,params);
        break;
    }
}


GL_APICALL GLenum GL_APIENTRY glGetError(void){
    GET_CTX_RET(GL_NO_ERROR)
    GLenum err = ctx->getGLerror();
    if(err != GL_NO_ERROR) {
        ctx->setGLerror(GL_NO_ERROR);
        return err;
    }
    return ctx->dispatcher().glGetError();
}

GL_APICALL void  GL_APIENTRY glGetFloatv(GLenum pname, GLfloat* params){
    GET_CTX();

    if (ctx->glGetFloatv(pname,params)) {
        return;
    }

    GLint i;

    switch (pname) {
    case GL_CURRENT_PROGRAM:
    case GL_FRAMEBUFFER_BINDING:
    case GL_RENDERBUFFER_BINDING:
        glGetIntegerv(pname,&i);
        *params = (GLfloat)i;
        break;
    case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
        *params = (GLfloat)getCompressedFormats(NULL); 
        break;    
    case GL_COMPRESSED_TEXTURE_FORMATS:
        {
            int nparams = getCompressedFormats(NULL);
            if (nparams>0) {
                int * iparams = new int[nparams];
                getCompressedFormats(iparams);
                for (int i=0; i<nparams; i++) params[i] = (GLfloat)iparams[i];
                delete [] iparams;
            }
        }
        break;

    case GL_SHADER_COMPILER:
    case GL_SHADER_BINARY_FORMATS:
    case GL_NUM_SHADER_BINARY_FORMATS:
    case GL_MAX_VERTEX_UNIFORM_VECTORS:
    case GL_MAX_VARYING_VECTORS:
    case GL_MAX_FRAGMENT_UNIFORM_VECTORS:
        if(ctx->getCaps()->GL_ARB_ES2_COMPATIBILITY)
            ctx->dispatcher().glGetFloatv(pname,params);
        else
        {
            glGetIntegerv(pname,&i);
            *params = (GLfloat)i;
        }
        break;

    case GL_STENCIL_BACK_VALUE_MASK:
    case GL_STENCIL_BACK_WRITEMASK:
    case GL_STENCIL_VALUE_MASK:
    case GL_STENCIL_WRITEMASK:
        {
            GLint myint = 0;
            glGetIntegerv(pname, &myint);
            // Two casts are used: since mask is unsigned integer,
            // the first cast converts to unsigned integer;
            // the second cast converts to float.
            *params = (GLfloat)((GLuint)(myint));
        }
        break;

    default:
        ctx->dispatcher().glGetFloatv(pname,params);
    }
}

GL_APICALL void  GL_APIENTRY glGetIntegerv(GLenum pname, GLint* params){
    int destroyCtx = 0;
    GET_CTX();

    if (!ctx) {
        ctx = createGLESContext();
        if (ctx)
            destroyCtx = 1;
    }
    if (ctx->glGetIntegerv(pname,params))
    {
        if (destroyCtx)
            deleteGLESContext(ctx);
            return;
    }
  
    bool es2 = ctx->getCaps()->GL_ARB_ES2_COMPATIBILITY;
    GLint i;

    switch (pname) {
    case GL_CURRENT_PROGRAM:
        if (ctx->shareGroup().get()) {
            ctx->dispatcher().glGetIntegerv(pname,&i);
            *params = ctx->shareGroup()->getLocalName(NamedObjectType::SHADER_OR_PROGRAM,
                                                      i);
        }
        break;
    case GL_FRAMEBUFFER_BINDING:
        if (ctx->shareGroup().get()) {
            ctx->dispatcher().glGetIntegerv(pname,&i);
            *params = ctx->shareGroup()->getLocalName(
                    NamedObjectType::FRAMEBUFFER, i);
        }
        break;
    case GL_RENDERBUFFER_BINDING:
        if (ctx->shareGroup().get()) {
            ctx->dispatcher().glGetIntegerv(pname,&i);
            *params = ctx->shareGroup()->getLocalName(
                    NamedObjectType::RENDERBUFFER, i);
        }
        break;

    case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
        *params = getCompressedFormats(NULL); 
        break;    
    case GL_COMPRESSED_TEXTURE_FORMATS:
        getCompressedFormats(params);
        break;

    case GL_SHADER_COMPILER:
        if(es2)
            ctx->dispatcher().glGetIntegerv(pname,params);
        else
            *params = 1;
        break;

    case GL_SHADER_BINARY_FORMATS:
        if(es2)
            ctx->dispatcher().glGetIntegerv(pname,params);
        break;

    case GL_NUM_SHADER_BINARY_FORMATS:
        if(es2)
            ctx->dispatcher().glGetIntegerv(pname,params);
        else
            *params = 0;
        break;

    case GL_MAX_VERTEX_UNIFORM_VECTORS:
        if(es2)
            ctx->dispatcher().glGetIntegerv(pname,params);
        else
            *params = 128;
        break;

    case GL_MAX_VARYING_VECTORS:
        if(es2)
            ctx->dispatcher().glGetIntegerv(pname,params);
        else
            *params = 8;
        break;

    case GL_MAX_FRAGMENT_UNIFORM_VECTORS:
        if(es2)
            ctx->dispatcher().glGetIntegerv(pname,params);
        else
            *params = 16;
        break;

    case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS:
        ctx->dispatcher().glGetIntegerv(pname,params);
        break;
    default:
        ctx->dispatcher().glGetIntegerv(pname,params);
    }
    if (destroyCtx)
            deleteGLESContext(ctx);
}

GL_APICALL void  GL_APIENTRY glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint* params){
    GET_CTX();
    SET_ERROR_IF(!(GLESv2Validate::framebufferTarget(target)         &&
                   GLESv2Validate::framebufferAttachment(attachment) &&
                   GLESv2Validate::framebufferAttachmentParams(pname)),GL_INVALID_ENUM);

    //
    // Take the attachment attribute from our state - if available
    //
    GLuint fbName = ctx->getFramebufferBinding();
    SET_ERROR_IF (!fbName, GL_INVALID_OPERATION);
    if (fbName) {
        auto fbObj = ctx->shareGroup()->getObjectData(
                NamedObjectType::FRAMEBUFFER, fbName);
        if (fbObj != NULL) {
            FramebufferData *fbData = (FramebufferData *)fbObj;
            GLenum target;
            GLuint name = fbData->getAttachment(attachment, &target, NULL);
            if (!name) {
                SET_ERROR_IF(pname != GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE &&
                        pname != GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, GL_INVALID_ENUM);
            }
            if (pname == GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE) {
                if (target == GL_TEXTURE_2D) {
                    *params = GL_TEXTURE;
                    return;
                }
                else if (target == GL_RENDERBUFFER) {
                    *params = GL_RENDERBUFFER;
                    return;
                } else {
                    *params = GL_NONE;
                }
            }
            else if (pname == GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME) {
                *params = name;
                return;
            }
        }
    }

    ctx->dispatcher().glGetFramebufferAttachmentParameterivEXT(target,attachment,pname,params);
}

GL_APICALL void  GL_APIENTRY glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params){
    GET_CTX();
    SET_ERROR_IF(!(GLESv2Validate::renderbufferTarget(target) && GLESv2Validate::renderbufferParams(pname)),GL_INVALID_ENUM);

    //
    // If this is a renderbuffer which is eglimage's target, we
    // should query the underlying eglimage's texture object instead.
    //
    GLuint rb = ctx->getRenderbufferBinding();
    if (rb) {
        auto objData = ctx->shareGroup()->getObjectData(
                NamedObjectType::RENDERBUFFER, rb);
        RenderbufferData *rbData = (RenderbufferData *)objData;
        if (rbData && rbData->eglImageGlobalTexObject) {
            GLenum texPname;
            switch(pname) {
                case GL_RENDERBUFFER_WIDTH:
                    texPname = GL_TEXTURE_WIDTH;
                    break;
                case GL_RENDERBUFFER_HEIGHT:
                    texPname = GL_TEXTURE_HEIGHT;
                    break;
                case GL_RENDERBUFFER_INTERNAL_FORMAT:
                    texPname = GL_TEXTURE_INTERNAL_FORMAT;
                    break;
                case GL_RENDERBUFFER_RED_SIZE:
                    texPname = GL_TEXTURE_RED_SIZE;
                    break;
                case GL_RENDERBUFFER_GREEN_SIZE:
                    texPname = GL_TEXTURE_GREEN_SIZE;
                    break;
                case GL_RENDERBUFFER_BLUE_SIZE:
                    texPname = GL_TEXTURE_BLUE_SIZE;
                    break;
                case GL_RENDERBUFFER_ALPHA_SIZE:
                    texPname = GL_TEXTURE_ALPHA_SIZE;
                    break;
                case GL_RENDERBUFFER_DEPTH_SIZE:
                    texPname = GL_TEXTURE_DEPTH_SIZE;
                    break;
                case GL_RENDERBUFFER_STENCIL_SIZE:
                default:
                    *params = 0; //XXX
                    return;
                    break;
            }

            GLint prevTex;
            ctx->dispatcher().glGetIntegerv(GL_TEXTURE_BINDING_2D, &prevTex);
            ctx->dispatcher().glBindTexture(GL_TEXTURE_2D,
                                            rbData->eglImageGlobalTexObject->getGlobalName());
            ctx->dispatcher().glGetTexLevelParameteriv(GL_TEXTURE_2D, 0,
                                                       texPname,
                                                       params);
            ctx->dispatcher().glBindTexture(GL_TEXTURE_2D, prevTex);
            return;
        }
    }

    ctx->dispatcher().glGetRenderbufferParameterivEXT(target,pname,params);
}


GL_APICALL void  GL_APIENTRY glGetProgramiv(GLuint program, GLenum pname, GLint* params){
    GET_CTX();
    SET_ERROR_IF(!GLESv2Validate::programParam(pname),GL_INVALID_ENUM);
    if(ctx->shareGroup().get()) {
        const GLuint globalProgramName = ctx->shareGroup()->getGlobalName(
                NamedObjectType::SHADER_OR_PROGRAM, program);
        SET_ERROR_IF(globalProgramName==0, GL_INVALID_VALUE);
        switch(pname) {
        case GL_DELETE_STATUS:
            {
            auto objData = ctx->shareGroup()->getObjectData(
                    NamedObjectType::SHADER_OR_PROGRAM, program);
            SET_ERROR_IF(!objData, GL_INVALID_OPERATION);
            SET_ERROR_IF(objData->getDataType() != PROGRAM_DATA,
                         GL_INVALID_OPERATION);
            ProgramData* programData = (ProgramData*)objData;
            params[0] = programData->getDeleteStatus() ? GL_TRUE : GL_FALSE;
            }
            break;
        case GL_LINK_STATUS:
            {
            auto objData = ctx->shareGroup()->getObjectData(
                    NamedObjectType::SHADER_OR_PROGRAM, program);
            SET_ERROR_IF(!objData, GL_INVALID_OPERATION);
            SET_ERROR_IF(objData->getDataType() != PROGRAM_DATA,
                         GL_INVALID_OPERATION);
            ProgramData* programData = (ProgramData*)objData;
            params[0] = programData->getLinkStatus();
            }
            break;
        //validate status should not return GL_TRUE if link failed
        case GL_VALIDATE_STATUS:
            {
            auto objData = ctx->shareGroup()->getObjectData(
                    NamedObjectType::SHADER_OR_PROGRAM, program);
            SET_ERROR_IF(!objData, GL_INVALID_OPERATION);
            SET_ERROR_IF(objData->getDataType() != PROGRAM_DATA,
                         GL_INVALID_OPERATION);
            ProgramData* programData = (ProgramData*)objData;
            if (programData->getLinkStatus() == GL_TRUE)
                ctx->dispatcher().glGetProgramiv(globalProgramName, pname,
                                                 params);
            else
                params[0] = GL_FALSE;
            }
            break;
        case GL_INFO_LOG_LENGTH:
            {
            auto objData = ctx->shareGroup()->getObjectData(
                    NamedObjectType::SHADER_OR_PROGRAM, program);
            SET_ERROR_IF(!objData, GL_INVALID_OPERATION);
            SET_ERROR_IF(objData->getDataType() != PROGRAM_DATA,
                         GL_INVALID_OPERATION);
            ProgramData* programData = (ProgramData*)objData;
            GLint logLength = strlen(programData->getInfoLog());
            params[0] = (logLength > 0) ? logLength + 1 : 0;
            }
            break;   
        default:
            ctx->dispatcher().glGetProgramiv(globalProgramName,pname,params);
        }
    }
}

GL_APICALL void  GL_APIENTRY glGetProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei* length, GLchar* infolog){
    GET_CTX();
    if(ctx->shareGroup().get()) {
        const GLuint globalProgramName = ctx->shareGroup()->getGlobalName(
                NamedObjectType::SHADER_OR_PROGRAM, program);
        SET_ERROR_IF(globalProgramName==0, GL_INVALID_VALUE);
        auto objData = ctx->shareGroup()->getObjectData(
                NamedObjectType::SHADER_OR_PROGRAM, program);
        SET_ERROR_IF(!objData ,GL_INVALID_OPERATION);
        SET_ERROR_IF(objData->getDataType()!=PROGRAM_DATA,GL_INVALID_OPERATION);
        ProgramData* programData = (ProgramData*)objData;

        if (bufsize==0) {
            if (length) {
                *length = 0;
            }
            return;
        }

        GLsizei logLength;
        logLength = strlen(programData->getInfoLog());
        
        GLsizei returnLength=0;
        if (infolog) {
            returnLength = bufsize-1 < logLength ? bufsize-1 : logLength;
            strncpy(infolog,programData->getInfoLog(),returnLength+1);
            infolog[returnLength] = '\0';
        }
        if (length) {
            *length = returnLength;
        }
    }
}

GL_APICALL void  GL_APIENTRY glGetShaderiv(GLuint shader, GLenum pname, GLint* params){
    GET_CTX();
    if(ctx->shareGroup().get()) {
        const GLuint globalShaderName = ctx->shareGroup()->getGlobalName(
                NamedObjectType::SHADER_OR_PROGRAM, shader);
        if (pname == GL_DELETE_STATUS) {
            SET_ERROR_IF(globalShaderName == 0, GL_INVALID_VALUE);
            auto objData = ctx->shareGroup()->getObjectData(
                    NamedObjectType::SHADER_OR_PROGRAM, shader);
            SET_ERROR_IF(!objData ,GL_INVALID_VALUE);
            SET_ERROR_IF(objData->getDataType()!=SHADER_DATA,GL_INVALID_VALUE);
            ShaderParser* sp = (ShaderParser*)objData;
            params[0]  = (sp->getDeleteStatus()) ? GL_TRUE : GL_FALSE;
            return;
        }
        SET_ERROR_IF(globalShaderName==0, GL_INVALID_VALUE);
        switch(pname) {
        case GL_INFO_LOG_LENGTH:
            {
            auto objData = ctx->shareGroup()->getObjectData(
                    NamedObjectType::SHADER_OR_PROGRAM, shader);
            SET_ERROR_IF(!objData, GL_INVALID_OPERATION);
            SET_ERROR_IF(objData->getDataType() != SHADER_DATA,
                         GL_INVALID_OPERATION);
            ShaderParser* sp = (ShaderParser*)objData;
            GLint logLength = strlen(sp->getInfoLog());
            params[0] = (logLength > 0) ? logLength + 1 : 0;
            }
            break;
        case GL_SHADER_SOURCE_LENGTH:
            {
            auto objData = ctx->shareGroup()->getObjectData(
                    NamedObjectType::SHADER_OR_PROGRAM, shader);
            SET_ERROR_IF(!objData, GL_INVALID_OPERATION);
            SET_ERROR_IF(objData->getDataType() != SHADER_DATA,
                         GL_INVALID_OPERATION);
            ShaderParser* sp = (ShaderParser*)objData;
            GLint srcLength = sp->getOriginalSrc().length();
            params[0] = (srcLength > 0) ? srcLength + 1 : 0;
            }
            break;
        default:
            ctx->dispatcher().glGetShaderiv(globalShaderName,pname,params);
        }
    }
}


GL_APICALL void  GL_APIENTRY glGetShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* infolog){
    GET_CTX();
    if(ctx->shareGroup().get()) {
        const GLuint globalShaderName = ctx->shareGroup()->getGlobalName(
                NamedObjectType::SHADER_OR_PROGRAM, shader);
        SET_ERROR_IF(globalShaderName==0, GL_INVALID_VALUE);
        auto objData = ctx->shareGroup()->getObjectData(
                NamedObjectType::SHADER_OR_PROGRAM, shader);
        SET_ERROR_IF(!objData ,GL_INVALID_OPERATION);
        SET_ERROR_IF(objData->getDataType()!=SHADER_DATA,GL_INVALID_OPERATION);
        ShaderParser* sp = (ShaderParser*)objData;

        if (bufsize==0) {
            if (length) {
                *length = 0;
            }
            return;
        }

        GLsizei logLength;
        logLength = strlen(sp->getInfoLog());
        
        GLsizei returnLength=0;
        if (infolog) {
            returnLength = bufsize-1 <logLength ? bufsize-1 : logLength;
            strncpy(infolog,sp->getInfoLog(),returnLength+1);
            infolog[returnLength] = '\0';
        }
        if (length) {
            *length = returnLength;
        }
    }
}

GL_APICALL void  GL_APIENTRY glGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision){
    GET_CTX_V2();
    SET_ERROR_IF(!(GLESv2Validate::shaderType(shadertype) && GLESv2Validate::precisionType(precisiontype)),GL_INVALID_ENUM);

    switch (precisiontype) {
    case GL_LOW_INT:
    case GL_MEDIUM_INT:
    case GL_HIGH_INT:
        range[0] = range[1] = 16;
        *precision = 0;
        break;

    case GL_LOW_FLOAT:
    case GL_MEDIUM_FLOAT:
    case GL_HIGH_FLOAT:
        if(ctx->dispatcher().glGetShaderPrecisionFormat != NULL) {
            ctx->dispatcher().glGetShaderPrecisionFormat(shadertype,precisiontype,range,precision);
        } else {
            range[0] = range[1] = 127;
            *precision = 24;
        }
        break;
    }
}

GL_APICALL void  GL_APIENTRY glGetShaderSource(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source){
    GET_CTX();
    if(ctx->shareGroup().get()) {
        const GLuint globalShaderName = ctx->shareGroup()->getGlobalName(
                NamedObjectType::SHADER_OR_PROGRAM, shader);
        SET_ERROR_IF(globalShaderName == 0, GL_INVALID_VALUE);
        auto objData = ctx->shareGroup()->getObjectData(
                NamedObjectType::SHADER_OR_PROGRAM, shader);
        SET_ERROR_IF(!objData, GL_INVALID_OPERATION);
        SET_ERROR_IF(objData->getDataType() != SHADER_DATA,
                     GL_INVALID_OPERATION);
        const std::string& src =
                ((ShaderParser*)objData)->getOriginalSrc();
        int srcLength = static_cast<int>(src.size());

        int returnLength = bufsize < srcLength ? bufsize - 1 : srcLength;
        if (returnLength) {
            strncpy(source, src.c_str(), returnLength);
            source[returnLength] = '\0';
       }

       if (length)
          *length = returnLength;
    }
}


GL_APICALL const GLubyte* GL_APIENTRY glGetString(GLenum name){
    GET_CTX_RET(NULL)
    static const GLubyte SHADING[] = "OpenGL ES GLSL ES 1.0.17";
    switch(name) {
        case GL_VENDOR:
            return (const GLubyte*)ctx->getVendorString();
        case GL_RENDERER:
            return (const GLubyte*)ctx->getRendererString();
        case GL_VERSION:
            return (const GLubyte*)ctx->getVersionString();
        case GL_SHADING_LANGUAGE_VERSION:
            return SHADING;
        case GL_EXTENSIONS:
            return (const GLubyte*)ctx->getExtensionString();
        default:
            RET_AND_SET_ERROR_IF(true,GL_INVALID_ENUM,NULL);
    }
}

GL_APICALL void  GL_APIENTRY glGetTexParameterfv(GLenum target, GLenum pname, GLfloat* params){
    GET_CTX();
    SET_ERROR_IF(!(GLESv2Validate::textureTarget(target) && GLESv2Validate::textureParams(pname)),GL_INVALID_ENUM);
    ctx->dispatcher().glGetTexParameterfv(target,pname,params);

}
GL_APICALL void  GL_APIENTRY glGetTexParameteriv(GLenum target, GLenum pname, GLint* params){
    GET_CTX();
    SET_ERROR_IF(!(GLESv2Validate::textureTarget(target) && GLESv2Validate::textureParams(pname)),GL_INVALID_ENUM);
    ctx->dispatcher().glGetTexParameteriv(target,pname,params);
}

GL_APICALL void  GL_APIENTRY glGetUniformfv(GLuint program, GLint location, GLfloat* params){
    GET_CTX();
    SET_ERROR_IF(location < 0,GL_INVALID_OPERATION);
    if(ctx->shareGroup().get()) {
        const GLuint globalProgramName = ctx->shareGroup()->getGlobalName(
                NamedObjectType::SHADER_OR_PROGRAM, program);
        SET_ERROR_IF(globalProgramName==0, GL_INVALID_VALUE);
        auto objData = ctx->shareGroup()->getObjectData(
                NamedObjectType::SHADER_OR_PROGRAM, program);
        SET_ERROR_IF(objData->getDataType()!=PROGRAM_DATA,GL_INVALID_OPERATION);
        ProgramData* pData = (ProgramData *)objData;
        SET_ERROR_IF(pData->getLinkStatus() != GL_TRUE,GL_INVALID_OPERATION);
        ctx->dispatcher().glGetUniformfv(globalProgramName,location,params);
    }
}

GL_APICALL void  GL_APIENTRY glGetUniformiv(GLuint program, GLint location, GLint* params){
    GET_CTX();
    SET_ERROR_IF(location < 0,GL_INVALID_OPERATION);
    if(ctx->shareGroup().get()) {
        const GLuint globalProgramName = ctx->shareGroup()->getGlobalName(
                NamedObjectType::SHADER_OR_PROGRAM, program);
        SET_ERROR_IF(globalProgramName==0, GL_INVALID_VALUE);
        auto objData = ctx->shareGroup()->getObjectData(
                NamedObjectType::SHADER_OR_PROGRAM, program);
        SET_ERROR_IF(objData->getDataType()!=PROGRAM_DATA,GL_INVALID_OPERATION);
        ProgramData* pData = (ProgramData *)objData;
        SET_ERROR_IF(pData->getLinkStatus() != GL_TRUE,GL_INVALID_OPERATION);
        ctx->dispatcher().glGetUniformiv(globalProgramName,location,params);
    }
}

GL_APICALL int GL_APIENTRY glGetUniformLocation(GLuint program, const GLchar* name){
    GET_CTX_RET(-1);
    if(ctx->shareGroup().get()) {
        const GLuint globalProgramName = ctx->shareGroup()->getGlobalName(
                NamedObjectType::SHADER_OR_PROGRAM, program);
        RET_AND_SET_ERROR_IF(globalProgramName==0, GL_INVALID_VALUE,-1);
        auto objData = ctx->shareGroup()->getObjectData(
                NamedObjectType::SHADER_OR_PROGRAM, program);
        RET_AND_SET_ERROR_IF(objData->getDataType()!=PROGRAM_DATA,GL_INVALID_OPERATION,-1);
        ProgramData* pData = (ProgramData *)objData;
        RET_AND_SET_ERROR_IF(pData->getLinkStatus() != GL_TRUE,GL_INVALID_OPERATION,-1);
        return ctx->dispatcher().glGetUniformLocation(globalProgramName,name);
    }
    return -1;
}

static bool s_invalidVertexAttribIndex(GLuint index) {
    GLint param=0;
    glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &param);
    return (param < 0 || index >= (GLuint)param);
}

GL_APICALL void  GL_APIENTRY glGetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params){
    GET_CTX_V2();
    SET_ERROR_IF(s_invalidVertexAttribIndex(index), GL_INVALID_VALUE);
    const GLESpointer* p = ctx->getPointer(index);
    if(p) {
        switch(pname){
        case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
            *params = 0;
            break;
        case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
            *params = p->isEnable();
            break;
        case GL_VERTEX_ATTRIB_ARRAY_SIZE:
            *params = p->getSize();
            break;
        case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
            *params = p->getStride();
            break;
        case GL_VERTEX_ATTRIB_ARRAY_TYPE:
            *params = p->getType();
            break;
        case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
            *params = p->isNormalize();
            break;
        case GL_CURRENT_VERTEX_ATTRIB:
            if(index == 0)
            {
                const float* att0 = ctx->getAtt0();
                for(int i=0; i<4; i++)
                    params[i] = att0[i];
            }
            else
                ctx->dispatcher().glGetVertexAttribfv(index,pname,params);
            break;
        default:
            ctx->setGLerror(GL_INVALID_ENUM);
        }
    } else {
        ctx->setGLerror(GL_INVALID_VALUE);
    }
}

GL_APICALL void  GL_APIENTRY glGetVertexAttribiv(GLuint index, GLenum pname, GLint* params){
    GET_CTX_V2();
    SET_ERROR_IF(s_invalidVertexAttribIndex(index), GL_INVALID_VALUE);
    const GLESpointer* p = ctx->getPointer(index);
    if(p) {
        switch(pname){
        case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
            *params = 0;
            break;
        case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
            *params = p->isEnable();
            break;
        case GL_VERTEX_ATTRIB_ARRAY_SIZE:
            *params = p->getSize();
            break;
        case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
            *params = p->getStride();
            break;
        case GL_VERTEX_ATTRIB_ARRAY_TYPE:
            *params = p->getType();
            break;
        case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
            *params = p->isNormalize();
            break;
        case GL_CURRENT_VERTEX_ATTRIB:
            if(index == 0)
            {
                const float* att0 = ctx->getAtt0();
                for(int i=0; i<4; i++)
                    params[i] = (GLint)att0[i];
            }
            else
                ctx->dispatcher().glGetVertexAttribiv(index,pname,params);
            break;
        default:
            ctx->setGLerror(GL_INVALID_ENUM);
        }
    } else {
        ctx->setGLerror(GL_INVALID_VALUE);
    }
}

GL_APICALL void  GL_APIENTRY glGetVertexAttribPointerv(GLuint index, GLenum pname, GLvoid** pointer){
    GET_CTX();
    SET_ERROR_IF(pname != GL_VERTEX_ATTRIB_ARRAY_POINTER,GL_INVALID_ENUM);
    SET_ERROR_IF((!GLESv2Validate::arrayIndex(ctx,index)),GL_INVALID_VALUE);

    const GLESpointer* p = ctx->getPointer(index);
    if(p) {
        *pointer = const_cast<void *>( p->getBufferData());
    } else {
        ctx->setGLerror(GL_INVALID_VALUE);
    }
}

GL_APICALL void  GL_APIENTRY glHint(GLenum target, GLenum mode){
    GET_CTX();
    SET_ERROR_IF(!GLESv2Validate::hintTargetMode(target,mode),GL_INVALID_ENUM);
    ctx->dispatcher().glHint(target,mode);
}

GL_APICALL GLboolean    GL_APIENTRY glIsEnabled(GLenum cap){
    GET_CTX_RET(GL_FALSE);
    RET_AND_SET_ERROR_IF(!GLESv2Validate::capability(cap),GL_INVALID_ENUM,GL_FALSE);
    return ctx->dispatcher().glIsEnabled(cap);
}

GL_APICALL GLboolean    GL_APIENTRY glIsBuffer(GLuint buffer){
    GET_CTX_RET(GL_FALSE)
    if(buffer && ctx->shareGroup().get()) {
        auto objData = ctx->shareGroup()->getObjectData(
                NamedObjectType::VERTEXBUFFER, buffer);
        return objData ? ((GLESbuffer*)objData)->wasBinded()
                             : GL_FALSE;
    }
    return GL_FALSE;
}

GL_APICALL GLboolean    GL_APIENTRY glIsFramebuffer(GLuint framebuffer){
    GET_CTX_RET(GL_FALSE)
    if(framebuffer && ctx->shareGroup().get()){
        return (ctx->shareGroup()->isObject(NamedObjectType::FRAMEBUFFER,
                                            framebuffer) &&
                ctx->getFramebufferBinding() == framebuffer)
                       ? GL_TRUE
                       : GL_FALSE;
    }
    return GL_FALSE;
}

GL_APICALL GLboolean    GL_APIENTRY glIsRenderbuffer(GLuint renderbuffer){
    GET_CTX_RET(GL_FALSE)
    if(renderbuffer && ctx->shareGroup().get()){
        return (ctx->shareGroup()->isObject(NamedObjectType::RENDERBUFFER,
                                            renderbuffer) &&
                ctx->getRenderbufferBinding() == renderbuffer)
                       ? GL_TRUE
                       : GL_FALSE;
    }
    return GL_FALSE;
}

GL_APICALL GLboolean    GL_APIENTRY glIsTexture(GLuint texture){
    GET_CTX_RET(GL_FALSE)
    if (texture==0)
        return GL_FALSE;
    TextureData* tex = getTextureData(texture);
    return tex ? tex->wasBound : GL_FALSE;
}

GL_APICALL GLboolean    GL_APIENTRY glIsProgram(GLuint program){
    GET_CTX_RET(GL_FALSE)
    if (program && ctx->shareGroup().get() &&
        ctx->shareGroup()->isObject(NamedObjectType::SHADER_OR_PROGRAM, program)) {
        const GLuint globalProgramName = ctx->shareGroup()->getGlobalName(
                NamedObjectType::SHADER_OR_PROGRAM, program);
        return ctx->dispatcher().glIsProgram(globalProgramName);
    }
    return GL_FALSE;
}

GL_APICALL GLboolean    GL_APIENTRY glIsShader(GLuint shader){
    GET_CTX_RET(GL_FALSE)
    if (shader && ctx->shareGroup().get() &&
        ctx->shareGroup()->isObject(NamedObjectType::SHADER_OR_PROGRAM, shader)) {
        const GLuint globalShaderName = ctx->shareGroup()->getGlobalName(
                NamedObjectType::SHADER_OR_PROGRAM, shader);
        return ctx->dispatcher().glIsShader(globalShaderName);
    }
    return GL_FALSE;
}

GL_APICALL void  GL_APIENTRY glLineWidth(GLfloat width){
    GET_CTX();
    ctx->dispatcher().glLineWidth(width);
}

GL_APICALL void  GL_APIENTRY glLinkProgram(GLuint program){
    GET_CTX();
    GLint linkStatus = GL_FALSE;
    if(ctx->shareGroup().get()) {
        const GLuint globalProgramName = ctx->shareGroup()->getGlobalName(
                NamedObjectType::SHADER_OR_PROGRAM, program);
        SET_ERROR_IF(globalProgramName==0, GL_INVALID_VALUE);

        auto objData = ctx->shareGroup()->getObjectData(
                NamedObjectType::SHADER_OR_PROGRAM, program);
        SET_ERROR_IF(!objData, GL_INVALID_OPERATION);
        SET_ERROR_IF(objData->getDataType()!=PROGRAM_DATA, GL_INVALID_OPERATION);
        ProgramData* programData = (ProgramData*)objData;
        GLint fragmentShader   = programData->getAttachedFragmentShader();
        GLint vertexShader =  programData->getAttachedVertexShader();
        if (vertexShader != 0 && fragmentShader!=0) {
            /* validating that the fragment & vertex shaders were compiled successfuly*/
            GLint fCompileStatus = GL_FALSE;
            GLint vCompileStatus = GL_FALSE;
            GLuint fragmentShaderGlobal = ctx->shareGroup()->getGlobalName(
                    NamedObjectType::SHADER_OR_PROGRAM, fragmentShader);
            GLuint vertexShaderGlobal = ctx->shareGroup()->getGlobalName(
                    NamedObjectType::SHADER_OR_PROGRAM, vertexShader);
            ctx->dispatcher().glGetShaderiv(fragmentShaderGlobal,GL_COMPILE_STATUS,&fCompileStatus);
            ctx->dispatcher().glGetShaderiv(vertexShaderGlobal,GL_COMPILE_STATUS,&vCompileStatus);

            if(fCompileStatus != 0 && vCompileStatus != 0){
                ctx->dispatcher().glLinkProgram(globalProgramName);
                ctx->dispatcher().glGetProgramiv(globalProgramName,GL_LINK_STATUS,&linkStatus);
            }
        }
        programData->setLinkStatus(linkStatus);
        
        GLsizei infoLogLength=0;
        GLchar* infoLog;
        ctx->dispatcher().glGetProgramiv(globalProgramName,GL_INFO_LOG_LENGTH,&infoLogLength);
        infoLog = new GLchar[infoLogLength+1];
        ctx->dispatcher().glGetProgramInfoLog(globalProgramName,infoLogLength,NULL,infoLog);
        programData->setInfoLog(infoLog);
    }
}

GL_APICALL void  GL_APIENTRY glPixelStorei(GLenum pname, GLint param){
    GET_CTX();
    SET_ERROR_IF(!GLESv2Validate::pixelStoreParam(pname),GL_INVALID_ENUM);
    SET_ERROR_IF(!((param==1)||(param==2)||(param==4)||(param==8)), GL_INVALID_VALUE);
    ctx->setUnpackAlignment(param);
    ctx->dispatcher().glPixelStorei(pname,param);
}

GL_APICALL void  GL_APIENTRY glPolygonOffset(GLfloat factor, GLfloat units){
    GET_CTX();
    ctx->dispatcher().glPolygonOffset(factor,units);
}

GL_APICALL void  GL_APIENTRY glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels){
    GET_CTX();
    SET_ERROR_IF(!(GLESv2Validate::readPixelFrmt(format) && GLESv2Validate::pixelType(ctx,type)),GL_INVALID_ENUM);
    SET_ERROR_IF((width < 0 || height < 0),GL_INVALID_VALUE);
    SET_ERROR_IF(!(GLESv2Validate::pixelOp(format,type)),GL_INVALID_OPERATION);
    SET_ERROR_IF(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE, GL_INVALID_FRAMEBUFFER_OPERATION);
    ctx->dispatcher().glReadPixels(x,y,width,height,format,type,pixels);
}


GL_APICALL void  GL_APIENTRY glReleaseShaderCompiler(void){
// this function doesn't work on Mac OS with MacOSX10.9sdk
#ifndef __APPLE__

    /* Use this function with mesa will cause potential bug. Specifically,
     * calling this function between glCompileShader() and glLinkProgram() will
     * release resources that would be potentially used by glLinkProgram,
     * resulting in a segmentation fault.
     */
    const char* env = ::getenv("ANDROID_GL_LIB");
    if (env && !strcmp(env, "mesa")) {
        return;
    }

    GET_CTX();

    if(ctx->dispatcher().glReleaseShaderCompiler != NULL)
    {
        ctx->dispatcher().glReleaseShaderCompiler();
    }
#endif // !__APPLE__
}

GL_APICALL void  GL_APIENTRY glRenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height){
    GET_CTX();
    GLenum internal = internalformat;
    switch (internalformat) {
    case GL_RGB565:
        internal = GL_RGB;
        break;
    case GL_RGB5_A1:
        internal = GL_RGBA;
        break;
    default:
        internal = internalformat;
        break;
    }

    // Get current bounded renderbuffer
    // raise INVALID_OPERATIOn if no renderbuffer is bounded
    GLuint rb = ctx->getRenderbufferBinding();
    SET_ERROR_IF(rb == 0,GL_INVALID_OPERATION);
    auto objData =
            ctx->shareGroup()->getObjectData(NamedObjectType::RENDERBUFFER, rb);
    RenderbufferData *rbData = (RenderbufferData *)objData;
    SET_ERROR_IF(!rbData,GL_INVALID_OPERATION);

    //
    // if the renderbuffer was an eglImage target, release
    // its underlying texture.
    //
    rbData->eglImageGlobalTexObject.reset();

    ctx->dispatcher().glRenderbufferStorageEXT(target,internal,width,height);
}

GL_APICALL void  GL_APIENTRY glSampleCoverage(GLclampf value, GLboolean invert){
    GET_CTX();
    ctx->dispatcher().glSampleCoverage(value,invert);
}

GL_APICALL void  GL_APIENTRY glScissor(GLint x, GLint y, GLsizei width, GLsizei height){
    GET_CTX();
    ctx->dispatcher().glScissor(x,y,width,height);
}

GL_APICALL void  GL_APIENTRY glShaderBinary(GLsizei n, const GLuint* shaders, GLenum binaryformat, const GLvoid* binary, GLsizei length){
    GET_CTX();

    SET_ERROR_IF( (ctx->dispatcher().glShaderBinary == NULL), GL_INVALID_OPERATION);

    if(ctx->shareGroup().get()){
        for(int i=0; i < n ; i++){
            const GLuint globalShaderName = ctx->shareGroup()->getGlobalName(
                    NamedObjectType::SHADER_OR_PROGRAM, shaders[i]);
            SET_ERROR_IF(globalShaderName == 0,GL_INVALID_VALUE);
            ctx->dispatcher().glShaderBinary(1,&globalShaderName,binaryformat,binary,length);
        }
    }
}

GL_APICALL void  GL_APIENTRY glShaderSource(GLuint shader, GLsizei count, const GLchar* const* string, const GLint* length){
    GET_CTX_V2();
    SET_ERROR_IF(count < 0,GL_INVALID_VALUE);
    if(ctx->shareGroup().get()){
        const GLuint globalShaderName = ctx->shareGroup()->getGlobalName(
                NamedObjectType::SHADER_OR_PROGRAM, shader);
        SET_ERROR_IF(globalShaderName == 0, GL_INVALID_VALUE);
        auto objData = ctx->shareGroup()->getObjectData(
                NamedObjectType::SHADER_OR_PROGRAM, shader);
        SET_ERROR_IF(!objData, GL_INVALID_OPERATION);
        SET_ERROR_IF(objData->getDataType() != SHADER_DATA,
                     GL_INVALID_OPERATION);
        ShaderParser* sp = (ShaderParser*)objData;
        sp->setSrc(ctx->glslVersion(), count, string, length);
        ctx->dispatcher().glShaderSource(globalShaderName, 1, sp->parsedLines(),
                                         NULL);
        sp->clear();
    }
}

GL_APICALL void  GL_APIENTRY glStencilFunc(GLenum func, GLint ref, GLuint mask){
    GET_CTX();
    ctx->dispatcher().glStencilFunc(func,ref,mask);
}
GL_APICALL void  GL_APIENTRY glStencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask){
    GET_CTX();
    ctx->dispatcher().glStencilFuncSeparate(face,func,ref,mask);
}
GL_APICALL void  GL_APIENTRY glStencilMask(GLuint mask){
    GET_CTX();
    ctx->dispatcher().glStencilMask(mask);
}

GL_APICALL void  GL_APIENTRY glStencilMaskSeparate(GLenum face, GLuint mask){
    GET_CTX();
    ctx->dispatcher().glStencilMaskSeparate(face,mask);
}

GL_APICALL void  GL_APIENTRY glStencilOp(GLenum fail, GLenum zfail, GLenum zpass){
    GET_CTX();
    ctx->dispatcher().glStencilOp(fail,zfail,zpass);
}

GL_APICALL void  GL_APIENTRY glStencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass){
    GET_CTX();
    switch (face) {
        case GL_FRONT:
        case GL_BACK:
        case GL_FRONT_AND_BACK:
            break;
        default:
            SET_ERROR_IF(1, GL_INVALID_ENUM);
    }
    ctx->dispatcher().glStencilOpSeparate(face, fail,zfail,zpass);
}

#define GL_RGBA32F                        0x8814
#define GL_RGB32F                         0x8815
GL_APICALL void  GL_APIENTRY glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid* pixels){
    GET_CTX();
    SET_ERROR_IF(!(GLESv2Validate::textureTargetEx(target) &&
                   GLESv2Validate::pixelFrmt(ctx,format)&&
                   GLESv2Validate::pixelType(ctx,type)),GL_INVALID_ENUM);

    SET_ERROR_IF(!GLESv2Validate::pixelItnlFrmt(ctx,internalformat), GL_INVALID_VALUE);
    SET_ERROR_IF((GLESv2Validate::textureIsCubeMap(target) && width != height), GL_INVALID_VALUE);
    SET_ERROR_IF((format == GL_DEPTH_COMPONENT || internalformat == GL_DEPTH_COMPONENT) &&
                    (type != GL_UNSIGNED_SHORT && type != GL_UNSIGNED_INT), GL_INVALID_OPERATION);

    SET_ERROR_IF((type == GL_UNSIGNED_SHORT || type == GL_UNSIGNED_INT) &&
                    (format != GL_DEPTH_COMPONENT || internalformat != GL_DEPTH_COMPONENT), GL_INVALID_OPERATION);

    SET_ERROR_IF(!GLESv2Validate::pixelOp(format,type) && internalformat == ((GLint)format),GL_INVALID_OPERATION);
    SET_ERROR_IF(!GLESv2Validate::pixelSizedFrmt(ctx, internalformat, format, type), GL_INVALID_OPERATION);
    SET_ERROR_IF(border != 0,GL_INVALID_VALUE);

    s_glInitTexImage2D(target,level,internalformat,width,height,border);
    if (type==GL_HALF_FLOAT_OES)
        type = GL_HALF_FLOAT_NV;
    if (pixels==NULL && type==GL_UNSIGNED_SHORT_5_5_5_1)
        type = GL_UNSIGNED_SHORT;
    if (type == GL_FLOAT)
        internalformat = (format == GL_RGBA) ? GL_RGBA32F : GL_RGB32F;
    ctx->dispatcher().glTexImage2D(target,level,internalformat,width,height,border,format,type,pixels);
}

GL_APICALL void  GL_APIENTRY glTexParameterf(GLenum target, GLenum pname, GLfloat param){
    GET_CTX();
    SET_ERROR_IF(!(GLESv2Validate::textureTarget(target) && GLESv2Validate::textureParams(pname)),GL_INVALID_ENUM);
    ctx->dispatcher().glTexParameterf(target,pname,param);
}
GL_APICALL void  GL_APIENTRY glTexParameterfv(GLenum target, GLenum pname, const GLfloat* params){
    GET_CTX();
    SET_ERROR_IF(!(GLESv2Validate::textureTarget(target) && GLESv2Validate::textureParams(pname)),GL_INVALID_ENUM);
    ctx->dispatcher().glTexParameterfv(target,pname,params);
}
GL_APICALL void  GL_APIENTRY glTexParameteri(GLenum target, GLenum pname, GLint param){
    GET_CTX();
    SET_ERROR_IF(!(GLESv2Validate::textureTarget(target) && GLESv2Validate::textureParams(pname)),GL_INVALID_ENUM);
    ctx->dispatcher().glTexParameteri(target,pname,param);
}
GL_APICALL void  GL_APIENTRY glTexParameteriv(GLenum target, GLenum pname, const GLint* params){
    GET_CTX();
    SET_ERROR_IF(!(GLESv2Validate::textureTarget(target) && GLESv2Validate::textureParams(pname)),GL_INVALID_ENUM);
    ctx->dispatcher().glTexParameteriv(target,pname,params);
}

GL_APICALL void  GL_APIENTRY glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid* pixels){
    GET_CTX();
    SET_ERROR_IF(!(GLESv2Validate::textureTargetEx(target)), GL_INVALID_ENUM);
    // set an error if level < 0 or level > log 2 max
    SET_ERROR_IF(level < 0 || 1<<level > ctx->getMaxTexSize(), GL_INVALID_VALUE);
    SET_ERROR_IF(xoffset < 0 || yoffset < 0 || width < 0 || height < 0, GL_INVALID_VALUE);
    if (ctx->shareGroup().get()) {
        TextureData *texData = getTextureTargetData(target);
        if (texData) {
            SET_ERROR_IF(xoffset + width > (GLint)texData->width ||
                     yoffset + height > (GLint)texData->height,
                     GL_INVALID_VALUE);
        }
    }
    SET_ERROR_IF(!(GLESv2Validate::pixelFrmt(ctx,format)&&
                   GLESv2Validate::pixelType(ctx,type)),GL_INVALID_ENUM);
    SET_ERROR_IF(!GLESv2Validate::pixelOp(format,type),GL_INVALID_OPERATION);
    SET_ERROR_IF(!pixels,GL_INVALID_OPERATION);
    if (type==GL_HALF_FLOAT_OES)
        type = GL_HALF_FLOAT_NV;

    ctx->dispatcher().glTexSubImage2D(target,level,xoffset,yoffset,width,height,format,type,pixels);

}

GL_APICALL void  GL_APIENTRY glUniform1f(GLint location, GLfloat x){
    GET_CTX();
    ctx->dispatcher().glUniform1f(location,x);
}
GL_APICALL void  GL_APIENTRY glUniform1fv(GLint location, GLsizei count, const GLfloat* v){
    GET_CTX();
    ctx->dispatcher().glUniform1fv(location,count,v);
}

GL_APICALL void  GL_APIENTRY glUniform1i(GLint location, GLint x){
    GET_CTX();
    ctx->dispatcher().glUniform1i(location,x);
}
GL_APICALL void  GL_APIENTRY glUniform1iv(GLint location, GLsizei count, const GLint* v){
    GET_CTX();
    ctx->dispatcher().glUniform1iv(location,count,v);
}
GL_APICALL void  GL_APIENTRY glUniform2f(GLint location, GLfloat x, GLfloat y){
    GET_CTX();
    ctx->dispatcher().glUniform2f(location,x,y);
}
GL_APICALL void  GL_APIENTRY glUniform2fv(GLint location, GLsizei count, const GLfloat* v){
    GET_CTX();
    ctx->dispatcher().glUniform2fv(location,count,v);
}
GL_APICALL void  GL_APIENTRY glUniform2i(GLint location, GLint x, GLint y){
    GET_CTX();
    ctx->dispatcher().glUniform2i(location,x,y);
}
GL_APICALL void  GL_APIENTRY glUniform2iv(GLint location, GLsizei count, const GLint* v){
    GET_CTX();
    ctx->dispatcher().glUniform2iv(location,count,v);
}
GL_APICALL void  GL_APIENTRY glUniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z){
    GET_CTX();
    ctx->dispatcher().glUniform3f(location,x,y,z);
}
GL_APICALL void  GL_APIENTRY glUniform3fv(GLint location, GLsizei count, const GLfloat* v){
    GET_CTX();
    ctx->dispatcher().glUniform3fv(location,count,v);
}
GL_APICALL void  GL_APIENTRY glUniform3i(GLint location, GLint x, GLint y, GLint z){
    GET_CTX();
    ctx->dispatcher().glUniform3i(location,x,y,z);
}

GL_APICALL void  GL_APIENTRY glUniform3iv(GLint location, GLsizei count, const GLint* v){
    GET_CTX();
    ctx->dispatcher().glUniform3iv(location,count,v);
}

GL_APICALL void  GL_APIENTRY glUniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w){
    GET_CTX();
    ctx->dispatcher().glUniform4f(location,x,y,z,w);
}

GL_APICALL void  GL_APIENTRY glUniform4fv(GLint location, GLsizei count, const GLfloat* v){
    GET_CTX();
    ctx->dispatcher().glUniform4fv(location,count,v);
}

GL_APICALL void  GL_APIENTRY glUniform4i(GLint location, GLint x, GLint y, GLint z, GLint w){
    GET_CTX();
    ctx->dispatcher().glUniform4i(location,x,y,z,w);
}

GL_APICALL void  GL_APIENTRY glUniform4iv(GLint location, GLsizei count, const GLint* v){
    GET_CTX();
    ctx->dispatcher().glUniform4iv(location,count,v);
}

GL_APICALL void  GL_APIENTRY glUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value){
    GET_CTX();
    SET_ERROR_IF(transpose != GL_FALSE,GL_INVALID_VALUE);
    ctx->dispatcher().glUniformMatrix2fv(location,count,transpose,value);
}

GL_APICALL void  GL_APIENTRY glUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value){
    GET_CTX();
    SET_ERROR_IF(transpose != GL_FALSE,GL_INVALID_VALUE);
    ctx->dispatcher().glUniformMatrix3fv(location,count,transpose,value);
}

GL_APICALL void  GL_APIENTRY glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value){
    GET_CTX();
    SET_ERROR_IF(transpose != GL_FALSE,GL_INVALID_VALUE);
    ctx->dispatcher().glUniformMatrix4fv(location,count,transpose,value);
}

static void s_unUseCurrentProgram() {
    GET_CTX();
    GLint localCurrentProgram = 0;
    glGetIntegerv(GL_CURRENT_PROGRAM, &localCurrentProgram);
    if (!localCurrentProgram) return;

    auto objData = ctx->shareGroup()->getObjectData(
            NamedObjectType::SHADER_OR_PROGRAM, localCurrentProgram);
    SET_ERROR_IF(objData->getDataType()!=PROGRAM_DATA,GL_INVALID_OPERATION);
    ProgramData* programData = (ProgramData*)objData;
    programData->setInUse(false);
    if (programData->getDeleteStatus()) {
        ctx->shareGroup()->deleteName(NamedObjectType::SHADER_OR_PROGRAM,
                                      localCurrentProgram);
    }
}

GL_APICALL void  GL_APIENTRY glUseProgram(GLuint program){
    GET_CTX();
    if(ctx->shareGroup().get()) {
        const GLuint globalProgramName = ctx->shareGroup()->getGlobalName(
                NamedObjectType::SHADER_OR_PROGRAM, program);
        SET_ERROR_IF(program!=0 && globalProgramName==0,GL_INVALID_VALUE);
        auto objData = ctx->shareGroup()->getObjectData(
                NamedObjectType::SHADER_OR_PROGRAM, program);
        SET_ERROR_IF(objData && (objData->getDataType()!=PROGRAM_DATA),GL_INVALID_OPERATION);

        s_unUseCurrentProgram();

        ProgramData* programData = (ProgramData*)objData;
        if (programData) programData->setInUse(true);

        ctx->dispatcher().glUseProgram(globalProgramName);
    }
}

GL_APICALL void  GL_APIENTRY glValidateProgram(GLuint program){
    GET_CTX();
    if(ctx->shareGroup().get()) {
        const GLuint globalProgramName = ctx->shareGroup()->getGlobalName(
                NamedObjectType::SHADER_OR_PROGRAM, program);
        SET_ERROR_IF(globalProgramName==0, GL_INVALID_VALUE);
        auto objData = ctx->shareGroup()->getObjectData(
                NamedObjectType::SHADER_OR_PROGRAM, program);
        SET_ERROR_IF(objData->getDataType()!=PROGRAM_DATA,GL_INVALID_OPERATION);
        ProgramData* programData = (ProgramData*)objData;
        ctx->dispatcher().glValidateProgram(globalProgramName);

        GLsizei infoLogLength=0;
        GLchar* infoLog;
        ctx->dispatcher().glGetProgramiv(globalProgramName,GL_INFO_LOG_LENGTH,&infoLogLength);
        infoLog = new GLchar[infoLogLength+1];
        ctx->dispatcher().glGetProgramInfoLog(globalProgramName,infoLogLength,NULL,infoLog);
        programData->setInfoLog(infoLog);
    }
}

GL_APICALL void  GL_APIENTRY glVertexAttrib1f(GLuint indx, GLfloat x){
    GET_CTX_V2();
    ctx->dispatcher().glVertexAttrib1f(indx,x);
    if(indx == 0)
        ctx->setAttribute0value(x, 0.0, 0.0, 1.0);
}

GL_APICALL void  GL_APIENTRY glVertexAttrib1fv(GLuint indx, const GLfloat* values){
    GET_CTX_V2();
    ctx->dispatcher().glVertexAttrib1fv(indx,values);
    if(indx == 0)
        ctx->setAttribute0value(values[0], 0.0, 0.0, 1.0);
}

GL_APICALL void  GL_APIENTRY glVertexAttrib2f(GLuint indx, GLfloat x, GLfloat y){
    GET_CTX_V2();
    ctx->dispatcher().glVertexAttrib2f(indx,x,y);
    if(indx == 0)
        ctx->setAttribute0value(x, y, 0.0, 1.0);
}

GL_APICALL void  GL_APIENTRY glVertexAttrib2fv(GLuint indx, const GLfloat* values){
    GET_CTX_V2();
    ctx->dispatcher().glVertexAttrib2fv(indx,values);
    if(indx == 0)
        ctx->setAttribute0value(values[0], values[1], 0.0, 1.0);
}

GL_APICALL void  GL_APIENTRY glVertexAttrib3f(GLuint indx, GLfloat x, GLfloat y, GLfloat z){
    GET_CTX_V2();
    ctx->dispatcher().glVertexAttrib3f(indx,x,y,z);
    if(indx == 0)
        ctx->setAttribute0value(x, y, z, 1.0);
}

GL_APICALL void  GL_APIENTRY glVertexAttrib3fv(GLuint indx, const GLfloat* values){
    GET_CTX_V2();
    ctx->dispatcher().glVertexAttrib3fv(indx,values);
    if(indx == 0)
        ctx->setAttribute0value(values[0], values[1], values[2], 1.0);
}

GL_APICALL void  GL_APIENTRY glVertexAttrib4f(GLuint indx, GLfloat x, GLfloat y, GLfloat z, GLfloat w){
    GET_CTX_V2();
    ctx->dispatcher().glVertexAttrib4f(indx,x,y,z,w);
    if(indx == 0)
        ctx->setAttribute0value(x, y, z, w);
}

GL_APICALL void  GL_APIENTRY glVertexAttrib4fv(GLuint indx, const GLfloat* values){
    GET_CTX_V2();
    ctx->dispatcher().glVertexAttrib4fv(indx,values);
    if(indx == 0)
        ctx->setAttribute0value(values[0], values[1], values[2], values[3]);
}

GL_APICALL void  GL_APIENTRY glVertexAttribPointer(GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr){
    GET_CTX();
    SET_ERROR_IF((!GLESv2Validate::arrayIndex(ctx,indx)),GL_INVALID_VALUE);
    if (type == GL_HALF_FLOAT_OES) type = GL_HALF_FLOAT;
    ctx->setPointer(indx,size,type,stride,ptr,normalized);
}

GL_APICALL void  GL_APIENTRY glViewport(GLint x, GLint y, GLsizei width, GLsizei height){
    GET_CTX();
    ctx->dispatcher().glViewport(x,y,width,height);
}

GL_APICALL void GL_APIENTRY glEGLImageTargetTexture2DOES(GLenum target, GLeglImageOES image)
{
    GET_CTX();
    SET_ERROR_IF(!GLESv2Validate::textureTargetLimited(target),GL_INVALID_ENUM);
    unsigned int imagehndl = SafeUIntFromPointer(image);
    ImagePtr img = s_eglIface->getEGLImage(imagehndl);
    if (img) {
        // Create the texture object in the underlying EGL implementation,
        // flag to the OpenGL layer to skip the image creation and map the
        // current binded texture object to the existing global object.
        if (ctx->shareGroup().get()) {
            ObjectLocalName tex = TextureLocalName(target,ctx->getBindedTexture(target));
            // replace mapping and bind the new global object
            ctx->shareGroup()->replaceGlobalObject(NamedObjectType::TEXTURE, tex,
                                                   img->globalTexObj);
            ctx->dispatcher().glBindTexture(GL_TEXTURE_2D, img->globalTexObj->getGlobalName());
            TextureData *texData = getTextureTargetData(target);
            SET_ERROR_IF(texData==NULL,GL_INVALID_OPERATION);
            texData->width = img->width;
            texData->height = img->height;
            texData->border = img->border;
            texData->internalFormat = img->internalFormat;
            texData->sourceEGLImage = imagehndl;
        }
    }
}

GL_APICALL void GL_APIENTRY glEGLImageTargetRenderbufferStorageOES(GLenum target, GLeglImageOES image)
{
    GET_CTX();
    SET_ERROR_IF(target != GL_RENDERBUFFER_OES,GL_INVALID_ENUM);
    unsigned int imagehndl = SafeUIntFromPointer(image);
    ImagePtr img = s_eglIface->getEGLImage(imagehndl);
    SET_ERROR_IF(!img,GL_INVALID_VALUE);
    SET_ERROR_IF(!ctx->shareGroup().get(),GL_INVALID_OPERATION);

    // Get current bounded renderbuffer
    // raise INVALID_OPERATIOn if no renderbuffer is bounded
    GLuint rb = ctx->getRenderbufferBinding();
    SET_ERROR_IF(rb == 0,GL_INVALID_OPERATION);
    auto objData =
            ctx->shareGroup()->getObjectData(NamedObjectType::RENDERBUFFER, rb);
    RenderbufferData *rbData = (RenderbufferData *)objData;
    SET_ERROR_IF(!rbData,GL_INVALID_OPERATION);

    //
    // acquire the texture in the renderbufferData that it is an eglImage target
    //
    rbData->eglImageGlobalTexObject = img->globalTexObj;

    //
    // if the renderbuffer is attached to a framebuffer
    // change the framebuffer attachment in the undelying OpenGL
    // to point to the eglImage texture object.
    //
    if (rbData->attachedFB) {
        // update the framebuffer attachment point to the
        // underlying texture of the img
        GLuint prevFB = ctx->getFramebufferBinding();
        if (prevFB != rbData->attachedFB) {
            ctx->dispatcher().glBindFramebufferEXT(GL_FRAMEBUFFER_EXT,
                                                   rbData->attachedFB);
        }
        ctx->dispatcher().glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,
                                                    rbData->attachedPoint,
                                                    GL_TEXTURE_2D,
                                                    img->globalTexObj->getGlobalName(),
                                                    0);
        if (prevFB != rbData->attachedFB) {
            ctx->dispatcher().glBindFramebufferEXT(GL_FRAMEBUFFER_EXT,
                                                   prevFB);
        }
    }
}

GL_APICALL GLsync GL_APIENTRY glFenceSync(GLenum condition, GLbitfield flags)
{
    GET_CTX_V2_RET(NULL);
    return ctx->dispatcher().glFenceSync(condition, flags);
}

GL_APICALL GLenum GL_APIENTRY glClientWaitSync(GLsync wait_on, GLbitfield flags, GLuint64 timeout)
{
    GET_CTX_V2_RET(GL_WAIT_FAILED);
    return ctx->dispatcher().glClientWaitSync(wait_on, flags, timeout);
}

GL_APICALL void GL_APIENTRY glWaitSync(GLsync wait_on, GLbitfield flags, GLuint64 timeout)
{
    GET_CTX_V2();
    ctx->dispatcher().glWaitSync(wait_on, flags, timeout);
}

GL_APICALL void GL_APIENTRY glDeleteSync(GLsync to_delete)
{
    GET_CTX_V2();
    ctx->dispatcher().glDeleteSync(to_delete);
}
