1/*
2* Copyright (C) 2011 The Android Open Source Project
3*
4* Licensed under the Apache License, Version 2.0 (the "License")
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
36extern "C" {
37
38//decleration
39static void initContext(GLEScontext* ctx,ShareGroupPtr grp);
40static void deleteGLESContext(GLEScontext* ctx);
41static void setShareGroup(GLEScontext* ctx,ShareGroupPtr grp);
42static GLEScontext* createGLESContext();
43static __translatorMustCastToProperFunctionPointerType getProcAddress(const char* procName);
44
45}
46
47/************************************** GLES EXTENSIONS *********************************************************/
48//extentions descriptor
49typedef std::map<std::string, __translatorMustCastToProperFunctionPointerType> ProcTableMap;
50ProcTableMap *s_glesExtensions = NULL;
51/****************************************************************************************************************/
52
53static EGLiface*  s_eglIface = NULL;
54static 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
66extern "C" {
67
68static 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}
76static GLEScontext* createGLESContext() {
77    return new GLESv2Context();
78}
79
80static void deleteGLESContext(GLEScontext* ctx) {
81    delete ctx;
82}
83
84static void setShareGroup(GLEScontext* ctx,ShareGroupPtr grp) {
85    if(ctx) {
86        ctx->setShareGroup(grp);
87    }
88}
89
90static __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
112GL_APICALL GLESiface* __translator_getIfaces(EGLiface* eglIface){
113    s_eglIface = eglIface;
114    return & s_glesIface;
115}
116
117}
118
119static ObjectLocalName TextureLocalName(GLenum target,unsigned int tex) {
120    GET_CTX_RET(0);
121    return (tex!=0? tex : ctx->getDefaultTextureName(target));
122}
123
124static 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
137static TextureData* getTextureTargetData(GLenum target){
138    GET_CTX_RET(NULL);
139    unsigned int tex = ctx->getBindedTexture(target);
140    return getTextureData(TextureLocalName(target,tex));
141}
142
143GL_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
150GL_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
172GL_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
186GL_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
201GL_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
222GL_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
244GL_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
272GL_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
277GL_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
283GL_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
289GL_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
295GL_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
302GL_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
309GL_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
317GL_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
324GL_APICALL void  GL_APIENTRY glClear(GLbitfield mask){
325    GET_CTX();
326    ctx->drawValidate();
327
328    ctx->dispatcher().glClear(mask);
329}
330GL_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}
334GL_APICALL void  GL_APIENTRY glClearDepthf(GLclampf depth){
335    GET_CTX();
336    ctx->dispatcher().glClearDepth(depth);
337}
338GL_APICALL void  GL_APIENTRY glClearStencil(GLint s){
339    GET_CTX();
340    ctx->dispatcher().glClearStencil(s);
341}
342GL_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
347GL_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
366GL_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
376GL_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
382GL_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
389GL_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
395GL_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
411GL_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
428GL_APICALL void  GL_APIENTRY glCullFace(GLenum mode){
429    GET_CTX();
430    ctx->dispatcher().glCullFace(mode);
431}
432
433GL_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
443GL_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
455GL_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
467GL_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
491GL_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
501GL_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
512GL_APICALL void  GL_APIENTRY glDepthFunc(GLenum func){
513    GET_CTX();
514    ctx->dispatcher().glDepthFunc(func);
515}
516GL_APICALL void  GL_APIENTRY glDepthMask(GLboolean flag){
517    GET_CTX();
518    ctx->dispatcher().glDepthMask(flag);
519}
520GL_APICALL void  GL_APIENTRY glDepthRangef(GLclampf zNear, GLclampf zFar){
521    GET_CTX();
522    ctx->dispatcher().glDepthRange(zNear,zFar);
523}
524
525GL_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
545GL_APICALL void  GL_APIENTRY glDisable(GLenum cap){
546    GET_CTX();
547    ctx->dispatcher().glDisable(cap);
548}
549
550GL_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
557GL_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
586GL_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<uintptr_t>(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
621GL_APICALL void  GL_APIENTRY glEnable(GLenum cap){
622    GET_CTX();
623    ctx->dispatcher().glEnable(cap);
624}
625
626GL_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
633GL_APICALL void  GL_APIENTRY glFinish(void){
634    GET_CTX();
635    ctx->dispatcher().glFinish();
636}
637GL_APICALL void  GL_APIENTRY glFlush(void){
638    GET_CTX();
639    ctx->dispatcher().glFlush();
640}
641
642
643GL_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
694GL_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
725GL_APICALL void  GL_APIENTRY glFrontFace(GLenum mode){
726    GET_CTX();
727    ctx->dispatcher().glFrontFace(mode);
728}
729
730GL_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
742GL_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
748GL_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
760GL_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
773GL_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
783GL_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
794GL_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
805GL_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
821GL_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
835GL_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
866GL_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
882GL_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
892GL_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
943GL_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
1036GL_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
1072GL_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
1134GL_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
1179GL_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
1211GL_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
1234GL_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
1266GL_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
1291GL_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
1317GL_APICALL const GLubyte* GL_APIENTRY glGetString(GLenum name){
1318    GET_CTX_RET(NULL)
1319    static const GLubyte SHADING[] = "OpenGL ES GLSL ES 1.0.17";
1320    switch(name) {
1321        case GL_VENDOR:
1322            return (const GLubyte*)ctx->getVendorString();
1323        case GL_RENDERER:
1324            return (const GLubyte*)ctx->getRendererString();
1325        case GL_VERSION:
1326            return (const GLubyte*)ctx->getVersionString();
1327        case GL_SHADING_LANGUAGE_VERSION:
1328            return SHADING;
1329        case GL_EXTENSIONS:
1330            return (const GLubyte*)ctx->getExtensionString();
1331        default:
1332            RET_AND_SET_ERROR_IF(true,GL_INVALID_ENUM,NULL);
1333    }
1334}
1335
1336GL_APICALL void  GL_APIENTRY glGetTexParameterfv(GLenum target, GLenum pname, GLfloat* params){
1337    GET_CTX();
1338    SET_ERROR_IF(!(GLESv2Validate::textureTarget(target) && GLESv2Validate::textureParams(pname)),GL_INVALID_ENUM);
1339    ctx->dispatcher().glGetTexParameterfv(target,pname,params);
1340
1341}
1342GL_APICALL void  GL_APIENTRY glGetTexParameteriv(GLenum target, GLenum pname, GLint* params){
1343    GET_CTX();
1344    SET_ERROR_IF(!(GLESv2Validate::textureTarget(target) && GLESv2Validate::textureParams(pname)),GL_INVALID_ENUM);
1345    ctx->dispatcher().glGetTexParameteriv(target,pname,params);
1346}
1347
1348GL_APICALL void  GL_APIENTRY glGetUniformfv(GLuint program, GLint location, GLfloat* params){
1349    GET_CTX();
1350    SET_ERROR_IF(location < 0,GL_INVALID_OPERATION);
1351    if(ctx->shareGroup().Ptr()) {
1352        const GLuint globalProgramName = ctx->shareGroup()->getGlobalName(SHADER,program);
1353        SET_ERROR_IF(globalProgramName==0, GL_INVALID_VALUE);
1354        ObjectDataPtr objData = ctx->shareGroup()->getObjectData(SHADER,program);
1355        SET_ERROR_IF(objData.Ptr()->getDataType()!=PROGRAM_DATA,GL_INVALID_OPERATION);
1356        ProgramData* pData = (ProgramData *)objData.Ptr();
1357        SET_ERROR_IF(pData->getLinkStatus() != GL_TRUE,GL_INVALID_OPERATION);
1358        ctx->dispatcher().glGetUniformfv(globalProgramName,location,params);
1359    }
1360}
1361
1362GL_APICALL void  GL_APIENTRY glGetUniformiv(GLuint program, GLint location, GLint* params){
1363    GET_CTX();
1364    SET_ERROR_IF(location < 0,GL_INVALID_OPERATION);
1365    if(ctx->shareGroup().Ptr()) {
1366        const GLuint globalProgramName = ctx->shareGroup()->getGlobalName(SHADER,program);
1367        SET_ERROR_IF(globalProgramName==0, GL_INVALID_VALUE);
1368        ObjectDataPtr objData = ctx->shareGroup()->getObjectData(SHADER,program);
1369        SET_ERROR_IF(objData.Ptr()->getDataType()!=PROGRAM_DATA,GL_INVALID_OPERATION);
1370        ProgramData* pData = (ProgramData *)objData.Ptr();
1371        SET_ERROR_IF(pData->getLinkStatus() != GL_TRUE,GL_INVALID_OPERATION);
1372        ctx->dispatcher().glGetUniformiv(globalProgramName,location,params);
1373    }
1374}
1375
1376GL_APICALL int GL_APIENTRY glGetUniformLocation(GLuint program, const GLchar* name){
1377    GET_CTX_RET(-1);
1378    if(ctx->shareGroup().Ptr()) {
1379        const GLuint globalProgramName = ctx->shareGroup()->getGlobalName(SHADER,program);
1380        RET_AND_SET_ERROR_IF(globalProgramName==0, GL_INVALID_VALUE,-1);
1381        ObjectDataPtr objData = ctx->shareGroup()->getObjectData(SHADER,program);
1382        RET_AND_SET_ERROR_IF(objData.Ptr()->getDataType()!=PROGRAM_DATA,GL_INVALID_OPERATION,-1);
1383        ProgramData* pData = (ProgramData *)objData.Ptr();
1384        RET_AND_SET_ERROR_IF(pData->getLinkStatus() != GL_TRUE,GL_INVALID_OPERATION,-1);
1385        return ctx->dispatcher().glGetUniformLocation(globalProgramName,name);
1386    }
1387    return -1;
1388}
1389
1390
1391
1392GL_APICALL void  GL_APIENTRY glGetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params){
1393    GET_CTX_V2();
1394    const GLESpointer* p = ctx->getPointer(index);
1395    if(p) {
1396        switch(pname){
1397        case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
1398            *params = 0;
1399            break;
1400        case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
1401            *params = p->isEnable();
1402            break;
1403        case GL_VERTEX_ATTRIB_ARRAY_SIZE:
1404            *params = p->getSize();
1405            break;
1406        case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
1407            *params = p->getStride();
1408            break;
1409        case GL_VERTEX_ATTRIB_ARRAY_TYPE:
1410            *params = p->getType();
1411            break;
1412        case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
1413            *params = p->isNormalize();
1414            break;
1415        case GL_CURRENT_VERTEX_ATTRIB:
1416            if(index == 0)
1417            {
1418                const float* att0 = ctx->getAtt0();
1419                for(int i=0; i<4; i++)
1420                    params[i] = att0[i];
1421            }
1422            else
1423                ctx->dispatcher().glGetVertexAttribfv(index,pname,params);
1424            break;
1425        default:
1426            ctx->setGLerror(GL_INVALID_ENUM);
1427        }
1428    } else {
1429        ctx->setGLerror(GL_INVALID_VALUE);
1430    }
1431}
1432
1433GL_APICALL void  GL_APIENTRY glGetVertexAttribiv(GLuint index, GLenum pname, GLint* params){
1434    GET_CTX_V2();
1435    const GLESpointer* p = ctx->getPointer(index);
1436    if(p) {
1437        switch(pname){
1438        case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
1439            *params = 0;
1440            break;
1441        case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
1442            *params = p->isEnable();
1443            break;
1444        case GL_VERTEX_ATTRIB_ARRAY_SIZE:
1445            *params = p->getSize();
1446            break;
1447        case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
1448            *params = p->getStride();
1449            break;
1450        case GL_VERTEX_ATTRIB_ARRAY_TYPE:
1451            *params = p->getType();
1452            break;
1453        case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
1454            *params = p->isNormalize();
1455            break;
1456        case GL_CURRENT_VERTEX_ATTRIB:
1457            if(index == 0)
1458            {
1459                const float* att0 = ctx->getAtt0();
1460                for(int i=0; i<4; i++)
1461                    params[i] = (GLint)att0[i];
1462            }
1463            else
1464                ctx->dispatcher().glGetVertexAttribiv(index,pname,params);
1465            break;
1466        default:
1467            ctx->setGLerror(GL_INVALID_ENUM);
1468        }
1469    } else {
1470        ctx->setGLerror(GL_INVALID_VALUE);
1471    }
1472}
1473
1474GL_APICALL void  GL_APIENTRY glGetVertexAttribPointerv(GLuint index, GLenum pname, GLvoid** pointer){
1475    GET_CTX();
1476    SET_ERROR_IF(pname != GL_VERTEX_ATTRIB_ARRAY_POINTER,GL_INVALID_ENUM);
1477    SET_ERROR_IF((!GLESv2Validate::arrayIndex(ctx,index)),GL_INVALID_VALUE);
1478
1479    const GLESpointer* p = ctx->getPointer(index);
1480    if(p) {
1481        *pointer = const_cast<void *>( p->getBufferData());
1482    } else {
1483        ctx->setGLerror(GL_INVALID_VALUE);
1484    }
1485}
1486
1487GL_APICALL void  GL_APIENTRY glHint(GLenum target, GLenum mode){
1488    GET_CTX();
1489    SET_ERROR_IF(!GLESv2Validate::hintTargetMode(target,mode),GL_INVALID_ENUM);
1490    ctx->dispatcher().glHint(target,mode);
1491}
1492
1493GL_APICALL GLboolean    GL_APIENTRY glIsEnabled(GLenum cap){
1494    GET_CTX_RET(GL_FALSE);
1495    RET_AND_SET_ERROR_IF(!GLESv2Validate::capability(cap),GL_INVALID_ENUM,GL_FALSE);
1496    return ctx->dispatcher().glIsEnabled(cap);
1497}
1498
1499GL_APICALL GLboolean    GL_APIENTRY glIsBuffer(GLuint buffer){
1500    GET_CTX_RET(GL_FALSE)
1501    if(buffer && ctx->shareGroup().Ptr()) {
1502       ObjectDataPtr objData = ctx->shareGroup()->getObjectData(VERTEXBUFFER,buffer);
1503       return objData.Ptr() ? ((GLESbuffer*)objData.Ptr())->wasBinded():GL_FALSE;
1504    }
1505    return GL_FALSE;
1506}
1507
1508GL_APICALL GLboolean    GL_APIENTRY glIsFramebuffer(GLuint framebuffer){
1509    GET_CTX_RET(GL_FALSE)
1510    if(framebuffer && ctx->shareGroup().Ptr()){
1511        return ctx->shareGroup()->isObject(FRAMEBUFFER,framebuffer) ? GL_TRUE :GL_FALSE;
1512    }
1513    return GL_FALSE;
1514}
1515
1516GL_APICALL GLboolean    GL_APIENTRY glIsRenderbuffer(GLuint renderbuffer){
1517    GET_CTX_RET(GL_FALSE)
1518    if(renderbuffer && ctx->shareGroup().Ptr()){
1519        return ctx->shareGroup()->isObject(RENDERBUFFER,renderbuffer) ? GL_TRUE :GL_FALSE;
1520    }
1521    return GL_FALSE;
1522}
1523
1524GL_APICALL GLboolean    GL_APIENTRY glIsTexture(GLuint texture){
1525    GET_CTX_RET(GL_FALSE)
1526    if (texture==0)
1527        return GL_FALSE;
1528    TextureData* tex = getTextureData(texture);
1529    return tex ? tex->wasBound : GL_FALSE;
1530}
1531
1532GL_APICALL GLboolean    GL_APIENTRY glIsProgram(GLuint program){
1533    GET_CTX_RET(GL_FALSE)
1534    if(program && ctx->shareGroup().Ptr() &&
1535       ctx->shareGroup()->isObject(SHADER,program)) {
1536        const GLuint globalProgramName = ctx->shareGroup()->getGlobalName(SHADER,program);
1537        return ctx->dispatcher().glIsProgram(globalProgramName);
1538    }
1539    return GL_FALSE;
1540}
1541
1542GL_APICALL GLboolean    GL_APIENTRY glIsShader(GLuint shader){
1543    GET_CTX_RET(GL_FALSE)
1544    if(shader && ctx->shareGroup().Ptr() &&
1545       ctx->shareGroup()->isObject(SHADER,shader)) {
1546        const GLuint globalShaderName = ctx->shareGroup()->getGlobalName(SHADER,shader);
1547        return ctx->dispatcher().glIsShader(globalShaderName);
1548    }
1549    return GL_FALSE;
1550}
1551
1552GL_APICALL void  GL_APIENTRY glLineWidth(GLfloat width){
1553    GET_CTX();
1554    ctx->dispatcher().glLineWidth(width);
1555}
1556
1557GL_APICALL void  GL_APIENTRY glLinkProgram(GLuint program){
1558    GET_CTX();
1559    GLint linkStatus = GL_FALSE;
1560    if(ctx->shareGroup().Ptr()) {
1561        const GLuint globalProgramName = ctx->shareGroup()->getGlobalName(SHADER,program);
1562        SET_ERROR_IF(globalProgramName==0, GL_INVALID_VALUE);
1563
1564        ObjectDataPtr objData = ctx->shareGroup()->getObjectData(SHADER,program);
1565        SET_ERROR_IF(!objData.Ptr(), GL_INVALID_OPERATION);
1566        SET_ERROR_IF(objData.Ptr()->getDataType()!=PROGRAM_DATA, GL_INVALID_OPERATION);
1567        ProgramData* programData = (ProgramData*)objData.Ptr();
1568        GLint fragmentShader   = programData->getAttachedFragmentShader();
1569        GLint vertexShader =  programData->getAttachedVertexShader();
1570        if (vertexShader != 0 && fragmentShader!=0) {
1571            /* validating that the fragment & vertex shaders were compiled successfuly*/
1572            GLint fCompileStatus = GL_FALSE;
1573            GLint vCompileStatus = GL_FALSE;
1574            GLuint fragmentShaderGlobal = ctx->shareGroup()->getGlobalName(SHADER,fragmentShader);
1575            GLuint vertexShaderGlobal = ctx->shareGroup()->getGlobalName(SHADER,vertexShader);
1576            ctx->dispatcher().glGetShaderiv(fragmentShaderGlobal,GL_COMPILE_STATUS,&fCompileStatus);
1577            ctx->dispatcher().glGetShaderiv(vertexShaderGlobal,GL_COMPILE_STATUS,&vCompileStatus);
1578
1579            if(fCompileStatus != 0 && vCompileStatus != 0){
1580                ctx->dispatcher().glLinkProgram(globalProgramName);
1581                ctx->dispatcher().glGetProgramiv(globalProgramName,GL_LINK_STATUS,&linkStatus);
1582            }
1583        }
1584        programData->setLinkStatus(linkStatus);
1585
1586        GLsizei infoLogLength=0;
1587        GLchar* infoLog;
1588        ctx->dispatcher().glGetProgramiv(globalProgramName,GL_INFO_LOG_LENGTH,&infoLogLength);
1589        infoLog = new GLchar[infoLogLength+1];
1590        ctx->dispatcher().glGetProgramInfoLog(globalProgramName,infoLogLength,NULL,infoLog);
1591        programData->setInfoLog(infoLog);
1592    }
1593}
1594
1595GL_APICALL void  GL_APIENTRY glPixelStorei(GLenum pname, GLint param){
1596    GET_CTX();
1597    SET_ERROR_IF(!GLESv2Validate::pixelStoreParam(pname),GL_INVALID_ENUM);
1598    SET_ERROR_IF(!((param==1)||(param==2)||(param==4)||(param==8)), GL_INVALID_VALUE);
1599    ctx->setUnpackAlignment(param);
1600    ctx->dispatcher().glPixelStorei(pname,param);
1601}
1602
1603GL_APICALL void  GL_APIENTRY glPolygonOffset(GLfloat factor, GLfloat units){
1604    GET_CTX();
1605    ctx->dispatcher().glPolygonOffset(factor,units);
1606}
1607
1608GL_APICALL void  GL_APIENTRY glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels){
1609    GET_CTX();
1610    SET_ERROR_IF(!(GLESv2Validate::readPixelFrmt(format) && GLESv2Validate::pixelType(ctx,type)),GL_INVALID_ENUM);
1611    SET_ERROR_IF(!(GLESv2Validate::pixelOp(format,type)),GL_INVALID_OPERATION);
1612    ctx->dispatcher().glReadPixels(x,y,width,height,format,type,pixels);
1613}
1614
1615
1616GL_APICALL void  GL_APIENTRY glReleaseShaderCompiler(void){
1617    GET_CTX();
1618
1619    if(ctx->dispatcher().glReleaseShaderCompiler != NULL)
1620    {
1621        ctx->dispatcher().glReleaseShaderCompiler();
1622    }
1623}
1624
1625GL_APICALL void  GL_APIENTRY glRenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height){
1626    GET_CTX();
1627    GLenum internal = internalformat;
1628    switch (internalformat) {
1629    case GL_RGB565:
1630        internal = GL_RGB;
1631        break;
1632    case GL_RGB5_A1:
1633        internal = GL_RGBA;
1634        break;
1635    default:
1636        internal = internalformat;
1637        break;
1638    }
1639
1640    // Get current bounded renderbuffer
1641    // raise INVALID_OPERATIOn if no renderbuffer is bounded
1642    GLuint rb = ctx->getRenderbufferBinding();
1643    SET_ERROR_IF(rb == 0,GL_INVALID_OPERATION);
1644    ObjectDataPtr objData = ctx->shareGroup()->getObjectData(RENDERBUFFER,rb);
1645    RenderbufferData *rbData = (RenderbufferData *)objData.Ptr();
1646    SET_ERROR_IF(!rbData,GL_INVALID_OPERATION);
1647
1648    //
1649    // if the renderbuffer was an eglImage target, detach from
1650    // the eglImage.
1651    //
1652    if (rbData->sourceEGLImage != 0) {
1653        if (rbData->eglImageDetach) {
1654            (*rbData->eglImageDetach)(rbData->sourceEGLImage);
1655        }
1656        rbData->sourceEGLImage = 0;
1657        rbData->eglImageGlobalTexName = 0;
1658    }
1659
1660    ctx->dispatcher().glRenderbufferStorageEXT(target,internal,width,height);
1661}
1662
1663GL_APICALL void  GL_APIENTRY glSampleCoverage(GLclampf value, GLboolean invert){
1664    GET_CTX();
1665    ctx->dispatcher().glSampleCoverage(value,invert);
1666}
1667
1668GL_APICALL void  GL_APIENTRY glScissor(GLint x, GLint y, GLsizei width, GLsizei height){
1669    GET_CTX();
1670    ctx->dispatcher().glScissor(x,y,width,height);
1671}
1672
1673GL_APICALL void  GL_APIENTRY glShaderBinary(GLsizei n, const GLuint* shaders, GLenum binaryformat, const GLvoid* binary, GLsizei length){
1674    GET_CTX();
1675
1676    SET_ERROR_IF( (ctx->dispatcher().glShaderBinary == NULL), GL_INVALID_OPERATION);
1677
1678    if(ctx->shareGroup().Ptr()){
1679        for(int i=0; i < n ; i++){
1680            const GLuint globalShaderName = ctx->shareGroup()->getGlobalName(SHADER,shaders[i]);
1681            SET_ERROR_IF(globalShaderName == 0,GL_INVALID_VALUE);
1682            ctx->dispatcher().glShaderBinary(1,&globalShaderName,binaryformat,binary,length);
1683        }
1684    }
1685}
1686
1687GL_APICALL void  GL_APIENTRY glShaderSource(GLuint shader, GLsizei count, const GLchar** string, const GLint* length){
1688    GET_CTX_V2();
1689    SET_ERROR_IF(count < 0,GL_INVALID_VALUE);
1690    if(ctx->shareGroup().Ptr()){
1691            const GLuint globalShaderName = ctx->shareGroup()->getGlobalName(SHADER,shader);
1692            SET_ERROR_IF(globalShaderName == 0,GL_INVALID_VALUE);
1693            ObjectDataPtr objData = ctx->shareGroup()->getObjectData(SHADER,shader);
1694            SET_ERROR_IF(!objData.Ptr(),GL_INVALID_OPERATION);
1695            SET_ERROR_IF(objData.Ptr()->getDataType()!=SHADER_DATA,GL_INVALID_OPERATION);
1696            ShaderParser* sp = (ShaderParser*)objData.Ptr();
1697            sp->setSrc(ctx->glslVersion(),count,string,length);
1698            ctx->dispatcher().glShaderSource(globalShaderName,1,sp->parsedLines(),NULL);
1699    }
1700}
1701
1702GL_APICALL void  GL_APIENTRY glStencilFunc(GLenum func, GLint ref, GLuint mask){
1703    GET_CTX();
1704    ctx->dispatcher().glStencilFunc(func,ref,mask);
1705}
1706GL_APICALL void  GL_APIENTRY glStencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask){
1707    GET_CTX();
1708    ctx->dispatcher().glStencilFuncSeparate(face,func,ref,mask);
1709}
1710GL_APICALL void  GL_APIENTRY glStencilMask(GLuint mask){
1711    GET_CTX();
1712    ctx->dispatcher().glStencilMask(mask);
1713}
1714
1715GL_APICALL void  GL_APIENTRY glStencilMaskSeparate(GLenum face, GLuint mask){
1716    GET_CTX();
1717    ctx->dispatcher().glStencilMaskSeparate(face,mask);
1718}
1719
1720GL_APICALL void  GL_APIENTRY glStencilOp(GLenum fail, GLenum zfail, GLenum zpass){
1721    GET_CTX();
1722    ctx->dispatcher().glStencilOp(fail,zfail,zpass);
1723}
1724
1725GL_APICALL void  GL_APIENTRY glStencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass){
1726    GET_CTX();
1727    ctx->dispatcher().glStencilOp(fail,zfail,zpass);
1728}
1729
1730GL_APICALL void  GL_APIENTRY glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid* pixels){
1731    GET_CTX();
1732    SET_ERROR_IF(!(GLESv2Validate::textureTargetEx(target) &&
1733                   GLESv2Validate::pixelFrmt(ctx,internalformat) &&
1734                   GLESv2Validate::pixelFrmt(ctx,format)&&
1735                   GLESv2Validate::pixelType(ctx,type)),GL_INVALID_ENUM);
1736
1737    SET_ERROR_IF((format == GL_DEPTH_COMPONENT || internalformat == GL_DEPTH_COMPONENT) &&
1738                    (type != GL_UNSIGNED_SHORT && type != GL_UNSIGNED_INT), GL_INVALID_OPERATION);
1739
1740    SET_ERROR_IF((type == GL_UNSIGNED_SHORT || type == GL_UNSIGNED_INT) &&
1741                    (format != GL_DEPTH_COMPONENT || internalformat != GL_DEPTH_COMPONENT), GL_INVALID_OPERATION);
1742
1743    SET_ERROR_IF(!(GLESv2Validate::pixelOp(format,type) && internalformat == ((GLint)format)),GL_INVALID_OPERATION);
1744    SET_ERROR_IF(border != 0,GL_INVALID_VALUE);
1745
1746    if (ctx->shareGroup().Ptr()){
1747        TextureData *texData = getTextureTargetData(target);
1748        if(texData) {
1749            texData->width = width;
1750            texData->height = height;
1751            texData->border = border;
1752            texData->internalFormat = internalformat;
1753            texData->target = target;
1754
1755            if (texData->sourceEGLImage != 0) {
1756                //
1757                // This texture was a target of EGLImage,
1758                // but now it is re-defined so we need to detach
1759                // from the EGLImage and re-generate global texture name
1760                // for it.
1761                //
1762                if (texData->eglImageDetach) {
1763                    (*texData->eglImageDetach)(texData->sourceEGLImage);
1764                }
1765                unsigned int tex = ctx->getBindedTexture(target);
1766                ctx->shareGroup()->replaceGlobalName(TEXTURE,
1767                                                     tex,
1768                                                     texData->oldGlobal);
1769                ctx->dispatcher().glBindTexture(GL_TEXTURE_2D, texData->oldGlobal);
1770                texData->sourceEGLImage = 0;
1771                texData->oldGlobal = 0;
1772            }
1773        }
1774    }
1775
1776    if (type==GL_HALF_FLOAT_OES)
1777        type = GL_HALF_FLOAT_NV;
1778    if (pixels==NULL && type==GL_UNSIGNED_SHORT_5_5_5_1)
1779        type = GL_UNSIGNED_SHORT;
1780    ctx->dispatcher().glTexImage2D(target,level,internalformat,width,height,border,format,type,pixels);
1781}
1782
1783
1784GL_APICALL void  GL_APIENTRY glTexParameterf(GLenum target, GLenum pname, GLfloat param){
1785    GET_CTX();
1786    SET_ERROR_IF(!(GLESv2Validate::textureTarget(target) && GLESv2Validate::textureParams(pname)),GL_INVALID_ENUM);
1787    ctx->dispatcher().glTexParameterf(target,pname,param);
1788}
1789GL_APICALL void  GL_APIENTRY glTexParameterfv(GLenum target, GLenum pname, const GLfloat* params){
1790    GET_CTX();
1791    SET_ERROR_IF(!(GLESv2Validate::textureTarget(target) && GLESv2Validate::textureParams(pname)),GL_INVALID_ENUM);
1792    ctx->dispatcher().glTexParameterfv(target,pname,params);
1793}
1794GL_APICALL void  GL_APIENTRY glTexParameteri(GLenum target, GLenum pname, GLint param){
1795    GET_CTX();
1796    SET_ERROR_IF(!(GLESv2Validate::textureTarget(target) && GLESv2Validate::textureParams(pname)),GL_INVALID_ENUM);
1797    ctx->dispatcher().glTexParameteri(target,pname,param);
1798}
1799GL_APICALL void  GL_APIENTRY glTexParameteriv(GLenum target, GLenum pname, const GLint* params){
1800    GET_CTX();
1801    SET_ERROR_IF(!(GLESv2Validate::textureTarget(target) && GLESv2Validate::textureParams(pname)),GL_INVALID_ENUM);
1802    ctx->dispatcher().glTexParameteriv(target,pname,params);
1803}
1804
1805GL_APICALL void  GL_APIENTRY glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid* pixels){
1806    GET_CTX();
1807    SET_ERROR_IF(!(GLESv2Validate::textureTargetEx(target) &&
1808                   GLESv2Validate::pixelFrmt(ctx,format)&&
1809                   GLESv2Validate::pixelType(ctx,type)),GL_INVALID_ENUM);
1810    SET_ERROR_IF(!GLESv2Validate::pixelOp(format,type),GL_INVALID_OPERATION);
1811    if (type==GL_HALF_FLOAT_OES)
1812        type = GL_HALF_FLOAT_NV;
1813
1814    ctx->dispatcher().glTexSubImage2D(target,level,xoffset,yoffset,width,height,format,type,pixels);
1815
1816}
1817
1818GL_APICALL void  GL_APIENTRY glUniform1f(GLint location, GLfloat x){
1819    GET_CTX();
1820    ctx->dispatcher().glUniform1f(location,x);
1821}
1822GL_APICALL void  GL_APIENTRY glUniform1fv(GLint location, GLsizei count, const GLfloat* v){
1823    GET_CTX();
1824    ctx->dispatcher().glUniform1fv(location,count,v);
1825}
1826
1827GL_APICALL void  GL_APIENTRY glUniform1i(GLint location, GLint x){
1828    GET_CTX();
1829    ctx->dispatcher().glUniform1i(location,x);
1830}
1831GL_APICALL void  GL_APIENTRY glUniform1iv(GLint location, GLsizei count, const GLint* v){
1832    GET_CTX();
1833    ctx->dispatcher().glUniform1iv(location,count,v);
1834}
1835GL_APICALL void  GL_APIENTRY glUniform2f(GLint location, GLfloat x, GLfloat y){
1836    GET_CTX();
1837    ctx->dispatcher().glUniform2f(location,x,y);
1838}
1839GL_APICALL void  GL_APIENTRY glUniform2fv(GLint location, GLsizei count, const GLfloat* v){
1840    GET_CTX();
1841    ctx->dispatcher().glUniform2fv(location,count,v);
1842}
1843GL_APICALL void  GL_APIENTRY glUniform2i(GLint location, GLint x, GLint y){
1844    GET_CTX();
1845    ctx->dispatcher().glUniform2i(location,x,y);
1846}
1847GL_APICALL void  GL_APIENTRY glUniform2iv(GLint location, GLsizei count, const GLint* v){
1848    GET_CTX();
1849    ctx->dispatcher().glUniform2iv(location,count,v);
1850}
1851GL_APICALL void  GL_APIENTRY glUniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z){
1852    GET_CTX();
1853    ctx->dispatcher().glUniform3f(location,x,y,z);
1854}
1855GL_APICALL void  GL_APIENTRY glUniform3fv(GLint location, GLsizei count, const GLfloat* v){
1856    GET_CTX();
1857    ctx->dispatcher().glUniform3fv(location,count,v);
1858}
1859GL_APICALL void  GL_APIENTRY glUniform3i(GLint location, GLint x, GLint y, GLint z){
1860    GET_CTX();
1861    ctx->dispatcher().glUniform3i(location,x,y,z);
1862}
1863
1864GL_APICALL void  GL_APIENTRY glUniform3iv(GLint location, GLsizei count, const GLint* v){
1865    GET_CTX();
1866    ctx->dispatcher().glUniform3iv(location,count,v);
1867}
1868
1869GL_APICALL void  GL_APIENTRY glUniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w){
1870    GET_CTX();
1871    ctx->dispatcher().glUniform4f(location,x,y,z,w);
1872}
1873
1874GL_APICALL void  GL_APIENTRY glUniform4fv(GLint location, GLsizei count, const GLfloat* v){
1875    GET_CTX();
1876    ctx->dispatcher().glUniform4fv(location,count,v);
1877}
1878
1879GL_APICALL void  GL_APIENTRY glUniform4i(GLint location, GLint x, GLint y, GLint z, GLint w){
1880    GET_CTX();
1881    ctx->dispatcher().glUniform4i(location,x,y,z,w);
1882}
1883
1884GL_APICALL void  GL_APIENTRY glUniform4iv(GLint location, GLsizei count, const GLint* v){
1885    GET_CTX();
1886    ctx->dispatcher().glUniform4iv(location,count,v);
1887}
1888
1889GL_APICALL void  GL_APIENTRY glUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value){
1890    GET_CTX();
1891    SET_ERROR_IF(transpose != GL_FALSE,GL_INVALID_VALUE);
1892    ctx->dispatcher().glUniformMatrix2fv(location,count,transpose,value);
1893}
1894
1895GL_APICALL void  GL_APIENTRY glUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value){
1896    GET_CTX();
1897    SET_ERROR_IF(transpose != GL_FALSE,GL_INVALID_VALUE);
1898    ctx->dispatcher().glUniformMatrix3fv(location,count,transpose,value);
1899}
1900
1901GL_APICALL void  GL_APIENTRY glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value){
1902    GET_CTX();
1903    SET_ERROR_IF(transpose != GL_FALSE,GL_INVALID_VALUE);
1904    ctx->dispatcher().glUniformMatrix4fv(location,count,transpose,value);
1905}
1906
1907GL_APICALL void  GL_APIENTRY glUseProgram(GLuint program){
1908    GET_CTX();
1909    if(ctx->shareGroup().Ptr()) {
1910        const GLuint globalProgramName = ctx->shareGroup()->getGlobalName(SHADER,program);
1911        SET_ERROR_IF(program!=0 && globalProgramName==0,GL_INVALID_VALUE);
1912        ObjectDataPtr objData = ctx->shareGroup()->getObjectData(SHADER,program);
1913        SET_ERROR_IF(objData.Ptr() && (objData.Ptr()->getDataType()!=PROGRAM_DATA),GL_INVALID_OPERATION);
1914        ctx->dispatcher().glUseProgram(globalProgramName);
1915    }
1916}
1917
1918GL_APICALL void  GL_APIENTRY glValidateProgram(GLuint program){
1919    GET_CTX();
1920    if(ctx->shareGroup().Ptr()) {
1921        const GLuint globalProgramName = ctx->shareGroup()->getGlobalName(SHADER,program);
1922        SET_ERROR_IF(globalProgramName==0, GL_INVALID_VALUE);
1923        ObjectDataPtr objData = ctx->shareGroup()->getObjectData(SHADER,program);
1924        SET_ERROR_IF(objData.Ptr()->getDataType()!=PROGRAM_DATA,GL_INVALID_OPERATION);
1925        ProgramData* programData = (ProgramData*)objData.Ptr();
1926        ctx->dispatcher().glValidateProgram(globalProgramName);
1927
1928        GLsizei infoLogLength=0;
1929        GLchar* infoLog;
1930        ctx->dispatcher().glGetProgramiv(globalProgramName,GL_INFO_LOG_LENGTH,&infoLogLength);
1931        infoLog = new GLchar[infoLogLength+1];
1932        ctx->dispatcher().glGetProgramInfoLog(globalProgramName,infoLogLength,NULL,infoLog);
1933        programData->setInfoLog(infoLog);
1934    }
1935}
1936
1937GL_APICALL void  GL_APIENTRY glVertexAttrib1f(GLuint indx, GLfloat x){
1938    GET_CTX_V2();
1939    ctx->dispatcher().glVertexAttrib1f(indx,x);
1940    if(indx == 0)
1941        ctx->setAttribute0value(x, 0.0, 0.0, 1.0);
1942}
1943
1944GL_APICALL void  GL_APIENTRY glVertexAttrib1fv(GLuint indx, const GLfloat* values){
1945    GET_CTX_V2();
1946    ctx->dispatcher().glVertexAttrib1fv(indx,values);
1947    if(indx == 0)
1948        ctx->setAttribute0value(values[0], 0.0, 0.0, 1.0);
1949}
1950
1951GL_APICALL void  GL_APIENTRY glVertexAttrib2f(GLuint indx, GLfloat x, GLfloat y){
1952    GET_CTX_V2();
1953    ctx->dispatcher().glVertexAttrib2f(indx,x,y);
1954    if(indx == 0)
1955        ctx->setAttribute0value(x, y, 0.0, 1.0);
1956}
1957
1958GL_APICALL void  GL_APIENTRY glVertexAttrib2fv(GLuint indx, const GLfloat* values){
1959    GET_CTX_V2();
1960    ctx->dispatcher().glVertexAttrib2fv(indx,values);
1961    if(indx == 0)
1962        ctx->setAttribute0value(values[0], values[1], 0.0, 1.0);
1963}
1964
1965GL_APICALL void  GL_APIENTRY glVertexAttrib3f(GLuint indx, GLfloat x, GLfloat y, GLfloat z){
1966    GET_CTX_V2();
1967    ctx->dispatcher().glVertexAttrib3f(indx,x,y,z);
1968    if(indx == 0)
1969        ctx->setAttribute0value(x, y, z, 1.0);
1970}
1971
1972GL_APICALL void  GL_APIENTRY glVertexAttrib3fv(GLuint indx, const GLfloat* values){
1973    GET_CTX_V2();
1974    ctx->dispatcher().glVertexAttrib3fv(indx,values);
1975    if(indx == 0)
1976        ctx->setAttribute0value(values[0], values[1], values[2], 1.0);
1977}
1978
1979GL_APICALL void  GL_APIENTRY glVertexAttrib4f(GLuint indx, GLfloat x, GLfloat y, GLfloat z, GLfloat w){
1980    GET_CTX_V2();
1981    ctx->dispatcher().glVertexAttrib4f(indx,x,y,z,w);
1982    if(indx == 0)
1983        ctx->setAttribute0value(x, y, z, w);
1984}
1985
1986GL_APICALL void  GL_APIENTRY glVertexAttrib4fv(GLuint indx, const GLfloat* values){
1987    GET_CTX_V2();
1988    ctx->dispatcher().glVertexAttrib4fv(indx,values);
1989    if(indx == 0)
1990        ctx->setAttribute0value(values[0], values[1], values[2], values[3]);
1991}
1992
1993GL_APICALL void  GL_APIENTRY glVertexAttribPointer(GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr){
1994    GET_CTX();
1995    SET_ERROR_IF((!GLESv2Validate::arrayIndex(ctx,indx)),GL_INVALID_VALUE);
1996    if (type == GL_HALF_FLOAT_OES) type = GL_HALF_FLOAT;
1997    ctx->setPointer(indx,size,type,stride,ptr,normalized);
1998}
1999
2000GL_APICALL void  GL_APIENTRY glViewport(GLint x, GLint y, GLsizei width, GLsizei height){
2001    GET_CTX();
2002    ctx->dispatcher().glViewport(x,y,width,height);
2003}
2004
2005GL_APICALL void GL_APIENTRY glEGLImageTargetTexture2DOES(GLenum target, GLeglImageOES image)
2006{
2007    GET_CTX();
2008    SET_ERROR_IF(!GLESv2Validate::textureTargetLimited(target),GL_INVALID_ENUM);
2009    unsigned int imagehndl = ToTargetCompatibleHandle((uintptr_t)image);
2010    EglImage *img = s_eglIface->eglAttachEGLImage(imagehndl);
2011    if (img) {
2012        // Create the texture object in the underlying EGL implementation,
2013        // flag to the OpenGL layer to skip the image creation and map the
2014        // current binded texture object to the existing global object.
2015        if (ctx->shareGroup().Ptr()) {
2016            ObjectLocalName tex = TextureLocalName(target,ctx->getBindedTexture(target));
2017            unsigned int oldGlobal = ctx->shareGroup()->getGlobalName(TEXTURE, tex);
2018            // Delete old texture object but only if it is not a target of a EGLImage
2019            if (oldGlobal) {
2020                TextureData* oldTexData = getTextureData(tex);
2021                if (!oldTexData || oldTexData->sourceEGLImage == 0) {
2022                    ctx->dispatcher().glDeleteTextures(1, &oldGlobal);
2023                }
2024            }
2025            // replace mapping and bind the new global object
2026            ctx->shareGroup()->replaceGlobalName(TEXTURE, tex,img->globalTexName);
2027            ctx->dispatcher().glBindTexture(GL_TEXTURE_2D, img->globalTexName);
2028            TextureData *texData = getTextureTargetData(target);
2029            SET_ERROR_IF(texData==NULL,GL_INVALID_OPERATION);
2030            texData->width = img->width;
2031            texData->height = img->height;
2032            texData->border = img->border;
2033            texData->internalFormat = img->internalFormat;
2034            texData->sourceEGLImage = imagehndl;
2035            texData->eglImageDetach = s_eglIface->eglDetachEGLImage;
2036            texData->oldGlobal = oldGlobal;
2037        }
2038    }
2039}
2040
2041GL_APICALL void GL_APIENTRY glEGLImageTargetRenderbufferStorageOES(GLenum target, GLeglImageOES image)
2042{
2043    GET_CTX();
2044    SET_ERROR_IF(target != GL_RENDERBUFFER_OES,GL_INVALID_ENUM);
2045    unsigned int imagehndl = ToTargetCompatibleHandle((uintptr_t)image);
2046    EglImage *img = s_eglIface->eglAttachEGLImage(imagehndl);
2047    SET_ERROR_IF(!img,GL_INVALID_VALUE);
2048    SET_ERROR_IF(!ctx->shareGroup().Ptr(),GL_INVALID_OPERATION);
2049
2050    // Get current bounded renderbuffer
2051    // raise INVALID_OPERATIOn if no renderbuffer is bounded
2052    GLuint rb = ctx->getRenderbufferBinding();
2053    SET_ERROR_IF(rb == 0,GL_INVALID_OPERATION);
2054    ObjectDataPtr objData = ctx->shareGroup()->getObjectData(RENDERBUFFER,rb);
2055    RenderbufferData *rbData = (RenderbufferData *)objData.Ptr();
2056    SET_ERROR_IF(!rbData,GL_INVALID_OPERATION);
2057
2058    //
2059    // flag in the renderbufferData that it is an eglImage target
2060    //
2061    rbData->sourceEGLImage = imagehndl;
2062    rbData->eglImageDetach = s_eglIface->eglDetachEGLImage;
2063    rbData->eglImageGlobalTexName = img->globalTexName;
2064
2065    //
2066    // if the renderbuffer is attached to a framebuffer
2067    // change the framebuffer attachment in the undelying OpenGL
2068    // to point to the eglImage texture object.
2069    //
2070    if (rbData->attachedFB) {
2071        // update the framebuffer attachment point to the
2072        // underlying texture of the img
2073        GLuint prevFB = ctx->getFramebufferBinding();
2074        if (prevFB != rbData->attachedFB) {
2075            ctx->dispatcher().glBindFramebufferEXT(GL_FRAMEBUFFER_EXT,
2076                                                   rbData->attachedFB);
2077        }
2078        ctx->dispatcher().glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,
2079                                                    rbData->attachedPoint,
2080                                                    GL_TEXTURE_2D,
2081                                                    img->globalTexName,0);
2082        if (prevFB != rbData->attachedFB) {
2083            ctx->dispatcher().glBindFramebufferEXT(GL_FRAMEBUFFER_EXT,
2084                                                   prevFB);
2085        }
2086    }
2087}
2088