• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include "GL2Encoder.h"
18 #include <assert.h>
19 #include <ctype.h>
20 
21 #ifndef MIN
22 #define MIN(a, b) ((a) < (b) ? (a) : (b))
23 #endif
24 
25 static GLubyte *gVendorString= (GLubyte *) "Android";
26 static GLubyte *gRendererString= (GLubyte *) "Android HW-GLES 2.0";
27 static GLubyte *gVersionString= (GLubyte *) "OpenGL ES 2.0";
28 static GLubyte *gExtensionsString= (GLubyte *) ""; // no extensions at this point;
29 
30 #define SET_ERROR_IF(condition,err) if((condition)) {                            \
31         ALOGE("%s:%s:%d GL error 0x%x\n", __FILE__, __FUNCTION__, __LINE__, err); \
32         ctx->setError(err);                                    \
33         return;                                                  \
34     }
35 
36 
37 #define RET_AND_SET_ERROR_IF(condition,err,ret) if((condition)) {                \
38         ALOGE("%s:%s:%d GL error 0x%x\n", __FILE__, __FUNCTION__, __LINE__, err); \
39         ctx->setError(err);                                    \
40         return ret;                                              \
41     }
42 
43 
GL2Encoder(IOStream * stream)44 GL2Encoder::GL2Encoder(IOStream *stream) : gl2_encoder_context_t(stream)
45 {
46     m_initialized = false;
47     m_state = NULL;
48     m_error = GL_NO_ERROR;
49     m_num_compressedTextureFormats = 0;
50     m_compressedTextureFormats = NULL;
51     //overrides
52     m_glFlush_enc = set_glFlush(s_glFlush);
53     m_glPixelStorei_enc = set_glPixelStorei(s_glPixelStorei);
54     m_glGetString_enc = set_glGetString(s_glGetString);
55     m_glBindBuffer_enc = set_glBindBuffer(s_glBindBuffer);
56     m_glBufferData_enc = set_glBufferData(s_glBufferData);
57     m_glBufferSubData_enc = set_glBufferSubData(s_glBufferSubData);
58     m_glDeleteBuffers_enc = set_glDeleteBuffers(s_glDeleteBuffers);
59     m_glDrawArrays_enc = set_glDrawArrays(s_glDrawArrays);
60     m_glDrawElements_enc = set_glDrawElements(s_glDrawElements);
61     m_glGetIntegerv_enc = set_glGetIntegerv(s_glGetIntegerv);
62     m_glGetFloatv_enc = set_glGetFloatv(s_glGetFloatv);
63     m_glGetBooleanv_enc = set_glGetBooleanv(s_glGetBooleanv);
64     m_glVertexAttribPointer_enc = set_glVertexAttribPointer(s_glVertexAtrribPointer);
65     m_glEnableVertexAttribArray_enc = set_glEnableVertexAttribArray(s_glEnableVertexAttribArray);
66     m_glDisableVertexAttribArray_enc = set_glDisableVertexAttribArray(s_glDisableVertexAttribArray);
67     m_glGetVertexAttribiv_enc = set_glGetVertexAttribiv(s_glGetVertexAttribiv);
68     m_glGetVertexAttribfv_enc = set_glGetVertexAttribfv(s_glGetVertexAttribfv);
69     m_glGetVertexAttribPointerv = set_glGetVertexAttribPointerv(s_glGetVertexAttribPointerv);
70     set_glShaderSource(s_glShaderSource);
71     set_glFinish(s_glFinish);
72     m_glGetError_enc = set_glGetError(s_glGetError);
73     m_glLinkProgram_enc = set_glLinkProgram(s_glLinkProgram);
74     m_glDeleteProgram_enc = set_glDeleteProgram(s_glDeleteProgram);
75     m_glGetUniformiv_enc = set_glGetUniformiv(s_glGetUniformiv);
76     m_glGetUniformfv_enc = set_glGetUniformfv(s_glGetUniformfv);
77     m_glCreateProgram_enc = set_glCreateProgram(s_glCreateProgram);
78     m_glCreateShader_enc = set_glCreateShader(s_glCreateShader);
79     m_glDeleteShader_enc = set_glDeleteShader(s_glDeleteShader);
80     m_glAttachShader_enc = set_glAttachShader(s_glAttachShader);
81     m_glDetachShader_enc = set_glDetachShader(s_glDetachShader);
82     m_glGetAttachedShaders_enc = set_glGetAttachedShaders(s_glGetAttachedShaders);
83     m_glGetShaderSource_enc = set_glGetShaderSource(s_glGetShaderSource);
84     m_glGetShaderInfoLog_enc = set_glGetShaderInfoLog(s_glGetShaderInfoLog);
85     m_glGetProgramInfoLog_enc = set_glGetProgramInfoLog(s_glGetProgramInfoLog);
86 
87     m_glGetUniformLocation_enc = set_glGetUniformLocation(s_glGetUniformLocation);
88     m_glUseProgram_enc = set_glUseProgram(s_glUseProgram);
89 
90     m_glUniform1f_enc = set_glUniform1f(s_glUniform1f);
91     m_glUniform1fv_enc = set_glUniform1fv(s_glUniform1fv);
92     m_glUniform1i_enc = set_glUniform1i(s_glUniform1i);
93     m_glUniform1iv_enc = set_glUniform1iv(s_glUniform1iv);
94     m_glUniform2f_enc = set_glUniform2f(s_glUniform2f);
95     m_glUniform2fv_enc = set_glUniform2fv(s_glUniform2fv);
96     m_glUniform2i_enc = set_glUniform2i(s_glUniform2i);
97     m_glUniform2iv_enc = set_glUniform2iv(s_glUniform2iv);
98     m_glUniform3f_enc = set_glUniform3f(s_glUniform3f);
99     m_glUniform3fv_enc = set_glUniform3fv(s_glUniform3fv);
100     m_glUniform3i_enc = set_glUniform3i(s_glUniform3i);
101     m_glUniform3iv_enc = set_glUniform3iv(s_glUniform3iv);
102     m_glUniform4f_enc = set_glUniform4f(s_glUniform4f);
103     m_glUniform4fv_enc = set_glUniform4fv(s_glUniform4fv);
104     m_glUniform4i_enc = set_glUniform4i(s_glUniform4i);
105     m_glUniform4iv_enc = set_glUniform4iv(s_glUniform4iv);
106     m_glUniformMatrix2fv_enc = set_glUniformMatrix2fv(s_glUniformMatrix2fv);
107     m_glUniformMatrix3fv_enc = set_glUniformMatrix3fv(s_glUniformMatrix3fv);
108     m_glUniformMatrix4fv_enc = set_glUniformMatrix4fv(s_glUniformMatrix4fv);
109 
110     m_glActiveTexture_enc = set_glActiveTexture(s_glActiveTexture);
111     m_glBindTexture_enc = set_glBindTexture(s_glBindTexture);
112     m_glDeleteTextures_enc = set_glDeleteTextures(s_glDeleteTextures);
113     m_glGetTexParameterfv_enc = set_glGetTexParameterfv(s_glGetTexParameterfv);
114     m_glGetTexParameteriv_enc = set_glGetTexParameteriv(s_glGetTexParameteriv);
115     m_glTexParameterf_enc = set_glTexParameterf(s_glTexParameterf);
116     m_glTexParameterfv_enc = set_glTexParameterfv(s_glTexParameterfv);
117     m_glTexParameteri_enc = set_glTexParameteri(s_glTexParameteri);
118     m_glTexParameteriv_enc = set_glTexParameteriv(s_glTexParameteriv);
119 }
120 
~GL2Encoder()121 GL2Encoder::~GL2Encoder()
122 {
123     delete m_compressedTextureFormats;
124 }
125 
s_glGetError(void * self)126 GLenum GL2Encoder::s_glGetError(void * self)
127 {
128     GL2Encoder *ctx = (GL2Encoder *)self;
129     GLenum err = ctx->getError();
130     if(err != GL_NO_ERROR) {
131         ctx->setError(GL_NO_ERROR);
132         return err;
133     }
134 
135     return ctx->m_glGetError_enc(self);
136 
137 }
138 
s_glFlush(void * self)139 void GL2Encoder::s_glFlush(void *self)
140 {
141     GL2Encoder *ctx = (GL2Encoder *) self;
142     ctx->m_glFlush_enc(self);
143     ctx->m_stream->flush();
144 }
145 
s_glGetString(void * self,GLenum name)146 const GLubyte *GL2Encoder::s_glGetString(void *self, GLenum name)
147 {
148     GLubyte *retval =  (GLubyte *) "";
149     switch(name) {
150     case GL_VENDOR:
151         retval = gVendorString;
152         break;
153     case GL_RENDERER:
154         retval = gRendererString;
155         break;
156     case GL_VERSION:
157         retval = gVersionString;
158         break;
159     case GL_EXTENSIONS:
160         retval = gExtensionsString;
161         break;
162     }
163     return retval;
164 }
165 
s_glPixelStorei(void * self,GLenum param,GLint value)166 void GL2Encoder::s_glPixelStorei(void *self, GLenum param, GLint value)
167 {
168     GL2Encoder *ctx = (GL2Encoder *)self;
169     ctx->m_glPixelStorei_enc(ctx, param, value);
170     assert(ctx->m_state != NULL);
171     ctx->m_state->setPixelStore(param, value);
172 }
173 
174 
s_glBindBuffer(void * self,GLenum target,GLuint id)175 void GL2Encoder::s_glBindBuffer(void *self, GLenum target, GLuint id)
176 {
177     GL2Encoder *ctx = (GL2Encoder *) self;
178     assert(ctx->m_state != NULL);
179     ctx->m_state->bindBuffer(target, id);
180     // TODO set error state if needed;
181     ctx->m_glBindBuffer_enc(self, target, id);
182 }
183 
s_glBufferData(void * self,GLenum target,GLsizeiptr size,const GLvoid * data,GLenum usage)184 void GL2Encoder::s_glBufferData(void * self, GLenum target, GLsizeiptr size, const GLvoid * data, GLenum usage)
185 {
186     GL2Encoder *ctx = (GL2Encoder *) self;
187     GLuint bufferId = ctx->m_state->getBuffer(target);
188     SET_ERROR_IF(bufferId==0, GL_INVALID_OPERATION);
189     SET_ERROR_IF(size<0, GL_INVALID_VALUE);
190 
191     ctx->m_shared->updateBufferData(bufferId, size, (void*)data);
192     ctx->m_glBufferData_enc(self, target, size, data, usage);
193 }
194 
s_glBufferSubData(void * self,GLenum target,GLintptr offset,GLsizeiptr size,const GLvoid * data)195 void GL2Encoder::s_glBufferSubData(void * self, GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid * data)
196 {
197     GL2Encoder *ctx = (GL2Encoder *) self;
198     GLuint bufferId = ctx->m_state->getBuffer(target);
199     SET_ERROR_IF(bufferId==0, GL_INVALID_OPERATION);
200 
201     GLenum res = ctx->m_shared->subUpdateBufferData(bufferId, offset, size, (void*)data);
202     SET_ERROR_IF(res, res);
203 
204     ctx->m_glBufferSubData_enc(self, target, offset, size, data);
205 }
206 
s_glDeleteBuffers(void * self,GLsizei n,const GLuint * buffers)207 void GL2Encoder::s_glDeleteBuffers(void * self, GLsizei n, const GLuint * buffers)
208 {
209     GL2Encoder *ctx = (GL2Encoder *) self;
210     SET_ERROR_IF(n<0, GL_INVALID_VALUE);
211     for (int i=0; i<n; i++) {
212         ctx->m_shared->deleteBufferData(buffers[i]);
213         ctx->m_glDeleteBuffers_enc(self,1,&buffers[i]);
214     }
215 }
216 
s_glVertexAtrribPointer(void * self,GLuint indx,GLint size,GLenum type,GLboolean normalized,GLsizei stride,const GLvoid * ptr)217 void GL2Encoder::s_glVertexAtrribPointer(void *self, GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid * ptr)
218 {
219     GL2Encoder *ctx = (GL2Encoder *)self;
220     assert(ctx->m_state != NULL);
221     ctx->m_state->setState(indx, size, type, normalized, stride, ptr);
222 }
223 
s_glGetIntegerv(void * self,GLenum param,GLint * ptr)224 void GL2Encoder::s_glGetIntegerv(void *self, GLenum param, GLint *ptr)
225 {
226     GL2Encoder *ctx = (GL2Encoder *) self;
227     assert(ctx->m_state != NULL);
228     GLClientState* state = ctx->m_state;
229 
230     switch (param) {
231     case GL_NUM_SHADER_BINARY_FORMATS:
232         *ptr = 0;
233         break;
234     case GL_SHADER_BINARY_FORMATS:
235         // do nothing
236         break;
237 
238     case GL_COMPRESSED_TEXTURE_FORMATS: {
239         GLint *compressedTextureFormats = ctx->getCompressedTextureFormats();
240         if (ctx->m_num_compressedTextureFormats > 0 &&
241                 compressedTextureFormats != NULL) {
242             memcpy(ptr, compressedTextureFormats,
243                     ctx->m_num_compressedTextureFormats * sizeof(GLint));
244         }
245         break;
246     }
247 
248     case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS:
249     case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:
250     case GL_MAX_TEXTURE_IMAGE_UNITS:
251         ctx->m_glGetIntegerv_enc(self, param, ptr);
252         *ptr = MIN(*ptr, GLClientState::MAX_TEXTURE_UNITS);
253         break;
254 
255     case GL_TEXTURE_BINDING_2D:
256         *ptr = state->getBoundTexture(GL_TEXTURE_2D);
257         break;
258     case GL_TEXTURE_BINDING_EXTERNAL_OES:
259         *ptr = state->getBoundTexture(GL_TEXTURE_EXTERNAL_OES);
260         break;
261 
262     default:
263         if (!ctx->m_state->getClientStateParameter<GLint>(param, ptr)) {
264             ctx->m_glGetIntegerv_enc(self, param, ptr);
265         }
266         break;
267     }
268 }
269 
270 
s_glGetFloatv(void * self,GLenum param,GLfloat * ptr)271 void GL2Encoder::s_glGetFloatv(void *self, GLenum param, GLfloat *ptr)
272 {
273     GL2Encoder *ctx = (GL2Encoder *)self;
274     assert(ctx->m_state != NULL);
275     GLClientState* state = ctx->m_state;
276 
277     switch (param) {
278     case GL_NUM_SHADER_BINARY_FORMATS:
279         *ptr = 0;
280         break;
281     case GL_SHADER_BINARY_FORMATS:
282         // do nothing
283         break;
284 
285     case GL_COMPRESSED_TEXTURE_FORMATS: {
286         GLint *compressedTextureFormats = ctx->getCompressedTextureFormats();
287         if (ctx->m_num_compressedTextureFormats > 0 &&
288                 compressedTextureFormats != NULL) {
289             for (int i = 0; i < ctx->m_num_compressedTextureFormats; i++) {
290                 ptr[i] = (GLfloat) compressedTextureFormats[i];
291             }
292         }
293         break;
294     }
295 
296     case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS:
297     case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:
298     case GL_MAX_TEXTURE_IMAGE_UNITS:
299         ctx->m_glGetFloatv_enc(self, param, ptr);
300         *ptr = MIN(*ptr, (GLfloat)GLClientState::MAX_TEXTURE_UNITS);
301         break;
302 
303     case GL_TEXTURE_BINDING_2D:
304         *ptr = (GLfloat)state->getBoundTexture(GL_TEXTURE_2D);
305         break;
306     case GL_TEXTURE_BINDING_EXTERNAL_OES:
307         *ptr = (GLfloat)state->getBoundTexture(GL_TEXTURE_EXTERNAL_OES);
308         break;
309 
310     default:
311         if (!ctx->m_state->getClientStateParameter<GLfloat>(param, ptr)) {
312             ctx->m_glGetFloatv_enc(self, param, ptr);
313         }
314         break;
315     }
316 }
317 
318 
s_glGetBooleanv(void * self,GLenum param,GLboolean * ptr)319 void GL2Encoder::s_glGetBooleanv(void *self, GLenum param, GLboolean *ptr)
320 {
321     GL2Encoder *ctx = (GL2Encoder *)self;
322     assert(ctx->m_state != NULL);
323     GLClientState* state = ctx->m_state;
324 
325     switch (param) {
326     case GL_NUM_SHADER_BINARY_FORMATS:
327         *ptr = GL_FALSE;
328         break;
329     case GL_SHADER_BINARY_FORMATS:
330         // do nothing
331         break;
332 
333     case GL_COMPRESSED_TEXTURE_FORMATS: {
334         GLint *compressedTextureFormats = ctx->getCompressedTextureFormats();
335         if (ctx->m_num_compressedTextureFormats > 0 &&
336                 compressedTextureFormats != NULL) {
337             for (int i = 0; i < ctx->m_num_compressedTextureFormats; i++) {
338                 ptr[i] = compressedTextureFormats[i] != 0 ? GL_TRUE : GL_FALSE;
339             }
340         }
341         break;
342     }
343 
344     case GL_TEXTURE_BINDING_2D:
345         *ptr = state->getBoundTexture(GL_TEXTURE_2D) != 0 ? GL_TRUE : GL_FALSE;
346         break;
347     case GL_TEXTURE_BINDING_EXTERNAL_OES:
348         *ptr = state->getBoundTexture(GL_TEXTURE_EXTERNAL_OES) != 0
349                 ? GL_TRUE : GL_FALSE;
350         break;
351 
352     default:
353         if (!ctx->m_state->getClientStateParameter<GLboolean>(param, ptr)) {
354             ctx->m_glGetBooleanv_enc(self, param, ptr);
355         }
356         break;
357     }
358 }
359 
360 
s_glEnableVertexAttribArray(void * self,GLuint index)361 void GL2Encoder::s_glEnableVertexAttribArray(void *self, GLuint index)
362 {
363     GL2Encoder *ctx = (GL2Encoder *)self;
364     assert(ctx->m_state);
365     ctx->m_state->enable(index, 1);
366 }
367 
s_glDisableVertexAttribArray(void * self,GLuint index)368 void GL2Encoder::s_glDisableVertexAttribArray(void *self, GLuint index)
369 {
370     GL2Encoder *ctx = (GL2Encoder *)self;
371     assert(ctx->m_state);
372     ctx->m_state->enable(index, 0);
373 }
374 
375 
s_glGetVertexAttribiv(void * self,GLuint index,GLenum pname,GLint * params)376 void GL2Encoder::s_glGetVertexAttribiv(void *self, GLuint index, GLenum pname, GLint *params)
377 {
378     GL2Encoder *ctx = (GL2Encoder *)self;
379     assert(ctx->m_state);
380 
381     if (!ctx->m_state->getVertexAttribParameter<GLint>(index, pname, params)) {
382         ctx->m_glGetVertexAttribiv_enc(self, index, pname, params);
383     }
384 }
385 
s_glGetVertexAttribfv(void * self,GLuint index,GLenum pname,GLfloat * params)386 void GL2Encoder::s_glGetVertexAttribfv(void *self, GLuint index, GLenum pname, GLfloat *params)
387 {
388     GL2Encoder *ctx = (GL2Encoder *)self;
389     assert(ctx->m_state);
390 
391     if (!ctx->m_state->getVertexAttribParameter<GLfloat>(index, pname, params)) {
392         ctx->m_glGetVertexAttribfv_enc(self, index, pname, params);
393     }
394 }
395 
s_glGetVertexAttribPointerv(void * self,GLuint index,GLenum pname,GLvoid ** pointer)396 void GL2Encoder::s_glGetVertexAttribPointerv(void *self, GLuint index, GLenum pname, GLvoid **pointer)
397 {
398     GL2Encoder *ctx = (GL2Encoder *)self;
399     if (ctx->m_state == NULL) return;
400 
401     const GLClientState::VertexAttribState *va_state = ctx->m_state->getState(index);
402     if (va_state != NULL) {
403         *pointer = va_state->data;
404     }
405 }
406 
407 
sendVertexAttributes(GLint first,GLsizei count)408 void GL2Encoder::sendVertexAttributes(GLint first, GLsizei count)
409 {
410     assert(m_state);
411 
412     for (int i = 0; i < m_state->nLocations(); i++) {
413         bool enableDirty;
414         const GLClientState::VertexAttribState *state = m_state->getStateAndEnableDirty(i, &enableDirty);
415 
416         if (!state) {
417             continue;
418         }
419 
420         if (!enableDirty && !state->enabled) {
421             continue;
422         }
423 
424 
425         if (state->enabled) {
426             m_glEnableVertexAttribArray_enc(this, i);
427 
428             unsigned int datalen = state->elementSize * count;
429             int stride = state->stride == 0 ? state->elementSize : state->stride;
430             int firstIndex = stride * first;
431 
432             this->m_glBindBuffer_enc(this, GL_ARRAY_BUFFER, state->bufferObject);
433             if (state->bufferObject == 0) {
434                 this->glVertexAttribPointerData(this, i, state->size, state->type, state->normalized, state->stride,
435                                                 (unsigned char *)state->data + firstIndex, datalen);
436             } else {
437                 this->glVertexAttribPointerOffset(this, i, state->size, state->type, state->normalized, state->stride,
438                                                   (uintptr_t) state->data + firstIndex);
439             }
440             this->m_glBindBuffer_enc(this, GL_ARRAY_BUFFER, m_state->currentArrayVbo());
441         } else {
442             this->m_glDisableVertexAttribArray_enc(this, i);
443         }
444     }
445 }
446 
s_glDrawArrays(void * self,GLenum mode,GLint first,GLsizei count)447 void GL2Encoder::s_glDrawArrays(void *self, GLenum mode, GLint first, GLsizei count)
448 {
449     GL2Encoder *ctx = (GL2Encoder *)self;
450     ctx->sendVertexAttributes(first, count);
451     ctx->m_glDrawArrays_enc(ctx, mode, 0, count);
452 }
453 
454 
s_glDrawElements(void * self,GLenum mode,GLsizei count,GLenum type,const void * indices)455 void GL2Encoder::s_glDrawElements(void *self, GLenum mode, GLsizei count, GLenum type, const void *indices)
456 {
457 
458     GL2Encoder *ctx = (GL2Encoder *)self;
459     assert(ctx->m_state != NULL);
460     SET_ERROR_IF(count<0, GL_INVALID_VALUE);
461 
462     bool has_immediate_arrays = false;
463     bool has_indirect_arrays = false;
464     int nLocations = ctx->m_state->nLocations();
465 
466     for (int i = 0; i < nLocations; i++) {
467         const GLClientState::VertexAttribState *state = ctx->m_state->getState(i);
468         if (state->enabled) {
469             if (state->bufferObject != 0) {
470                 has_indirect_arrays = true;
471             } else {
472                 has_immediate_arrays = true;
473             }
474         }
475     }
476 
477     if (!has_immediate_arrays && !has_indirect_arrays) {
478         ALOGE("glDrawElements: no data bound to the command - ignoring\n");
479         return;
480     }
481 
482     bool adjustIndices = true;
483     if (ctx->m_state->currentIndexVbo() != 0) {
484         if (!has_immediate_arrays) {
485             ctx->sendVertexAttributes(0, count);
486             ctx->m_glBindBuffer_enc(self, GL_ELEMENT_ARRAY_BUFFER, ctx->m_state->currentIndexVbo());
487             ctx->glDrawElementsOffset(ctx, mode, count, type, (uintptr_t)indices);
488             adjustIndices = false;
489         } else {
490             BufferData * buf = ctx->m_shared->getBufferData(ctx->m_state->currentIndexVbo());
491             ctx->m_glBindBuffer_enc(self, GL_ELEMENT_ARRAY_BUFFER, 0);
492             indices = (void*)((GLintptr)buf->m_fixedBuffer.ptr() + (GLintptr)indices);
493         }
494     }
495     if (adjustIndices) {
496         void *adjustedIndices = (void*)indices;
497         int minIndex = 0, maxIndex = 0;
498 
499         switch(type) {
500         case GL_BYTE:
501         case GL_UNSIGNED_BYTE:
502             GLUtils::minmax<unsigned char>((unsigned char *)indices, count, &minIndex, &maxIndex);
503             if (minIndex != 0) {
504                 adjustedIndices =  ctx->m_fixedBuffer.alloc(glSizeof(type) * count);
505                 GLUtils::shiftIndices<unsigned char>((unsigned char *)indices,
506                                                  (unsigned char *)adjustedIndices,
507                                                  count, -minIndex);
508             }
509             break;
510         case GL_SHORT:
511         case GL_UNSIGNED_SHORT:
512             GLUtils::minmax<unsigned short>((unsigned short *)indices, count, &minIndex, &maxIndex);
513             if (minIndex != 0) {
514                 adjustedIndices = ctx->m_fixedBuffer.alloc(glSizeof(type) * count);
515                 GLUtils::shiftIndices<unsigned short>((unsigned short *)indices,
516                                                   (unsigned short *)adjustedIndices,
517                                                   count, -minIndex);
518             }
519             break;
520         default:
521             ALOGE("unsupported index buffer type %d\n", type);
522         }
523         if (has_indirect_arrays || 1) {
524             ctx->sendVertexAttributes(minIndex, maxIndex - minIndex + 1);
525             ctx->glDrawElementsData(ctx, mode, count, type, adjustedIndices,
526                                     count * glSizeof(type));
527             // XXX - OPTIMIZATION (see the other else branch) should be implemented
528             if(!has_indirect_arrays) {
529                 //ALOGD("unoptimized drawelements !!!\n");
530             }
531         } else {
532             // we are all direct arrays and immidate mode index array -
533             // rebuild the arrays and the index array;
534             ALOGE("glDrawElements: direct index & direct buffer data - will be implemented in later versions;\n");
535         }
536     }
537 }
538 
539 
getCompressedTextureFormats()540 GLint * GL2Encoder::getCompressedTextureFormats()
541 {
542     if (m_compressedTextureFormats == NULL) {
543         this->glGetIntegerv(this, GL_NUM_COMPRESSED_TEXTURE_FORMATS,
544                             &m_num_compressedTextureFormats);
545         if (m_num_compressedTextureFormats > 0) {
546             // get number of texture formats;
547             m_compressedTextureFormats = new GLint[m_num_compressedTextureFormats];
548             this->glGetCompressedTextureFormats(this, m_num_compressedTextureFormats, m_compressedTextureFormats);
549         }
550     }
551     return m_compressedTextureFormats;
552 }
553 
554 // Replace uses of samplerExternalOES with sampler2D, recording the names of
555 // modified shaders in data. Also remove
556 //   #extension GL_OES_EGL_image_external : require
557 // statements.
558 //
559 // This implementation assumes the input has already been pre-processed. If not,
560 // a few cases will be mishandled:
561 //
562 // 1. "mySampler" will be incorrectly recorded as being a samplerExternalOES in
563 //    the following code:
564 //      #if 1
565 //      uniform sampler2D mySampler;
566 //      #else
567 //      uniform samplerExternalOES mySampler;
568 //      #endif
569 //
570 // 2. Comments that look like sampler declarations will be incorrectly modified
571 //    and recorded:
572 //      // samplerExternalOES hahaFooledYou
573 //
574 // 3. However, GLSL ES does not have a concatentation operator, so things like
575 //    this (valid in C) are invalid and not a problem:
576 //      #define SAMPLER(TYPE, NAME) uniform sampler#TYPE NAME
577 //      SAMPLER(ExternalOES, mySampler);
578 //
replaceSamplerExternalWith2D(char * const str,ShaderData * const data)579 static bool replaceSamplerExternalWith2D(char* const str, ShaderData* const data)
580 {
581     static const char STR_HASH_EXTENSION[] = "#extension";
582     static const char STR_GL_OES_EGL_IMAGE_EXTERNAL[] = "GL_OES_EGL_image_external";
583     static const char STR_SAMPLER_EXTERNAL_OES[] = "samplerExternalOES";
584     static const char STR_SAMPLER2D_SPACE[]      = "sampler2D         ";
585 
586     // -- overwrite all "#extension GL_OES_EGL_image_external : xxx" statements
587     char* c = str;
588     while ((c = strstr(c, STR_HASH_EXTENSION))) {
589         char* start = c;
590         c += sizeof(STR_HASH_EXTENSION)-1;
591         while (isspace(*c) && *c != '\0') {
592             c++;
593         }
594         if (strncmp(c, STR_GL_OES_EGL_IMAGE_EXTERNAL,
595                 sizeof(STR_GL_OES_EGL_IMAGE_EXTERNAL)-1) == 0)
596         {
597             // #extension statements are terminated by end of line
598             c = start;
599             while (*c != '\0' && *c != '\r' && *c != '\n') {
600                 *c++ = ' ';
601             }
602         }
603     }
604 
605     // -- replace "samplerExternalOES" with "sampler2D" and record name
606     c = str;
607     while ((c = strstr(c, STR_SAMPLER_EXTERNAL_OES))) {
608         // Make sure "samplerExternalOES" isn't a substring of a larger token
609         if (c == str || !isspace(*(c-1))) {
610             c++;
611             continue;
612         }
613         char* sampler_start = c;
614         c += sizeof(STR_SAMPLER_EXTERNAL_OES)-1;
615         if (!isspace(*c) && *c != '\0') {
616             continue;
617         }
618 
619         // capture sampler name
620         while (isspace(*c) && *c != '\0') {
621             c++;
622         }
623         if (!isalpha(*c) && *c != '_') {
624             // not an identifier
625             return false;
626         }
627         char* name_start = c;
628         do {
629             c++;
630         } while (isalnum(*c) || *c == '_');
631         data->samplerExternalNames.push_back(
632                 android::String8(name_start, c - name_start));
633 
634         // memcpy instead of strcpy since we don't want the NUL terminator
635         memcpy(sampler_start, STR_SAMPLER2D_SPACE, sizeof(STR_SAMPLER2D_SPACE)-1);
636     }
637 
638     return true;
639 }
640 
s_glShaderSource(void * self,GLuint shader,GLsizei count,const GLchar * const * string,const GLint * length)641 void GL2Encoder::s_glShaderSource(void *self, GLuint shader, GLsizei count, const GLchar *const *string, const GLint *length)
642 {
643     GL2Encoder* ctx = (GL2Encoder*)self;
644     ShaderData* shaderData = ctx->m_shared->getShaderData(shader);
645     SET_ERROR_IF(!shaderData, GL_INVALID_VALUE);
646 
647     int len = glUtilsCalcShaderSourceLen((char**)string, (GLint*)length, count);
648     char *str = new char[len + 1];
649     glUtilsPackStrings(str, (char**)string, (GLint*)length, count);
650 
651     // TODO: pre-process str before calling replaceSamplerExternalWith2D().
652     // Perhaps we can borrow Mesa's pre-processor?
653 
654     if (!replaceSamplerExternalWith2D(str, shaderData)) {
655         delete str;
656         ctx->setError(GL_OUT_OF_MEMORY);
657         return;
658     }
659 
660     ctx->glShaderString(ctx, shader, str, len + 1);
661     delete str;
662 }
663 
s_glFinish(void * self)664 void GL2Encoder::s_glFinish(void *self)
665 {
666     GL2Encoder *ctx = (GL2Encoder *)self;
667     ctx->glFinishRoundTrip(self);
668 }
669 
s_glLinkProgram(void * self,GLuint program)670 void GL2Encoder::s_glLinkProgram(void * self, GLuint program)
671 {
672     GL2Encoder *ctx = (GL2Encoder *)self;
673     ctx->m_glLinkProgram_enc(self, program);
674 
675     GLint linkStatus = 0;
676     ctx->glGetProgramiv(self,program,GL_LINK_STATUS,&linkStatus);
677     if (!linkStatus)
678         return;
679 
680     //get number of active uniforms in the program
681     GLint numUniforms=0;
682     ctx->glGetProgramiv(self, program, GL_ACTIVE_UNIFORMS, &numUniforms);
683     ctx->m_shared->initProgramData(program,numUniforms);
684 
685     //get the length of the longest uniform name
686     GLint maxLength=0;
687     ctx->glGetProgramiv(self, program, GL_ACTIVE_UNIFORM_MAX_LENGTH, &maxLength);
688 
689     GLint size;
690     GLenum type;
691     GLchar *name = new GLchar[maxLength+1];
692     GLint location;
693     //for each active uniform, get its size and starting location.
694     for (GLint i=0 ; i<numUniforms ; ++i)
695     {
696         ctx->glGetActiveUniform(self, program, i, maxLength, NULL, &size, &type, name);
697         location = ctx->m_glGetUniformLocation_enc(self, program, name);
698         ctx->m_shared->setProgramIndexInfo(program, i, location, size, type, name);
699     }
700     ctx->m_shared->setupLocationShiftWAR(program);
701 
702     delete[] name;
703 }
704 
s_glDeleteProgram(void * self,GLuint program)705 void GL2Encoder::s_glDeleteProgram(void *self, GLuint program)
706 {
707     GL2Encoder *ctx = (GL2Encoder*)self;
708     ctx->m_glDeleteProgram_enc(self, program);
709 
710     ctx->m_shared->deleteProgramData(program);
711 }
712 
s_glGetUniformiv(void * self,GLuint program,GLint location,GLint * params)713 void GL2Encoder::s_glGetUniformiv(void *self, GLuint program, GLint location, GLint* params)
714 {
715     GL2Encoder *ctx = (GL2Encoder*)self;
716     SET_ERROR_IF(!ctx->m_shared->isProgram(program), GL_INVALID_VALUE);
717     SET_ERROR_IF(!ctx->m_shared->isProgramInitialized(program), GL_INVALID_OPERATION);
718     GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
719     SET_ERROR_IF(ctx->m_shared->getProgramUniformType(program,hostLoc)==0, GL_INVALID_OPERATION);
720     ctx->m_glGetUniformiv_enc(self, program, hostLoc, params);
721 }
s_glGetUniformfv(void * self,GLuint program,GLint location,GLfloat * params)722 void GL2Encoder::s_glGetUniformfv(void *self, GLuint program, GLint location, GLfloat* params)
723 {
724     GL2Encoder *ctx = (GL2Encoder*)self;
725     SET_ERROR_IF(!ctx->m_shared->isProgram(program), GL_INVALID_VALUE);
726     SET_ERROR_IF(!ctx->m_shared->isProgramInitialized(program), GL_INVALID_OPERATION);
727     GLint hostLoc = ctx->m_shared->locationWARAppToHost(program,location);
728     SET_ERROR_IF(ctx->m_shared->getProgramUniformType(program,hostLoc)==0, GL_INVALID_OPERATION);
729     ctx->m_glGetUniformfv_enc(self, program, hostLoc, params);
730 }
731 
s_glCreateProgram(void * self)732 GLuint GL2Encoder::s_glCreateProgram(void * self)
733 {
734     GL2Encoder *ctx = (GL2Encoder*)self;
735     GLuint program = ctx->m_glCreateProgram_enc(self);
736     if (program!=0)
737         ctx->m_shared->addProgramData(program);
738     return program;
739 }
740 
s_glCreateShader(void * self,GLenum shaderType)741 GLuint GL2Encoder::s_glCreateShader(void *self, GLenum shaderType)
742 {
743     GL2Encoder *ctx = (GL2Encoder*)self;
744     GLuint shader = ctx->m_glCreateShader_enc(self, shaderType);
745     if (shader != 0) {
746         if (!ctx->m_shared->addShaderData(shader)) {
747             ctx->m_glDeleteShader_enc(self, shader);
748             return 0;
749         }
750     }
751     return shader;
752 }
753 
s_glGetAttachedShaders(void * self,GLuint program,GLsizei maxCount,GLsizei * count,GLuint * shaders)754 void GL2Encoder::s_glGetAttachedShaders(void *self, GLuint program, GLsizei maxCount,
755         GLsizei* count, GLuint* shaders)
756 {
757     GL2Encoder *ctx = (GL2Encoder*)self;
758     SET_ERROR_IF(maxCount < 0, GL_INVALID_VALUE);
759     ctx->m_glGetAttachedShaders_enc(self, program, maxCount, count, shaders);
760 }
761 
s_glGetShaderSource(void * self,GLuint shader,GLsizei bufsize,GLsizei * length,GLchar * source)762 void GL2Encoder::s_glGetShaderSource(void *self, GLuint shader, GLsizei bufsize,
763             GLsizei* length, GLchar* source)
764 {
765     GL2Encoder *ctx = (GL2Encoder*)self;
766     SET_ERROR_IF(bufsize < 0, GL_INVALID_VALUE);
767     ctx->m_glGetShaderSource_enc(self, shader, bufsize, length, source);
768 }
769 
s_glGetShaderInfoLog(void * self,GLuint shader,GLsizei bufsize,GLsizei * length,GLchar * infolog)770 void GL2Encoder::s_glGetShaderInfoLog(void *self, GLuint shader, GLsizei bufsize,
771         GLsizei* length, GLchar* infolog)
772 {
773     GL2Encoder *ctx = (GL2Encoder*)self;
774     SET_ERROR_IF(bufsize < 0, GL_INVALID_VALUE);
775     ctx->m_glGetShaderInfoLog_enc(self, shader, bufsize, length, infolog);
776 }
777 
s_glGetProgramInfoLog(void * self,GLuint program,GLsizei bufsize,GLsizei * length,GLchar * infolog)778 void GL2Encoder::s_glGetProgramInfoLog(void *self, GLuint program, GLsizei bufsize,
779         GLsizei* length, GLchar* infolog)
780 {
781     GL2Encoder *ctx = (GL2Encoder*)self;
782     SET_ERROR_IF(bufsize < 0, GL_INVALID_VALUE);
783     ctx->m_glGetProgramInfoLog_enc(self, program, bufsize, length, infolog);
784 }
785 
s_glDeleteShader(void * self,GLenum shader)786 void GL2Encoder::s_glDeleteShader(void *self, GLenum shader)
787 {
788     GL2Encoder *ctx = (GL2Encoder*)self;
789     ctx->m_glDeleteShader_enc(self,shader);
790     ctx->m_shared->unrefShaderData(shader);
791 }
792 
s_glAttachShader(void * self,GLuint program,GLuint shader)793 void GL2Encoder::s_glAttachShader(void *self, GLuint program, GLuint shader)
794 {
795     GL2Encoder *ctx = (GL2Encoder*)self;
796     ctx->m_glAttachShader_enc(self, program, shader);
797     ctx->m_shared->attachShader(program, shader);
798 }
799 
s_glDetachShader(void * self,GLuint program,GLuint shader)800 void GL2Encoder::s_glDetachShader(void *self, GLuint program, GLuint shader)
801 {
802     GL2Encoder *ctx = (GL2Encoder*)self;
803     ctx->m_glDetachShader_enc(self, program, shader);
804     ctx->m_shared->detachShader(program, shader);
805 }
806 
s_glGetUniformLocation(void * self,GLuint program,const GLchar * name)807 int GL2Encoder::s_glGetUniformLocation(void *self, GLuint program, const GLchar *name)
808 {
809     if (!name) return -1;
810 
811     GL2Encoder *ctx = (GL2Encoder*)self;
812 
813     // if we need the uniform location WAR
814     // parse array index from the end of the name string
815     int arrIndex = 0;
816     bool needLocationWAR = ctx->m_shared->needUniformLocationWAR(program);
817     if (needLocationWAR) {
818         int namelen = strlen(name);
819         if (name[namelen-1] == ']') {
820             char *brace = strrchr(name,'[');
821             if (!brace || sscanf(brace+1,"%d",&arrIndex) != 1) {
822                 return -1;
823             }
824 
825         }
826     }
827 
828     int hostLoc = ctx->m_glGetUniformLocation_enc(self, program, name);
829     if (hostLoc >= 0 && needLocationWAR) {
830         return ctx->m_shared->locationWARHostToApp(program, hostLoc, arrIndex);
831     }
832     return hostLoc;
833 }
834 
updateHostTexture2DBinding(GLenum texUnit,GLenum newTarget)835 bool GL2Encoder::updateHostTexture2DBinding(GLenum texUnit, GLenum newTarget)
836 {
837     if (newTarget != GL_TEXTURE_2D && newTarget != GL_TEXTURE_EXTERNAL_OES)
838         return false;
839 
840     m_state->setActiveTextureUnit(texUnit);
841 
842     GLenum oldTarget = m_state->getPriorityEnabledTarget(GL_TEXTURE_2D);
843     if (newTarget != oldTarget) {
844         if (newTarget == GL_TEXTURE_EXTERNAL_OES) {
845             m_state->disableTextureTarget(GL_TEXTURE_2D);
846             m_state->enableTextureTarget(GL_TEXTURE_EXTERNAL_OES);
847         } else {
848             m_state->disableTextureTarget(GL_TEXTURE_EXTERNAL_OES);
849             m_state->enableTextureTarget(GL_TEXTURE_2D);
850         }
851         m_glActiveTexture_enc(this, texUnit);
852         m_glBindTexture_enc(this, GL_TEXTURE_2D,
853                 m_state->getBoundTexture(newTarget));
854         return true;
855     }
856 
857     return false;
858 }
859 
s_glUseProgram(void * self,GLuint program)860 void GL2Encoder::s_glUseProgram(void *self, GLuint program)
861 {
862     GL2Encoder *ctx = (GL2Encoder*)self;
863     GLClientState* state = ctx->m_state;
864     GLSharedGroupPtr shared = ctx->m_shared;
865 
866     ctx->m_glUseProgram_enc(self, program);
867     ctx->m_state->setCurrentProgram(program);
868 
869     GLenum origActiveTexture = state->getActiveTextureUnit();
870     GLenum hostActiveTexture = origActiveTexture;
871     GLint samplerIdx = -1;
872     GLint samplerVal;
873     GLenum samplerTarget;
874     while ((samplerIdx = shared->getNextSamplerUniform(program, samplerIdx, &samplerVal, &samplerTarget)) != -1) {
875         if (samplerVal < 0 || samplerVal >= GLClientState::MAX_TEXTURE_UNITS)
876             continue;
877         if (ctx->updateHostTexture2DBinding(GL_TEXTURE0 + samplerVal,
878                 samplerTarget))
879         {
880             hostActiveTexture = GL_TEXTURE0 + samplerVal;
881         }
882     }
883     state->setActiveTextureUnit(origActiveTexture);
884     if (hostActiveTexture != origActiveTexture) {
885         ctx->m_glActiveTexture_enc(self, origActiveTexture);
886     }
887 }
888 
s_glUniform1f(void * self,GLint location,GLfloat x)889 void GL2Encoder::s_glUniform1f(void *self , GLint location, GLfloat x)
890 {
891     GL2Encoder *ctx = (GL2Encoder*)self;
892     GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentProgram(),location);
893     ctx->m_glUniform1f_enc(self, hostLoc, x);
894 }
895 
s_glUniform1fv(void * self,GLint location,GLsizei count,const GLfloat * v)896 void GL2Encoder::s_glUniform1fv(void *self , GLint location, GLsizei count, const GLfloat* v)
897 {
898     GL2Encoder *ctx = (GL2Encoder*)self;
899     GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentProgram(),location);
900     ctx->m_glUniform1fv_enc(self, hostLoc, count, v);
901 }
902 
s_glUniform1i(void * self,GLint location,GLint x)903 void GL2Encoder::s_glUniform1i(void *self , GLint location, GLint x)
904 {
905     GL2Encoder *ctx = (GL2Encoder*)self;
906     GLClientState* state = ctx->m_state;
907     GLSharedGroupPtr shared = ctx->m_shared;
908 
909     GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentProgram(),location);
910     ctx->m_glUniform1i_enc(self, hostLoc, x);
911 
912     GLenum target;
913     if (shared->setSamplerUniform(state->currentProgram(), location, x, &target)) {
914         GLenum origActiveTexture = state->getActiveTextureUnit();
915         if (ctx->updateHostTexture2DBinding(GL_TEXTURE0 + x, target)) {
916             ctx->m_glActiveTexture_enc(self, origActiveTexture);
917         }
918         state->setActiveTextureUnit(origActiveTexture);
919     }
920 }
921 
s_glUniform1iv(void * self,GLint location,GLsizei count,const GLint * v)922 void GL2Encoder::s_glUniform1iv(void *self , GLint location, GLsizei count, const GLint* v)
923 {
924     GL2Encoder *ctx = (GL2Encoder*)self;
925     GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentProgram(),location);
926     ctx->m_glUniform1iv_enc(self, hostLoc, count, v);
927 }
928 
s_glUniform2f(void * self,GLint location,GLfloat x,GLfloat y)929 void GL2Encoder::s_glUniform2f(void *self , GLint location, GLfloat x, GLfloat y)
930 {
931     GL2Encoder *ctx = (GL2Encoder*)self;
932     GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentProgram(),location);
933     ctx->m_glUniform2f_enc(self, hostLoc, x, y);
934 }
935 
s_glUniform2fv(void * self,GLint location,GLsizei count,const GLfloat * v)936 void GL2Encoder::s_glUniform2fv(void *self , GLint location, GLsizei count, const GLfloat* v)
937 {
938     GL2Encoder *ctx = (GL2Encoder*)self;
939     GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentProgram(),location);
940     ctx->m_glUniform2fv_enc(self, hostLoc, count, v);
941 }
942 
s_glUniform2i(void * self,GLint location,GLint x,GLint y)943 void GL2Encoder::s_glUniform2i(void *self , GLint location, GLint x, GLint y)
944 {
945     GL2Encoder *ctx = (GL2Encoder*)self;
946     GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentProgram(),location);
947     ctx->m_glUniform2i_enc(self, hostLoc, x, y);
948 }
949 
s_glUniform2iv(void * self,GLint location,GLsizei count,const GLint * v)950 void GL2Encoder::s_glUniform2iv(void *self , GLint location, GLsizei count, const GLint* v)
951 {
952     GL2Encoder *ctx = (GL2Encoder*)self;
953     GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentProgram(),location);
954     ctx->m_glUniform2iv_enc(self, hostLoc, count, v);
955 }
956 
s_glUniform3f(void * self,GLint location,GLfloat x,GLfloat y,GLfloat z)957 void GL2Encoder::s_glUniform3f(void *self , GLint location, GLfloat x, GLfloat y, GLfloat z)
958 {
959     GL2Encoder *ctx = (GL2Encoder*)self;
960     GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentProgram(),location);
961     ctx->m_glUniform3f_enc(self, hostLoc, x, y, z);
962 }
963 
s_glUniform3fv(void * self,GLint location,GLsizei count,const GLfloat * v)964 void GL2Encoder::s_glUniform3fv(void *self , GLint location, GLsizei count, const GLfloat* v)
965 {
966     GL2Encoder *ctx = (GL2Encoder*)self;
967     GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentProgram(),location);
968     ctx->m_glUniform3fv_enc(self, hostLoc, count, v);
969 }
970 
s_glUniform3i(void * self,GLint location,GLint x,GLint y,GLint z)971 void GL2Encoder::s_glUniform3i(void *self , GLint location, GLint x, GLint y, GLint z)
972 {
973     GL2Encoder *ctx = (GL2Encoder*)self;
974     GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentProgram(),location);
975     ctx->m_glUniform3i_enc(self, hostLoc, x, y, z);
976 }
977 
s_glUniform3iv(void * self,GLint location,GLsizei count,const GLint * v)978 void GL2Encoder::s_glUniform3iv(void *self , GLint location, GLsizei count, const GLint* v)
979 {
980     GL2Encoder *ctx = (GL2Encoder*)self;
981     GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentProgram(),location);
982     ctx->m_glUniform3iv_enc(self, hostLoc, count, v);
983 }
984 
s_glUniform4f(void * self,GLint location,GLfloat x,GLfloat y,GLfloat z,GLfloat w)985 void GL2Encoder::s_glUniform4f(void *self , GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
986 {
987     GL2Encoder *ctx = (GL2Encoder*)self;
988     GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentProgram(),location);
989     ctx->m_glUniform4f_enc(self, hostLoc, x, y, z, w);
990 }
991 
s_glUniform4fv(void * self,GLint location,GLsizei count,const GLfloat * v)992 void GL2Encoder::s_glUniform4fv(void *self , GLint location, GLsizei count, const GLfloat* v)
993 {
994     GL2Encoder *ctx = (GL2Encoder*)self;
995     GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentProgram(),location);
996     ctx->m_glUniform4fv_enc(self, hostLoc, count, v);
997 }
998 
s_glUniform4i(void * self,GLint location,GLint x,GLint y,GLint z,GLint w)999 void GL2Encoder::s_glUniform4i(void *self , GLint location, GLint x, GLint y, GLint z, GLint w)
1000 {
1001     GL2Encoder *ctx = (GL2Encoder*)self;
1002     GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentProgram(),location);
1003     ctx->m_glUniform4i_enc(self, hostLoc, x, y, z, w);
1004 }
1005 
s_glUniform4iv(void * self,GLint location,GLsizei count,const GLint * v)1006 void GL2Encoder::s_glUniform4iv(void *self , GLint location, GLsizei count, const GLint* v)
1007 {
1008     GL2Encoder *ctx = (GL2Encoder*)self;
1009     GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentProgram(),location);
1010     ctx->m_glUniform4iv_enc(self, hostLoc, count, v);
1011 }
1012 
s_glUniformMatrix2fv(void * self,GLint location,GLsizei count,GLboolean transpose,const GLfloat * value)1013 void GL2Encoder::s_glUniformMatrix2fv(void *self , GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
1014 {
1015     GL2Encoder *ctx = (GL2Encoder*)self;
1016     GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentProgram(),location);
1017     ctx->m_glUniformMatrix2fv_enc(self, hostLoc, count, transpose, value);
1018 }
1019 
s_glUniformMatrix3fv(void * self,GLint location,GLsizei count,GLboolean transpose,const GLfloat * value)1020 void GL2Encoder::s_glUniformMatrix3fv(void *self , GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
1021 {
1022     GL2Encoder *ctx = (GL2Encoder*)self;
1023     GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentProgram(),location);
1024     ctx->m_glUniformMatrix3fv_enc(self, hostLoc, count, transpose, value);
1025 }
1026 
s_glUniformMatrix4fv(void * self,GLint location,GLsizei count,GLboolean transpose,const GLfloat * value)1027 void GL2Encoder::s_glUniformMatrix4fv(void *self , GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
1028 {
1029     GL2Encoder *ctx = (GL2Encoder*)self;
1030     GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentProgram(),location);
1031     ctx->m_glUniformMatrix4fv_enc(self, hostLoc, count, transpose, value);
1032 }
1033 
s_glActiveTexture(void * self,GLenum texture)1034 void GL2Encoder::s_glActiveTexture(void* self, GLenum texture)
1035 {
1036     GL2Encoder* ctx = (GL2Encoder*)self;
1037     GLClientState* state = ctx->m_state;
1038     GLenum err;
1039 
1040     SET_ERROR_IF((err = state->setActiveTextureUnit(texture)) != GL_NO_ERROR, err);
1041 
1042     ctx->m_glActiveTexture_enc(ctx, texture);
1043 }
1044 
s_glBindTexture(void * self,GLenum target,GLuint texture)1045 void GL2Encoder::s_glBindTexture(void* self, GLenum target, GLuint texture)
1046 {
1047     GL2Encoder* ctx = (GL2Encoder*)self;
1048     GLClientState* state = ctx->m_state;
1049     GLenum err;
1050     GLboolean firstUse;
1051 
1052     SET_ERROR_IF((err = state->bindTexture(target, texture, &firstUse)) != GL_NO_ERROR, err);
1053 
1054     if (target != GL_TEXTURE_2D && target != GL_TEXTURE_EXTERNAL_OES) {
1055         ctx->m_glBindTexture_enc(ctx, target, texture);
1056         return;
1057     }
1058 
1059     GLenum priorityTarget = state->getPriorityEnabledTarget(GL_TEXTURE_2D);
1060 
1061     if (target == GL_TEXTURE_EXTERNAL_OES && firstUse) {
1062         ctx->m_glBindTexture_enc(ctx, GL_TEXTURE_2D, texture);
1063         ctx->m_glTexParameteri_enc(ctx, GL_TEXTURE_2D,
1064                 GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1065         ctx->m_glTexParameteri_enc(ctx, GL_TEXTURE_2D,
1066                 GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1067         ctx->m_glTexParameteri_enc(ctx, GL_TEXTURE_2D,
1068                 GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1069 
1070         if (target != priorityTarget) {
1071             ctx->m_glBindTexture_enc(ctx, GL_TEXTURE_2D,
1072                     state->getBoundTexture(GL_TEXTURE_2D));
1073         }
1074     }
1075 
1076     if (target == priorityTarget) {
1077         ctx->m_glBindTexture_enc(ctx, GL_TEXTURE_2D, texture);
1078     }
1079 }
1080 
s_glDeleteTextures(void * self,GLsizei n,const GLuint * textures)1081 void GL2Encoder::s_glDeleteTextures(void* self, GLsizei n, const GLuint* textures)
1082 {
1083     GL2Encoder* ctx = (GL2Encoder*)self;
1084     GLClientState* state = ctx->m_state;
1085 
1086     state->deleteTextures(n, textures);
1087     ctx->m_glDeleteTextures_enc(ctx, n, textures);
1088 }
1089 
s_glGetTexParameterfv(void * self,GLenum target,GLenum pname,GLfloat * params)1090 void GL2Encoder::s_glGetTexParameterfv(void* self,
1091         GLenum target, GLenum pname, GLfloat* params)
1092 {
1093     GL2Encoder* ctx = (GL2Encoder*)self;
1094     const GLClientState* state = ctx->m_state;
1095 
1096     if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
1097         ctx->override2DTextureTarget(target);
1098         ctx->m_glGetTexParameterfv_enc(ctx, GL_TEXTURE_2D, pname, params);
1099         ctx->restore2DTextureTarget();
1100     } else {
1101         ctx->m_glGetTexParameterfv_enc(ctx, target, pname, params);
1102     }
1103 }
1104 
s_glGetTexParameteriv(void * self,GLenum target,GLenum pname,GLint * params)1105 void GL2Encoder::s_glGetTexParameteriv(void* self,
1106         GLenum target, GLenum pname, GLint* params)
1107 {
1108     GL2Encoder* ctx = (GL2Encoder*)self;
1109     const GLClientState* state = ctx->m_state;
1110 
1111     switch (pname) {
1112     case GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES:
1113         *params = 1;
1114         break;
1115 
1116     default:
1117         if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
1118             ctx->override2DTextureTarget(target);
1119             ctx->m_glGetTexParameteriv_enc(ctx, GL_TEXTURE_2D, pname, params);
1120             ctx->restore2DTextureTarget();
1121         } else {
1122             ctx->m_glGetTexParameteriv_enc(ctx, target, pname, params);
1123         }
1124         break;
1125     }
1126 }
1127 
isValidTextureExternalParam(GLenum pname,GLenum param)1128 static bool isValidTextureExternalParam(GLenum pname, GLenum param)
1129 {
1130     switch (pname) {
1131     case GL_TEXTURE_MIN_FILTER:
1132     case GL_TEXTURE_MAG_FILTER:
1133         return param == GL_NEAREST || param == GL_LINEAR;
1134 
1135     case GL_TEXTURE_WRAP_S:
1136     case GL_TEXTURE_WRAP_T:
1137         return param == GL_CLAMP_TO_EDGE;
1138 
1139     default:
1140         return true;
1141     }
1142 }
1143 
s_glTexParameterf(void * self,GLenum target,GLenum pname,GLfloat param)1144 void GL2Encoder::s_glTexParameterf(void* self,
1145         GLenum target, GLenum pname, GLfloat param)
1146 {
1147     GL2Encoder* ctx = (GL2Encoder*)self;
1148     const GLClientState* state = ctx->m_state;
1149 
1150     SET_ERROR_IF((target == GL_TEXTURE_EXTERNAL_OES &&
1151             !isValidTextureExternalParam(pname, (GLenum)param)),
1152             GL_INVALID_ENUM);
1153 
1154     if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
1155         ctx->override2DTextureTarget(target);
1156         ctx->m_glTexParameterf_enc(ctx, GL_TEXTURE_2D, pname, param);
1157         ctx->restore2DTextureTarget();
1158     } else {
1159         ctx->m_glTexParameterf_enc(ctx, target, pname, param);
1160     }
1161 }
1162 
s_glTexParameterfv(void * self,GLenum target,GLenum pname,const GLfloat * params)1163 void GL2Encoder::s_glTexParameterfv(void* self,
1164         GLenum target, GLenum pname, const GLfloat* params)
1165 {
1166     GL2Encoder* ctx = (GL2Encoder*)self;
1167     const GLClientState* state = ctx->m_state;
1168 
1169     SET_ERROR_IF((target == GL_TEXTURE_EXTERNAL_OES &&
1170             !isValidTextureExternalParam(pname, (GLenum)params[0])),
1171             GL_INVALID_ENUM);
1172 
1173     if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
1174         ctx->override2DTextureTarget(target);
1175         ctx->m_glTexParameterfv_enc(ctx, GL_TEXTURE_2D, pname, params);
1176         ctx->restore2DTextureTarget();
1177     } else {
1178         ctx->m_glTexParameterfv_enc(ctx, target, pname, params);
1179     }
1180 }
1181 
s_glTexParameteri(void * self,GLenum target,GLenum pname,GLint param)1182 void GL2Encoder::s_glTexParameteri(void* self,
1183         GLenum target, GLenum pname, GLint param)
1184 {
1185     GL2Encoder* ctx = (GL2Encoder*)self;
1186     const GLClientState* state = ctx->m_state;
1187 
1188     SET_ERROR_IF((target == GL_TEXTURE_EXTERNAL_OES &&
1189             !isValidTextureExternalParam(pname, (GLenum)param)),
1190             GL_INVALID_ENUM);
1191 
1192     if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
1193         ctx->override2DTextureTarget(target);
1194         ctx->m_glTexParameteri_enc(ctx, GL_TEXTURE_2D, pname, param);
1195         ctx->restore2DTextureTarget();
1196     } else {
1197         ctx->m_glTexParameteri_enc(ctx, target, pname, param);
1198     }
1199 }
1200 
s_glTexParameteriv(void * self,GLenum target,GLenum pname,const GLint * params)1201 void GL2Encoder::s_glTexParameteriv(void* self,
1202         GLenum target, GLenum pname, const GLint* params)
1203 {
1204     GL2Encoder* ctx = (GL2Encoder*)self;
1205     const GLClientState* state = ctx->m_state;
1206 
1207     SET_ERROR_IF((target == GL_TEXTURE_EXTERNAL_OES &&
1208             !isValidTextureExternalParam(pname, (GLenum)params[0])),
1209             GL_INVALID_ENUM);
1210 
1211     if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
1212         ctx->override2DTextureTarget(target);
1213         ctx->m_glTexParameteriv_enc(ctx, GL_TEXTURE_2D, pname, params);
1214         ctx->restore2DTextureTarget();
1215     } else {
1216         ctx->m_glTexParameteriv_enc(ctx, target, pname, params);
1217     }
1218 }
1219 
override2DTextureTarget(GLenum target)1220 void GL2Encoder::override2DTextureTarget(GLenum target)
1221 {
1222     if ((target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) &&
1223         target != m_state->getPriorityEnabledTarget(GL_TEXTURE_2D)) {
1224             m_glBindTexture_enc(this, GL_TEXTURE_2D,
1225                     m_state->getBoundTexture(target));
1226     }
1227 }
1228 
restore2DTextureTarget()1229 void GL2Encoder::restore2DTextureTarget()
1230 {
1231     GLenum priorityTarget = m_state->getPriorityEnabledTarget(GL_TEXTURE_2D);
1232     m_glBindTexture_enc(this, GL_TEXTURE_2D,
1233             m_state->getBoundTexture(priorityTarget));
1234 }
1235