Home | History | Annotate | Download | only in GLESv2_enc
      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 
     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 
    116 GL2Encoder::~GL2Encoder()
    117 {
    118     delete m_compressedTextureFormats;
    119 }
    120 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 //
    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 
    636 void GL2Encoder::s_glShaderSource(void *self, GLuint shader, GLsizei count, const GLchar **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 
    659 void GL2Encoder::s_glFinish(void *self)
    660 {
    661     GL2Encoder *ctx = (GL2Encoder *)self;
    662     ctx->glFinishRoundTrip(self);
    663 }
    664 
    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 
    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 
    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 }
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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