Home | History | Annotate | Download | only in GLES_V2
      1 /*
      2 * Copyright(C) 2011 The Android Open Source Project
      3 *
      4 * Licensed under the Apache License, Version 2.0(the "License"){    GET_CTX();}
      5 * you may not use this file except in compliance with the License.
      6 * You may obtain a copy of the License at
      7 *
      8 * http://www.apache.org/licenses/LICENSE-2.0
      9 *
     10 * Unless required by applicable law or agreed to in writing, software
     11 * distributed under the License is distributed on an "AS IS" BASIS,
     12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13 * See the License for the specific language governing permissions and
     14 * limitations under the License.
     15 */
     16 
     17 #ifdef _WIN32
     18 #undef  GL_APICALL
     19 #define GL_API __declspec(dllexport)
     20 #define GL_APICALL __declspec(dllexport)
     21 #endif
     22 
     23 #define GL_GLEXT_PROTOTYPES
     24 #include <stdio.h>
     25 #include <GLES2/gl2.h>
     26 #include <GLES2/gl2ext.h>
     27 #include <GLcommon/TranslatorIfaces.h>
     28 #include <GLcommon/gldefs.h>
     29 #include "GLESv2Context.h"
     30 #include "GLESv2Validate.h"
     31 #include "ShaderParser.h"
     32 #include "ProgramData.h"
     33 #include <GLcommon/TextureUtils.h>
     34 #include <GLcommon/FramebufferData.h>
     35 
     36 extern "C" {
     37 
     38 //decleration
     39 static void initContext(GLEScontext* ctx,ShareGroupPtr grp);
     40 static void deleteGLESContext(GLEScontext* ctx);
     41 static void setShareGroup(GLEScontext* ctx,ShareGroupPtr grp);
     42 static GLEScontext* createGLESContext();
     43 static __translatorMustCastToProperFunctionPointerType getProcAddress(const char* procName);
     44 
     45 }
     46 
     47 /************************************** GLES EXTENSIONS *********************************************************/
     48 //extentions descriptor
     49 typedef std::map<std::string, __translatorMustCastToProperFunctionPointerType> ProcTableMap;
     50 ProcTableMap *s_glesExtensions = NULL;
     51 /****************************************************************************************************************/
     52 
     53 static EGLiface*  s_eglIface = NULL;
     54 static GLESiface  s_glesIface = {
     55     createGLESContext:createGLESContext,
     56     initContext      :initContext,
     57     deleteGLESContext:deleteGLESContext,
     58     flush            :(FUNCPTR)glFlush,
     59     finish           :(FUNCPTR)glFinish,
     60     setShareGroup    :setShareGroup,
     61     getProcAddress   :getProcAddress
     62 };
     63 
     64 #include <GLcommon/GLESmacros.h>
     65 
     66 extern "C" {
     67 
     68 static void initContext(GLEScontext* ctx,ShareGroupPtr grp) {
     69     if (!ctx->isInitialized()) {
     70         ctx->setShareGroup(grp);
     71         ctx->init();
     72         glBindTexture(GL_TEXTURE_2D,0);
     73         glBindTexture(GL_TEXTURE_CUBE_MAP,0);
     74     }
     75 }
     76 static GLEScontext* createGLESContext() {
     77     return new GLESv2Context();
     78 }
     79 
     80 static void deleteGLESContext(GLEScontext* ctx) {
     81     delete ctx;
     82 }
     83 
     84 static void setShareGroup(GLEScontext* ctx,ShareGroupPtr grp) {
     85     if(ctx) {
     86         ctx->setShareGroup(grp);
     87     }
     88 }
     89 
     90 static __translatorMustCastToProperFunctionPointerType getProcAddress(const char* procName) {
     91     GET_CTX_RET(NULL)
     92     ctx->getGlobalLock();
     93     static bool proc_table_initialized = false;
     94     if (!proc_table_initialized) {
     95         proc_table_initialized = true;
     96         if (!s_glesExtensions)
     97             s_glesExtensions = new ProcTableMap();
     98         else
     99             s_glesExtensions->clear();
    100         (*s_glesExtensions)["glEGLImageTargetTexture2DOES"] = (__translatorMustCastToProperFunctionPointerType)glEGLImageTargetTexture2DOES;
    101         (*s_glesExtensions)["glEGLImageTargetRenderbufferStorageOES"]=(__translatorMustCastToProperFunctionPointerType)glEGLImageTargetRenderbufferStorageOES;
    102     }
    103     __translatorMustCastToProperFunctionPointerType ret=NULL;
    104     ProcTableMap::iterator val = s_glesExtensions->find(procName);
    105     if (val!=s_glesExtensions->end())
    106         ret = val->second;
    107     ctx->releaseGlobalLock();
    108 
    109     return ret;
    110 }
    111 
    112 GL_APICALL GLESiface* __translator_getIfaces(EGLiface* eglIface){
    113     s_eglIface = eglIface;
    114     return & s_glesIface;
    115 }
    116 
    117 }
    118 
    119 static ObjectLocalName TextureLocalName(GLenum target,unsigned int tex) {
    120     GET_CTX_RET(0);
    121     return (tex!=0? tex : ctx->getDefaultTextureName(target));
    122 }
    123 
    124 static TextureData* getTextureData(ObjectLocalName tex) {
    125     GET_CTX_RET(NULL);
    126     TextureData *texData = NULL;
    127     ObjectDataPtr objData = ctx->shareGroup()->getObjectData(TEXTURE,tex);
    128     if(!objData.Ptr()){
    129         texData = new TextureData();
    130         ctx->shareGroup()->setObjectData(TEXTURE, tex, ObjectDataPtr(texData));
    131     } else {
    132         texData = (TextureData*)objData.Ptr();
    133     }
    134     return texData;
    135 }
    136 
    137 static TextureData* getTextureTargetData(GLenum target){
    138     GET_CTX_RET(NULL);
    139     unsigned int tex = ctx->getBindedTexture(target);
    140     return getTextureData(TextureLocalName(target,tex));
    141 }
    142 
    143 GL_APICALL void  GL_APIENTRY glActiveTexture(GLenum texture){
    144     GET_CTX_V2();
    145     SET_ERROR_IF (!GLESv2Validate::textureEnum(texture,ctx->getMaxTexUnits()),GL_INVALID_ENUM);
    146     ctx->setActiveTexture(texture);
    147     ctx->dispatcher().glActiveTexture(texture);
    148 }
    149 
    150 GL_APICALL void  GL_APIENTRY glAttachShader(GLuint program, GLuint shader){
    151     GET_CTX();
    152     if(ctx->shareGroup().Ptr()) {
    153         const GLuint globalProgramName = ctx->shareGroup()->getGlobalName(SHADER,program);
    154         SET_ERROR_IF(globalProgramName==0, GL_INVALID_VALUE);
    155         const GLuint globalShaderName  = ctx->shareGroup()->getGlobalName(SHADER,shader);
    156         SET_ERROR_IF(globalShaderName==0, GL_INVALID_VALUE);
    157 
    158         ObjectDataPtr programData = ctx->shareGroup()->getObjectData(SHADER,program);
    159         ObjectDataPtr shaderData = ctx->shareGroup()->getObjectData(SHADER,shader);
    160         SET_ERROR_IF(!shaderData.Ptr() || !programData.Ptr() ,GL_INVALID_OPERATION);
    161         SET_ERROR_IF(!(shaderData.Ptr()->getDataType() ==SHADER_DATA) ||
    162                      !(programData.Ptr()->getDataType()==PROGRAM_DATA) ,GL_INVALID_OPERATION);
    163 
    164         GLenum shaderType = ((ShaderParser*)shaderData.Ptr())->getType();
    165         ProgramData* pData = (ProgramData*)programData.Ptr();
    166         SET_ERROR_IF((pData->getAttachedShader(shaderType)!=0), GL_INVALID_OPERATION);
    167         pData->attachShader(shader,shaderType);
    168         ctx->dispatcher().glAttachShader(globalProgramName,globalShaderName);
    169     }
    170 }
    171 
    172 GL_APICALL void  GL_APIENTRY glBindAttribLocation(GLuint program, GLuint index, const GLchar* name){
    173     GET_CTX();
    174     SET_ERROR_IF(!GLESv2Validate::attribName(name),GL_INVALID_OPERATION);
    175     SET_ERROR_IF(!GLESv2Validate::attribIndex(index),GL_INVALID_VALUE);
    176     if(ctx->shareGroup().Ptr()) {
    177         const GLuint globalProgramName = ctx->shareGroup()->getGlobalName(SHADER,program);
    178         SET_ERROR_IF(globalProgramName==0, GL_INVALID_VALUE);
    179         ObjectDataPtr objData = ctx->shareGroup()->getObjectData(SHADER,program);
    180         SET_ERROR_IF(objData.Ptr()->getDataType()!=PROGRAM_DATA,GL_INVALID_OPERATION);
    181 
    182         ctx->dispatcher().glBindAttribLocation(globalProgramName,index,name);
    183     }
    184 }
    185 
    186 GL_APICALL void  GL_APIENTRY glBindBuffer(GLenum target, GLuint buffer){
    187     GET_CTX();
    188     SET_ERROR_IF(!GLESv2Validate::bufferTarget(target),GL_INVALID_ENUM);
    189     //if buffer wasn't generated before,generate one
    190     if(buffer && ctx->shareGroup().Ptr() && !ctx->shareGroup()->isObject(VERTEXBUFFER,buffer)){
    191         ctx->shareGroup()->genName(VERTEXBUFFER,buffer);
    192         ctx->shareGroup()->setObjectData(VERTEXBUFFER,buffer,ObjectDataPtr(new GLESbuffer()));
    193     }
    194     ctx->bindBuffer(target,buffer);
    195     if (buffer) {
    196         GLESbuffer* vbo = (GLESbuffer*)ctx->shareGroup()->getObjectData(VERTEXBUFFER,buffer).Ptr();
    197         vbo->setBinded();
    198     }
    199 }
    200 
    201 GL_APICALL void  GL_APIENTRY glBindFramebuffer(GLenum target, GLuint framebuffer){
    202     GET_CTX();
    203     SET_ERROR_IF(!GLESv2Validate::framebufferTarget(target),GL_INVALID_ENUM);
    204 
    205     GLuint globalFrameBufferName = framebuffer;
    206     if(framebuffer && ctx->shareGroup().Ptr()){
    207         globalFrameBufferName = ctx->shareGroup()->getGlobalName(FRAMEBUFFER,framebuffer);
    208         //if framebuffer wasn't generated before,generate one
    209         if(!globalFrameBufferName){
    210             ctx->shareGroup()->genName(FRAMEBUFFER,framebuffer);
    211             ctx->shareGroup()->setObjectData(FRAMEBUFFER, framebuffer,
    212                                              ObjectDataPtr(new FramebufferData(framebuffer)));
    213             globalFrameBufferName = ctx->shareGroup()->getGlobalName(FRAMEBUFFER,framebuffer);
    214         }
    215     }
    216     ctx->dispatcher().glBindFramebufferEXT(target,globalFrameBufferName);
    217 
    218     // update framebuffer binding state
    219     ctx->setFramebufferBinding(framebuffer);
    220 }
    221 
    222 GL_APICALL void  GL_APIENTRY glBindRenderbuffer(GLenum target, GLuint renderbuffer){
    223     GET_CTX();
    224     SET_ERROR_IF(!GLESv2Validate::renderbufferTarget(target),GL_INVALID_ENUM);
    225 
    226     GLuint globalRenderBufferName = renderbuffer;
    227     if(renderbuffer && ctx->shareGroup().Ptr()){
    228         globalRenderBufferName = ctx->shareGroup()->getGlobalName(RENDERBUFFER,renderbuffer);
    229         //if renderbuffer wasn't generated before,generate one
    230         if(!globalRenderBufferName){
    231             ctx->shareGroup()->genName(RENDERBUFFER,renderbuffer);
    232             ctx->shareGroup()->setObjectData(RENDERBUFFER,
    233                                          renderbuffer,
    234                                          ObjectDataPtr(new RenderbufferData()));
    235             globalRenderBufferName = ctx->shareGroup()->getGlobalName(RENDERBUFFER,renderbuffer);
    236         }
    237     }
    238     ctx->dispatcher().glBindRenderbufferEXT(target,globalRenderBufferName);
    239 
    240     // update renderbuffer binding state
    241     ctx->setRenderbufferBinding(renderbuffer);
    242 }
    243 
    244 GL_APICALL void  GL_APIENTRY glBindTexture(GLenum target, GLuint texture){
    245     GET_CTX();
    246     SET_ERROR_IF(!GLESv2Validate::textureTarget(target),GL_INVALID_ENUM)
    247 
    248     //for handling default texture (0)
    249     ObjectLocalName localTexName = TextureLocalName(target,texture);
    250 
    251     GLuint globalTextureName = localTexName;
    252     if(ctx->shareGroup().Ptr()){
    253         globalTextureName = ctx->shareGroup()->getGlobalName(TEXTURE,localTexName);
    254         //if texture wasn't generated before,generate one
    255         if(!globalTextureName){
    256             ctx->shareGroup()->genName(TEXTURE,localTexName);
    257             globalTextureName = ctx->shareGroup()->getGlobalName(TEXTURE,localTexName);
    258         }
    259 
    260         TextureData* texData = getTextureData(localTexName);
    261         if (texData->target==0)
    262             texData->target = target;
    263         //if texture was already bound to another target
    264         SET_ERROR_IF(ctx->GLTextureTargetToLocal(texData->target) != ctx->GLTextureTargetToLocal(target), GL_INVALID_OPERATION);
    265         texData->wasBound = true;
    266     }
    267 
    268     ctx->setBindedTexture(target,texture);
    269     ctx->dispatcher().glBindTexture(target,globalTextureName);
    270 }
    271 
    272 GL_APICALL void  GL_APIENTRY glBlendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha){
    273     GET_CTX();
    274     ctx->dispatcher().glBlendColor(red,green,blue,alpha);
    275 }
    276 
    277 GL_APICALL void  GL_APIENTRY glBlendEquation( GLenum mode ){
    278     GET_CTX();
    279     SET_ERROR_IF(!GLESv2Validate::blendEquationMode(mode),GL_INVALID_ENUM)
    280     ctx->dispatcher().glBlendEquation(mode);
    281 }
    282 
    283 GL_APICALL void  GL_APIENTRY glBlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha){
    284     GET_CTX();
    285     SET_ERROR_IF(!(GLESv2Validate::blendEquationMode(modeRGB) && GLESv2Validate::blendEquationMode(modeAlpha)),GL_INVALID_ENUM);
    286     ctx->dispatcher().glBlendEquationSeparate(modeRGB,modeAlpha);
    287 }
    288 
    289 GL_APICALL void  GL_APIENTRY glBlendFunc(GLenum sfactor, GLenum dfactor){
    290     GET_CTX();
    291     SET_ERROR_IF(!GLESv2Validate::blendSrc(sfactor) || !GLESv2Validate::blendDst(dfactor),GL_INVALID_ENUM)
    292     ctx->dispatcher().glBlendFunc(sfactor,dfactor);
    293 }
    294 
    295 GL_APICALL void  GL_APIENTRY glBlendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha){
    296     GET_CTX();
    297     SET_ERROR_IF(
    298 !(GLESv2Validate::blendSrc(srcRGB) && GLESv2Validate::blendDst(dstRGB) && GLESv2Validate::blendSrc(srcAlpha) && GLESv2Validate::blendDst(dstAlpha)),GL_INVALID_ENUM);
    299     ctx->dispatcher().glBlendFuncSeparate(srcRGB,dstRGB,srcAlpha,dstAlpha);
    300 }
    301 
    302 GL_APICALL void  GL_APIENTRY glBufferData(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage){
    303     GET_CTX();
    304     SET_ERROR_IF(!GLESv2Validate::bufferTarget(target),GL_INVALID_ENUM);
    305     SET_ERROR_IF(!ctx->isBindedBuffer(target),GL_INVALID_OPERATION);
    306     ctx->setBufferData(target,size,data,usage);
    307 }
    308 
    309 GL_APICALL void  GL_APIENTRY glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data){
    310     GET_CTX();
    311     SET_ERROR_IF(!ctx->isBindedBuffer(target),GL_INVALID_OPERATION);
    312     SET_ERROR_IF(!GLESv2Validate::bufferTarget(target),GL_INVALID_ENUM);
    313     SET_ERROR_IF(!ctx->setBufferSubData(target,offset,size,data),GL_INVALID_VALUE);
    314 }
    315 
    316 
    317 GL_APICALL GLenum GL_APIENTRY glCheckFramebufferStatus(GLenum target){
    318     GET_CTX_RET(GL_FRAMEBUFFER_COMPLETE);
    319     RET_AND_SET_ERROR_IF(!GLESv2Validate::framebufferTarget(target),GL_INVALID_ENUM,GL_FRAMEBUFFER_COMPLETE);
    320     ctx->drawValidate();
    321     return ctx->dispatcher().glCheckFramebufferStatusEXT(target);
    322 }
    323 
    324 GL_APICALL void  GL_APIENTRY glClear(GLbitfield mask){
    325     GET_CTX();
    326     ctx->drawValidate();
    327 
    328     ctx->dispatcher().glClear(mask);
    329 }
    330 GL_APICALL void  GL_APIENTRY glClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha){
    331     GET_CTX();
    332     ctx->dispatcher().glClearColor(red,green,blue,alpha);
    333 }
    334 GL_APICALL void  GL_APIENTRY glClearDepthf(GLclampf depth){
    335     GET_CTX();
    336     ctx->dispatcher().glClearDepth(depth);
    337 }
    338 GL_APICALL void  GL_APIENTRY glClearStencil(GLint s){
    339     GET_CTX();
    340     ctx->dispatcher().glClearStencil(s);
    341 }
    342 GL_APICALL void  GL_APIENTRY glColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha){
    343     GET_CTX();
    344     ctx->dispatcher().glColorMask(red,green,blue,alpha);
    345 }
    346 
    347 GL_APICALL void  GL_APIENTRY glCompileShader(GLuint shader){
    348     GET_CTX();
    349     if(ctx->shareGroup().Ptr()) {
    350         const GLuint globalShaderName = ctx->shareGroup()->getGlobalName(SHADER,shader);
    351         SET_ERROR_IF(globalShaderName==0, GL_INVALID_VALUE);
    352         ObjectDataPtr objData = ctx->shareGroup()->getObjectData(SHADER,shader);
    353         SET_ERROR_IF(objData.Ptr()->getDataType()!= SHADER_DATA,GL_INVALID_OPERATION);
    354         ShaderParser* sp = (ShaderParser*)objData.Ptr();
    355         ctx->dispatcher().glCompileShader(globalShaderName);
    356 
    357         GLsizei infoLogLength=0;
    358         GLchar* infoLog;
    359         ctx->dispatcher().glGetShaderiv(globalShaderName,GL_INFO_LOG_LENGTH,&infoLogLength);
    360         infoLog = new GLchar[infoLogLength+1];
    361         ctx->dispatcher().glGetShaderInfoLog(globalShaderName,infoLogLength,NULL,infoLog);
    362         sp->setInfoLog(infoLog);
    363     }
    364 }
    365 
    366 GL_APICALL void  GL_APIENTRY glCompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid* data)
    367 {
    368     GET_CTX();
    369     SET_ERROR_IF(!GLESv2Validate::textureTargetEx(target),GL_INVALID_ENUM);
    370 
    371     doCompressedTexImage2D(ctx, target, level, internalformat,
    372                                 width, height, border,
    373                                 imageSize, data, (void*)glTexImage2D);
    374 }
    375 
    376 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){
    377     GET_CTX();
    378     SET_ERROR_IF(!GLESv2Validate::textureTargetEx(target),GL_INVALID_ENUM);
    379     ctx->dispatcher().glCompressedTexSubImage2D(target,level,xoffset,yoffset,width,height,format,imageSize,data);
    380 }
    381 
    382 GL_APICALL void  GL_APIENTRY glCopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border){
    383     GET_CTX();
    384     SET_ERROR_IF(!(GLESv2Validate::pixelFrmt(ctx,internalformat) && GLESv2Validate::textureTargetEx(target)),GL_INVALID_ENUM);
    385     SET_ERROR_IF(border != 0,GL_INVALID_VALUE);
    386     ctx->dispatcher().glCopyTexImage2D(target,level,internalformat,x,y,width,height,border);
    387 }
    388 
    389 GL_APICALL void  GL_APIENTRY glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height){
    390     GET_CTX();
    391     SET_ERROR_IF(!GLESv2Validate::textureTargetEx(target),GL_INVALID_ENUM);
    392     ctx->dispatcher().glCopyTexSubImage2D(target,level,xoffset,yoffset,x,y,width,height);
    393 }
    394 
    395 GL_APICALL GLuint GL_APIENTRY glCreateProgram(void){
    396     GET_CTX_RET(0);
    397     const GLuint globalProgramName = ctx->dispatcher().glCreateProgram();
    398     if(ctx->shareGroup().Ptr() && globalProgramName) {
    399             ProgramData* programInfo = new ProgramData();
    400             const GLuint localProgramName = ctx->shareGroup()->genName(SHADER, 0, true);
    401             ctx->shareGroup()->replaceGlobalName(SHADER,localProgramName,globalProgramName);
    402             ctx->shareGroup()->setObjectData(SHADER,localProgramName,ObjectDataPtr(programInfo));
    403             return localProgramName;
    404     }
    405     if(globalProgramName){
    406         ctx->dispatcher().glDeleteProgram(globalProgramName);
    407     }
    408     return 0;
    409 }
    410 
    411 GL_APICALL GLuint GL_APIENTRY glCreateShader(GLenum type){
    412     GET_CTX_V2_RET(0);
    413     RET_AND_SET_ERROR_IF(!GLESv2Validate::shaderType(type),GL_INVALID_ENUM,0);
    414     const GLuint globalShaderName = ctx->dispatcher().glCreateShader(type);
    415     if(ctx->shareGroup().Ptr() && globalShaderName) {
    416             const GLuint localShaderName = ctx->shareGroup()->genName(SHADER, 0, true);
    417             ShaderParser* sp = new ShaderParser(type);
    418             ctx->shareGroup()->replaceGlobalName(SHADER,localShaderName,globalShaderName);
    419             ctx->shareGroup()->setObjectData(SHADER,localShaderName,ObjectDataPtr(sp));
    420             return localShaderName;
    421     }
    422     if(globalShaderName){
    423         ctx->dispatcher().glDeleteShader(globalShaderName);
    424     }
    425     return 0;
    426 }
    427 
    428 GL_APICALL void  GL_APIENTRY glCullFace(GLenum mode){
    429     GET_CTX();
    430     ctx->dispatcher().glCullFace(mode);
    431 }
    432 
    433 GL_APICALL void  GL_APIENTRY glDeleteBuffers(GLsizei n, const GLuint* buffers){
    434     GET_CTX();
    435     SET_ERROR_IF(n<0,GL_INVALID_VALUE);
    436     if(ctx->shareGroup().Ptr()) {
    437         for(int i=0; i < n; i++){
    438            ctx->shareGroup()->deleteName(VERTEXBUFFER,buffers[i]);
    439         }
    440     }
    441 }
    442 
    443 GL_APICALL void  GL_APIENTRY glDeleteFramebuffers(GLsizei n, const GLuint* framebuffers){
    444     GET_CTX();
    445     SET_ERROR_IF(n<0,GL_INVALID_VALUE);
    446     if(ctx->shareGroup().Ptr()) {
    447         for(int i=0; i < n; i++){
    448            const GLuint globalFrameBufferName = ctx->shareGroup()->getGlobalName(FRAMEBUFFER,framebuffers[i]);
    449            ctx->shareGroup()->deleteName(FRAMEBUFFER,framebuffers[i]);
    450            ctx->dispatcher().glDeleteFramebuffersEXT(1,&globalFrameBufferName);
    451         }
    452     }
    453 }
    454 
    455 GL_APICALL void  GL_APIENTRY glDeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers){
    456     GET_CTX();
    457     SET_ERROR_IF(n<0,GL_INVALID_VALUE);
    458     if(ctx->shareGroup().Ptr()) {
    459         for(int i=0; i < n; i++){
    460            const GLuint globalRenderBufferName = ctx->shareGroup()->getGlobalName(RENDERBUFFER,renderbuffers[i]);
    461            ctx->shareGroup()->deleteName(RENDERBUFFER,renderbuffers[i]);
    462            ctx->dispatcher().glDeleteRenderbuffersEXT(1,&globalRenderBufferName);
    463         }
    464     }
    465 }
    466 
    467 GL_APICALL void  GL_APIENTRY glDeleteTextures(GLsizei n, const GLuint* textures){
    468     GET_CTX();
    469     SET_ERROR_IF(n<0,GL_INVALID_VALUE);
    470     if(ctx->shareGroup().Ptr()) {
    471         for(int i=0; i < n; i++){
    472             if (textures[i]!=0) {
    473                 TextureData* tData = getTextureData(textures[i]);
    474                 // delete the underlying OpenGL texture but only if this
    475                 // texture is not a target of EGLImage.
    476                 if (!tData || tData->sourceEGLImage == 0) {
    477                     const GLuint globalTextureName = ctx->shareGroup()->getGlobalName(TEXTURE,textures[i]);
    478                     ctx->dispatcher().glDeleteTextures(1,&globalTextureName);
    479                 }
    480                 ctx->shareGroup()->deleteName(TEXTURE,textures[i]);
    481 
    482                 if (ctx->getBindedTexture(GL_TEXTURE_2D) == textures[i])
    483                     ctx->setBindedTexture(GL_TEXTURE_2D,0);
    484                 if (ctx->getBindedTexture(GL_TEXTURE_CUBE_MAP) == textures[i])
    485                     ctx->setBindedTexture(GL_TEXTURE_CUBE_MAP,0);
    486             }
    487         }
    488     }
    489 }
    490 
    491 GL_APICALL void  GL_APIENTRY glDeleteProgram(GLuint program){
    492     GET_CTX();
    493     if(program && ctx->shareGroup().Ptr()) {
    494         const GLuint globalProgramName = ctx->shareGroup()->getGlobalName(SHADER,program);
    495         SET_ERROR_IF(!globalProgramName, GL_INVALID_VALUE);
    496         ctx->shareGroup()->deleteName(SHADER,program);
    497         ctx->dispatcher().glDeleteProgram(globalProgramName);
    498     }
    499 }
    500 
    501 GL_APICALL void  GL_APIENTRY glDeleteShader(GLuint shader){
    502     GET_CTX();
    503     if(shader && ctx->shareGroup().Ptr()) {
    504         const GLuint globalShaderName = ctx->shareGroup()->getGlobalName(SHADER,shader);
    505         SET_ERROR_IF(!globalShaderName, GL_INVALID_VALUE);
    506         ctx->shareGroup()->deleteName(SHADER,shader);
    507         ctx->dispatcher().glDeleteShader(globalShaderName);
    508     }
    509 
    510 }
    511 
    512 GL_APICALL void  GL_APIENTRY glDepthFunc(GLenum func){
    513     GET_CTX();
    514     ctx->dispatcher().glDepthFunc(func);
    515 }
    516 GL_APICALL void  GL_APIENTRY glDepthMask(GLboolean flag){
    517     GET_CTX();
    518     ctx->dispatcher().glDepthMask(flag);
    519 }
    520 GL_APICALL void  GL_APIENTRY glDepthRangef(GLclampf zNear, GLclampf zFar){
    521     GET_CTX();
    522     ctx->dispatcher().glDepthRange(zNear,zFar);
    523 }
    524 
    525 GL_APICALL void  GL_APIENTRY glDetachShader(GLuint program, GLuint shader){
    526     GET_CTX();
    527     if(ctx->shareGroup().Ptr()) {
    528         const GLuint globalProgramName = ctx->shareGroup()->getGlobalName(SHADER,program);
    529         SET_ERROR_IF(globalProgramName==0, GL_INVALID_VALUE);
    530         const GLuint globalShaderName  = ctx->shareGroup()->getGlobalName(SHADER,shader);
    531         SET_ERROR_IF(globalShaderName==0, GL_INVALID_VALUE);
    532 
    533         ObjectDataPtr objData = ctx->shareGroup()->getObjectData(SHADER,program);
    534         SET_ERROR_IF(!objData.Ptr(),GL_INVALID_OPERATION);
    535         SET_ERROR_IF(!(objData.Ptr()->getDataType()==PROGRAM_DATA) ,GL_INVALID_OPERATION);
    536 
    537         ProgramData* programData = (ProgramData*)objData.Ptr();
    538         SET_ERROR_IF(!programData->isAttached(shader),GL_INVALID_OPERATION);
    539         programData->detachShader(shader);
    540 
    541         ctx->dispatcher().glDetachShader(globalProgramName,globalShaderName);
    542     }
    543 }
    544 
    545 GL_APICALL void  GL_APIENTRY glDisable(GLenum cap){
    546     GET_CTX();
    547     ctx->dispatcher().glDisable(cap);
    548 }
    549 
    550 GL_APICALL void  GL_APIENTRY glDisableVertexAttribArray(GLuint index){
    551     GET_CTX();
    552     SET_ERROR_IF((!GLESv2Validate::arrayIndex(ctx,index)),GL_INVALID_VALUE);
    553     ctx->enableArr(index,false);
    554     ctx->dispatcher().glDisableVertexAttribArray(index);
    555 }
    556 
    557 GL_APICALL void  GL_APIENTRY glDrawArrays(GLenum mode, GLint first, GLsizei count){
    558     GET_CTX_V2();
    559     SET_ERROR_IF(count < 0,GL_INVALID_VALUE)
    560     SET_ERROR_IF(!GLESv2Validate::drawMode(mode),GL_INVALID_ENUM);
    561 
    562     ctx->drawValidate();
    563 
    564     GLESConversionArrays tmpArrs;
    565     ctx->setupArraysPointers(tmpArrs,first,count,0,NULL,true);
    566 
    567     ctx->validateAtt0PreDraw(count);
    568 
    569     //Enable texture generation for GL_POINTS and gl_PointSize shader variable
    570     //GLES2 assumes this is enabled by default, we need to set this state for GL
    571     if (mode==GL_POINTS) {
    572         ctx->dispatcher().glEnable(GL_POINT_SPRITE);
    573         ctx->dispatcher().glEnable(GL_VERTEX_PROGRAM_POINT_SIZE);
    574     }
    575 
    576     ctx->dispatcher().glDrawArrays(mode,first,count);
    577 
    578     if (mode==GL_POINTS) {
    579         ctx->dispatcher().glDisable(GL_VERTEX_PROGRAM_POINT_SIZE);
    580         ctx->dispatcher().glDisable(GL_POINT_SPRITE);
    581     }
    582 
    583     ctx->validateAtt0PostDraw();
    584 }
    585 
    586 GL_APICALL void  GL_APIENTRY glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid* elementsIndices){
    587     GET_CTX_V2();
    588     SET_ERROR_IF(count < 0,GL_INVALID_VALUE)
    589     SET_ERROR_IF(!(GLESv2Validate::drawMode(mode) && GLESv2Validate::drawType(type)),GL_INVALID_ENUM);
    590 
    591     ctx->drawValidate();
    592 
    593     const GLvoid* indices = elementsIndices;
    594     if(ctx->isBindedBuffer(GL_ELEMENT_ARRAY_BUFFER)) { // if vbo is binded take the indices from the vbo
    595         const unsigned char* buf = static_cast<unsigned char *>(ctx->getBindedBuffer(GL_ELEMENT_ARRAY_BUFFER));
    596         indices = buf+reinterpret_cast<unsigned int>(elementsIndices);
    597     }
    598 
    599     GLESConversionArrays tmpArrs;
    600     ctx->setupArraysPointers(tmpArrs,0,count,type,indices,false);
    601 
    602     int maxIndex = ctx->findMaxIndex(count, type, indices);
    603     ctx->validateAtt0PreDraw(maxIndex);
    604 
    605     //See glDrawArrays
    606     if (mode==GL_POINTS) {
    607         ctx->dispatcher().glEnable(GL_POINT_SPRITE);
    608         ctx->dispatcher().glEnable(GL_VERTEX_PROGRAM_POINT_SIZE);
    609     }
    610 
    611     ctx->dispatcher().glDrawElements(mode,count,type,indices);
    612 
    613     if (mode==GL_POINTS) {
    614         ctx->dispatcher().glDisable(GL_VERTEX_PROGRAM_POINT_SIZE);
    615         ctx->dispatcher().glDisable(GL_POINT_SPRITE);
    616     }
    617 
    618     ctx->validateAtt0PostDraw();
    619 }
    620 
    621 GL_APICALL void  GL_APIENTRY glEnable(GLenum cap){
    622     GET_CTX();
    623     ctx->dispatcher().glEnable(cap);
    624 }
    625 
    626 GL_APICALL void  GL_APIENTRY glEnableVertexAttribArray(GLuint index){
    627     GET_CTX();
    628     SET_ERROR_IF(!(GLESv2Validate::arrayIndex(ctx,index)),GL_INVALID_VALUE);
    629     ctx->enableArr(index,true);
    630     ctx->dispatcher().glEnableVertexAttribArray(index);
    631 }
    632 
    633 GL_APICALL void  GL_APIENTRY glFinish(void){
    634     GET_CTX();
    635     ctx->dispatcher().glFinish();
    636 }
    637 GL_APICALL void  GL_APIENTRY glFlush(void){
    638     GET_CTX();
    639     ctx->dispatcher().glFlush();
    640 }
    641 
    642 
    643 GL_APICALL void  GL_APIENTRY glFramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer){
    644     GET_CTX();
    645     SET_ERROR_IF(!(GLESv2Validate::framebufferTarget(target)              &&
    646                    GLESv2Validate::renderbufferTarget(renderbuffertarget) &&
    647                    GLESv2Validate::framebufferAttachment(attachment)),GL_INVALID_ENUM);
    648     SET_ERROR_IF(!ctx->shareGroup().Ptr(), GL_INVALID_OPERATION);
    649 
    650     GLuint globalRenderbufferName = 0;
    651     ObjectDataPtr obj;
    652 
    653     // generate the renderbuffer object if not yet exist
    654     if(renderbuffer) {
    655         if (!ctx->shareGroup()->isObject(RENDERBUFFER,renderbuffer)) {
    656             ctx->shareGroup()->genName(RENDERBUFFER,renderbuffer);
    657             obj = ObjectDataPtr(new RenderbufferData());
    658             ctx->shareGroup()->setObjectData(RENDERBUFFER,
    659                                          renderbuffer, obj);
    660         }
    661         else {
    662             obj = ctx->shareGroup()->getObjectData(RENDERBUFFER, renderbuffer);
    663         }
    664 
    665         globalRenderbufferName = ctx->shareGroup()->getGlobalName(RENDERBUFFER,renderbuffer);
    666     }
    667 
    668     // Update the the current framebuffer object attachment state
    669     GLuint fbName = ctx->getFramebufferBinding();
    670     ObjectDataPtr fbObj = ctx->shareGroup()->getObjectData(FRAMEBUFFER,fbName);
    671     if (fbObj.Ptr() != NULL) {
    672         FramebufferData *fbData = (FramebufferData *)fbObj.Ptr();
    673         fbData->setAttachment(attachment, renderbuffertarget, renderbuffer, obj);
    674     }
    675 
    676     if (renderbuffer && obj.Ptr() != NULL) {
    677         RenderbufferData *rbData = (RenderbufferData *)obj.Ptr();
    678         if (rbData->sourceEGLImage != 0) {
    679             //
    680             // This renderbuffer object is an eglImage target
    681             // attach the eglimage's texture instead the renderbuffer.
    682             //
    683             ctx->dispatcher().glFramebufferTexture2DEXT(target,
    684                                                     attachment,
    685                                                     GL_TEXTURE_2D,
    686                                                     rbData->eglImageGlobalTexName,0);
    687             return;
    688         }
    689     }
    690 
    691     ctx->dispatcher().glFramebufferRenderbufferEXT(target,attachment,renderbuffertarget,globalRenderbufferName);
    692 }
    693 
    694 GL_APICALL void  GL_APIENTRY glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level){
    695     GET_CTX();
    696     SET_ERROR_IF(!(GLESv2Validate::framebufferTarget(target) &&
    697                    GLESv2Validate::textureTargetEx(textarget)  &&
    698                    GLESv2Validate::framebufferAttachment(attachment)),GL_INVALID_ENUM);
    699     SET_ERROR_IF(level != 0, GL_INVALID_VALUE);
    700     SET_ERROR_IF(!ctx->shareGroup().Ptr(), GL_INVALID_OPERATION);
    701 
    702     GLuint globalTextureName = 0;
    703 
    704     if(texture) {
    705         if (!ctx->shareGroup()->isObject(TEXTURE,texture)) {
    706             ctx->shareGroup()->genName(TEXTURE,texture);
    707         }
    708         ObjectLocalName texname = TextureLocalName(textarget,texture);
    709         globalTextureName = ctx->shareGroup()->getGlobalName(TEXTURE,texname);
    710     }
    711 
    712     ctx->dispatcher().glFramebufferTexture2DEXT(target,attachment,textarget,globalTextureName,level);
    713 
    714     // Update the the current framebuffer object attachment state
    715     GLuint fbName = ctx->getFramebufferBinding();
    716     ObjectDataPtr fbObj = ctx->shareGroup()->getObjectData(FRAMEBUFFER,fbName);
    717     if (fbObj.Ptr() != NULL) {
    718         FramebufferData *fbData = (FramebufferData *)fbObj.Ptr();
    719         fbData->setAttachment(attachment, textarget,
    720                               texture, ObjectDataPtr(NULL));
    721     }
    722 }
    723 
    724 
    725 GL_APICALL void  GL_APIENTRY glFrontFace(GLenum mode){
    726     GET_CTX();
    727     ctx->dispatcher().glFrontFace(mode);
    728 }
    729 
    730 GL_APICALL void  GL_APIENTRY glGenBuffers(GLsizei n, GLuint* buffers){
    731     GET_CTX();
    732     SET_ERROR_IF(n<0,GL_INVALID_VALUE);
    733     if(ctx->shareGroup().Ptr()) {
    734         for(int i=0; i<n ;i++) {
    735             buffers[i] = ctx->shareGroup()->genName(VERTEXBUFFER, 0, true);
    736             //generating vbo object related to this buffer name
    737             ctx->shareGroup()->setObjectData(VERTEXBUFFER,buffers[i],ObjectDataPtr(new GLESbuffer()));
    738         }
    739     }
    740 }
    741 
    742 GL_APICALL void  GL_APIENTRY glGenerateMipmap(GLenum target){
    743     GET_CTX();
    744     SET_ERROR_IF(!GLESv2Validate::textureTargetEx(target),GL_INVALID_ENUM);
    745     ctx->dispatcher().glGenerateMipmapEXT(target);
    746 }
    747 
    748 GL_APICALL void  GL_APIENTRY glGenFramebuffers(GLsizei n, GLuint* framebuffers){
    749     GET_CTX();
    750     SET_ERROR_IF(n<0,GL_INVALID_VALUE);
    751     if(ctx->shareGroup().Ptr()) {
    752         for(int i=0; i<n ;i++) {
    753             framebuffers[i] = ctx->shareGroup()->genName(FRAMEBUFFER, 0 ,true);
    754             ctx->shareGroup()->setObjectData(FRAMEBUFFER, framebuffers[i],
    755                                              ObjectDataPtr(new FramebufferData(framebuffers[i])));
    756         }
    757     }
    758 }
    759 
    760 GL_APICALL void  GL_APIENTRY glGenRenderbuffers(GLsizei n, GLuint* renderbuffers){
    761     GET_CTX();
    762     SET_ERROR_IF(n<0,GL_INVALID_VALUE);
    763     if(ctx->shareGroup().Ptr()) {
    764         for(int i=0; i<n ;i++) {
    765             renderbuffers[i] = ctx->shareGroup()->genName(RENDERBUFFER, 0, true);
    766             ctx->shareGroup()->setObjectData(RENDERBUFFER,
    767                                          renderbuffers[i],
    768                                          ObjectDataPtr(new RenderbufferData()));
    769         }
    770     }
    771 }
    772 
    773 GL_APICALL void  GL_APIENTRY glGenTextures(GLsizei n, GLuint* textures){
    774     GET_CTX();
    775     SET_ERROR_IF(n<0,GL_INVALID_VALUE);
    776     if(ctx->shareGroup().Ptr()) {
    777         for(int i=0; i<n ;i++) {
    778             textures[i] = ctx->shareGroup()->genName(TEXTURE, 0, true);
    779         }
    780     }
    781 }
    782 
    783 GL_APICALL void  GL_APIENTRY glGetActiveAttrib(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name){
    784     GET_CTX();
    785     if(ctx->shareGroup().Ptr()) {
    786         const GLuint globalProgramName = ctx->shareGroup()->getGlobalName(SHADER,program);
    787         SET_ERROR_IF(globalProgramName==0, GL_INVALID_VALUE);
    788         ObjectDataPtr objData = ctx->shareGroup()->getObjectData(SHADER,program);
    789         SET_ERROR_IF(objData.Ptr()->getDataType()!=PROGRAM_DATA,GL_INVALID_OPERATION);
    790         ctx->dispatcher().glGetActiveAttrib(globalProgramName,index,bufsize,length,size,type,name);
    791     }
    792 }
    793 
    794 GL_APICALL void  GL_APIENTRY glGetActiveUniform(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name){
    795     GET_CTX();
    796     if(ctx->shareGroup().Ptr()) {
    797         const GLuint globalProgramName = ctx->shareGroup()->getGlobalName(SHADER,program);
    798         SET_ERROR_IF(globalProgramName==0, GL_INVALID_VALUE);
    799         ObjectDataPtr objData = ctx->shareGroup()->getObjectData(SHADER,program);
    800         SET_ERROR_IF(objData.Ptr()->getDataType()!=PROGRAM_DATA,GL_INVALID_OPERATION);
    801         ctx->dispatcher().glGetActiveUniform(globalProgramName,index,bufsize,length,size,type,name);
    802     }
    803 }
    804 
    805 GL_APICALL void  GL_APIENTRY glGetAttachedShaders(GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders){
    806     GET_CTX();
    807     if(ctx->shareGroup().Ptr()) {
    808         const GLuint globalProgramName = ctx->shareGroup()->getGlobalName(SHADER,program);
    809         SET_ERROR_IF(globalProgramName==0, GL_INVALID_VALUE);
    810         ctx->dispatcher().glGetAttachedShaders(globalProgramName,maxcount,count,shaders);
    811         ObjectDataPtr objData = ctx->shareGroup()->getObjectData(SHADER,program);
    812         SET_ERROR_IF(objData.Ptr()->getDataType()!=PROGRAM_DATA,GL_INVALID_OPERATION);
    813         GLint numShaders=0;
    814         ctx->dispatcher().glGetProgramiv(globalProgramName,GL_ATTACHED_SHADERS,&numShaders);
    815         for(int i=0 ; i < maxcount && i<numShaders ;i++){
    816            shaders[i] = ctx->shareGroup()->getLocalName(SHADER,shaders[i]);
    817         }
    818     }
    819 }
    820 
    821 GL_APICALL int GL_APIENTRY glGetAttribLocation(GLuint program, const GLchar* name){
    822      GET_CTX_RET(-1);
    823      if(ctx->shareGroup().Ptr()) {
    824         const GLuint globalProgramName = ctx->shareGroup()->getGlobalName(SHADER,program);
    825         RET_AND_SET_ERROR_IF(globalProgramName==0, GL_INVALID_VALUE,-1);
    826         ObjectDataPtr objData = ctx->shareGroup()->getObjectData(SHADER,program);
    827         RET_AND_SET_ERROR_IF(objData.Ptr()->getDataType()!=PROGRAM_DATA,GL_INVALID_OPERATION,-1);
    828         ProgramData* pData = (ProgramData *)objData.Ptr();
    829         RET_AND_SET_ERROR_IF(pData->getLinkStatus() != GL_TRUE,GL_INVALID_OPERATION,-1);
    830         return ctx->dispatcher().glGetAttribLocation(globalProgramName,name);
    831      }
    832      return -1;
    833 }
    834 
    835 GL_APICALL void  GL_APIENTRY glGetBooleanv(GLenum pname, GLboolean* params){
    836     GET_CTX();
    837 
    838     if (ctx->glGetBooleanv(pname,params))
    839     {
    840         return;
    841     }
    842 
    843     switch(pname)
    844     {
    845         case GL_SHADER_COMPILER:
    846         case GL_SHADER_BINARY_FORMATS:
    847         case GL_NUM_SHADER_BINARY_FORMATS:
    848         case GL_MAX_VERTEX_UNIFORM_VECTORS:
    849         case GL_MAX_VARYING_VECTORS:
    850         case GL_MAX_FRAGMENT_UNIFORM_VECTORS:
    851             if(ctx->getCaps()->GL_ARB_ES2_COMPATIBILITY)
    852                 ctx->dispatcher().glGetBooleanv(pname,params);
    853             else
    854             {
    855                 GLint iparam;
    856                 glGetIntegerv(pname,&iparam);
    857                 *params = (iparam != 0);
    858             }
    859             break;
    860 
    861         default:
    862             ctx->dispatcher().glGetBooleanv(pname,params);
    863     }
    864 }
    865 
    866 GL_APICALL void  GL_APIENTRY glGetBufferParameteriv(GLenum target, GLenum pname, GLint* params){
    867     GET_CTX();
    868     SET_ERROR_IF(!(GLESv2Validate::bufferTarget(target) && GLESv2Validate::bufferParam(pname)),GL_INVALID_ENUM);
    869     SET_ERROR_IF(!ctx->isBindedBuffer(target),GL_INVALID_OPERATION);
    870     bool ret = true;
    871     switch(pname) {
    872     case GL_BUFFER_SIZE:
    873         ctx->getBufferSize(target,params);
    874         break;
    875     case GL_BUFFER_USAGE:
    876         ctx->getBufferUsage(target,params);
    877         break;
    878     }
    879 }
    880 
    881 
    882 GL_APICALL GLenum GL_APIENTRY glGetError(void){
    883     GET_CTX_RET(GL_NO_ERROR)
    884     GLenum err = ctx->getGLerror();
    885     if(err != GL_NO_ERROR) {
    886         ctx->setGLerror(GL_NO_ERROR);
    887         return err;
    888     }
    889     return ctx->dispatcher().glGetError();
    890 }
    891 
    892 GL_APICALL void  GL_APIENTRY glGetFloatv(GLenum pname, GLfloat* params){
    893     GET_CTX();
    894 
    895     if (ctx->glGetFloatv(pname,params)) {
    896         return;
    897     }
    898 
    899     GLint i;
    900 
    901     switch (pname) {
    902     case GL_CURRENT_PROGRAM:
    903     case GL_FRAMEBUFFER_BINDING:
    904     case GL_RENDERBUFFER_BINDING:
    905         glGetIntegerv(pname,&i);
    906         *params = (GLfloat)i;
    907         break;
    908     case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
    909         *params = (GLfloat)getCompressedFormats(NULL);
    910         break;
    911     case GL_COMPRESSED_TEXTURE_FORMATS:
    912         {
    913             int nparams = getCompressedFormats(NULL);
    914             if (nparams>0) {
    915                 int * iparams = new int[nparams];
    916                 getCompressedFormats(iparams);
    917                 for (int i=0; i<nparams; i++) params[i] = (GLfloat)iparams[i];
    918                 delete [] iparams;
    919             }
    920         }
    921         break;
    922 
    923     case GL_SHADER_COMPILER:
    924     case GL_SHADER_BINARY_FORMATS:
    925     case GL_NUM_SHADER_BINARY_FORMATS:
    926     case GL_MAX_VERTEX_UNIFORM_VECTORS:
    927     case GL_MAX_VARYING_VECTORS:
    928     case GL_MAX_FRAGMENT_UNIFORM_VECTORS:
    929         if(ctx->getCaps()->GL_ARB_ES2_COMPATIBILITY)
    930             ctx->dispatcher().glGetFloatv(pname,params);
    931         else
    932         {
    933             glGetIntegerv(pname,&i);
    934             *params = (GLfloat)i;
    935         }
    936         break;
    937 
    938     default:
    939         ctx->dispatcher().glGetFloatv(pname,params);
    940     }
    941 }
    942 
    943 GL_APICALL void  GL_APIENTRY glGetIntegerv(GLenum pname, GLint* params){
    944     GET_CTX();
    945 
    946     if (ctx->glGetIntegerv(pname,params))
    947     {
    948         return;
    949     }
    950 
    951     bool es2 = ctx->getCaps()->GL_ARB_ES2_COMPATIBILITY;
    952     GLint i;
    953 
    954     switch (pname) {
    955     case GL_CURRENT_PROGRAM:
    956         if (ctx->shareGroup().Ptr()) {
    957             ctx->dispatcher().glGetIntegerv(pname,&i);
    958             *params = ctx->shareGroup()->getLocalName(SHADER,i);
    959         }
    960         break;
    961     case GL_FRAMEBUFFER_BINDING:
    962         if (ctx->shareGroup().Ptr()) {
    963             ctx->dispatcher().glGetIntegerv(pname,&i);
    964             *params = ctx->shareGroup()->getLocalName(FRAMEBUFFER,i);
    965         }
    966         break;
    967     case GL_RENDERBUFFER_BINDING:
    968         if (ctx->shareGroup().Ptr()) {
    969             ctx->dispatcher().glGetIntegerv(pname,&i);
    970             *params = ctx->shareGroup()->getLocalName(RENDERBUFFER,i);
    971         }
    972         break;
    973 
    974     case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
    975         *params = getCompressedFormats(NULL);
    976         break;
    977     case GL_COMPRESSED_TEXTURE_FORMATS:
    978         getCompressedFormats(params);
    979         break;
    980 
    981     case GL_SHADER_COMPILER:
    982         if(es2)
    983             ctx->dispatcher().glGetIntegerv(pname,params);
    984         else
    985             *params = 1;
    986         break;
    987 
    988     case GL_SHADER_BINARY_FORMATS:
    989         if(es2)
    990             ctx->dispatcher().glGetIntegerv(pname,params);
    991         break;
    992 
    993     case GL_NUM_SHADER_BINARY_FORMATS:
    994         if(es2)
    995             ctx->dispatcher().glGetIntegerv(pname,params);
    996         else
    997             *params = 0;
    998         break;
    999 
   1000     case GL_MAX_VERTEX_UNIFORM_VECTORS:
   1001         if(es2)
   1002             ctx->dispatcher().glGetIntegerv(pname,params);
   1003         else
   1004             *params = 128;
   1005         break;
   1006 
   1007     case GL_MAX_VARYING_VECTORS:
   1008         if(es2)
   1009             ctx->dispatcher().glGetIntegerv(pname,params);
   1010         else
   1011             *params = 8;
   1012         break;
   1013 
   1014     case GL_MAX_FRAGMENT_UNIFORM_VECTORS:
   1015         if(es2)
   1016             ctx->dispatcher().glGetIntegerv(pname,params);
   1017         else
   1018             *params = 16;
   1019         break;
   1020 
   1021     case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS:
   1022         ctx->dispatcher().glGetIntegerv(pname,params);
   1023         if(*params > 16)
   1024         {
   1025             // GLES spec requires only 2, and the ATI driver erronously
   1026             // returns 32 (although it supports only 16). This WAR is simple,
   1027             // compliant and good enough for developers.
   1028             *params = 16;
   1029         }
   1030         break;
   1031     default:
   1032         ctx->dispatcher().glGetIntegerv(pname,params);
   1033     }
   1034 }
   1035 
   1036 GL_APICALL void  GL_APIENTRY glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint* params){
   1037     GET_CTX();
   1038     SET_ERROR_IF(!(GLESv2Validate::framebufferTarget(target)         &&
   1039                    GLESv2Validate::framebufferAttachment(attachment) &&
   1040                    GLESv2Validate::framebufferAttachmentParams(pname)),GL_INVALID_ENUM);
   1041 
   1042     //
   1043     // Take the attachment attribute from our state - if available
   1044     //
   1045     GLuint fbName = ctx->getFramebufferBinding();
   1046     if (fbName) {
   1047         ObjectDataPtr fbObj = ctx->shareGroup()->getObjectData(FRAMEBUFFER,fbName);
   1048         if (fbObj.Ptr() != NULL) {
   1049             FramebufferData *fbData = (FramebufferData *)fbObj.Ptr();
   1050             GLenum target;
   1051             GLuint name = fbData->getAttachment(attachment, &target, NULL);
   1052             if (pname == GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE) {
   1053                 if (target == GL_TEXTURE_2D) {
   1054                     *params = GL_TEXTURE;
   1055                     return;
   1056                 }
   1057                 else if (target == GL_RENDERBUFFER) {
   1058                     *params = GL_RENDERBUFFER;
   1059                     return;
   1060                 }
   1061             }
   1062             else if (pname == GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME) {
   1063                 *params = name;
   1064                 return;
   1065             }
   1066         }
   1067     }
   1068 
   1069     ctx->dispatcher().glGetFramebufferAttachmentParameterivEXT(target,attachment,pname,params);
   1070 }
   1071 
   1072 GL_APICALL void  GL_APIENTRY glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params){
   1073     GET_CTX();
   1074     SET_ERROR_IF(!(GLESv2Validate::renderbufferTarget(target) && GLESv2Validate::renderbufferParams(pname)),GL_INVALID_ENUM);
   1075 
   1076     //
   1077     // If this is a renderbuffer which is eglimage's target, we
   1078     // should query the underlying eglimage's texture object instead.
   1079     //
   1080     GLuint rb = ctx->getRenderbufferBinding();
   1081     if (rb) {
   1082         ObjectDataPtr objData = ctx->shareGroup()->getObjectData(RENDERBUFFER,rb);
   1083         RenderbufferData *rbData = (RenderbufferData *)objData.Ptr();
   1084         if (rbData && rbData->sourceEGLImage != 0) {
   1085             GLenum texPname;
   1086             switch(pname) {
   1087                 case GL_RENDERBUFFER_WIDTH:
   1088                     texPname = GL_TEXTURE_WIDTH;
   1089                     break;
   1090                 case GL_RENDERBUFFER_HEIGHT:
   1091                     texPname = GL_TEXTURE_HEIGHT;
   1092                     break;
   1093                 case GL_RENDERBUFFER_INTERNAL_FORMAT:
   1094                     texPname = GL_TEXTURE_INTERNAL_FORMAT;
   1095                     break;
   1096                 case GL_RENDERBUFFER_RED_SIZE:
   1097                     texPname = GL_TEXTURE_RED_SIZE;
   1098                     break;
   1099                 case GL_RENDERBUFFER_GREEN_SIZE:
   1100                     texPname = GL_TEXTURE_GREEN_SIZE;
   1101                     break;
   1102                 case GL_RENDERBUFFER_BLUE_SIZE:
   1103                     texPname = GL_TEXTURE_BLUE_SIZE;
   1104                     break;
   1105                 case GL_RENDERBUFFER_ALPHA_SIZE:
   1106                     texPname = GL_TEXTURE_ALPHA_SIZE;
   1107                     break;
   1108                 case GL_RENDERBUFFER_DEPTH_SIZE:
   1109                     texPname = GL_TEXTURE_DEPTH_SIZE;
   1110                     break;
   1111                 case GL_RENDERBUFFER_STENCIL_SIZE:
   1112                 default:
   1113                     *params = 0; //XXX
   1114                     return;
   1115                     break;
   1116             }
   1117 
   1118             GLint prevTex;
   1119             ctx->dispatcher().glGetIntegerv(GL_TEXTURE_BINDING_2D, &prevTex);
   1120             ctx->dispatcher().glBindTexture(GL_TEXTURE_2D,
   1121                                             rbData->eglImageGlobalTexName);
   1122             ctx->dispatcher().glGetTexLevelParameteriv(GL_TEXTURE_2D, 0,
   1123                                                        texPname,
   1124                                                        params);
   1125             ctx->dispatcher().glBindTexture(GL_TEXTURE_2D, prevTex);
   1126             return;
   1127         }
   1128     }
   1129 
   1130     ctx->dispatcher().glGetRenderbufferParameterivEXT(target,pname,params);
   1131 }
   1132 
   1133 
   1134 GL_APICALL void  GL_APIENTRY glGetProgramiv(GLuint program, GLenum pname, GLint* params){
   1135     GET_CTX();
   1136     SET_ERROR_IF(!GLESv2Validate::programParam(pname),GL_INVALID_ENUM);
   1137     if(ctx->shareGroup().Ptr()) {
   1138         const GLuint globalProgramName = ctx->shareGroup()->getGlobalName(SHADER,program);
   1139         SET_ERROR_IF(globalProgramName==0, GL_INVALID_VALUE);
   1140         switch(pname) {
   1141         case GL_LINK_STATUS:
   1142             {
   1143                 ObjectDataPtr objData = ctx->shareGroup()->getObjectData(SHADER,program);
   1144                 SET_ERROR_IF(!objData.Ptr() ,GL_INVALID_OPERATION);
   1145                 SET_ERROR_IF(objData.Ptr()->getDataType()!=PROGRAM_DATA,GL_INVALID_OPERATION);
   1146                 ProgramData* programData = (ProgramData*)objData.Ptr();
   1147                 params[0] = programData->getLinkStatus();
   1148             }
   1149             break;
   1150         //validate status should not return GL_TRUE if link failed
   1151         case GL_VALIDATE_STATUS:
   1152             {
   1153                 ObjectDataPtr objData = ctx->shareGroup()->getObjectData(SHADER,program);
   1154                 SET_ERROR_IF(!objData.Ptr() ,GL_INVALID_OPERATION);
   1155                 SET_ERROR_IF(objData.Ptr()->getDataType()!=PROGRAM_DATA,GL_INVALID_OPERATION);
   1156                 ProgramData* programData = (ProgramData*)objData.Ptr();
   1157                 if (programData->getLinkStatus()==GL_TRUE)
   1158                     ctx->dispatcher().glGetProgramiv(globalProgramName,pname,params);
   1159                 else
   1160                     params[0] = GL_FALSE;
   1161             }
   1162             break;
   1163         case GL_INFO_LOG_LENGTH:
   1164             {
   1165                 ObjectDataPtr objData = ctx->shareGroup()->getObjectData(SHADER,program);
   1166                 SET_ERROR_IF(!objData.Ptr() ,GL_INVALID_OPERATION);
   1167                 SET_ERROR_IF(objData.Ptr()->getDataType()!=PROGRAM_DATA,GL_INVALID_OPERATION);
   1168                 ProgramData* programData = (ProgramData*)objData.Ptr();
   1169                 GLint logLength = strlen(programData->getInfoLog());
   1170                 params[0] = (logLength>0) ? logLength+1 : 0;
   1171             }
   1172             break;
   1173         default:
   1174             ctx->dispatcher().glGetProgramiv(globalProgramName,pname,params);
   1175         }
   1176     }
   1177 }
   1178 
   1179 GL_APICALL void  GL_APIENTRY glGetProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei* length, GLchar* infolog){
   1180     GET_CTX();
   1181     if(ctx->shareGroup().Ptr()) {
   1182         const GLuint globalProgramName = ctx->shareGroup()->getGlobalName(SHADER,program);
   1183         SET_ERROR_IF(globalProgramName==0, GL_INVALID_VALUE);
   1184         ObjectDataPtr objData = ctx->shareGroup()->getObjectData(SHADER,program);
   1185         SET_ERROR_IF(!objData.Ptr() ,GL_INVALID_OPERATION);
   1186         SET_ERROR_IF(objData.Ptr()->getDataType()!=PROGRAM_DATA,GL_INVALID_OPERATION);
   1187         ProgramData* programData = (ProgramData*)objData.Ptr();
   1188 
   1189         if (bufsize==0) {
   1190             if (length) {
   1191                 *length = 0;
   1192             }
   1193             return;
   1194         }
   1195 
   1196         GLsizei logLength;
   1197         logLength = strlen(programData->getInfoLog());
   1198 
   1199         GLsizei returnLength=0;
   1200         if (infolog) {
   1201             returnLength = bufsize-1 < logLength ? bufsize-1 : logLength;
   1202             strncpy(infolog,programData->getInfoLog(),returnLength+1);
   1203             infolog[returnLength] = '\0';
   1204         }
   1205         if (length) {
   1206             *length = returnLength;
   1207         }
   1208     }
   1209 }
   1210 
   1211 GL_APICALL void  GL_APIENTRY glGetShaderiv(GLuint shader, GLenum pname, GLint* params){
   1212     GET_CTX();
   1213     if(ctx->shareGroup().Ptr()) {
   1214         const GLuint globalShaderName = ctx->shareGroup()->getGlobalName(SHADER,shader);
   1215         SET_ERROR_IF(globalShaderName==0, GL_INVALID_VALUE);
   1216         switch(pname) {
   1217         case GL_INFO_LOG_LENGTH:
   1218             {
   1219                 ObjectDataPtr objData = ctx->shareGroup()->getObjectData(SHADER,shader);
   1220                 SET_ERROR_IF(!objData.Ptr() ,GL_INVALID_OPERATION);
   1221                 SET_ERROR_IF(objData.Ptr()->getDataType()!=SHADER_DATA,GL_INVALID_OPERATION);
   1222                 ShaderParser* sp = (ShaderParser*)objData.Ptr();
   1223                 GLint logLength = strlen(sp->getInfoLog());
   1224                 params[0] = (logLength>0) ? logLength+1 : 0;
   1225             }
   1226             break;
   1227         default:
   1228             ctx->dispatcher().glGetShaderiv(globalShaderName,pname,params);
   1229         }
   1230     }
   1231 }
   1232 
   1233 
   1234 GL_APICALL void  GL_APIENTRY glGetShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* infolog){
   1235     GET_CTX();
   1236     if(ctx->shareGroup().Ptr()) {
   1237         const GLuint globalShaderName = ctx->shareGroup()->getGlobalName(SHADER,shader);
   1238         SET_ERROR_IF(globalShaderName==0, GL_INVALID_VALUE);
   1239         ObjectDataPtr objData = ctx->shareGroup()->getObjectData(SHADER,shader);
   1240         SET_ERROR_IF(!objData.Ptr() ,GL_INVALID_OPERATION);
   1241         SET_ERROR_IF(objData.Ptr()->getDataType()!=SHADER_DATA,GL_INVALID_OPERATION);
   1242         ShaderParser* sp = (ShaderParser*)objData.Ptr();
   1243 
   1244         if (bufsize==0) {
   1245             if (length) {
   1246                 *length = 0;
   1247             }
   1248             return;
   1249         }
   1250 
   1251         GLsizei logLength;
   1252         logLength = strlen(sp->getInfoLog());
   1253 
   1254         GLsizei returnLength=0;
   1255         if (infolog) {
   1256             returnLength = bufsize-1 <logLength ? bufsize-1 : logLength;
   1257             strncpy(infolog,sp->getInfoLog(),returnLength+1);
   1258             infolog[returnLength] = '\0';
   1259         }
   1260         if (length) {
   1261             *length = returnLength;
   1262         }
   1263     }
   1264 }
   1265 
   1266 GL_APICALL void  GL_APIENTRY glGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision){
   1267     GET_CTX_V2();
   1268     SET_ERROR_IF(!(GLESv2Validate::shaderType(shadertype) && GLESv2Validate::precisionType(precisiontype)),GL_INVALID_ENUM);
   1269 
   1270     switch (precisiontype) {
   1271     case GL_LOW_INT:
   1272     case GL_MEDIUM_INT:
   1273     case GL_HIGH_INT:
   1274         range[0] = range[1] = 16;
   1275         *precision = 0;
   1276         break;
   1277 
   1278     case GL_LOW_FLOAT:
   1279     case GL_MEDIUM_FLOAT:
   1280     case GL_HIGH_FLOAT:
   1281         if(ctx->dispatcher().glGetShaderPrecisionFormat != NULL) {
   1282             ctx->dispatcher().glGetShaderPrecisionFormat(shadertype,precisiontype,range,precision);
   1283         } else {
   1284             range[0] = range[1] = 127;
   1285             *precision = 24;
   1286         }
   1287         break;
   1288     }
   1289 }
   1290 
   1291 GL_APICALL void  GL_APIENTRY glGetShaderSource(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source){
   1292     GET_CTX();
   1293     if(ctx->shareGroup().Ptr()) {
   1294        const GLuint globalShaderName = ctx->shareGroup()->getGlobalName(SHADER,shader);
   1295        SET_ERROR_IF(globalShaderName == 0,GL_INVALID_VALUE);
   1296        ObjectDataPtr objData = ctx->shareGroup()->getObjectData(SHADER,shader);
   1297        SET_ERROR_IF(!objData.Ptr(),GL_INVALID_OPERATION);
   1298        SET_ERROR_IF(objData.Ptr()->getDataType()!=SHADER_DATA,GL_INVALID_OPERATION);
   1299        const char* src = ((ShaderParser*)objData.Ptr())->getOriginalSrc();
   1300        int srcLength = 0;
   1301        if (src) {
   1302             srcLength = strlen(src);
   1303        }
   1304 
   1305        int returnLength = bufsize<srcLength ? bufsize-1 : srcLength;
   1306        if (returnLength) {
   1307             strncpy(source,src, returnLength);
   1308             source[returnLength] = '\0';
   1309        }
   1310 
   1311        if (length)
   1312           *length = returnLength;
   1313     }
   1314 }
   1315 
   1316 
   1317 GL_APICALL const GLubyte* GL_APIENTRY glGetString(GLenum name){
   1318     GET_CTX_RET(NULL)
   1319     static GLubyte VENDOR[]     = "Google";
   1320     static GLubyte RENDERER[]   = "OpenGL ES 2.0";
   1321     static GLubyte VERSION[]    = "OpenGL ES 2.0";
   1322     static GLubyte SHADING[]    = "OpenGL ES GLSL ES 1.0.17";
   1323     switch(name) {
   1324         case GL_VENDOR:
   1325             return VENDOR;
   1326         case GL_RENDERER:
   1327             return RENDERER;
   1328         case GL_VERSION:
   1329             return VERSION;
   1330         case GL_SHADING_LANGUAGE_VERSION:
   1331             return SHADING;
   1332         case GL_EXTENSIONS:
   1333             return (const GLubyte*)ctx->getExtensionString();
   1334         default:
   1335             RET_AND_SET_ERROR_IF(true,GL_INVALID_ENUM,NULL);
   1336     }
   1337 }
   1338 
   1339 GL_APICALL void  GL_APIENTRY glGetTexParameterfv(GLenum target, GLenum pname, GLfloat* params){
   1340     GET_CTX();
   1341     SET_ERROR_IF(!(GLESv2Validate::textureTarget(target) && GLESv2Validate::textureParams(pname)),GL_INVALID_ENUM);
   1342     ctx->dispatcher().glGetTexParameterfv(target,pname,params);
   1343 
   1344 }
   1345 GL_APICALL void  GL_APIENTRY glGetTexParameteriv(GLenum target, GLenum pname, GLint* params){
   1346     GET_CTX();
   1347     SET_ERROR_IF(!(GLESv2Validate::textureTarget(target) && GLESv2Validate::textureParams(pname)),GL_INVALID_ENUM);
   1348     ctx->dispatcher().glGetTexParameteriv(target,pname,params);
   1349 }
   1350 
   1351 GL_APICALL void  GL_APIENTRY glGetUniformfv(GLuint program, GLint location, GLfloat* params){
   1352     GET_CTX();
   1353     SET_ERROR_IF(location < 0,GL_INVALID_OPERATION);
   1354     if(ctx->shareGroup().Ptr()) {
   1355         const GLuint globalProgramName = ctx->shareGroup()->getGlobalName(SHADER,program);
   1356         SET_ERROR_IF(globalProgramName==0, GL_INVALID_VALUE);
   1357         ObjectDataPtr objData = ctx->shareGroup()->getObjectData(SHADER,program);
   1358         SET_ERROR_IF(objData.Ptr()->getDataType()!=PROGRAM_DATA,GL_INVALID_OPERATION);
   1359         ProgramData* pData = (ProgramData *)objData.Ptr();
   1360         SET_ERROR_IF(pData->getLinkStatus() != GL_TRUE,GL_INVALID_OPERATION);
   1361         ctx->dispatcher().glGetUniformfv(globalProgramName,location,params);
   1362     }
   1363 }
   1364 
   1365 GL_APICALL void  GL_APIENTRY glGetUniformiv(GLuint program, GLint location, GLint* params){
   1366     GET_CTX();
   1367     SET_ERROR_IF(location < 0,GL_INVALID_OPERATION);
   1368     if(ctx->shareGroup().Ptr()) {
   1369         const GLuint globalProgramName = ctx->shareGroup()->getGlobalName(SHADER,program);
   1370         SET_ERROR_IF(globalProgramName==0, GL_INVALID_VALUE);
   1371         ObjectDataPtr objData = ctx->shareGroup()->getObjectData(SHADER,program);
   1372         SET_ERROR_IF(objData.Ptr()->getDataType()!=PROGRAM_DATA,GL_INVALID_OPERATION);
   1373         ProgramData* pData = (ProgramData *)objData.Ptr();
   1374         SET_ERROR_IF(pData->getLinkStatus() != GL_TRUE,GL_INVALID_OPERATION);
   1375         ctx->dispatcher().glGetUniformiv(globalProgramName,location,params);
   1376     }
   1377 }
   1378 
   1379 GL_APICALL int GL_APIENTRY glGetUniformLocation(GLuint program, const GLchar* name){
   1380     GET_CTX_RET(-1);
   1381     if(ctx->shareGroup().Ptr()) {
   1382         const GLuint globalProgramName = ctx->shareGroup()->getGlobalName(SHADER,program);
   1383         RET_AND_SET_ERROR_IF(globalProgramName==0, GL_INVALID_VALUE,-1);
   1384         ObjectDataPtr objData = ctx->shareGroup()->getObjectData(SHADER,program);
   1385         RET_AND_SET_ERROR_IF(objData.Ptr()->getDataType()!=PROGRAM_DATA,GL_INVALID_OPERATION,-1);
   1386         ProgramData* pData = (ProgramData *)objData.Ptr();
   1387         RET_AND_SET_ERROR_IF(pData->getLinkStatus() != GL_TRUE,GL_INVALID_OPERATION,-1);
   1388         return ctx->dispatcher().glGetUniformLocation(globalProgramName,name);
   1389     }
   1390     return -1;
   1391 }
   1392 
   1393 
   1394 
   1395 GL_APICALL void  GL_APIENTRY glGetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params){
   1396     GET_CTX_V2();
   1397     const GLESpointer* p = ctx->getPointer(index);
   1398     if(p) {
   1399         switch(pname){
   1400         case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
   1401             *params = 0;
   1402             break;
   1403         case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
   1404             *params = p->isEnable();
   1405             break;
   1406         case GL_VERTEX_ATTRIB_ARRAY_SIZE:
   1407             *params = p->getSize();
   1408             break;
   1409         case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
   1410             *params = p->getStride();
   1411             break;
   1412         case GL_VERTEX_ATTRIB_ARRAY_TYPE:
   1413             *params = p->getType();
   1414             break;
   1415         case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
   1416             *params = p->isNormalize();
   1417             break;
   1418         case GL_CURRENT_VERTEX_ATTRIB:
   1419             if(index == 0)
   1420             {
   1421                 const float* att0 = ctx->getAtt0();
   1422                 for(int i=0; i<4; i++)
   1423                     params[i] = att0[i];
   1424             }
   1425             else
   1426                 ctx->dispatcher().glGetVertexAttribfv(index,pname,params);
   1427             break;
   1428         default:
   1429             ctx->setGLerror(GL_INVALID_ENUM);
   1430         }
   1431     } else {
   1432         ctx->setGLerror(GL_INVALID_VALUE);
   1433     }
   1434 }
   1435 
   1436 GL_APICALL void  GL_APIENTRY glGetVertexAttribiv(GLuint index, GLenum pname, GLint* params){
   1437     GET_CTX_V2();
   1438     const GLESpointer* p = ctx->getPointer(index);
   1439     if(p) {
   1440         switch(pname){
   1441         case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
   1442             *params = 0;
   1443             break;
   1444         case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
   1445             *params = p->isEnable();
   1446             break;
   1447         case GL_VERTEX_ATTRIB_ARRAY_SIZE:
   1448             *params = p->getSize();
   1449             break;
   1450         case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
   1451             *params = p->getStride();
   1452             break;
   1453         case GL_VERTEX_ATTRIB_ARRAY_TYPE:
   1454             *params = p->getType();
   1455             break;
   1456         case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
   1457             *params = p->isNormalize();
   1458             break;
   1459         case GL_CURRENT_VERTEX_ATTRIB:
   1460             if(index == 0)
   1461             {
   1462                 const float* att0 = ctx->getAtt0();
   1463                 for(int i=0; i<4; i++)
   1464                     params[i] = (GLint)att0[i];
   1465             }
   1466             else
   1467                 ctx->dispatcher().glGetVertexAttribiv(index,pname,params);
   1468             break;
   1469         default:
   1470             ctx->setGLerror(GL_INVALID_ENUM);
   1471         }
   1472     } else {
   1473         ctx->setGLerror(GL_INVALID_VALUE);
   1474     }
   1475 }
   1476 
   1477 GL_APICALL void  GL_APIENTRY glGetVertexAttribPointerv(GLuint index, GLenum pname, GLvoid** pointer){
   1478     GET_CTX();
   1479     SET_ERROR_IF(pname != GL_VERTEX_ATTRIB_ARRAY_POINTER,GL_INVALID_ENUM);
   1480     SET_ERROR_IF((!GLESv2Validate::arrayIndex(ctx,index)),GL_INVALID_VALUE);
   1481 
   1482     const GLESpointer* p = ctx->getPointer(index);
   1483     if(p) {
   1484         *pointer = const_cast<void *>( p->getBufferData());
   1485     } else {
   1486         ctx->setGLerror(GL_INVALID_VALUE);
   1487     }
   1488 }
   1489 
   1490 GL_APICALL void  GL_APIENTRY glHint(GLenum target, GLenum mode){
   1491     GET_CTX();
   1492     SET_ERROR_IF(!GLESv2Validate::hintTargetMode(target,mode),GL_INVALID_ENUM);
   1493     ctx->dispatcher().glHint(target,mode);
   1494 }
   1495 
   1496 GL_APICALL GLboolean    GL_APIENTRY glIsEnabled(GLenum cap){
   1497     GET_CTX_RET(GL_FALSE);
   1498     RET_AND_SET_ERROR_IF(!GLESv2Validate::capability(cap),GL_INVALID_ENUM,GL_FALSE);
   1499     return ctx->dispatcher().glIsEnabled(cap);
   1500 }
   1501 
   1502 GL_APICALL GLboolean    GL_APIENTRY glIsBuffer(GLuint buffer){
   1503     GET_CTX_RET(GL_FALSE)
   1504     if(buffer && ctx->shareGroup().Ptr()) {
   1505        ObjectDataPtr objData = ctx->shareGroup()->getObjectData(VERTEXBUFFER,buffer);
   1506        return objData.Ptr() ? ((GLESbuffer*)objData.Ptr())->wasBinded():GL_FALSE;
   1507     }
   1508     return GL_FALSE;
   1509 }
   1510 
   1511 GL_APICALL GLboolean    GL_APIENTRY glIsFramebuffer(GLuint framebuffer){
   1512     GET_CTX_RET(GL_FALSE)
   1513     if(framebuffer && ctx->shareGroup().Ptr()){
   1514         return ctx->shareGroup()->isObject(FRAMEBUFFER,framebuffer) ? GL_TRUE :GL_FALSE;
   1515     }
   1516     return GL_FALSE;
   1517 }
   1518 
   1519 GL_APICALL GLboolean    GL_APIENTRY glIsRenderbuffer(GLuint renderbuffer){
   1520     GET_CTX_RET(GL_FALSE)
   1521     if(renderbuffer && ctx->shareGroup().Ptr()){
   1522         return ctx->shareGroup()->isObject(RENDERBUFFER,renderbuffer) ? GL_TRUE :GL_FALSE;
   1523     }
   1524     return GL_FALSE;
   1525 }
   1526 
   1527 GL_APICALL GLboolean    GL_APIENTRY glIsTexture(GLuint texture){
   1528     GET_CTX_RET(GL_FALSE)
   1529     if (texture==0)
   1530         return GL_FALSE;
   1531     TextureData* tex = getTextureData(texture);
   1532     return tex ? tex->wasBound : GL_FALSE;
   1533 }
   1534 
   1535 GL_APICALL GLboolean    GL_APIENTRY glIsProgram(GLuint program){
   1536     GET_CTX_RET(GL_FALSE)
   1537     if(program && ctx->shareGroup().Ptr() &&
   1538        ctx->shareGroup()->isObject(SHADER,program)) {
   1539         const GLuint globalProgramName = ctx->shareGroup()->getGlobalName(SHADER,program);
   1540         return ctx->dispatcher().glIsProgram(globalProgramName);
   1541     }
   1542     return GL_FALSE;
   1543 }
   1544 
   1545 GL_APICALL GLboolean    GL_APIENTRY glIsShader(GLuint shader){
   1546     GET_CTX_RET(GL_FALSE)
   1547     if(shader && ctx->shareGroup().Ptr() &&
   1548        ctx->shareGroup()->isObject(SHADER,shader)) {
   1549         const GLuint globalShaderName = ctx->shareGroup()->getGlobalName(SHADER,shader);
   1550         return ctx->dispatcher().glIsShader(globalShaderName);
   1551     }
   1552     return GL_FALSE;
   1553 }
   1554 
   1555 GL_APICALL void  GL_APIENTRY glLineWidth(GLfloat width){
   1556     GET_CTX();
   1557     ctx->dispatcher().glLineWidth(width);
   1558 }
   1559 
   1560 GL_APICALL void  GL_APIENTRY glLinkProgram(GLuint program){
   1561     GET_CTX();
   1562     GLint linkStatus = GL_FALSE;
   1563     if(ctx->shareGroup().Ptr()) {
   1564         const GLuint globalProgramName = ctx->shareGroup()->getGlobalName(SHADER,program);
   1565         SET_ERROR_IF(globalProgramName==0, GL_INVALID_VALUE);
   1566 
   1567         ObjectDataPtr objData = ctx->shareGroup()->getObjectData(SHADER,program);
   1568         SET_ERROR_IF(!objData.Ptr(), GL_INVALID_OPERATION);
   1569         SET_ERROR_IF(objData.Ptr()->getDataType()!=PROGRAM_DATA, GL_INVALID_OPERATION);
   1570         ProgramData* programData = (ProgramData*)objData.Ptr();
   1571         GLint fragmentShader   = programData->getAttachedFragmentShader();
   1572         GLint vertexShader =  programData->getAttachedVertexShader();
   1573         if (vertexShader != 0 && fragmentShader!=0) {
   1574             /* validating that the fragment & vertex shaders were compiled successfuly*/
   1575             GLint fCompileStatus = GL_FALSE;
   1576             GLint vCompileStatus = GL_FALSE;
   1577             GLuint fragmentShaderGlobal = ctx->shareGroup()->getGlobalName(SHADER,fragmentShader);
   1578             GLuint vertexShaderGlobal = ctx->shareGroup()->getGlobalName(SHADER,vertexShader);
   1579             ctx->dispatcher().glGetShaderiv(fragmentShaderGlobal,GL_COMPILE_STATUS,&fCompileStatus);
   1580             ctx->dispatcher().glGetShaderiv(vertexShaderGlobal,GL_COMPILE_STATUS,&vCompileStatus);
   1581 
   1582             if(fCompileStatus != 0 && vCompileStatus != 0){
   1583                 ctx->dispatcher().glLinkProgram(globalProgramName);
   1584                 ctx->dispatcher().glGetProgramiv(globalProgramName,GL_LINK_STATUS,&linkStatus);
   1585             }
   1586         }
   1587         programData->setLinkStatus(linkStatus);
   1588 
   1589         GLsizei infoLogLength=0;
   1590         GLchar* infoLog;
   1591         ctx->dispatcher().glGetProgramiv(globalProgramName,GL_INFO_LOG_LENGTH,&infoLogLength);
   1592         infoLog = new GLchar[infoLogLength+1];
   1593         ctx->dispatcher().glGetProgramInfoLog(globalProgramName,infoLogLength,NULL,infoLog);
   1594         programData->setInfoLog(infoLog);
   1595     }
   1596 }
   1597 
   1598 GL_APICALL void  GL_APIENTRY glPixelStorei(GLenum pname, GLint param){
   1599     GET_CTX();
   1600     SET_ERROR_IF(!GLESv2Validate::pixelStoreParam(pname),GL_INVALID_ENUM);
   1601     SET_ERROR_IF(!((param==1)||(param==2)||(param==4)||(param==8)), GL_INVALID_VALUE);
   1602     ctx->setUnpackAlignment(param);
   1603     ctx->dispatcher().glPixelStorei(pname,param);
   1604 }
   1605 
   1606 GL_APICALL void  GL_APIENTRY glPolygonOffset(GLfloat factor, GLfloat units){
   1607     GET_CTX();
   1608     ctx->dispatcher().glPolygonOffset(factor,units);
   1609 }
   1610 
   1611 GL_APICALL void  GL_APIENTRY glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels){
   1612     GET_CTX();
   1613     SET_ERROR_IF(!(GLESv2Validate::readPixelFrmt(format) && GLESv2Validate::pixelType(ctx,type)),GL_INVALID_ENUM);
   1614     SET_ERROR_IF(!(GLESv2Validate::pixelOp(format,type)),GL_INVALID_OPERATION);
   1615     ctx->dispatcher().glReadPixels(x,y,width,height,format,type,pixels);
   1616 }
   1617 
   1618 
   1619 GL_APICALL void  GL_APIENTRY glReleaseShaderCompiler(void){
   1620     GET_CTX();
   1621 
   1622     if(ctx->dispatcher().glReleaseShaderCompiler != NULL)
   1623     {
   1624         ctx->dispatcher().glReleaseShaderCompiler();
   1625     }
   1626 }
   1627 
   1628 GL_APICALL void  GL_APIENTRY glRenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height){
   1629     GET_CTX();
   1630     GLenum internal = internalformat;
   1631     switch (internalformat) {
   1632     case GL_RGB565:
   1633         internal = GL_RGB;
   1634         break;
   1635     case GL_RGB5_A1:
   1636         internal = GL_RGBA;
   1637         break;
   1638     default:
   1639         internal = internalformat;
   1640         break;
   1641     }
   1642 
   1643     // Get current bounded renderbuffer
   1644     // raise INVALID_OPERATIOn if no renderbuffer is bounded
   1645     GLuint rb = ctx->getRenderbufferBinding();
   1646     SET_ERROR_IF(rb == 0,GL_INVALID_OPERATION);
   1647     ObjectDataPtr objData = ctx->shareGroup()->getObjectData(RENDERBUFFER,rb);
   1648     RenderbufferData *rbData = (RenderbufferData *)objData.Ptr();
   1649     SET_ERROR_IF(!rbData,GL_INVALID_OPERATION);
   1650 
   1651     //
   1652     // if the renderbuffer was an eglImage target, detach from
   1653     // the eglImage.
   1654     //
   1655     if (rbData->sourceEGLImage != 0) {
   1656         if (rbData->eglImageDetach) {
   1657             (*rbData->eglImageDetach)(rbData->sourceEGLImage);
   1658         }
   1659         rbData->sourceEGLImage = 0;
   1660         rbData->eglImageGlobalTexName = 0;
   1661     }
   1662 
   1663     ctx->dispatcher().glRenderbufferStorageEXT(target,internal,width,height);
   1664 }
   1665 
   1666 GL_APICALL void  GL_APIENTRY glSampleCoverage(GLclampf value, GLboolean invert){
   1667     GET_CTX();
   1668     ctx->dispatcher().glSampleCoverage(value,invert);
   1669 }
   1670 
   1671 GL_APICALL void  GL_APIENTRY glScissor(GLint x, GLint y, GLsizei width, GLsizei height){
   1672     GET_CTX();
   1673     ctx->dispatcher().glScissor(x,y,width,height);
   1674 }
   1675 
   1676 GL_APICALL void  GL_APIENTRY glShaderBinary(GLsizei n, const GLuint* shaders, GLenum binaryformat, const GLvoid* binary, GLsizei length){
   1677     GET_CTX();
   1678 
   1679     SET_ERROR_IF( (ctx->dispatcher().glShaderBinary == NULL), GL_INVALID_OPERATION);
   1680 
   1681     if(ctx->shareGroup().Ptr()){
   1682         for(int i=0; i < n ; i++){
   1683             const GLuint globalShaderName = ctx->shareGroup()->getGlobalName(SHADER,shaders[i]);
   1684             SET_ERROR_IF(globalShaderName == 0,GL_INVALID_VALUE);
   1685             ctx->dispatcher().glShaderBinary(1,&globalShaderName,binaryformat,binary,length);
   1686         }
   1687     }
   1688 }
   1689 
   1690 GL_APICALL void  GL_APIENTRY glShaderSource(GLuint shader, GLsizei count, const GLchar** string, const GLint* length){
   1691     GET_CTX_V2();
   1692     SET_ERROR_IF(count < 0,GL_INVALID_VALUE);
   1693     if(ctx->shareGroup().Ptr()){
   1694             const GLuint globalShaderName = ctx->shareGroup()->getGlobalName(SHADER,shader);
   1695             SET_ERROR_IF(globalShaderName == 0,GL_INVALID_VALUE);
   1696             ObjectDataPtr objData = ctx->shareGroup()->getObjectData(SHADER,shader);
   1697             SET_ERROR_IF(!objData.Ptr(),GL_INVALID_OPERATION);
   1698             SET_ERROR_IF(objData.Ptr()->getDataType()!=SHADER_DATA,GL_INVALID_OPERATION);
   1699             ShaderParser* sp = (ShaderParser*)objData.Ptr();
   1700             sp->setSrc(ctx->glslVersion(),count,string,length);
   1701             ctx->dispatcher().glShaderSource(globalShaderName,1,sp->parsedLines(),NULL);
   1702     }
   1703 }
   1704 
   1705 GL_APICALL void  GL_APIENTRY glStencilFunc(GLenum func, GLint ref, GLuint mask){
   1706     GET_CTX();
   1707     ctx->dispatcher().glStencilFunc(func,ref,mask);
   1708 }
   1709 GL_APICALL void  GL_APIENTRY glStencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask){
   1710     GET_CTX();
   1711     ctx->dispatcher().glStencilFuncSeparate(face,func,ref,mask);
   1712 }
   1713 GL_APICALL void  GL_APIENTRY glStencilMask(GLuint mask){
   1714     GET_CTX();
   1715     ctx->dispatcher().glStencilMask(mask);
   1716 }
   1717 
   1718 GL_APICALL void  GL_APIENTRY glStencilMaskSeparate(GLenum face, GLuint mask){
   1719     GET_CTX();
   1720     ctx->dispatcher().glStencilMaskSeparate(face,mask);
   1721 }
   1722 
   1723 GL_APICALL void  GL_APIENTRY glStencilOp(GLenum fail, GLenum zfail, GLenum zpass){
   1724     GET_CTX();
   1725     ctx->dispatcher().glStencilOp(fail,zfail,zpass);
   1726 }
   1727 
   1728 GL_APICALL void  GL_APIENTRY glStencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass){
   1729     GET_CTX();
   1730     ctx->dispatcher().glStencilOp(fail,zfail,zpass);
   1731 }
   1732 
   1733 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){
   1734     GET_CTX();
   1735     SET_ERROR_IF(!(GLESv2Validate::textureTargetEx(target) &&
   1736                    GLESv2Validate::pixelFrmt(ctx,internalformat) &&
   1737                    GLESv2Validate::pixelFrmt(ctx,format)&&
   1738                    GLESv2Validate::pixelType(ctx,type)),GL_INVALID_ENUM);
   1739 
   1740     SET_ERROR_IF((format == GL_DEPTH_COMPONENT || internalformat == GL_DEPTH_COMPONENT) &&
   1741                     (type != GL_UNSIGNED_SHORT && type != GL_UNSIGNED_INT), GL_INVALID_OPERATION);
   1742 
   1743     SET_ERROR_IF((type == GL_UNSIGNED_SHORT || type == GL_UNSIGNED_INT) &&
   1744                     (format != GL_DEPTH_COMPONENT || internalformat != GL_DEPTH_COMPONENT), GL_INVALID_OPERATION);
   1745 
   1746     SET_ERROR_IF(!(GLESv2Validate::pixelOp(format,type) && internalformat == ((GLint)format)),GL_INVALID_OPERATION);
   1747     SET_ERROR_IF(border != 0,GL_INVALID_VALUE);
   1748 
   1749     if (ctx->shareGroup().Ptr()){
   1750         TextureData *texData = getTextureTargetData(target);
   1751         if(texData) {
   1752             texData->width = width;
   1753             texData->height = height;
   1754             texData->border = border;
   1755             texData->internalFormat = internalformat;
   1756             texData->target = target;
   1757 
   1758             if (texData->sourceEGLImage != 0) {
   1759                 //
   1760                 // This texture was a target of EGLImage,
   1761                 // but now it is re-defined so we need to detach
   1762                 // from the EGLImage and re-generate global texture name
   1763                 // for it.
   1764                 //
   1765                 if (texData->eglImageDetach) {
   1766                     (*texData->eglImageDetach)(texData->sourceEGLImage);
   1767                 }
   1768                 unsigned int tex = ctx->getBindedTexture(target);
   1769                 ctx->shareGroup()->replaceGlobalName(TEXTURE,
   1770                                                      tex,
   1771                                                      texData->oldGlobal);
   1772                 ctx->dispatcher().glBindTexture(GL_TEXTURE_2D, texData->oldGlobal);
   1773                 texData->sourceEGLImage = 0;
   1774                 texData->oldGlobal = 0;
   1775             }
   1776         }
   1777     }
   1778 
   1779     if (type==GL_HALF_FLOAT_OES)
   1780         type = GL_HALF_FLOAT_NV;
   1781     if (pixels==NULL && type==GL_UNSIGNED_SHORT_5_5_5_1)
   1782         type = GL_UNSIGNED_SHORT;
   1783     ctx->dispatcher().glTexImage2D(target,level,internalformat,width,height,border,format,type,pixels);
   1784 }
   1785 
   1786 
   1787 GL_APICALL void  GL_APIENTRY glTexParameterf(GLenum target, GLenum pname, GLfloat param){
   1788     GET_CTX();
   1789     SET_ERROR_IF(!(GLESv2Validate::textureTarget(target) && GLESv2Validate::textureParams(pname)),GL_INVALID_ENUM);
   1790     ctx->dispatcher().glTexParameterf(target,pname,param);
   1791 }
   1792 GL_APICALL void  GL_APIENTRY glTexParameterfv(GLenum target, GLenum pname, const GLfloat* params){
   1793     GET_CTX();
   1794     SET_ERROR_IF(!(GLESv2Validate::textureTarget(target) && GLESv2Validate::textureParams(pname)),GL_INVALID_ENUM);
   1795     ctx->dispatcher().glTexParameterfv(target,pname,params);
   1796 }
   1797 GL_APICALL void  GL_APIENTRY glTexParameteri(GLenum target, GLenum pname, GLint param){
   1798     GET_CTX();
   1799     SET_ERROR_IF(!(GLESv2Validate::textureTarget(target) && GLESv2Validate::textureParams(pname)),GL_INVALID_ENUM);
   1800     ctx->dispatcher().glTexParameteri(target,pname,param);
   1801 }
   1802 GL_APICALL void  GL_APIENTRY glTexParameteriv(GLenum target, GLenum pname, const GLint* params){
   1803     GET_CTX();
   1804     SET_ERROR_IF(!(GLESv2Validate::textureTarget(target) && GLESv2Validate::textureParams(pname)),GL_INVALID_ENUM);
   1805     ctx->dispatcher().glTexParameteriv(target,pname,params);
   1806 }
   1807 
   1808 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){
   1809     GET_CTX();
   1810     SET_ERROR_IF(!(GLESv2Validate::textureTargetEx(target) &&
   1811                    GLESv2Validate::pixelFrmt(ctx,format)&&
   1812                    GLESv2Validate::pixelType(ctx,type)),GL_INVALID_ENUM);
   1813     SET_ERROR_IF(!GLESv2Validate::pixelOp(format,type),GL_INVALID_OPERATION);
   1814     if (type==GL_HALF_FLOAT_OES)
   1815         type = GL_HALF_FLOAT_NV;
   1816 
   1817     ctx->dispatcher().glTexSubImage2D(target,level,xoffset,yoffset,width,height,format,type,pixels);
   1818 
   1819 }
   1820 
   1821 GL_APICALL void  GL_APIENTRY glUniform1f(GLint location, GLfloat x){
   1822     GET_CTX();
   1823     ctx->dispatcher().glUniform1f(location,x);
   1824 }
   1825 GL_APICALL void  GL_APIENTRY glUniform1fv(GLint location, GLsizei count, const GLfloat* v){
   1826     GET_CTX();
   1827     ctx->dispatcher().glUniform1fv(location,count,v);
   1828 }
   1829 
   1830 GL_APICALL void  GL_APIENTRY glUniform1i(GLint location, GLint x){
   1831     GET_CTX();
   1832     ctx->dispatcher().glUniform1i(location,x);
   1833 }
   1834 GL_APICALL void  GL_APIENTRY glUniform1iv(GLint location, GLsizei count, const GLint* v){
   1835     GET_CTX();
   1836     ctx->dispatcher().glUniform1iv(location,count,v);
   1837 }
   1838 GL_APICALL void  GL_APIENTRY glUniform2f(GLint location, GLfloat x, GLfloat y){
   1839     GET_CTX();
   1840     ctx->dispatcher().glUniform2f(location,x,y);
   1841 }
   1842 GL_APICALL void  GL_APIENTRY glUniform2fv(GLint location, GLsizei count, const GLfloat* v){
   1843     GET_CTX();
   1844     ctx->dispatcher().glUniform2fv(location,count,v);
   1845 }
   1846 GL_APICALL void  GL_APIENTRY glUniform2i(GLint location, GLint x, GLint y){
   1847     GET_CTX();
   1848     ctx->dispatcher().glUniform2i(location,x,y);
   1849 }
   1850 GL_APICALL void  GL_APIENTRY glUniform2iv(GLint location, GLsizei count, const GLint* v){
   1851     GET_CTX();
   1852     ctx->dispatcher().glUniform2iv(location,count,v);
   1853 }
   1854 GL_APICALL void  GL_APIENTRY glUniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z){
   1855     GET_CTX();
   1856     ctx->dispatcher().glUniform3f(location,x,y,z);
   1857 }
   1858 GL_APICALL void  GL_APIENTRY glUniform3fv(GLint location, GLsizei count, const GLfloat* v){
   1859     GET_CTX();
   1860     ctx->dispatcher().glUniform3fv(location,count,v);
   1861 }
   1862 GL_APICALL void  GL_APIENTRY glUniform3i(GLint location, GLint x, GLint y, GLint z){
   1863     GET_CTX();
   1864     ctx->dispatcher().glUniform3i(location,x,y,z);
   1865 }
   1866 
   1867 GL_APICALL void  GL_APIENTRY glUniform3iv(GLint location, GLsizei count, const GLint* v){
   1868     GET_CTX();
   1869     ctx->dispatcher().glUniform3iv(location,count,v);
   1870 }
   1871 
   1872 GL_APICALL void  GL_APIENTRY glUniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w){
   1873     GET_CTX();
   1874     ctx->dispatcher().glUniform4f(location,x,y,z,w);
   1875 }
   1876 
   1877 GL_APICALL void  GL_APIENTRY glUniform4fv(GLint location, GLsizei count, const GLfloat* v){
   1878     GET_CTX();
   1879     ctx->dispatcher().glUniform4fv(location,count,v);
   1880 }
   1881 
   1882 GL_APICALL void  GL_APIENTRY glUniform4i(GLint location, GLint x, GLint y, GLint z, GLint w){
   1883     GET_CTX();
   1884     ctx->dispatcher().glUniform4i(location,x,y,z,w);
   1885 }
   1886 
   1887 GL_APICALL void  GL_APIENTRY glUniform4iv(GLint location, GLsizei count, const GLint* v){
   1888     GET_CTX();
   1889     ctx->dispatcher().glUniform4iv(location,count,v);
   1890 }
   1891 
   1892 GL_APICALL void  GL_APIENTRY glUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value){
   1893     GET_CTX();
   1894     SET_ERROR_IF(transpose != GL_FALSE,GL_INVALID_VALUE);
   1895     ctx->dispatcher().glUniformMatrix2fv(location,count,transpose,value);
   1896 }
   1897 
   1898 GL_APICALL void  GL_APIENTRY glUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value){
   1899     GET_CTX();
   1900     SET_ERROR_IF(transpose != GL_FALSE,GL_INVALID_VALUE);
   1901     ctx->dispatcher().glUniformMatrix3fv(location,count,transpose,value);
   1902 }
   1903 
   1904 GL_APICALL void  GL_APIENTRY glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value){
   1905     GET_CTX();
   1906     SET_ERROR_IF(transpose != GL_FALSE,GL_INVALID_VALUE);
   1907     ctx->dispatcher().glUniformMatrix4fv(location,count,transpose,value);
   1908 }
   1909 
   1910 GL_APICALL void  GL_APIENTRY glUseProgram(GLuint program){
   1911     GET_CTX();
   1912     if(ctx->shareGroup().Ptr()) {
   1913         const GLuint globalProgramName = ctx->shareGroup()->getGlobalName(SHADER,program);
   1914         SET_ERROR_IF(program!=0 && globalProgramName==0,GL_INVALID_VALUE);
   1915         ObjectDataPtr objData = ctx->shareGroup()->getObjectData(SHADER,program);
   1916         SET_ERROR_IF(objData.Ptr() && (objData.Ptr()->getDataType()!=PROGRAM_DATA),GL_INVALID_OPERATION);
   1917         ctx->dispatcher().glUseProgram(globalProgramName);
   1918     }
   1919 }
   1920 
   1921 GL_APICALL void  GL_APIENTRY glValidateProgram(GLuint program){
   1922     GET_CTX();
   1923     if(ctx->shareGroup().Ptr()) {
   1924         const GLuint globalProgramName = ctx->shareGroup()->getGlobalName(SHADER,program);
   1925         SET_ERROR_IF(globalProgramName==0, GL_INVALID_VALUE);
   1926         ObjectDataPtr objData = ctx->shareGroup()->getObjectData(SHADER,program);
   1927         SET_ERROR_IF(objData.Ptr()->getDataType()!=PROGRAM_DATA,GL_INVALID_OPERATION);
   1928         ProgramData* programData = (ProgramData*)objData.Ptr();
   1929         ctx->dispatcher().glValidateProgram(globalProgramName);
   1930 
   1931         GLsizei infoLogLength=0;
   1932         GLchar* infoLog;
   1933         ctx->dispatcher().glGetProgramiv(globalProgramName,GL_INFO_LOG_LENGTH,&infoLogLength);
   1934         infoLog = new GLchar[infoLogLength+1];
   1935         ctx->dispatcher().glGetProgramInfoLog(globalProgramName,infoLogLength,NULL,infoLog);
   1936         programData->setInfoLog(infoLog);
   1937     }
   1938 }
   1939 
   1940 GL_APICALL void  GL_APIENTRY glVertexAttrib1f(GLuint indx, GLfloat x){
   1941     GET_CTX_V2();
   1942     ctx->dispatcher().glVertexAttrib1f(indx,x);
   1943     if(indx == 0)
   1944         ctx->setAttribute0value(x, 0.0, 0.0, 1.0);
   1945 }
   1946 
   1947 GL_APICALL void  GL_APIENTRY glVertexAttrib1fv(GLuint indx, const GLfloat* values){
   1948     GET_CTX_V2();
   1949     ctx->dispatcher().glVertexAttrib1fv(indx,values);
   1950     if(indx == 0)
   1951         ctx->setAttribute0value(values[0], 0.0, 0.0, 1.0);
   1952 }
   1953 
   1954 GL_APICALL void  GL_APIENTRY glVertexAttrib2f(GLuint indx, GLfloat x, GLfloat y){
   1955     GET_CTX_V2();
   1956     ctx->dispatcher().glVertexAttrib2f(indx,x,y);
   1957     if(indx == 0)
   1958         ctx->setAttribute0value(x, y, 0.0, 1.0);
   1959 }
   1960 
   1961 GL_APICALL void  GL_APIENTRY glVertexAttrib2fv(GLuint indx, const GLfloat* values){
   1962     GET_CTX_V2();
   1963     ctx->dispatcher().glVertexAttrib2fv(indx,values);
   1964     if(indx == 0)
   1965         ctx->setAttribute0value(values[0], values[1], 0.0, 1.0);
   1966 }
   1967 
   1968 GL_APICALL void  GL_APIENTRY glVertexAttrib3f(GLuint indx, GLfloat x, GLfloat y, GLfloat z){
   1969     GET_CTX_V2();
   1970     ctx->dispatcher().glVertexAttrib3f(indx,x,y,z);
   1971     if(indx == 0)
   1972         ctx->setAttribute0value(x, y, z, 1.0);
   1973 }
   1974 
   1975 GL_APICALL void  GL_APIENTRY glVertexAttrib3fv(GLuint indx, const GLfloat* values){
   1976     GET_CTX_V2();
   1977     ctx->dispatcher().glVertexAttrib3fv(indx,values);
   1978     if(indx == 0)
   1979         ctx->setAttribute0value(values[0], values[1], values[2], 1.0);
   1980 }
   1981 
   1982 GL_APICALL void  GL_APIENTRY glVertexAttrib4f(GLuint indx, GLfloat x, GLfloat y, GLfloat z, GLfloat w){
   1983     GET_CTX_V2();
   1984     ctx->dispatcher().glVertexAttrib4f(indx,x,y,z,w);
   1985     if(indx == 0)
   1986         ctx->setAttribute0value(x, y, z, w);
   1987 }
   1988 
   1989 GL_APICALL void  GL_APIENTRY glVertexAttrib4fv(GLuint indx, const GLfloat* values){
   1990     GET_CTX_V2();
   1991     ctx->dispatcher().glVertexAttrib4fv(indx,values);
   1992     if(indx == 0)
   1993         ctx->setAttribute0value(values[0], values[1], values[2], values[3]);
   1994 }
   1995 
   1996 GL_APICALL void  GL_APIENTRY glVertexAttribPointer(GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr){
   1997     GET_CTX();
   1998     SET_ERROR_IF((!GLESv2Validate::arrayIndex(ctx,indx)),GL_INVALID_VALUE);
   1999     if (type == GL_HALF_FLOAT_OES) type = GL_HALF_FLOAT;
   2000     ctx->setPointer(indx,size,type,stride,ptr,normalized);
   2001 }
   2002 
   2003 GL_APICALL void  GL_APIENTRY glViewport(GLint x, GLint y, GLsizei width, GLsizei height){
   2004     GET_CTX();
   2005     ctx->dispatcher().glViewport(x,y,width,height);
   2006 }
   2007 
   2008 GL_APICALL void GL_APIENTRY glEGLImageTargetTexture2DOES(GLenum target, GLeglImageOES image)
   2009 {
   2010     GET_CTX();
   2011     SET_ERROR_IF(!GLESv2Validate::textureTargetLimited(target),GL_INVALID_ENUM);
   2012     EglImage *img = s_eglIface->eglAttachEGLImage((unsigned int)image);
   2013     if (img) {
   2014         // Create the texture object in the underlying EGL implementation,
   2015         // flag to the OpenGL layer to skip the image creation and map the
   2016         // current binded texture object to the existing global object.
   2017         if (ctx->shareGroup().Ptr()) {
   2018             ObjectLocalName tex = TextureLocalName(target,ctx->getBindedTexture(target));
   2019             unsigned int oldGlobal = ctx->shareGroup()->getGlobalName(TEXTURE, tex);
   2020             // Delete old texture object
   2021             if (oldGlobal) {
   2022                 ctx->dispatcher().glDeleteTextures(1, &oldGlobal);
   2023             }
   2024             // replace mapping and bind the new global object
   2025             ctx->shareGroup()->replaceGlobalName(TEXTURE, tex,img->globalTexName);
   2026             ctx->dispatcher().glBindTexture(GL_TEXTURE_2D, img->globalTexName);
   2027             TextureData *texData = getTextureTargetData(target);
   2028             SET_ERROR_IF(texData==NULL,GL_INVALID_OPERATION);
   2029             texData->sourceEGLImage = (unsigned int)image;
   2030             texData->eglImageDetach = s_eglIface->eglDetachEGLImage;
   2031             texData->oldGlobal = oldGlobal;
   2032         }
   2033     }
   2034 }
   2035 
   2036 GL_APICALL void GL_APIENTRY glEGLImageTargetRenderbufferStorageOES(GLenum target, GLeglImageOES image)
   2037 {
   2038     GET_CTX();
   2039     SET_ERROR_IF(target != GL_RENDERBUFFER_OES,GL_INVALID_ENUM);
   2040     EglImage *img = s_eglIface->eglAttachEGLImage((unsigned int)image);
   2041     SET_ERROR_IF(!img,GL_INVALID_VALUE);
   2042     SET_ERROR_IF(!ctx->shareGroup().Ptr(),GL_INVALID_OPERATION);
   2043 
   2044     // Get current bounded renderbuffer
   2045     // raise INVALID_OPERATIOn if no renderbuffer is bounded
   2046     GLuint rb = ctx->getRenderbufferBinding();
   2047     SET_ERROR_IF(rb == 0,GL_INVALID_OPERATION);
   2048     ObjectDataPtr objData = ctx->shareGroup()->getObjectData(RENDERBUFFER,rb);
   2049     RenderbufferData *rbData = (RenderbufferData *)objData.Ptr();
   2050     SET_ERROR_IF(!rbData,GL_INVALID_OPERATION);
   2051 
   2052     //
   2053     // flag in the renderbufferData that it is an eglImage target
   2054     //
   2055     rbData->sourceEGLImage = (unsigned int)image;
   2056     rbData->eglImageDetach = s_eglIface->eglDetachEGLImage;
   2057     rbData->eglImageGlobalTexName = img->globalTexName;
   2058 
   2059     //
   2060     // if the renderbuffer is attached to a framebuffer
   2061     // change the framebuffer attachment in the undelying OpenGL
   2062     // to point to the eglImage texture object.
   2063     //
   2064     if (rbData->attachedFB) {
   2065         // update the framebuffer attachment point to the
   2066         // underlying texture of the img
   2067         GLuint prevFB = ctx->getFramebufferBinding();
   2068         if (prevFB != rbData->attachedFB) {
   2069             ctx->dispatcher().glBindFramebufferEXT(GL_FRAMEBUFFER_EXT,
   2070                                                    rbData->attachedFB);
   2071         }
   2072         ctx->dispatcher().glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,
   2073                                                     rbData->attachedPoint,
   2074                                                     GL_TEXTURE_2D,
   2075                                                     img->globalTexName,0);
   2076         if (prevFB != rbData->attachedFB) {
   2077             ctx->dispatcher().glBindFramebufferEXT(GL_FRAMEBUFFER_EXT,
   2078                                                    prevFB);
   2079         }
   2080     }
   2081 }
   2082