Home | History | Annotate | Download | only in GLESv1_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 #include "GLEncoder.h"
     17 #include "glUtils.h"
     18 #include "FixedBuffer.h"
     19 #include <cutils/log.h>
     20 #include <assert.h>
     21 
     22 #ifndef MIN
     23 #define MIN(a, b) ((a) < (b) ? (a) : (b))
     24 #endif
     25 
     26 static GLubyte *gVendorString= (GLubyte *) "Android";
     27 static GLubyte *gRendererString= (GLubyte *) "Android HW-GLES 1.0";
     28 static GLubyte *gVersionString= (GLubyte *) "OpenGL ES-CM 1.0";
     29 static GLubyte *gExtensionsString= (GLubyte *) "GL_OES_EGL_image_external ";
     30 
     31 #define SET_ERROR_IF(condition,err) if((condition)) {                            \
     32         ALOGE("%s:%s:%d GL error 0x%x\n", __FILE__, __FUNCTION__, __LINE__, err); \
     33         ctx->setError(err);                                    \
     34         return;                                                  \
     35     }
     36 
     37 
     38 #define RET_AND_SET_ERROR_IF(condition,err,ret) if((condition)) {                \
     39         ALOGE("%s:%s:%d GL error 0x%x\n", __FILE__, __FUNCTION__, __LINE__, err); \
     40         ctx->setError(err);                                    \
     41         return ret;                                              \
     42     }
     43 
     44 GLenum GLEncoder::s_glGetError(void * self)
     45 {
     46     GLEncoder *ctx = (GLEncoder *)self;
     47     GLenum err = ctx->getError();
     48     if(err != GL_NO_ERROR) {
     49         ctx->setError(GL_NO_ERROR);
     50         return err;
     51     }
     52 
     53     return ctx->m_glGetError_enc(self);
     54 
     55 }
     56 
     57 GLint * GLEncoder::getCompressedTextureFormats()
     58 {
     59     if (m_compressedTextureFormats == NULL) {
     60         this->glGetIntegerv(this, GL_NUM_COMPRESSED_TEXTURE_FORMATS,
     61                             &m_num_compressedTextureFormats);
     62         if (m_num_compressedTextureFormats > 0) {
     63             // get number of texture formats;
     64             m_compressedTextureFormats = new GLint[m_num_compressedTextureFormats];
     65             this->glGetCompressedTextureFormats(this, m_num_compressedTextureFormats, m_compressedTextureFormats);
     66         }
     67     }
     68     return m_compressedTextureFormats;
     69 }
     70 
     71 void GLEncoder::s_glGetIntegerv(void *self, GLenum param, GLint *ptr)
     72 {
     73     GLEncoder *ctx = (GLEncoder *)self;
     74     assert(ctx->m_state != NULL);
     75     GLClientState* state = ctx->m_state;
     76 
     77     switch (param) {
     78     case GL_COMPRESSED_TEXTURE_FORMATS: {
     79         GLint * compressedTextureFormats = ctx->getCompressedTextureFormats();
     80         if (ctx->m_num_compressedTextureFormats > 0 &&
     81                 compressedTextureFormats != NULL) {
     82             memcpy(ptr, compressedTextureFormats,
     83                    ctx->m_num_compressedTextureFormats * sizeof(GLint));
     84         }
     85         break;
     86     }
     87 
     88     case GL_MAX_TEXTURE_UNITS:
     89         ctx->m_glGetIntegerv_enc(self, param, ptr);
     90         *ptr = MIN(*ptr, GLClientState::MAX_TEXTURE_UNITS);
     91         break;
     92 
     93     case GL_TEXTURE_BINDING_2D:
     94         *ptr = state->getBoundTexture(GL_TEXTURE_2D);
     95         break;
     96 
     97     case GL_TEXTURE_BINDING_EXTERNAL_OES:
     98         *ptr = state->getBoundTexture(GL_TEXTURE_EXTERNAL_OES);
     99         break;
    100 
    101     default:
    102         if (!state->getClientStateParameter<GLint>(param,ptr)) {
    103             ctx->m_glGetIntegerv_enc(self, param, ptr);
    104         }
    105         break;
    106     }
    107 }
    108 
    109 void GLEncoder::s_glGetFloatv(void *self, GLenum param, GLfloat *ptr)
    110 {
    111     GLEncoder *ctx = (GLEncoder *)self;
    112     assert(ctx->m_state != NULL);
    113     GLClientState* state = ctx->m_state;
    114 
    115     switch (param) {
    116     case GL_COMPRESSED_TEXTURE_FORMATS: {
    117         GLint * compressedTextureFormats = ctx->getCompressedTextureFormats();
    118         if (ctx->m_num_compressedTextureFormats > 0 &&
    119                 compressedTextureFormats != NULL) {
    120             for (int i = 0; i < ctx->m_num_compressedTextureFormats; i++) {
    121                 ptr[i] = (GLfloat) compressedTextureFormats[i];
    122             }
    123         }
    124         break;
    125     }
    126 
    127     case GL_MAX_TEXTURE_UNITS:
    128         ctx->m_glGetFloatv_enc(self, param, ptr);
    129         *ptr = MIN(*ptr, (GLfloat)GLClientState::MAX_TEXTURE_UNITS);
    130         break;
    131 
    132     case GL_TEXTURE_BINDING_2D:
    133         *ptr = (GLfloat)state->getBoundTexture(GL_TEXTURE_2D);
    134         break;
    135 
    136     case GL_TEXTURE_BINDING_EXTERNAL_OES:
    137         *ptr = (GLfloat)state->getBoundTexture(GL_TEXTURE_EXTERNAL_OES);
    138         break;
    139 
    140     default:
    141         if (!state->getClientStateParameter<GLfloat>(param,ptr)) {
    142             ctx->m_glGetFloatv_enc(self, param, ptr);
    143         }
    144         break;
    145     }
    146 }
    147 
    148 void GLEncoder::s_glGetFixedv(void *self, GLenum param, GLfixed *ptr)
    149 {
    150     GLEncoder *ctx = (GLEncoder *)self;
    151     assert(ctx->m_state != NULL);
    152     GLClientState* state = ctx->m_state;
    153 
    154     switch (param) {
    155     case GL_COMPRESSED_TEXTURE_FORMATS: {
    156         GLint * compressedTextureFormats = ctx->getCompressedTextureFormats();
    157         if (ctx->m_num_compressedTextureFormats > 0 &&
    158                 compressedTextureFormats != NULL) {
    159             for (int i = 0; i < ctx->m_num_compressedTextureFormats; i++) {
    160                 ptr[i] =  compressedTextureFormats[i] << 16;
    161             }
    162         }
    163         break;
    164     }
    165 
    166     case GL_MAX_TEXTURE_UNITS:
    167         ctx->m_glGetFixedv_enc(self, param, ptr);
    168         *ptr = MIN(*ptr, GLClientState::MAX_TEXTURE_UNITS << 16);
    169         break;
    170 
    171     case GL_TEXTURE_BINDING_2D:
    172         *ptr = state->getBoundTexture(GL_TEXTURE_2D) << 16;
    173         break;
    174 
    175     case GL_TEXTURE_BINDING_EXTERNAL_OES:
    176         *ptr = state->getBoundTexture(GL_TEXTURE_EXTERNAL_OES) << 16;
    177         break;
    178 
    179     default:
    180         if (!state->getClientStateParameter<GLfixed>(param,ptr)) {
    181             ctx->m_glGetFixedv_enc(self, param, ptr);
    182         }
    183         break;
    184     }
    185 }
    186 
    187 void GLEncoder::s_glGetBooleanv(void *self, GLenum param, GLboolean *ptr)
    188 {
    189     GLEncoder *ctx = (GLEncoder *)self;
    190     assert(ctx->m_state != NULL);
    191     GLClientState* state = ctx->m_state;
    192 
    193     switch (param) {
    194     case GL_COMPRESSED_TEXTURE_FORMATS: {
    195         GLint* compressedTextureFormats = ctx->getCompressedTextureFormats();
    196         if (ctx->m_num_compressedTextureFormats > 0 &&
    197                 compressedTextureFormats != NULL) {
    198             for (int i = 0; i < ctx->m_num_compressedTextureFormats; i++) {
    199                 ptr[i] = compressedTextureFormats[i] != 0 ? GL_TRUE : GL_FALSE;
    200             }
    201         }
    202         break;
    203     }
    204 
    205     case GL_TEXTURE_BINDING_2D:
    206         *ptr = state->getBoundTexture(GL_TEXTURE_2D) != 0 ? GL_TRUE : GL_FALSE;
    207         break;
    208 
    209     case GL_TEXTURE_BINDING_EXTERNAL_OES:
    210         *ptr = state->getBoundTexture(GL_TEXTURE_EXTERNAL_OES) != 0
    211                 ? GL_TRUE : GL_FALSE;
    212         break;
    213 
    214     default:
    215         if (!state->getClientStateParameter<GLboolean>(param,ptr)) {
    216             ctx->m_glGetBooleanv_enc(self, param, ptr);
    217         }
    218         break;
    219     }
    220 }
    221 
    222 void GLEncoder::s_glGetPointerv(void * self, GLenum param, GLvoid **params)
    223 {
    224     GLEncoder * ctx = (GLEncoder *) self;
    225     assert(ctx->m_state != NULL);
    226     ctx->m_state->getClientStatePointer(param,params);
    227 }
    228 
    229 void GLEncoder::s_glFlush(void *self)
    230 {
    231     GLEncoder *ctx = (GLEncoder *)self;
    232     ctx->m_glFlush_enc(self);
    233     ctx->m_stream->flush();
    234 }
    235 
    236 const GLubyte *GLEncoder::s_glGetString(void *self, GLenum name)
    237 {
    238     (void)self;
    239 
    240     GLubyte *retval =  (GLubyte *) "";
    241     switch(name) {
    242     case GL_VENDOR:
    243         retval = gVendorString;
    244         break;
    245     case GL_RENDERER:
    246         retval = gRendererString;
    247         break;
    248     case GL_VERSION:
    249         retval = gVersionString;
    250         break;
    251     case GL_EXTENSIONS:
    252         retval = gExtensionsString;
    253         break;
    254     }
    255     return retval;
    256 }
    257 
    258 void GLEncoder::s_glPixelStorei(void *self, GLenum param, GLint value)
    259 {
    260     GLEncoder *ctx = (GLEncoder *)self;
    261     ctx->m_glPixelStorei_enc(ctx, param, value);
    262     ALOG_ASSERT(ctx->m_state, "GLEncoder::s_glPixelStorei");
    263     ctx->m_state->setPixelStore(param, value);
    264 }
    265 
    266 void GLEncoder::s_glVertexPointer(void *self, int size, GLenum type, GLsizei stride, const void *data)
    267 {
    268     GLEncoder *ctx = (GLEncoder *)self;
    269     assert(ctx->m_state != NULL);
    270     ctx->m_state->setState(GLClientState::VERTEX_LOCATION, size, type, false, stride, data);
    271 }
    272 
    273 void GLEncoder::s_glNormalPointer(void *self, GLenum type, GLsizei stride, const void *data)
    274 {
    275     GLEncoder *ctx = (GLEncoder *)self;
    276     assert(ctx->m_state != NULL);
    277     ctx->m_state->setState(GLClientState::NORMAL_LOCATION, 3, type, false, stride, data);
    278 }
    279 
    280 void GLEncoder::s_glColorPointer(void *self, int size, GLenum type, GLsizei stride, const void *data)
    281 {
    282     GLEncoder *ctx = (GLEncoder *)self;
    283     assert(ctx->m_state != NULL);
    284     ctx->m_state->setState(GLClientState::COLOR_LOCATION, size, type, false, stride, data);
    285 }
    286 
    287 void GLEncoder::s_glPointSizePointerOES(void *self, GLenum type, GLsizei stride, const void *data)
    288 {
    289     GLEncoder *ctx = (GLEncoder *)self;
    290     assert(ctx->m_state != NULL);
    291     ctx->m_state->setState(GLClientState::POINTSIZE_LOCATION, 1, type, false, stride, data);
    292 }
    293 
    294 void GLEncoder::s_glClientActiveTexture(void *self, GLenum texture)
    295 {
    296     GLEncoder *ctx = (GLEncoder *)self;
    297     assert(ctx->m_state != NULL);
    298     ctx->m_state->setActiveTexture(texture - GL_TEXTURE0);
    299 }
    300 
    301 void GLEncoder::s_glTexCoordPointer(void *self, int size, GLenum type, GLsizei stride, const void *data)
    302 {
    303     GLEncoder *ctx = (GLEncoder *)self;
    304     assert(ctx->m_state != NULL);
    305     int loc = ctx->m_state->getLocation(GL_TEXTURE_COORD_ARRAY);
    306     ctx->m_state->setState(loc, size, type, false, stride, data);
    307 }
    308 
    309 void GLEncoder::s_glMatrixIndexPointerOES(void *self, int size, GLenum type, GLsizei stride, const void * data)
    310 {
    311     GLEncoder *ctx = (GLEncoder *)self;
    312     assert(ctx->m_state != NULL);
    313     int loc = ctx->m_state->getLocation(GL_MATRIX_INDEX_ARRAY_OES);
    314     ctx->m_state->setState(loc, size, type, false, stride, data);
    315 }
    316 
    317 void GLEncoder::s_glWeightPointerOES(void * self, int size, GLenum type, GLsizei stride, const void * data)
    318 {
    319     GLEncoder *ctx = (GLEncoder *)self;
    320     assert(ctx->m_state != NULL);
    321     int loc = ctx->m_state->getLocation(GL_WEIGHT_ARRAY_OES);
    322     ctx->m_state->setState(loc, size, type, false, stride, data);
    323 }
    324 
    325 void GLEncoder::s_glEnableClientState(void *self, GLenum state)
    326 {
    327     GLEncoder *ctx = (GLEncoder *) self;
    328     assert(ctx->m_state != NULL);
    329     int loc = ctx->m_state->getLocation(state);
    330     ctx->m_state->enable(loc, 1);
    331 }
    332 
    333 void GLEncoder::s_glDisableClientState(void *self, GLenum state)
    334 {
    335     GLEncoder *ctx = (GLEncoder *) self;
    336     assert(ctx->m_state != NULL);
    337     int loc = ctx->m_state->getLocation(state);
    338     ctx->m_state->enable(loc, 0);
    339 }
    340 
    341 GLboolean GLEncoder::s_glIsEnabled(void *self, GLenum cap)
    342 {
    343     GLEncoder *ctx = (GLEncoder *) self;
    344     assert(ctx->m_state != NULL);
    345     int loc = ctx->m_state->getLocation(cap);
    346     const GLClientState::VertexAttribState *state = ctx->m_state->getState(loc);
    347 
    348     if (state!=NULL)
    349       return state->enabled;
    350 
    351     return ctx->m_glIsEnabled_enc(self,cap);
    352 }
    353 
    354 void GLEncoder::s_glBindBuffer(void *self, GLenum target, GLuint id)
    355 {
    356     GLEncoder *ctx = (GLEncoder *) self;
    357     assert(ctx->m_state != NULL);
    358     ctx->m_state->bindBuffer(target, id);
    359     // TODO set error state if needed;
    360     ctx->m_glBindBuffer_enc(self, target, id);
    361 }
    362 
    363 void GLEncoder::s_glBufferData(void * self, GLenum target, GLsizeiptr size, const GLvoid * data, GLenum usage)
    364 {
    365     GLEncoder *ctx = (GLEncoder *) self;
    366     GLuint bufferId = ctx->m_state->getBuffer(target);
    367     SET_ERROR_IF(bufferId==0, GL_INVALID_OPERATION);
    368     SET_ERROR_IF(size<0, GL_INVALID_VALUE);
    369 
    370     ctx->m_shared->updateBufferData(bufferId, size, (void*)data);
    371     ctx->m_glBufferData_enc(self, target, size, data, usage);
    372 }
    373 
    374 void GLEncoder::s_glBufferSubData(void * self, GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid * data)
    375 {
    376     GLEncoder *ctx = (GLEncoder *) self;
    377     GLuint bufferId = ctx->m_state->getBuffer(target);
    378     SET_ERROR_IF(bufferId==0, GL_INVALID_OPERATION);
    379 
    380     GLenum res = ctx->m_shared->subUpdateBufferData(bufferId, offset, size, (void*)data);
    381     SET_ERROR_IF(res, res);
    382 
    383     ctx->m_glBufferSubData_enc(self, target, offset, size, data);
    384 }
    385 
    386 void GLEncoder::s_glDeleteBuffers(void * self, GLsizei n, const GLuint * buffers)
    387 {
    388     GLEncoder *ctx = (GLEncoder *) self;
    389     SET_ERROR_IF(n<0, GL_INVALID_VALUE);
    390     for (int i=0; i<n; i++) {
    391         ctx->m_shared->deleteBufferData(buffers[i]);
    392         ctx->m_glDeleteBuffers_enc(self,1,&buffers[i]);
    393     }
    394 }
    395 
    396 void GLEncoder::sendVertexData(unsigned int first, unsigned int count)
    397 {
    398     assert(m_state != NULL);
    399     GLenum prevActiveTexUnit = m_state->getActiveTextureUnit();
    400     for (int i = 0; i < GLClientState::LAST_LOCATION; i++) {
    401         bool enableDirty;
    402         const GLClientState::VertexAttribState *state = m_state->getStateAndEnableDirty(i, &enableDirty);
    403 
    404         // do not process if state not valid
    405         if (!state) continue;
    406 
    407         // do not send disable state if state was already disabled
    408         if (!enableDirty && !state->enabled) continue;
    409 
    410         if ( i >= GLClientState::TEXCOORD0_LOCATION &&
    411             i <= GLClientState::TEXCOORD7_LOCATION ) {
    412             m_glClientActiveTexture_enc(this, GL_TEXTURE0 + i - GLClientState::TEXCOORD0_LOCATION);
    413         }
    414 
    415         if (state->enabled) {
    416             if (enableDirty)
    417                 m_glEnableClientState_enc(this, state->glConst);
    418 
    419             unsigned int datalen = state->elementSize * count;
    420             int stride = state->stride;
    421             if (stride == 0) stride = state->elementSize;
    422             int firstIndex = stride * first;
    423 
    424             this->m_glBindBuffer_enc(this, GL_ARRAY_BUFFER, state->bufferObject);
    425             if (state->bufferObject == 0) {
    426 
    427                 switch(i) {
    428                 case GLClientState::VERTEX_LOCATION:
    429                     this->glVertexPointerData(this, state->size, state->type, state->stride,
    430                                               (unsigned char *)state->data + firstIndex, datalen);
    431                     break;
    432                 case GLClientState::NORMAL_LOCATION:
    433                     this->glNormalPointerData(this, state->type, state->stride,
    434                                               (unsigned char *)state->data + firstIndex, datalen);
    435                     break;
    436                 case GLClientState::COLOR_LOCATION:
    437                     this->glColorPointerData(this, state->size, state->type, state->stride,
    438                                              (unsigned char *)state->data + firstIndex, datalen);
    439                     break;
    440                 case GLClientState::TEXCOORD0_LOCATION:
    441                 case GLClientState::TEXCOORD1_LOCATION:
    442                 case GLClientState::TEXCOORD2_LOCATION:
    443                 case GLClientState::TEXCOORD3_LOCATION:
    444                 case GLClientState::TEXCOORD4_LOCATION:
    445                 case GLClientState::TEXCOORD5_LOCATION:
    446                 case GLClientState::TEXCOORD6_LOCATION:
    447                 case GLClientState::TEXCOORD7_LOCATION:
    448                     m_state->setActiveTextureUnit(i - GLClientState::TEXCOORD0_LOCATION + GL_TEXTURE0);
    449                     if (m_state->getPriorityEnabledTarget(GL_INVALID_ENUM) != GL_INVALID_ENUM) {
    450                         this->glTexCoordPointerData(this, i - GLClientState::TEXCOORD0_LOCATION, state->size, state->type, state->stride,
    451                                                 (unsigned char *)state->data + firstIndex, datalen);
    452                     }
    453                     break;
    454                 case GLClientState::POINTSIZE_LOCATION:
    455                     this->glPointSizePointerData(this, state->type, state->stride,
    456                                                  (unsigned char *) state->data + firstIndex, datalen);
    457                     break;
    458                 case GLClientState::WEIGHT_LOCATION:
    459                     this->glWeightPointerData(this, state->size, state->type, state->stride,
    460                                               (unsigned char * ) state->data + firstIndex, datalen);
    461                     break;
    462                 case GLClientState::MATRIXINDEX_LOCATION:
    463                     this->glMatrixIndexPointerData(this, state->size, state->type, state->stride,
    464                                                   (unsigned char *)state->data + firstIndex, datalen);
    465                     break;
    466                 }
    467             } else {
    468 
    469                 switch(i) {
    470                 case GLClientState::VERTEX_LOCATION:
    471                     this->glVertexPointerOffset(this, state->size, state->type, state->stride,
    472                                                 (uintptr_t)state->data + firstIndex);
    473                     break;
    474                 case GLClientState::NORMAL_LOCATION:
    475                     this->glNormalPointerOffset(this, state->type, state->stride,
    476                                                 (uintptr_t)state->data + firstIndex);
    477                     break;
    478                 case GLClientState::POINTSIZE_LOCATION:
    479                     this->glPointSizePointerOffset(this, state->type, state->stride,
    480                                                    (uintptr_t)state->data + firstIndex);
    481                     break;
    482                 case GLClientState::COLOR_LOCATION:
    483                     this->glColorPointerOffset(this, state->size, state->type, state->stride,
    484                                                (uintptr_t)state->data + firstIndex);
    485                     break;
    486                 case GLClientState::TEXCOORD0_LOCATION:
    487                 case GLClientState::TEXCOORD1_LOCATION:
    488                 case GLClientState::TEXCOORD2_LOCATION:
    489                 case GLClientState::TEXCOORD3_LOCATION:
    490                 case GLClientState::TEXCOORD4_LOCATION:
    491                 case GLClientState::TEXCOORD5_LOCATION:
    492                 case GLClientState::TEXCOORD6_LOCATION:
    493                 case GLClientState::TEXCOORD7_LOCATION:
    494                     this->glTexCoordPointerOffset(this, state->size, state->type, state->stride,
    495                                                   (uintptr_t)state->data + firstIndex);
    496                     break;
    497                 case GLClientState::WEIGHT_LOCATION:
    498                     this->glWeightPointerOffset(this,state->size,state->type,state->stride,
    499                                                 (uintptr_t)state->data+firstIndex);
    500                     break;
    501                 case GLClientState::MATRIXINDEX_LOCATION:
    502                     this->glMatrixIndexPointerOffset(this,state->size,state->type,state->stride,
    503                                               (uintptr_t)state->data+firstIndex);
    504                     break;
    505                 }
    506             }
    507             this->m_glBindBuffer_enc(this, GL_ARRAY_BUFFER, m_state->currentArrayVbo());
    508         } else {
    509             this->m_glDisableClientState_enc(this, state->glConst);
    510         }
    511     }
    512     m_state->setActiveTextureUnit(prevActiveTexUnit);
    513 }
    514 
    515 void GLEncoder::s_glDrawArrays(void *self, GLenum mode, GLint first, GLsizei count)
    516 {
    517     GLEncoder *ctx = (GLEncoder *)self;
    518 
    519     bool has_arrays = false;
    520     for (int i = 0; i < GLClientState::LAST_LOCATION; i++) {
    521         const GLClientState::VertexAttribState *state = ctx->m_state->getState(i);
    522         if (state->enabled) {
    523             if (state->bufferObject || state->data) {
    524                 has_arrays = true;
    525             } else {
    526                 ALOGE("glDrawArrays: a vertex attribute array is enabled with no data bound\n");
    527                 ctx->setError(GL_INVALID_OPERATION);
    528                 return;
    529             }
    530         }
    531     }
    532     if (!has_arrays) {
    533         ALOGE("glDrawArrays: no data bound to the command - ignoring\n");
    534         return;
    535     }
    536 
    537     ctx->sendVertexData(first, count);
    538     ctx->m_glDrawArrays_enc(ctx, mode, /*first*/ 0, count);
    539     ctx->m_stream->flush();
    540 }
    541 
    542 void GLEncoder::s_glDrawElements(void *self, GLenum mode, GLsizei count, GLenum type, const void *indices)
    543 {
    544 
    545     GLEncoder *ctx = (GLEncoder *)self;
    546     assert(ctx->m_state != NULL);
    547     SET_ERROR_IF(count<0, GL_INVALID_VALUE);
    548 
    549     bool has_immediate_arrays = false;
    550     bool has_indirect_arrays = false;
    551 
    552     for (int i = 0; i < GLClientState::LAST_LOCATION; i++) {
    553         const GLClientState::VertexAttribState *state = ctx->m_state->getState(i);
    554         if (state->enabled) {
    555             if (state->bufferObject != 0) {
    556                 has_indirect_arrays = true;
    557             } else if (state->data) {
    558                 has_immediate_arrays = true;
    559             } else {
    560                 ALOGE("glDrawElements: a vertex attribute array is enabled with no data bound\n");
    561                 ctx->setError(GL_INVALID_OPERATION);
    562                 return;
    563             }
    564         }
    565     }
    566 
    567     if (!has_immediate_arrays && !has_indirect_arrays) {
    568         ALOGE("glDrawElements: no data bound to the command - ignoring\n");
    569         return;
    570     }
    571 
    572     bool adjustIndices = true;
    573     if (ctx->m_state->currentIndexVbo() != 0) {
    574         if (!has_immediate_arrays) {
    575             ctx->sendVertexData(0, count);
    576             ctx->m_glBindBuffer_enc(self, GL_ELEMENT_ARRAY_BUFFER, ctx->m_state->currentIndexVbo());
    577             ctx->glDrawElementsOffset(ctx, mode, count, type, (uintptr_t)indices);
    578             ctx->m_stream->flush();
    579             adjustIndices = false;
    580         } else {
    581             BufferData * buf = ctx->m_shared->getBufferData(ctx->m_state->currentIndexVbo());
    582             ctx->m_glBindBuffer_enc(self, GL_ELEMENT_ARRAY_BUFFER, 0);
    583             indices = (void*)((GLintptr)buf->m_fixedBuffer.ptr() + (GLintptr)indices);
    584         }
    585     }
    586     if (adjustIndices) {
    587         void *adjustedIndices = (void*)indices;
    588         int minIndex = 0, maxIndex = 0;
    589 
    590         switch(type) {
    591         case GL_BYTE:
    592         case GL_UNSIGNED_BYTE:
    593             GLUtils::minmax<unsigned char>((unsigned char *)indices, count, &minIndex, &maxIndex);
    594             if (minIndex != 0) {
    595                 adjustedIndices =  ctx->m_fixedBuffer.alloc(glSizeof(type) * count);
    596                 GLUtils::shiftIndices<unsigned char>((unsigned char *)indices,
    597                                                  (unsigned char *)adjustedIndices,
    598                                                  count, -minIndex);
    599             }
    600             break;
    601         case GL_SHORT:
    602         case GL_UNSIGNED_SHORT:
    603             GLUtils::minmax<unsigned short>((unsigned short *)indices, count, &minIndex, &maxIndex);
    604             if (minIndex != 0) {
    605                 adjustedIndices = ctx->m_fixedBuffer.alloc(glSizeof(type) * count);
    606                 GLUtils::shiftIndices<unsigned short>((unsigned short *)indices,
    607                                                  (unsigned short *)adjustedIndices,
    608                                                  count, -minIndex);
    609             }
    610             break;
    611         case GL_INT:
    612         case GL_UNSIGNED_INT:
    613             GLUtils::minmax<unsigned int>((unsigned int *)indices, count, &minIndex, &maxIndex);
    614             if (minIndex != 0) {
    615                 adjustedIndices = ctx->m_fixedBuffer.alloc(glSizeof(type) * count);
    616                 GLUtils::shiftIndices<unsigned int>((unsigned int *)indices,
    617                                                  (unsigned int *)adjustedIndices,
    618                                                  count, -minIndex);
    619             }
    620             break;
    621         default:
    622             ALOGE("unsupported index buffer type %d\n", type);
    623         }
    624         if (has_indirect_arrays || 1) {
    625             ctx->sendVertexData(minIndex, maxIndex - minIndex + 1);
    626             ctx->glDrawElementsData(ctx, mode, count, type, adjustedIndices,
    627                                       count * glSizeof(type));
    628             ctx->m_stream->flush();
    629             // XXX - OPTIMIZATION (see the other else branch) should be implemented
    630             if(!has_indirect_arrays) {
    631                 //ALOGD("unoptimized drawelements !!!\n");
    632             }
    633         } else {
    634             // we are all direct arrays and immidate mode index array -
    635             // rebuild the arrays and the index array;
    636             ALOGE("glDrawElements: direct index & direct buffer data - will be implemented in later versions;\n");
    637         }
    638     }
    639 }
    640 
    641 void GLEncoder::s_glActiveTexture(void* self, GLenum texture)
    642 {
    643     GLEncoder* ctx = (GLEncoder*)self;
    644     GLClientState* state = ctx->m_state;
    645     GLenum err;
    646 
    647     if ((err = state->setActiveTextureUnit(texture)) != GL_NO_ERROR) {
    648         ALOGE("%s:%s:%d GL error %#x\n", __FILE__, __FUNCTION__, __LINE__, err);
    649         ctx->setError(err);
    650         return;
    651     }
    652 
    653     ctx->m_glActiveTexture_enc(ctx, texture);
    654 }
    655 
    656 void GLEncoder::s_glBindTexture(void* self, GLenum target, GLuint texture)
    657 {
    658     GLEncoder* ctx = (GLEncoder*)self;
    659     GLClientState* state = ctx->m_state;
    660     GLenum err;
    661 
    662     GLboolean firstUse;
    663     if ((err = state->bindTexture(target, texture, &firstUse)) != GL_NO_ERROR) {
    664         ALOGE("%s:%s:%d GL error %#x\n", __FILE__, __FUNCTION__, __LINE__, err);
    665         ctx->setError(err);
    666         return;
    667     }
    668 
    669     if (target != GL_TEXTURE_2D && target != GL_TEXTURE_EXTERNAL_OES) {
    670         ctx->m_glBindTexture_enc(ctx, target, texture);
    671         return;
    672     }
    673 
    674     GLenum priorityTarget = state->getPriorityEnabledTarget(GL_TEXTURE_2D);
    675 
    676     if (target == GL_TEXTURE_EXTERNAL_OES && firstUse) {
    677         // set TEXTURE_EXTERNAL_OES default states which differ from TEXTURE_2D
    678         ctx->m_glBindTexture_enc(ctx, GL_TEXTURE_2D, texture);
    679         ctx->m_glTexParameteri_enc(ctx, GL_TEXTURE_2D,
    680                 GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    681         ctx->m_glTexParameteri_enc(ctx, GL_TEXTURE_2D,
    682                 GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    683         ctx->m_glTexParameteri_enc(ctx, GL_TEXTURE_2D,
    684                 GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    685 
    686         if (target != priorityTarget) {
    687             ctx->m_glBindTexture_enc(ctx, GL_TEXTURE_2D,
    688                     state->getBoundTexture(GL_TEXTURE_2D));
    689         }
    690     }
    691 
    692     if (target == priorityTarget) {
    693         ctx->m_glBindTexture_enc(ctx, GL_TEXTURE_2D, texture);
    694     }
    695 }
    696 
    697 void GLEncoder::s_glDeleteTextures(void* self, GLsizei n, const GLuint* textures)
    698 {
    699     GLEncoder* ctx = (GLEncoder*)self;
    700     GLClientState* state = ctx->m_state;
    701 
    702     state->deleteTextures(n, textures);
    703     ctx->m_glDeleteTextures_enc(ctx, n, textures);
    704 }
    705 
    706 void GLEncoder::s_glDisable(void* self, GLenum cap)
    707 {
    708     GLEncoder* ctx = (GLEncoder*)self;
    709     GLClientState* state = ctx->m_state;
    710 
    711     if (cap == GL_TEXTURE_2D || cap == GL_TEXTURE_EXTERNAL_OES) {
    712         GLenum prevTarget = state->getPriorityEnabledTarget(GL_INVALID_ENUM);
    713         state->disableTextureTarget(cap);
    714         GLenum currTarget = state->getPriorityEnabledTarget(GL_INVALID_ENUM);
    715 
    716         if (prevTarget != currTarget) {
    717             if (currTarget == GL_INVALID_ENUM) {
    718                 ctx->m_glDisable_enc(ctx, GL_TEXTURE_2D);
    719                 currTarget = GL_TEXTURE_2D;
    720             }
    721             // maintain the invariant that when TEXTURE_EXTERNAL_OES is
    722             // disabled, the TEXTURE_2D binding is active, even if
    723             // TEXTURE_2D is also disabled.
    724             ctx->m_glBindTexture_enc(ctx, GL_TEXTURE_2D,
    725                     state->getBoundTexture(currTarget));
    726         }
    727 
    728     } else {
    729         ctx->m_glDisable_enc(ctx, cap);
    730     }
    731 }
    732 
    733 void GLEncoder::s_glEnable(void* self, GLenum cap)
    734 {
    735     GLEncoder* ctx = (GLEncoder*)self;
    736     GLClientState* state = ctx->m_state;
    737 
    738     if (cap == GL_TEXTURE_2D || cap == GL_TEXTURE_EXTERNAL_OES) {
    739         GLenum prevTarget = state->getPriorityEnabledTarget(GL_INVALID_ENUM);
    740         state->enableTextureTarget(cap);
    741         GLenum currTarget = state->getPriorityEnabledTarget(GL_INVALID_ENUM);
    742 
    743         if (prevTarget != currTarget) {
    744             if (prevTarget == GL_INVALID_ENUM) {
    745                 ctx->m_glEnable_enc(ctx, GL_TEXTURE_2D);
    746             }
    747             if (currTarget == GL_TEXTURE_EXTERNAL_OES) {
    748                 ctx->m_glBindTexture_enc(ctx, GL_TEXTURE_2D,
    749                         state->getBoundTexture(currTarget));
    750             }
    751         }
    752 
    753     } else {
    754         ctx->m_glEnable_enc(ctx, cap);
    755     }
    756 }
    757 
    758 void GLEncoder::s_glGetTexParameterfv(void* self,
    759         GLenum target, GLenum pname, GLfloat* params)
    760 {
    761     GLEncoder* ctx = (GLEncoder*)self;
    762     const GLClientState* state = ctx->m_state;
    763 
    764     if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
    765         ctx->override2DTextureTarget(target);
    766         ctx->m_glGetTexParameterfv_enc(ctx, GL_TEXTURE_2D, pname, params);
    767         ctx->restore2DTextureTarget();
    768     } else {
    769         ctx->m_glGetTexParameterfv_enc(ctx, target, pname, params);
    770     }
    771 }
    772 
    773 void GLEncoder::s_glGetTexParameteriv(void* self,
    774         GLenum target, GLenum pname, GLint* params)
    775 {
    776     GLEncoder* ctx = (GLEncoder*)self;
    777     const GLClientState* state = ctx->m_state;
    778 
    779     switch (pname) {
    780     case GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES:
    781         *params = 1;
    782         break;
    783 
    784     default:
    785         if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
    786             ctx->override2DTextureTarget(target);
    787             ctx->m_glGetTexParameteriv_enc(ctx, GL_TEXTURE_2D, pname, params);
    788             ctx->restore2DTextureTarget();
    789         } else {
    790             ctx->m_glGetTexParameteriv_enc(ctx, target, pname, params);
    791         }
    792         break;
    793     }
    794 }
    795 
    796 void GLEncoder::s_glGetTexParameterxv(void* self,
    797         GLenum target, GLenum pname, GLfixed* params)
    798 {
    799     GLEncoder* ctx = (GLEncoder*)self;
    800     const GLClientState* state = ctx->m_state;
    801 
    802     if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
    803         ctx->override2DTextureTarget(target);
    804         ctx->m_glGetTexParameterxv_enc(ctx, GL_TEXTURE_2D, pname, params);
    805         ctx->restore2DTextureTarget();
    806     } else {
    807         ctx->m_glGetTexParameterxv_enc(ctx, target, pname, params);
    808     }
    809 }
    810 
    811 static bool isValidTextureExternalParam(GLenum pname, GLenum param)
    812 {
    813     switch (pname) {
    814     case GL_TEXTURE_MIN_FILTER:
    815     case GL_TEXTURE_MAG_FILTER:
    816         return param == GL_NEAREST || param == GL_LINEAR;
    817 
    818     case GL_TEXTURE_WRAP_S:
    819     case GL_TEXTURE_WRAP_T:
    820         return param == GL_CLAMP_TO_EDGE;
    821 
    822     case GL_GENERATE_MIPMAP:
    823         return param == GL_FALSE;
    824 
    825     default:
    826         return true;
    827     }
    828 }
    829 
    830 void GLEncoder::s_glTexParameterf(void* self,
    831         GLenum target, GLenum pname, GLfloat param)
    832 {
    833     GLEncoder* ctx = (GLEncoder*)self;
    834     const GLClientState* state = ctx->m_state;
    835 
    836     SET_ERROR_IF((target == GL_TEXTURE_EXTERNAL_OES &&
    837             !isValidTextureExternalParam(pname, (GLenum)param)),
    838             GL_INVALID_ENUM);
    839 
    840     if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
    841         ctx->override2DTextureTarget(target);
    842         ctx->m_glTexParameterf_enc(ctx, GL_TEXTURE_2D, pname, param);
    843         ctx->restore2DTextureTarget();
    844     } else {
    845         ctx->m_glTexParameterf_enc(ctx, target, pname, param);
    846     }
    847 }
    848 
    849 void GLEncoder::s_glTexParameterfv(void* self,
    850         GLenum target, GLenum pname, const GLfloat* params)
    851 {
    852     GLEncoder* ctx = (GLEncoder*)self;
    853     const GLClientState* state = ctx->m_state;
    854 
    855     SET_ERROR_IF((target == GL_TEXTURE_EXTERNAL_OES &&
    856             !isValidTextureExternalParam(pname, (GLenum)params[0])),
    857             GL_INVALID_ENUM);
    858 
    859     if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
    860         ctx->override2DTextureTarget(target);
    861         ctx->m_glTexParameterfv_enc(ctx, GL_TEXTURE_2D, pname, params);
    862         ctx->restore2DTextureTarget();
    863     } else {
    864         ctx->m_glTexParameterfv_enc(ctx, target, pname, params);
    865     }
    866 }
    867 
    868 void GLEncoder::s_glTexParameteri(void* self,
    869         GLenum target, GLenum pname, GLint param)
    870 {
    871     GLEncoder* ctx = (GLEncoder*)self;
    872     const GLClientState* state = ctx->m_state;
    873 
    874     SET_ERROR_IF((target == GL_TEXTURE_EXTERNAL_OES &&
    875             !isValidTextureExternalParam(pname, (GLenum)param)),
    876             GL_INVALID_ENUM);
    877 
    878     if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
    879         ctx->override2DTextureTarget(target);
    880         ctx->m_glTexParameteri_enc(ctx, GL_TEXTURE_2D, pname, param);
    881         ctx->restore2DTextureTarget();
    882     } else {
    883         ctx->m_glTexParameteri_enc(ctx, target, pname, param);
    884     }
    885 }
    886 
    887 void GLEncoder::s_glTexParameterx(void* self,
    888         GLenum target, GLenum pname, GLfixed param)
    889 {
    890     GLEncoder* ctx = (GLEncoder*)self;
    891     const GLClientState* state = ctx->m_state;
    892 
    893     SET_ERROR_IF((target == GL_TEXTURE_EXTERNAL_OES &&
    894             !isValidTextureExternalParam(pname, (GLenum)param)),
    895             GL_INVALID_ENUM);
    896 
    897     if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
    898         ctx->override2DTextureTarget(target);
    899         ctx->m_glTexParameterx_enc(ctx, GL_TEXTURE_2D, pname, param);
    900         ctx->restore2DTextureTarget();
    901     } else {
    902         ctx->m_glTexParameterx_enc(ctx, target, pname, param);
    903     }
    904 }
    905 
    906 void GLEncoder::s_glTexParameteriv(void* self,
    907         GLenum target, GLenum pname, const GLint* params)
    908 {
    909     GLEncoder* ctx = (GLEncoder*)self;
    910     const GLClientState* state = ctx->m_state;
    911 
    912     SET_ERROR_IF((target == GL_TEXTURE_EXTERNAL_OES &&
    913             !isValidTextureExternalParam(pname, (GLenum)params[0])),
    914             GL_INVALID_ENUM);
    915 
    916     if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
    917         ctx->override2DTextureTarget(target);
    918         ctx->m_glTexParameteriv_enc(ctx, GL_TEXTURE_2D, pname, params);
    919         ctx->restore2DTextureTarget();
    920     } else {
    921         ctx->m_glTexParameteriv_enc(ctx, target, pname, params);
    922     }
    923 }
    924 
    925 void GLEncoder::s_glTexParameterxv(void* self,
    926         GLenum target, GLenum pname, const GLfixed* params)
    927 {
    928     GLEncoder* ctx = (GLEncoder*)self;
    929     const GLClientState* state = ctx->m_state;
    930 
    931     SET_ERROR_IF((target == GL_TEXTURE_EXTERNAL_OES &&
    932             !isValidTextureExternalParam(pname, (GLenum)params[0])),
    933             GL_INVALID_ENUM);
    934 
    935     if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
    936         ctx->override2DTextureTarget(target);
    937         ctx->m_glTexParameterxv_enc(ctx, GL_TEXTURE_2D, pname, params);
    938         ctx->restore2DTextureTarget();
    939     } else {
    940         ctx->m_glTexParameterxv_enc(ctx, target, pname, params);
    941     }
    942 }
    943 
    944 void GLEncoder::override2DTextureTarget(GLenum target)
    945 {
    946     if ((target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) &&
    947         target != m_state->getPriorityEnabledTarget(GL_TEXTURE_2D)) {
    948             m_glBindTexture_enc(this, GL_TEXTURE_2D,
    949                     m_state->getBoundTexture(target));
    950     }
    951 }
    952 
    953 void GLEncoder::restore2DTextureTarget()
    954 {
    955     GLenum priorityTarget = m_state->getPriorityEnabledTarget(GL_TEXTURE_2D);
    956     m_glBindTexture_enc(this, GL_TEXTURE_2D,
    957             m_state->getBoundTexture(priorityTarget));
    958 }
    959 
    960 void GLEncoder::s_glGenFramebuffersOES(void* self,
    961         GLsizei n, GLuint* framebuffers) {
    962     GLEncoder* ctx = (GLEncoder*)self;
    963     GLClientState* state = ctx->m_state;
    964 
    965     SET_ERROR_IF(n < 0, GL_INVALID_VALUE);
    966 
    967     ctx->m_glGenFramebuffersOES_enc(self, n, framebuffers);
    968     state->addFramebuffers(n, framebuffers);
    969 }
    970 
    971 void GLEncoder::s_glDeleteFramebuffersOES(void* self,
    972         GLsizei n, const GLuint* framebuffers) {
    973     GLEncoder* ctx = (GLEncoder*)self;
    974     GLClientState* state = ctx->m_state;
    975 
    976     SET_ERROR_IF(n < 0, GL_INVALID_VALUE);
    977 
    978     ctx->m_glDeleteFramebuffersOES_enc(self, n, framebuffers);
    979     state->removeFramebuffers(n, framebuffers);
    980 }
    981 
    982 void GLEncoder::s_glBindFramebufferOES(void* self,
    983         GLenum target, GLuint framebuffer) {
    984     GLEncoder* ctx = (GLEncoder*)self;
    985     GLClientState* state = ctx->m_state;
    986 
    987     SET_ERROR_IF((target != GL_FRAMEBUFFER),
    988                  GL_INVALID_ENUM);
    989 
    990     state->bindFramebuffer(target, framebuffer);
    991 
    992     ctx->m_glBindFramebufferOES_enc(self, target, framebuffer);
    993 }
    994 
    995 void GLEncoder::s_glFramebufferTexture2DOES(void*self,
    996         GLenum target, GLenum attachment,
    997         GLenum textarget, GLuint texture, GLint level) {
    998     GLEncoder* ctx = (GLEncoder*)self;
    999     GLClientState* state = ctx->m_state;
   1000 
   1001     state->attachTextureObject(attachment, texture);
   1002 
   1003     ctx->m_glFramebufferTexture2DOES_enc(self, target, attachment, textarget, texture, level);
   1004 }
   1005 
   1006 void GLEncoder::s_glFramebufferTexture2DMultisampleIMG(void* self,
   1007         GLenum target, GLenum attachment,
   1008         GLenum textarget, GLuint texture, GLint level, GLsizei samples) {
   1009     GLEncoder* ctx = (GLEncoder*)self;
   1010     GLClientState* state = ctx->m_state;
   1011 
   1012     state->attachTextureObject(attachment, texture);
   1013 
   1014     ctx->m_glFramebufferTexture2DMultisampleIMG_enc(self, target, attachment, textarget, texture, level, samples);
   1015 }
   1016 
   1017 void GLEncoder::s_glGetFramebufferAttachmentParameterivOES(void* self,
   1018         GLenum target, GLenum attachment, GLenum pname, GLint* params)
   1019 {
   1020     GLEncoder* ctx = (GLEncoder*)self;
   1021     const GLClientState* state = ctx->m_state;
   1022 
   1023     SET_ERROR_IF(state->boundFramebuffer() == 0,
   1024                  GL_INVALID_OPERATION);
   1025     SET_ERROR_IF((pname != GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE) &&
   1026                  (!state->attachmentHasObject(attachment)),
   1027                  GL_INVALID_ENUM);
   1028 
   1029     ctx->m_glGetFramebufferAttachmentParameterivOES_enc(self, target, attachment, pname, params);
   1030 }
   1031 
   1032 GLEncoder::GLEncoder(IOStream *stream, ChecksumCalculator *protocol)
   1033         : gl_encoder_context_t(stream, protocol)
   1034 {
   1035     m_initialized = false;
   1036     m_state = NULL;
   1037     m_error = GL_NO_ERROR;
   1038     m_num_compressedTextureFormats = 0;
   1039     m_compressedTextureFormats = NULL;
   1040 
   1041     // overrides;
   1042 #define OVERRIDE(name)  m_##name##_enc = this-> name ; this-> name = &s_##name
   1043 
   1044     OVERRIDE(glFlush);
   1045     OVERRIDE(glPixelStorei);
   1046     OVERRIDE(glVertexPointer);
   1047     OVERRIDE(glNormalPointer);
   1048     OVERRIDE(glColorPointer);
   1049     OVERRIDE(glPointSizePointerOES);
   1050     OVERRIDE(glClientActiveTexture);
   1051     OVERRIDE(glTexCoordPointer);
   1052     OVERRIDE(glMatrixIndexPointerOES);
   1053     OVERRIDE(glWeightPointerOES);
   1054 
   1055     OVERRIDE(glGetIntegerv);
   1056     OVERRIDE(glGetFloatv);
   1057     OVERRIDE(glGetBooleanv);
   1058     OVERRIDE(glGetFixedv);
   1059     OVERRIDE(glGetPointerv);
   1060 
   1061     OVERRIDE(glBindBuffer);
   1062     OVERRIDE(glBufferData);
   1063     OVERRIDE(glBufferSubData);
   1064     OVERRIDE(glDeleteBuffers);
   1065 
   1066     OVERRIDE(glEnableClientState);
   1067     OVERRIDE(glDisableClientState);
   1068     OVERRIDE(glIsEnabled);
   1069     OVERRIDE(glDrawArrays);
   1070     OVERRIDE(glDrawElements);
   1071 
   1072     this->glGetString = s_glGetString;
   1073     this->glFinish = s_glFinish;
   1074 
   1075     OVERRIDE(glGetError);
   1076 
   1077     OVERRIDE(glActiveTexture);
   1078     OVERRIDE(glBindTexture);
   1079     OVERRIDE(glDeleteTextures);
   1080     OVERRIDE(glDisable);
   1081     OVERRIDE(glEnable);
   1082     OVERRIDE(glGetTexParameterfv);
   1083     OVERRIDE(glGetTexParameteriv);
   1084     OVERRIDE(glGetTexParameterxv);
   1085     OVERRIDE(glTexParameterf);
   1086     OVERRIDE(glTexParameterfv);
   1087     OVERRIDE(glTexParameteri);
   1088     OVERRIDE(glTexParameterx);
   1089     OVERRIDE(glTexParameteriv);
   1090     OVERRIDE(glTexParameterxv);
   1091 
   1092     OVERRIDE(glGenFramebuffersOES);
   1093     OVERRIDE(glDeleteFramebuffersOES);
   1094     OVERRIDE(glBindFramebufferOES);
   1095     OVERRIDE(glFramebufferTexture2DOES);
   1096     OVERRIDE(glFramebufferTexture2DMultisampleIMG);
   1097     OVERRIDE(glGetFramebufferAttachmentParameterivOES);
   1098 }
   1099 
   1100 GLEncoder::~GLEncoder()
   1101 {
   1102     delete [] m_compressedTextureFormats;
   1103 }
   1104 
   1105 size_t GLEncoder::pixelDataSize(GLsizei width, GLsizei height, GLenum format, GLenum type, int pack)
   1106 {
   1107     assert(m_state != NULL);
   1108     return m_state->pixelDataSize(width, height, format, type, pack);
   1109 }
   1110 
   1111 void GLEncoder::s_glFinish(void *self)
   1112 {
   1113     GLEncoder *ctx = (GLEncoder *)self;
   1114     ctx->glFinishRoundTrip(self);
   1115 }
   1116