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