• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #include "GL2Encoder.h"
2 #include <assert.h>
3 
4 
5 static GLubyte *gVendorString= (GLubyte *) "Android";
6 static GLubyte *gRendererString= (GLubyte *) "Android HW-GLES 2.0";
7 static GLubyte *gVersionString= (GLubyte *) "OpenGL ES 2.0";
8 static GLubyte *gExtensionsString= (GLubyte *) ""; // no extensions at this point;
9 
10 #define SET_ERROR_IF(condition,err) if((condition)) {                            \
11         LOGE("%s:%s:%d GL error 0x%x\n", __FILE__, __FUNCTION__, __LINE__, err); \
12         ctx->setError(err);                                    \
13         return;                                                  \
14     }
15 
16 
17 #define RET_AND_SET_ERROR_IF(condition,err,ret) if((condition)) {                \
18         LOGE("%s:%s:%d GL error 0x%x\n", __FILE__, __FUNCTION__, __LINE__, err); \
19         ctx->setError(err);                                    \
20         return ret;                                              \
21     }
22 
23 
GL2Encoder(IOStream * stream)24 GL2Encoder::GL2Encoder(IOStream *stream) : gl2_encoder_context_t(stream)
25 {
26     m_initialized = false;
27     m_state = NULL;
28     m_error = GL_NO_ERROR;
29     m_num_compressedTextureFormats = 0;
30     m_compressedTextureFormats = NULL;
31     //overrides
32     m_glFlush_enc = set_glFlush(s_glFlush);
33     m_glPixelStorei_enc = set_glPixelStorei(s_glPixelStorei);
34     m_glGetString_enc = set_glGetString(s_glGetString);
35     m_glBindBuffer_enc = set_glBindBuffer(s_glBindBuffer);
36     m_glDrawArrays_enc = set_glDrawArrays(s_glDrawArrays);
37     m_glDrawElements_enc = set_glDrawElements(s_glDrawElements);
38     m_glGetIntegerv_enc = set_glGetIntegerv(s_glGetIntegerv);
39     m_glGetFloatv_enc = set_glGetFloatv(s_glGetFloatv);
40     m_glGetBooleanv_enc = set_glGetBooleanv(s_glGetBooleanv);
41     m_glVertexAttribPointer_enc = set_glVertexAttribPointer(s_glVertexAtrribPointer);
42     m_glEnableVertexAttribArray_enc = set_glEnableVertexAttribArray(s_glEnableVertexAttribArray);
43     m_glDisableVertexAttribArray_enc = set_glDisableVertexAttribArray(s_glDisableVertexAttribArray);
44     m_glGetVertexAttribiv_enc = set_glGetVertexAttribiv(s_glGetVertexAttribiv);
45     m_glGetVertexAttribfv_enc = set_glGetVertexAttribfv(s_glGetVertexAttribfv);
46     m_glGetVertexAttribPointerv = set_glGetVertexAttribPointerv(s_glGetVertexAttribPointerv);
47     set_glShaderSource(s_glShaderSource);
48     set_glFinish(s_glFinish);
49     m_glGetError_enc = set_glGetError(s_glGetError);
50     m_glLinkProgram_enc = set_glLinkProgram(s_glLinkProgram);
51     m_glDeleteProgram_enc = set_glDeleteProgram(s_glDeleteProgram);
52     m_glGetUniformiv_enc = set_glGetUniformiv(s_glGetUniformiv);
53     m_glGetUniformfv_enc = set_glGetUniformfv(s_glGetUniformfv);
54     m_glCreateProgram_enc = set_glCreateProgram(s_glCreateProgram);
55     m_glCreateShader_enc = set_glCreateShader(s_glCreateShader);
56     m_glDeleteShader_enc = set_glDeleteShader(s_glDeleteShader);
57     m_glGetUniformLocation_enc = set_glGetUniformLocation(s_glGetUniformLocation);
58     m_glUseProgram_enc = set_glUseProgram(s_glUseProgram);
59 
60     m_glUniform1f_enc = set_glUniform1f(s_glUniform1f);
61     m_glUniform1fv_enc = set_glUniform1fv(s_glUniform1fv);
62     m_glUniform1i_enc = set_glUniform1i(s_glUniform1i);
63     m_glUniform1iv_enc = set_glUniform1iv(s_glUniform1iv);
64     m_glUniform2f_enc = set_glUniform2f(s_glUniform2f);
65     m_glUniform2fv_enc = set_glUniform2fv(s_glUniform2fv);
66     m_glUniform2i_enc = set_glUniform2i(s_glUniform2i);
67     m_glUniform2iv_enc = set_glUniform2iv(s_glUniform2iv);
68     m_glUniform3f_enc = set_glUniform3f(s_glUniform3f);
69     m_glUniform3fv_enc = set_glUniform3fv(s_glUniform3fv);
70     m_glUniform3i_enc = set_glUniform3i(s_glUniform3i);
71     m_glUniform3iv_enc = set_glUniform3iv(s_glUniform3iv);
72     m_glUniform4f_enc = set_glUniform4f(s_glUniform4f);
73     m_glUniform4fv_enc = set_glUniform4fv(s_glUniform4fv);
74     m_glUniform4i_enc = set_glUniform4i(s_glUniform4i);
75     m_glUniform4iv_enc = set_glUniform4iv(s_glUniform4iv);
76     m_glUniformMatrix2fv_enc = set_glUniformMatrix2fv(s_glUniformMatrix2fv);
77     m_glUniformMatrix3fv_enc = set_glUniformMatrix3fv(s_glUniformMatrix3fv);
78     m_glUniformMatrix4fv_enc = set_glUniformMatrix4fv(s_glUniformMatrix4fv);
79 }
80 
~GL2Encoder()81 GL2Encoder::~GL2Encoder()
82 {
83     delete m_compressedTextureFormats;
84 }
85 
s_glGetError(void * self)86 GLenum GL2Encoder::s_glGetError(void * self)
87 {
88     GL2Encoder *ctx = (GL2Encoder *)self;
89     GLenum err = ctx->getError();
90     if(err != GL_NO_ERROR) {
91         ctx->setError(GL_NO_ERROR);
92         return err;
93     }
94 
95     return ctx->m_glGetError_enc(self);
96 
97 }
98 
s_glFlush(void * self)99 void GL2Encoder::s_glFlush(void *self)
100 {
101     GL2Encoder *ctx = (GL2Encoder *) self;
102     ctx->m_glFlush_enc(self);
103     ctx->m_stream->flush();
104 }
105 
s_glGetString(void * self,GLenum name)106 const GLubyte *GL2Encoder::s_glGetString(void *self, GLenum name)
107 {
108     GLubyte *retval =  (GLubyte *) "";
109     switch(name) {
110     case GL_VENDOR:
111         retval = gVendorString;
112         break;
113     case GL_RENDERER:
114         retval = gRendererString;
115         break;
116     case GL_VERSION:
117         retval = gVersionString;
118         break;
119     case GL_EXTENSIONS:
120         retval = gExtensionsString;
121         break;
122     }
123     return retval;
124 }
125 
s_glPixelStorei(void * self,GLenum param,GLint value)126 void GL2Encoder::s_glPixelStorei(void *self, GLenum param, GLint value)
127 {
128     GL2Encoder *ctx = (GL2Encoder *)self;
129     ctx->m_glPixelStorei_enc(ctx, param, value);
130     assert(ctx->m_state != NULL);
131     ctx->m_state->setPixelStore(param, value);
132 }
133 
134 
s_glBindBuffer(void * self,GLenum target,GLuint id)135 void GL2Encoder::s_glBindBuffer(void *self, GLenum target, GLuint id)
136 {
137     GL2Encoder *ctx = (GL2Encoder *) self;
138     assert(ctx->m_state != NULL);
139     ctx->m_state->bindBuffer(target, id);
140     // TODO set error state if needed;
141     ctx->m_glBindBuffer_enc(self, target, id);
142 }
143 
s_glBufferData(void * self,GLenum target,GLsizeiptr size,const GLvoid * data,GLenum usage)144 void GL2Encoder::s_glBufferData(void * self, GLenum target, GLsizeiptr size, const GLvoid * data, GLenum usage)
145 {
146     GL2Encoder *ctx = (GL2Encoder *) self;
147     GLuint bufferId = ctx->m_state->getBuffer(target);
148     SET_ERROR_IF(bufferId==0, GL_INVALID_OPERATION);
149     SET_ERROR_IF(size<0, GL_INVALID_VALUE);
150 
151     ctx->m_shared->updateBufferData(bufferId, size, (void*)data);
152     ctx->m_glBufferData_enc(self, target, size, data, usage);
153 }
154 
s_glBufferSubData(void * self,GLenum target,GLintptr offset,GLsizeiptr size,const GLvoid * data)155 void GL2Encoder::s_glBufferSubData(void * self, GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid * data)
156 {
157     GL2Encoder *ctx = (GL2Encoder *) self;
158     GLuint bufferId = ctx->m_state->getBuffer(target);
159     SET_ERROR_IF(bufferId==0, GL_INVALID_OPERATION);
160 
161     GLenum res = ctx->m_shared->subUpdateBufferData(bufferId, offset, size, (void*)data);
162     SET_ERROR_IF(res, res);
163 
164     ctx->m_glBufferSubData_enc(self, target, offset, size, data);
165 }
166 
s_glDeleteBuffers(void * self,GLsizei n,const GLuint * buffers)167 void GL2Encoder::s_glDeleteBuffers(void * self, GLsizei n, const GLuint * buffers)
168 {
169     GL2Encoder *ctx = (GL2Encoder *) self;
170     SET_ERROR_IF(n<0, GL_INVALID_VALUE);
171     for (int i=0; i<n; i++) {
172         ctx->m_shared->deleteBufferData(buffers[i]);
173         ctx->m_glDeleteBuffers_enc(self,1,&buffers[i]);
174     }
175 }
176 
s_glVertexAtrribPointer(void * self,GLuint indx,GLint size,GLenum type,GLboolean normalized,GLsizei stride,const GLvoid * ptr)177 void GL2Encoder::s_glVertexAtrribPointer(void *self, GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid * ptr)
178 {
179     GL2Encoder *ctx = (GL2Encoder *)self;
180     assert(ctx->m_state != NULL);
181     ctx->m_state->setState(indx, size, type, normalized, stride, ptr);
182 }
183 
s_glGetIntegerv(void * self,GLenum param,GLint * params)184 void GL2Encoder::s_glGetIntegerv(void *self, GLenum param, GLint *params)
185 {
186     GL2Encoder *ctx = (GL2Encoder *) self;
187     assert(ctx->m_state != NULL);
188     if (param == GL_NUM_SHADER_BINARY_FORMATS) {
189         *params = 0;
190     } else if (param == GL_SHADER_BINARY_FORMATS) {
191         // do nothing
192     } else  if (param == GL_COMPRESSED_TEXTURE_FORMATS) {
193         GLint *compressedTextureFormats = ctx->getCompressedTextureFormats();
194         if (ctx->m_num_compressedTextureFormats > 0 && compressedTextureFormats != NULL) {
195             memcpy(params, compressedTextureFormats, ctx->m_num_compressedTextureFormats * sizeof(GLint));
196         }
197     } else if (!ctx->m_state->getClientStateParameter<GLint>(param, params)) {
198         ctx->m_glGetIntegerv_enc(self, param, params);
199     }
200 }
201 
202 
s_glGetFloatv(void * self,GLenum param,GLfloat * ptr)203 void GL2Encoder::s_glGetFloatv(void *self, GLenum param, GLfloat *ptr)
204 {
205     GL2Encoder *ctx = (GL2Encoder *)self;
206     assert(ctx->m_state != NULL);
207     if (param == GL_NUM_SHADER_BINARY_FORMATS) {
208         *ptr = 0;
209     } else if (param == GL_SHADER_BINARY_FORMATS) {
210         // do nothing;
211     } else  if (param == GL_COMPRESSED_TEXTURE_FORMATS) {
212         GLint * compressedTextureFormats = ctx->getCompressedTextureFormats();
213         if (ctx->m_num_compressedTextureFormats > 0 && compressedTextureFormats != NULL) {
214             for (int i = 0; i < ctx->m_num_compressedTextureFormats; i++) {
215                 ptr[i] = (GLfloat) compressedTextureFormats[i];
216             }
217         }
218     }
219     else if (!ctx->m_state->getClientStateParameter<GLfloat>(param,ptr)) {
220         ctx->m_glGetFloatv_enc(self, param, ptr);
221     }
222 }
223 
224 
s_glGetBooleanv(void * self,GLenum param,GLboolean * ptr)225 void GL2Encoder::s_glGetBooleanv(void *self, GLenum param, GLboolean *ptr)
226 {
227     GL2Encoder *ctx = (GL2Encoder *)self;
228     assert(ctx->m_state != NULL);
229     if (param == GL_COMPRESSED_TEXTURE_FORMATS) {
230         // ignore the command, although we should have generated a GLerror;
231     }
232     else if (!ctx->m_state->getClientStateParameter<GLboolean>(param,ptr)) {
233         ctx->m_glGetBooleanv_enc(self, param, ptr);
234     }
235 }
236 
237 
s_glEnableVertexAttribArray(void * self,GLuint index)238 void GL2Encoder::s_glEnableVertexAttribArray(void *self, GLuint index)
239 {
240     GL2Encoder *ctx = (GL2Encoder *)self;
241     assert(ctx->m_state);
242     ctx->m_state->enable(index, 1);
243 }
244 
s_glDisableVertexAttribArray(void * self,GLuint index)245 void GL2Encoder::s_glDisableVertexAttribArray(void *self, GLuint index)
246 {
247     GL2Encoder *ctx = (GL2Encoder *)self;
248     assert(ctx->m_state);
249     ctx->m_state->enable(index, 0);
250 }
251 
252 
s_glGetVertexAttribiv(void * self,GLuint index,GLenum pname,GLint * params)253 void GL2Encoder::s_glGetVertexAttribiv(void *self, GLuint index, GLenum pname, GLint *params)
254 {
255     GL2Encoder *ctx = (GL2Encoder *)self;
256     assert(ctx->m_state);
257 
258     if (!ctx->m_state->getVertexAttribParameter<GLint>(index, pname, params)) {
259         ctx->m_glGetVertexAttribiv_enc(self, index, pname, params);
260     }
261 }
262 
s_glGetVertexAttribfv(void * self,GLuint index,GLenum pname,GLfloat * params)263 void GL2Encoder::s_glGetVertexAttribfv(void *self, GLuint index, GLenum pname, GLfloat *params)
264 {
265     GL2Encoder *ctx = (GL2Encoder *)self;
266     assert(ctx->m_state);
267 
268     if (!ctx->m_state->getVertexAttribParameter<GLfloat>(index, pname, params)) {
269         ctx->m_glGetVertexAttribfv_enc(self, index, pname, params);
270     }
271 }
272 
s_glGetVertexAttribPointerv(void * self,GLuint index,GLenum pname,GLvoid ** pointer)273 void GL2Encoder::s_glGetVertexAttribPointerv(void *self, GLuint index, GLenum pname, GLvoid **pointer)
274 {
275     GL2Encoder *ctx = (GL2Encoder *)self;
276     if (ctx->m_state == NULL) return;
277 
278     const GLClientState::VertexAttribState *va_state = ctx->m_state->getState(index);
279     if (va_state != NULL) {
280         *pointer = va_state->data;
281     }
282 }
283 
284 
sendVertexAttributes(GLint first,GLsizei count)285 void GL2Encoder::sendVertexAttributes(GLint first, GLsizei count)
286 {
287     assert(m_state);
288 
289     for (int i = 0; i < m_state->nLocations(); i++) {
290         bool enableDirty;
291         const GLClientState::VertexAttribState *state = m_state->getStateAndEnableDirty(i, &enableDirty);
292 
293         if (!state) {
294             continue;
295         }
296 
297         if (!enableDirty && !state->enabled) {
298             continue;
299         }
300 
301 
302         if (state->enabled) {
303             m_glEnableVertexAttribArray_enc(this, i);
304 
305             unsigned int datalen = state->elementSize * count;
306             int stride = state->stride == 0 ? state->elementSize : state->stride;
307             int firstIndex = stride * first;
308 
309             if (state->bufferObject == 0) {
310                 this->glVertexAttribPointerData(this, i, state->size, state->type, state->normalized, state->stride,
311                                                 (unsigned char *)state->data + firstIndex, datalen);
312             } else {
313                 this->m_glBindBuffer_enc(this, GL_ARRAY_BUFFER, state->bufferObject);
314                 this->glVertexAttribPointerOffset(this, i, state->size, state->type, state->normalized, state->stride,
315                                                   (GLuint) state->data + firstIndex);
316                 this->m_glBindBuffer_enc(this, GL_ARRAY_BUFFER, m_state->currentArrayVbo());
317             }
318         } else {
319             this->m_glDisableVertexAttribArray_enc(this, i);
320         }
321     }
322 }
323 
s_glDrawArrays(void * self,GLenum mode,GLint first,GLsizei count)324 void GL2Encoder::s_glDrawArrays(void *self, GLenum mode, GLint first, GLsizei count)
325 {
326     GL2Encoder *ctx = (GL2Encoder *)self;
327     ctx->sendVertexAttributes(first, count);
328     ctx->m_glDrawArrays_enc(ctx, mode, 0, count);
329 }
330 
331 
s_glDrawElements(void * self,GLenum mode,GLsizei count,GLenum type,const void * indices)332 void GL2Encoder::s_glDrawElements(void *self, GLenum mode, GLsizei count, GLenum type, const void *indices)
333 {
334 
335     GL2Encoder *ctx = (GL2Encoder *)self;
336     assert(ctx->m_state != NULL);
337     SET_ERROR_IF(count<0, GL_INVALID_VALUE);
338 
339     bool has_immediate_arrays = false;
340     bool has_indirect_arrays = false;
341     int nLocations = ctx->m_state->nLocations();
342 
343     for (int i = 0; i < nLocations; i++) {
344         const GLClientState::VertexAttribState *state = ctx->m_state->getState(i);
345         if (state->enabled) {
346             if (state->bufferObject != 0) {
347                 has_indirect_arrays = true;
348             } else {
349                 has_immediate_arrays = true;
350             }
351         }
352     }
353 
354     if (!has_immediate_arrays && !has_indirect_arrays) {
355         LOGE("glDrawElements: no data bound to the command - ignoring\n");
356         return;
357     }
358 
359     bool adjustIndices = true;
360     if (ctx->m_state->currentIndexVbo() != 0) {
361         if (!has_immediate_arrays) {
362             ctx->sendVertexAttributes(0, count);
363             ctx->m_glBindBuffer_enc(self, GL_ELEMENT_ARRAY_BUFFER, ctx->m_state->currentIndexVbo());
364             ctx->glDrawElementsOffset(ctx, mode, count, type, (GLuint)indices);
365             adjustIndices = false;
366         } else {
367             BufferData * buf = ctx->m_shared->getBufferData(ctx->m_state->currentIndexVbo());
368             ctx->m_glBindBuffer_enc(self, GL_ELEMENT_ARRAY_BUFFER, 0);
369             indices = (void*)((GLintptr)buf->m_fixedBuffer.ptr() + (GLintptr)indices);
370         }
371     }
372     if (adjustIndices) {
373         void *adjustedIndices = (void*)indices;
374         int minIndex = 0, maxIndex = 0;
375 
376         switch(type) {
377         case GL_BYTE:
378         case GL_UNSIGNED_BYTE:
379             GLUtils::minmax<unsigned char>((unsigned char *)indices, count, &minIndex, &maxIndex);
380             if (minIndex != 0) {
381                 adjustedIndices =  ctx->m_fixedBuffer.alloc(glSizeof(type) * count);
382                 GLUtils::shiftIndices<unsigned char>((unsigned char *)indices,
383                                                  (unsigned char *)adjustedIndices,
384                                                  count, -minIndex);
385             }
386             break;
387         case GL_SHORT:
388         case GL_UNSIGNED_SHORT:
389             GLUtils::minmax<unsigned short>((unsigned short *)indices, count, &minIndex, &maxIndex);
390             if (minIndex != 0) {
391                 adjustedIndices = ctx->m_fixedBuffer.alloc(glSizeof(type) * count);
392                 GLUtils::shiftIndices<unsigned short>((unsigned short *)indices,
393                                                   (unsigned short *)adjustedIndices,
394                                                   count, -minIndex);
395             }
396             break;
397         default:
398             LOGE("unsupported index buffer type %d\n", type);
399         }
400         if (has_indirect_arrays || 1) {
401             ctx->sendVertexAttributes(minIndex, maxIndex - minIndex + 1);
402             ctx->glDrawElementsData(ctx, mode, count, type, adjustedIndices,
403                                     count * glSizeof(type));
404             // XXX - OPTIMIZATION (see the other else branch) should be implemented
405             if(!has_indirect_arrays) {
406                 //LOGD("unoptimized drawelements !!!\n");
407             }
408         } else {
409             // we are all direct arrays and immidate mode index array -
410             // rebuild the arrays and the index array;
411             LOGE("glDrawElements: direct index & direct buffer data - will be implemented in later versions;\n");
412         }
413     }
414 }
415 
416 
getCompressedTextureFormats()417 GLint * GL2Encoder::getCompressedTextureFormats()
418 {
419     if (m_compressedTextureFormats == NULL) {
420         this->glGetIntegerv(this, GL_NUM_COMPRESSED_TEXTURE_FORMATS,
421                             &m_num_compressedTextureFormats);
422         if (m_num_compressedTextureFormats > 0) {
423             // get number of texture formats;
424             m_compressedTextureFormats = new GLint[m_num_compressedTextureFormats];
425             this->glGetCompressedTextureFormats(this, m_num_compressedTextureFormats, m_compressedTextureFormats);
426         }
427     }
428     return m_compressedTextureFormats;
429 }
430 
s_glShaderSource(void * self,GLuint shader,GLsizei count,const GLchar ** string,const GLint * length)431 void GL2Encoder::s_glShaderSource(void *self, GLuint shader, GLsizei count, const GLchar **string, const GLint *length)
432 {
433     int len = glUtilsCalcShaderSourceLen((char**)string, (GLint*)length, count);
434     char *str = new char[len + 1];
435     glUtilsPackStrings(str, (char**)string, (GLint*)length, count);
436 
437     GL2Encoder *ctx = (GL2Encoder *)self;
438     ctx->glShaderString(ctx, shader, str, len + 1);
439     delete str;
440 }
441 
s_glFinish(void * self)442 void GL2Encoder::s_glFinish(void *self)
443 {
444     GL2Encoder *ctx = (GL2Encoder *)self;
445     ctx->glFinishRoundTrip(self);
446 }
447 
s_glLinkProgram(void * self,GLuint program)448 void GL2Encoder::s_glLinkProgram(void * self, GLuint program)
449 {
450     GL2Encoder *ctx = (GL2Encoder *)self;
451     ctx->m_glLinkProgram_enc(self, program);
452 
453     GLint linkStatus = 0;
454     ctx->glGetProgramiv(self,program,GL_LINK_STATUS,&linkStatus);
455     if (!linkStatus)
456         return;
457 
458     //get number of active uniforms in the program
459     GLint numUniforms=0;
460     ctx->glGetProgramiv(self, program, GL_ACTIVE_UNIFORMS, &numUniforms);
461     ctx->m_shared->initProgramData(program,numUniforms);
462 
463     //get the length of the longest uniform name
464     GLint maxLength=0;
465     ctx->glGetProgramiv(self, program, GL_ACTIVE_UNIFORM_MAX_LENGTH, &maxLength);
466 
467     GLint size;
468     GLenum type;
469     GLchar *name = new GLchar[maxLength+1];
470     GLint location;
471     //for each active uniform, get its size and starting location.
472     for (GLint i=0 ; i<numUniforms ; ++i)
473     {
474         ctx->glGetActiveUniform(self, program, i, maxLength, NULL, &size, &type, name);
475         location = ctx->m_glGetUniformLocation_enc(self, program, name);
476         ctx->m_shared->setProgramIndexInfo(program, i, location, size, type);
477     }
478     ctx->m_shared->setupLocationShiftWAR(program);
479 
480     delete[] name;
481 }
482 
s_glDeleteProgram(void * self,GLuint program)483 void GL2Encoder::s_glDeleteProgram(void *self, GLuint program)
484 {
485     GL2Encoder *ctx = (GL2Encoder*)self;
486     ctx->m_glDeleteProgram_enc(self, program);
487 
488     ctx->m_shared->deleteProgramData(program);
489 }
490 
s_glGetUniformiv(void * self,GLuint program,GLint location,GLint * params)491 void GL2Encoder::s_glGetUniformiv(void *self, GLuint program, GLint location, GLint* params)
492 {
493     GL2Encoder *ctx = (GL2Encoder*)self;
494     SET_ERROR_IF(!(ctx->m_shared->isProgram(program) || ctx->m_shared->isShader(program)), GL_INVALID_VALUE);
495     SET_ERROR_IF(!ctx->m_shared->isProgramInitialized(program), GL_INVALID_OPERATION);
496     GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
497     SET_ERROR_IF(ctx->m_shared->getProgramUniformType(program,hostLoc)==0, GL_INVALID_OPERATION);
498     ctx->m_glGetUniformiv_enc(self, program, hostLoc, params);
499 }
s_glGetUniformfv(void * self,GLuint program,GLint location,GLfloat * params)500 void GL2Encoder::s_glGetUniformfv(void *self, GLuint program, GLint location, GLfloat* params)
501 {
502     GL2Encoder *ctx = (GL2Encoder*)self;
503     SET_ERROR_IF(!(ctx->m_shared->isProgram(program) || ctx->m_shared->isShader(program)), GL_INVALID_VALUE);
504     SET_ERROR_IF(!ctx->m_shared->isProgramInitialized(program), GL_INVALID_OPERATION);
505     GLint hostLoc = ctx->m_shared->locationWARAppToHost(program,location);
506     SET_ERROR_IF(ctx->m_shared->getProgramUniformType(program,hostLoc)==0, GL_INVALID_OPERATION);
507     ctx->m_glGetUniformfv_enc(self, program, hostLoc, params);
508 }
509 
s_glCreateProgram(void * self)510 GLuint GL2Encoder::s_glCreateProgram(void * self)
511 {
512     GL2Encoder *ctx = (GL2Encoder*)self;
513     GLuint program = ctx->m_glCreateProgram_enc(self);
514     if (program!=0)
515         ctx->m_shared->addProgramData(program);
516     return program;
517 }
518 
s_glCreateShader(void * self,GLenum shaderType)519 GLuint GL2Encoder::s_glCreateShader(void *self, GLenum shaderType)
520 {
521     GL2Encoder *ctx = (GL2Encoder*)self;
522     GLuint shader = ctx->m_glCreateShader_enc(self, shaderType);
523     if (shader!=0)
524         ctx->m_shared->addShaderData(shader);
525     return shader;
526 }
527 
s_glDeleteShader(void * self,GLenum shader)528 void GL2Encoder::s_glDeleteShader(void *self, GLenum shader)
529 {
530     GL2Encoder *ctx = (GL2Encoder*)self;
531     ctx->m_glDeleteShader_enc(self,shader);
532     ctx->m_shared->deleteShaderData(shader);
533 }
534 
s_glGetUniformLocation(void * self,GLuint program,const GLchar * name)535 int GL2Encoder::s_glGetUniformLocation(void *self, GLuint program, const GLchar *name)
536 {
537     if (!name) return -1;
538 
539     GL2Encoder *ctx = (GL2Encoder*)self;
540 
541     // if we need the uniform location WAR
542     // parse array index from the end of the name string
543     int arrIndex = 0;
544     bool needLocationWAR = ctx->m_shared->needUniformLocationWAR(program);
545     if (needLocationWAR) {
546         int namelen = strlen(name);
547         if (name[namelen-1] == ']') {
548             char *brace = strrchr(name,'[');
549             if (!brace || sscanf(brace+1,"%d",&arrIndex) != 1) {
550                 return -1;
551             }
552 
553         }
554     }
555 
556     int hostLoc = ctx->m_glGetUniformLocation_enc(self, program, name);
557     if (hostLoc >= 0 && needLocationWAR) {
558         return ctx->m_shared->locationWARHostToApp(program, hostLoc, arrIndex);
559     }
560     return hostLoc;
561 }
562 
s_glUseProgram(void * self,GLuint program)563 void GL2Encoder::s_glUseProgram(void *self, GLuint program)
564 {
565     GL2Encoder *ctx = (GL2Encoder*)self;
566     ctx->m_glUseProgram_enc(self, program);
567     ctx->m_state->setCurrentProgram(program);
568 }
569 
s_glUniform1f(void * self,GLint location,GLfloat x)570 void GL2Encoder::s_glUniform1f(void *self , GLint location, GLfloat x)
571 {
572     GL2Encoder *ctx = (GL2Encoder*)self;
573     GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentProgram(),location);
574     ctx->m_glUniform1f_enc(self, hostLoc, x);
575 }
576 
s_glUniform1fv(void * self,GLint location,GLsizei count,const GLfloat * v)577 void GL2Encoder::s_glUniform1fv(void *self , GLint location, GLsizei count, const GLfloat* v)
578 {
579     GL2Encoder *ctx = (GL2Encoder*)self;
580     GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentProgram(),location);
581     ctx->m_glUniform1fv_enc(self, hostLoc, count, v);
582 }
583 
s_glUniform1i(void * self,GLint location,GLint x)584 void GL2Encoder::s_glUniform1i(void *self , GLint location, GLint x)
585 {
586     GL2Encoder *ctx = (GL2Encoder*)self;
587     GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentProgram(),location);
588     ctx->m_glUniform1i_enc(self, hostLoc, x);
589 }
590 
s_glUniform1iv(void * self,GLint location,GLsizei count,const GLint * v)591 void GL2Encoder::s_glUniform1iv(void *self , GLint location, GLsizei count, const GLint* v)
592 {
593     GL2Encoder *ctx = (GL2Encoder*)self;
594     GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentProgram(),location);
595     ctx->m_glUniform1iv_enc(self, hostLoc, count, v);
596 }
597 
s_glUniform2f(void * self,GLint location,GLfloat x,GLfloat y)598 void GL2Encoder::s_glUniform2f(void *self , GLint location, GLfloat x, GLfloat y)
599 {
600     GL2Encoder *ctx = (GL2Encoder*)self;
601     GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentProgram(),location);
602     ctx->m_glUniform2f_enc(self, hostLoc, x, y);
603 }
604 
s_glUniform2fv(void * self,GLint location,GLsizei count,const GLfloat * v)605 void GL2Encoder::s_glUniform2fv(void *self , GLint location, GLsizei count, const GLfloat* v)
606 {
607     GL2Encoder *ctx = (GL2Encoder*)self;
608     GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentProgram(),location);
609     ctx->m_glUniform2fv_enc(self, hostLoc, count, v);
610 }
611 
s_glUniform2i(void * self,GLint location,GLint x,GLint y)612 void GL2Encoder::s_glUniform2i(void *self , GLint location, GLint x, GLint y)
613 {
614     GL2Encoder *ctx = (GL2Encoder*)self;
615     GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentProgram(),location);
616     ctx->m_glUniform2i_enc(self, hostLoc, x, y);
617 }
618 
s_glUniform2iv(void * self,GLint location,GLsizei count,const GLint * v)619 void GL2Encoder::s_glUniform2iv(void *self , GLint location, GLsizei count, const GLint* v)
620 {
621     GL2Encoder *ctx = (GL2Encoder*)self;
622     GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentProgram(),location);
623     ctx->m_glUniform2iv_enc(self, hostLoc, count, v);
624 }
625 
s_glUniform3f(void * self,GLint location,GLfloat x,GLfloat y,GLfloat z)626 void GL2Encoder::s_glUniform3f(void *self , GLint location, GLfloat x, GLfloat y, GLfloat z)
627 {
628     GL2Encoder *ctx = (GL2Encoder*)self;
629     GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentProgram(),location);
630     ctx->m_glUniform3f_enc(self, hostLoc, x, y, z);
631 }
632 
s_glUniform3fv(void * self,GLint location,GLsizei count,const GLfloat * v)633 void GL2Encoder::s_glUniform3fv(void *self , GLint location, GLsizei count, const GLfloat* v)
634 {
635     GL2Encoder *ctx = (GL2Encoder*)self;
636     GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentProgram(),location);
637     ctx->m_glUniform3fv_enc(self, hostLoc, count, v);
638 }
639 
s_glUniform3i(void * self,GLint location,GLint x,GLint y,GLint z)640 void GL2Encoder::s_glUniform3i(void *self , GLint location, GLint x, GLint y, GLint z)
641 {
642     GL2Encoder *ctx = (GL2Encoder*)self;
643     GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentProgram(),location);
644     ctx->m_glUniform3i_enc(self, hostLoc, x, y, z);
645 }
646 
s_glUniform3iv(void * self,GLint location,GLsizei count,const GLint * v)647 void GL2Encoder::s_glUniform3iv(void *self , GLint location, GLsizei count, const GLint* v)
648 {
649     GL2Encoder *ctx = (GL2Encoder*)self;
650     GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentProgram(),location);
651     ctx->m_glUniform3iv_enc(self, hostLoc, count, v);
652 }
653 
s_glUniform4f(void * self,GLint location,GLfloat x,GLfloat y,GLfloat z,GLfloat w)654 void GL2Encoder::s_glUniform4f(void *self , GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
655 {
656     GL2Encoder *ctx = (GL2Encoder*)self;
657     GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentProgram(),location);
658     ctx->m_glUniform4f_enc(self, hostLoc, x, y, z, w);
659 }
660 
s_glUniform4fv(void * self,GLint location,GLsizei count,const GLfloat * v)661 void GL2Encoder::s_glUniform4fv(void *self , GLint location, GLsizei count, const GLfloat* v)
662 {
663     GL2Encoder *ctx = (GL2Encoder*)self;
664     GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentProgram(),location);
665     ctx->m_glUniform4fv_enc(self, hostLoc, count, v);
666 }
667 
s_glUniform4i(void * self,GLint location,GLint x,GLint y,GLint z,GLint w)668 void GL2Encoder::s_glUniform4i(void *self , GLint location, GLint x, GLint y, GLint z, GLint w)
669 {
670     GL2Encoder *ctx = (GL2Encoder*)self;
671     GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentProgram(),location);
672     ctx->m_glUniform4i_enc(self, hostLoc, x, y, z, w);
673 }
674 
s_glUniform4iv(void * self,GLint location,GLsizei count,const GLint * v)675 void GL2Encoder::s_glUniform4iv(void *self , GLint location, GLsizei count, const GLint* v)
676 {
677     GL2Encoder *ctx = (GL2Encoder*)self;
678     GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentProgram(),location);
679     ctx->m_glUniform4iv_enc(self, hostLoc, count, v);
680 }
681 
s_glUniformMatrix2fv(void * self,GLint location,GLsizei count,GLboolean transpose,const GLfloat * value)682 void GL2Encoder::s_glUniformMatrix2fv(void *self , GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
683 {
684     GL2Encoder *ctx = (GL2Encoder*)self;
685     GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentProgram(),location);
686     ctx->m_glUniformMatrix2fv_enc(self, hostLoc, count, transpose, value);
687 }
688 
s_glUniformMatrix3fv(void * self,GLint location,GLsizei count,GLboolean transpose,const GLfloat * value)689 void GL2Encoder::s_glUniformMatrix3fv(void *self , GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
690 {
691     GL2Encoder *ctx = (GL2Encoder*)self;
692     GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentProgram(),location);
693     ctx->m_glUniformMatrix3fv_enc(self, hostLoc, count, transpose, value);
694 }
695 
s_glUniformMatrix4fv(void * self,GLint location,GLsizei count,GLboolean transpose,const GLfloat * value)696 void GL2Encoder::s_glUniformMatrix4fv(void *self , GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
697 {
698     GL2Encoder *ctx = (GL2Encoder*)self;
699     GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentProgram(),location);
700     ctx->m_glUniformMatrix4fv_enc(self, hostLoc, count, transpose, value);
701 }
702 
703