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->setVertexAttribState(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->setVertexAttribState(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->setVertexAttribState(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->setVertexAttribState(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->setVertexAttribState(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->setVertexAttribState(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->setVertexAttribState(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     return state.enabled;
    348 }
    349 
    350 void GLEncoder::s_glBindBuffer(void *self, GLenum target, GLuint id)
    351 {
    352     GLEncoder *ctx = (GLEncoder *) self;
    353     assert(ctx->m_state != NULL);
    354     ctx->m_state->bindBuffer(target, id);
    355     // TODO set error state if needed;
    356     ctx->m_glBindBuffer_enc(self, target, id);
    357 }
    358 
    359 void GLEncoder::s_glBufferData(void * self, GLenum target, GLsizeiptr size, const GLvoid * data, GLenum usage)
    360 {
    361     GLEncoder *ctx = (GLEncoder *) self;
    362     GLuint bufferId = ctx->m_state->getBuffer(target);
    363     SET_ERROR_IF(bufferId==0, GL_INVALID_OPERATION);
    364     SET_ERROR_IF(size<0, GL_INVALID_VALUE);
    365 
    366     ctx->m_shared->updateBufferData(bufferId, size, (void*)data);
    367     ctx->m_glBufferData_enc(self, target, size, data, usage);
    368 }
    369 
    370 void GLEncoder::s_glBufferSubData(void * self, GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid * data)
    371 {
    372     GLEncoder *ctx = (GLEncoder *) self;
    373     GLuint bufferId = ctx->m_state->getBuffer(target);
    374     SET_ERROR_IF(bufferId==0, GL_INVALID_OPERATION);
    375 
    376     GLenum res = ctx->m_shared->subUpdateBufferData(bufferId, offset, size, (void*)data);
    377     SET_ERROR_IF(res, res);
    378 
    379     ctx->m_glBufferSubData_enc(self, target, offset, size, data);
    380 }
    381 
    382 void GLEncoder::s_glDeleteBuffers(void * self, GLsizei n, const GLuint * buffers)
    383 {
    384     GLEncoder *ctx = (GLEncoder *) self;
    385     SET_ERROR_IF(n<0, GL_INVALID_VALUE);
    386     for (int i=0; i<n; i++) {
    387         ctx->m_shared->deleteBufferData(buffers[i]);
    388         ctx->m_glDeleteBuffers_enc(self,1,&buffers[i]);
    389     }
    390 }
    391 
    392 void GLEncoder::sendVertexData(unsigned int first, unsigned int count)
    393 {
    394     assert(m_state != NULL);
    395     GLenum prevActiveTexUnit = m_state->getActiveTextureUnit();
    396     for (int i = 0; i < GLClientState::LAST_LOCATION; i++) {
    397         bool enableDirty;
    398         const GLClientState::VertexAttribState& state = m_state->getStateAndEnableDirty(i, &enableDirty);
    399 
    400         // do not send disable state if state was already disabled
    401         if (!enableDirty && !state.enabled) continue;
    402 
    403         if ( i >= GLClientState::TEXCOORD0_LOCATION &&
    404             i <= GLClientState::TEXCOORD7_LOCATION ) {
    405             m_glClientActiveTexture_enc(this, GL_TEXTURE0 + i - GLClientState::TEXCOORD0_LOCATION);
    406         }
    407 
    408         if (state.enabled) {
    409             if (enableDirty)
    410                 m_glEnableClientState_enc(this, state.glConst);
    411 
    412             unsigned int datalen = state.elementSize * count;
    413             int stride = state.stride;
    414             if (stride == 0) stride = state.elementSize;
    415             int firstIndex = stride * first;
    416 
    417             this->m_glBindBuffer_enc(this, GL_ARRAY_BUFFER, state.bufferObject);
    418             if (state.bufferObject == 0) {
    419 
    420                 switch(i) {
    421                 case GLClientState::VERTEX_LOCATION:
    422                     this->glVertexPointerData(this, state.size, state.type, state.stride,
    423                                               (unsigned char *)state.data + firstIndex, datalen);
    424                     break;
    425                 case GLClientState::NORMAL_LOCATION:
    426                     this->glNormalPointerData(this, state.type, state.stride,
    427                                               (unsigned char *)state.data + firstIndex, datalen);
    428                     break;
    429                 case GLClientState::COLOR_LOCATION:
    430                     this->glColorPointerData(this, state.size, state.type, state.stride,
    431                                              (unsigned char *)state.data + firstIndex, datalen);
    432                     break;
    433                 case GLClientState::TEXCOORD0_LOCATION:
    434                 case GLClientState::TEXCOORD1_LOCATION:
    435                 case GLClientState::TEXCOORD2_LOCATION:
    436                 case GLClientState::TEXCOORD3_LOCATION:
    437                 case GLClientState::TEXCOORD4_LOCATION:
    438                 case GLClientState::TEXCOORD5_LOCATION:
    439                 case GLClientState::TEXCOORD6_LOCATION:
    440                 case GLClientState::TEXCOORD7_LOCATION:
    441                     m_state->setActiveTextureUnit(i - GLClientState::TEXCOORD0_LOCATION + GL_TEXTURE0);
    442                     if (m_state->getPriorityEnabledTarget(GL_INVALID_ENUM) != GL_INVALID_ENUM) {
    443                         this->glTexCoordPointerData(this, i - GLClientState::TEXCOORD0_LOCATION, state.size, state.type, state.stride,
    444                                                 (unsigned char *)state.data + firstIndex, datalen);
    445                     }
    446                     break;
    447                 case GLClientState::POINTSIZE_LOCATION:
    448                     this->glPointSizePointerData(this, state.type, state.stride,
    449                                                  (unsigned char *) state.data + firstIndex, datalen);
    450                     break;
    451                 case GLClientState::WEIGHT_LOCATION:
    452                     this->glWeightPointerData(this, state.size, state.type, state.stride,
    453                                               (unsigned char * ) state.data + firstIndex, datalen);
    454                     break;
    455                 case GLClientState::MATRIXINDEX_LOCATION:
    456                     this->glMatrixIndexPointerData(this, state.size, state.type, state.stride,
    457                                                   (unsigned char *)state.data + firstIndex, datalen);
    458                     break;
    459                 }
    460             } else {
    461 
    462                 switch(i) {
    463                 case GLClientState::VERTEX_LOCATION:
    464                     this->glVertexPointerOffset(this, state.size, state.type, state.stride,
    465                                                 (uintptr_t)state.data + firstIndex);
    466                     break;
    467                 case GLClientState::NORMAL_LOCATION:
    468                     this->glNormalPointerOffset(this, state.type, state.stride,
    469                                                 (uintptr_t)state.data + firstIndex);
    470                     break;
    471                 case GLClientState::POINTSIZE_LOCATION:
    472                     this->glPointSizePointerOffset(this, state.type, state.stride,
    473                                                    (uintptr_t)state.data + firstIndex);
    474                     break;
    475                 case GLClientState::COLOR_LOCATION:
    476                     this->glColorPointerOffset(this, state.size, state.type, state.stride,
    477                                                (uintptr_t)state.data + firstIndex);
    478                     break;
    479                 case GLClientState::TEXCOORD0_LOCATION:
    480                 case GLClientState::TEXCOORD1_LOCATION:
    481                 case GLClientState::TEXCOORD2_LOCATION:
    482                 case GLClientState::TEXCOORD3_LOCATION:
    483                 case GLClientState::TEXCOORD4_LOCATION:
    484                 case GLClientState::TEXCOORD5_LOCATION:
    485                 case GLClientState::TEXCOORD6_LOCATION:
    486                 case GLClientState::TEXCOORD7_LOCATION:
    487                     this->glTexCoordPointerOffset(this, state.size, state.type, state.stride,
    488                                                   (uintptr_t)state.data + firstIndex);
    489                     break;
    490                 case GLClientState::WEIGHT_LOCATION:
    491                     this->glWeightPointerOffset(this,state.size,state.type,state.stride,
    492                                                 (uintptr_t)state.data+firstIndex);
    493                     break;
    494                 case GLClientState::MATRIXINDEX_LOCATION:
    495                     this->glMatrixIndexPointerOffset(this,state.size,state.type,state.stride,
    496                                               (uintptr_t)state.data+firstIndex);
    497                     break;
    498                 }
    499             }
    500             this->m_glBindBuffer_enc(this, GL_ARRAY_BUFFER, m_state->currentArrayVbo());
    501         } else {
    502             this->m_glDisableClientState_enc(this, state.glConst);
    503         }
    504     }
    505     m_state->setActiveTextureUnit(prevActiveTexUnit);
    506 }
    507 
    508 void GLEncoder::s_glDrawArrays(void *self, GLenum mode, GLint first, GLsizei count)
    509 {
    510     GLEncoder *ctx = (GLEncoder *)self;
    511 
    512     bool has_arrays = false;
    513     for (int i = 0; i < GLClientState::LAST_LOCATION; i++) {
    514         const GLClientState::VertexAttribState& state = ctx->m_state->getState(i);
    515         if (state.enabled) {
    516             if (state.bufferObject || state.data) {
    517                 has_arrays = true;
    518             } else {
    519                 ALOGE("glDrawArrays: a vertex attribute array is enabled with no data bound\n");
    520                 ctx->setError(GL_INVALID_OPERATION);
    521                 return;
    522             }
    523         }
    524     }
    525     if (!has_arrays) {
    526         ALOGE("glDrawArrays: no data bound to the command - ignoring\n");
    527         return;
    528     }
    529 
    530     ctx->sendVertexData(first, count);
    531     ctx->m_glDrawArrays_enc(ctx, mode, /*first*/ 0, count);
    532     ctx->m_stream->flush();
    533 }
    534 
    535 void GLEncoder::s_glDrawElements(void *self, GLenum mode, GLsizei count, GLenum type, const void *indices)
    536 {
    537 
    538     GLEncoder *ctx = (GLEncoder *)self;
    539     assert(ctx->m_state != NULL);
    540     SET_ERROR_IF(count<0, GL_INVALID_VALUE);
    541 
    542     bool has_immediate_arrays = false;
    543     bool has_indirect_arrays = false;
    544 
    545     for (int i = 0; i < GLClientState::LAST_LOCATION; i++) {
    546         const GLClientState::VertexAttribState& state = ctx->m_state->getState(i);
    547         if (state.enabled) {
    548             if (state.bufferObject != 0) {
    549                 has_indirect_arrays = true;
    550             } else if (state.data) {
    551                 has_immediate_arrays = true;
    552             } else {
    553                 ALOGE("glDrawElements: a vertex attribute array is enabled with no data bound\n");
    554                 ctx->setError(GL_INVALID_OPERATION);
    555                 return;
    556             }
    557         }
    558     }
    559 
    560     if (!has_immediate_arrays && !has_indirect_arrays) {
    561         ALOGE("glDrawElements: no data bound to the command - ignoring\n");
    562         return;
    563     }
    564 
    565     bool adjustIndices = true;
    566     if (ctx->m_state->currentIndexVbo() != 0) {
    567         if (!has_immediate_arrays) {
    568             ctx->sendVertexData(0, count);
    569             ctx->m_glBindBuffer_enc(self, GL_ELEMENT_ARRAY_BUFFER, ctx->m_state->currentIndexVbo());
    570             ctx->glDrawElementsOffset(ctx, mode, count, type, (uintptr_t)indices);
    571             ctx->m_stream->flush();
    572             adjustIndices = false;
    573         } else {
    574             BufferData * buf = ctx->m_shared->getBufferData(ctx->m_state->currentIndexVbo());
    575             ctx->m_glBindBuffer_enc(self, GL_ELEMENT_ARRAY_BUFFER, 0);
    576             indices = (void*)((GLintptr)buf->m_fixedBuffer.ptr() + (GLintptr)indices);
    577         }
    578     }
    579     if (adjustIndices) {
    580         void *adjustedIndices = (void*)indices;
    581         int minIndex = 0, maxIndex = 0;
    582 
    583         switch(type) {
    584         case GL_BYTE:
    585         case GL_UNSIGNED_BYTE:
    586             GLUtils::minmax<unsigned char>((unsigned char *)indices, count, &minIndex, &maxIndex);
    587             if (minIndex != 0) {
    588                 adjustedIndices =  ctx->m_fixedBuffer.alloc(glSizeof(type) * count);
    589                 GLUtils::shiftIndices<unsigned char>((unsigned char *)indices,
    590                                                  (unsigned char *)adjustedIndices,
    591                                                  count, -minIndex);
    592             }
    593             break;
    594         case GL_SHORT:
    595         case GL_UNSIGNED_SHORT:
    596             GLUtils::minmax<unsigned short>((unsigned short *)indices, count, &minIndex, &maxIndex);
    597             if (minIndex != 0) {
    598                 adjustedIndices = ctx->m_fixedBuffer.alloc(glSizeof(type) * count);
    599                 GLUtils::shiftIndices<unsigned short>((unsigned short *)indices,
    600                                                  (unsigned short *)adjustedIndices,
    601                                                  count, -minIndex);
    602             }
    603             break;
    604         case GL_INT:
    605         case GL_UNSIGNED_INT:
    606             GLUtils::minmax<unsigned int>((unsigned int *)indices, count, &minIndex, &maxIndex);
    607             if (minIndex != 0) {
    608                 adjustedIndices = ctx->m_fixedBuffer.alloc(glSizeof(type) * count);
    609                 GLUtils::shiftIndices<unsigned int>((unsigned int *)indices,
    610                                                  (unsigned int *)adjustedIndices,
    611                                                  count, -minIndex);
    612             }
    613             break;
    614         default:
    615             ALOGE("unsupported index buffer type %d\n", type);
    616         }
    617         if (has_indirect_arrays || 1) {
    618             ctx->sendVertexData(minIndex, maxIndex - minIndex + 1);
    619             ctx->glDrawElementsData(ctx, mode, count, type, adjustedIndices,
    620                                       count * glSizeof(type));
    621             ctx->m_stream->flush();
    622             // XXX - OPTIMIZATION (see the other else branch) should be implemented
    623             if(!has_indirect_arrays) {
    624                 //ALOGD("unoptimized drawelements !!!\n");
    625             }
    626         } else {
    627             // we are all direct arrays and immidate mode index array -
    628             // rebuild the arrays and the index array;
    629             ALOGE("glDrawElements: direct index & direct buffer data - will be implemented in later versions;\n");
    630         }
    631     }
    632 }
    633 
    634 void GLEncoder::s_glActiveTexture(void* self, GLenum texture)
    635 {
    636     GLEncoder* ctx = (GLEncoder*)self;
    637     GLClientState* state = ctx->m_state;
    638     GLenum err;
    639 
    640     if ((err = state->setActiveTextureUnit(texture)) != GL_NO_ERROR) {
    641         ALOGE("%s:%s:%d GL error %#x\n", __FILE__, __FUNCTION__, __LINE__, err);
    642         ctx->setError(err);
    643         return;
    644     }
    645 
    646     ctx->m_glActiveTexture_enc(ctx, texture);
    647 }
    648 
    649 void GLEncoder::s_glBindTexture(void* self, GLenum target, GLuint texture)
    650 {
    651     GLEncoder* ctx = (GLEncoder*)self;
    652     GLClientState* state = ctx->m_state;
    653     GLenum err;
    654 
    655     GLboolean firstUse;
    656     if ((err = state->bindTexture(target, texture, &firstUse)) != GL_NO_ERROR) {
    657         ALOGE("%s:%s:%d GL error %#x\n", __FILE__, __FUNCTION__, __LINE__, err);
    658         ctx->setError(err);
    659         return;
    660     }
    661 
    662     if (target != GL_TEXTURE_2D && target != GL_TEXTURE_EXTERNAL_OES) {
    663         ctx->m_glBindTexture_enc(ctx, target, texture);
    664         return;
    665     }
    666 
    667     GLenum priorityTarget = state->getPriorityEnabledTarget(GL_TEXTURE_2D);
    668 
    669     if (target == GL_TEXTURE_EXTERNAL_OES && firstUse) {
    670         // set TEXTURE_EXTERNAL_OES default states which differ from TEXTURE_2D
    671         ctx->m_glBindTexture_enc(ctx, GL_TEXTURE_2D, texture);
    672         ctx->m_glTexParameteri_enc(ctx, GL_TEXTURE_2D,
    673                 GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    674         ctx->m_glTexParameteri_enc(ctx, GL_TEXTURE_2D,
    675                 GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    676         ctx->m_glTexParameteri_enc(ctx, GL_TEXTURE_2D,
    677                 GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    678 
    679         if (target != priorityTarget) {
    680             ctx->m_glBindTexture_enc(ctx, GL_TEXTURE_2D,
    681                     state->getBoundTexture(GL_TEXTURE_2D));
    682         }
    683     }
    684 
    685     if (target == priorityTarget) {
    686         ctx->m_glBindTexture_enc(ctx, GL_TEXTURE_2D, texture);
    687     }
    688 }
    689 
    690 void GLEncoder::s_glDeleteTextures(void* self, GLsizei n, const GLuint* textures)
    691 {
    692     GLEncoder* ctx = (GLEncoder*)self;
    693     GLClientState* state = ctx->m_state;
    694 
    695     state->deleteTextures(n, textures);
    696     ctx->m_glDeleteTextures_enc(ctx, n, textures);
    697 }
    698 
    699 void GLEncoder::s_glDisable(void* self, GLenum cap)
    700 {
    701     GLEncoder* ctx = (GLEncoder*)self;
    702     GLClientState* state = ctx->m_state;
    703 
    704     if (cap == GL_TEXTURE_2D || cap == GL_TEXTURE_EXTERNAL_OES) {
    705         GLenum prevTarget = state->getPriorityEnabledTarget(GL_INVALID_ENUM);
    706         state->disableTextureTarget(cap);
    707         GLenum currTarget = state->getPriorityEnabledTarget(GL_INVALID_ENUM);
    708 
    709         if (prevTarget != currTarget) {
    710             if (currTarget == GL_INVALID_ENUM) {
    711                 ctx->m_glDisable_enc(ctx, GL_TEXTURE_2D);
    712                 currTarget = GL_TEXTURE_2D;
    713             }
    714             // maintain the invariant that when TEXTURE_EXTERNAL_OES is
    715             // disabled, the TEXTURE_2D binding is active, even if
    716             // TEXTURE_2D is also disabled.
    717             ctx->m_glBindTexture_enc(ctx, GL_TEXTURE_2D,
    718                     state->getBoundTexture(currTarget));
    719         }
    720 
    721     } else {
    722         ctx->m_glDisable_enc(ctx, cap);
    723     }
    724 }
    725 
    726 void GLEncoder::s_glEnable(void* self, GLenum cap)
    727 {
    728     GLEncoder* ctx = (GLEncoder*)self;
    729     GLClientState* state = ctx->m_state;
    730 
    731     if (cap == GL_TEXTURE_2D || cap == GL_TEXTURE_EXTERNAL_OES) {
    732         GLenum prevTarget = state->getPriorityEnabledTarget(GL_INVALID_ENUM);
    733         state->enableTextureTarget(cap);
    734         GLenum currTarget = state->getPriorityEnabledTarget(GL_INVALID_ENUM);
    735 
    736         if (prevTarget != currTarget) {
    737             if (prevTarget == GL_INVALID_ENUM) {
    738                 ctx->m_glEnable_enc(ctx, GL_TEXTURE_2D);
    739             }
    740             if (currTarget == GL_TEXTURE_EXTERNAL_OES) {
    741                 ctx->m_glBindTexture_enc(ctx, GL_TEXTURE_2D,
    742                         state->getBoundTexture(currTarget));
    743             }
    744         }
    745 
    746     } else {
    747         ctx->m_glEnable_enc(ctx, cap);
    748     }
    749 }
    750 
    751 void GLEncoder::s_glGetTexParameterfv(void* self,
    752         GLenum target, GLenum pname, GLfloat* params)
    753 {
    754     GLEncoder* ctx = (GLEncoder*)self;
    755     const GLClientState* state = ctx->m_state;
    756 
    757     if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
    758         ctx->override2DTextureTarget(target);
    759         ctx->m_glGetTexParameterfv_enc(ctx, GL_TEXTURE_2D, pname, params);
    760         ctx->restore2DTextureTarget();
    761     } else {
    762         ctx->m_glGetTexParameterfv_enc(ctx, target, pname, params);
    763     }
    764 }
    765 
    766 void GLEncoder::s_glGetTexParameteriv(void* self,
    767         GLenum target, GLenum pname, GLint* params)
    768 {
    769     GLEncoder* ctx = (GLEncoder*)self;
    770     const GLClientState* state = ctx->m_state;
    771 
    772     switch (pname) {
    773     case GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES:
    774         *params = 1;
    775         break;
    776 
    777     default:
    778         if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
    779             ctx->override2DTextureTarget(target);
    780             ctx->m_glGetTexParameteriv_enc(ctx, GL_TEXTURE_2D, pname, params);
    781             ctx->restore2DTextureTarget();
    782         } else {
    783             ctx->m_glGetTexParameteriv_enc(ctx, target, pname, params);
    784         }
    785         break;
    786     }
    787 }
    788 
    789 void GLEncoder::s_glGetTexParameterxv(void* self,
    790         GLenum target, GLenum pname, GLfixed* params)
    791 {
    792     GLEncoder* ctx = (GLEncoder*)self;
    793     const GLClientState* state = ctx->m_state;
    794 
    795     if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
    796         ctx->override2DTextureTarget(target);
    797         ctx->m_glGetTexParameterxv_enc(ctx, GL_TEXTURE_2D, pname, params);
    798         ctx->restore2DTextureTarget();
    799     } else {
    800         ctx->m_glGetTexParameterxv_enc(ctx, target, pname, params);
    801     }
    802 }
    803 
    804 static bool isValidTextureExternalParam(GLenum pname, GLenum param)
    805 {
    806     switch (pname) {
    807     case GL_TEXTURE_MIN_FILTER:
    808     case GL_TEXTURE_MAG_FILTER:
    809         return param == GL_NEAREST || param == GL_LINEAR;
    810 
    811     case GL_TEXTURE_WRAP_S:
    812     case GL_TEXTURE_WRAP_T:
    813         return param == GL_CLAMP_TO_EDGE;
    814 
    815     case GL_GENERATE_MIPMAP:
    816         return param == GL_FALSE;
    817 
    818     default:
    819         return true;
    820     }
    821 }
    822 
    823 void GLEncoder::s_glTexParameterf(void* self,
    824         GLenum target, GLenum pname, GLfloat param)
    825 {
    826     GLEncoder* ctx = (GLEncoder*)self;
    827     const GLClientState* state = ctx->m_state;
    828 
    829     SET_ERROR_IF((target == GL_TEXTURE_EXTERNAL_OES &&
    830             !isValidTextureExternalParam(pname, (GLenum)param)),
    831             GL_INVALID_ENUM);
    832 
    833     if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
    834         ctx->override2DTextureTarget(target);
    835         ctx->m_glTexParameterf_enc(ctx, GL_TEXTURE_2D, pname, param);
    836         ctx->restore2DTextureTarget();
    837     } else {
    838         ctx->m_glTexParameterf_enc(ctx, target, pname, param);
    839     }
    840 }
    841 
    842 void GLEncoder::s_glTexParameterfv(void* self,
    843         GLenum target, GLenum pname, const GLfloat* params)
    844 {
    845     GLEncoder* ctx = (GLEncoder*)self;
    846     const GLClientState* state = ctx->m_state;
    847 
    848     SET_ERROR_IF((target == GL_TEXTURE_EXTERNAL_OES &&
    849             !isValidTextureExternalParam(pname, (GLenum)params[0])),
    850             GL_INVALID_ENUM);
    851 
    852     if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
    853         ctx->override2DTextureTarget(target);
    854         ctx->m_glTexParameterfv_enc(ctx, GL_TEXTURE_2D, pname, params);
    855         ctx->restore2DTextureTarget();
    856     } else {
    857         ctx->m_glTexParameterfv_enc(ctx, target, pname, params);
    858     }
    859 }
    860 
    861 void GLEncoder::s_glTexParameteri(void* self,
    862         GLenum target, GLenum pname, GLint param)
    863 {
    864     GLEncoder* ctx = (GLEncoder*)self;
    865     const GLClientState* state = ctx->m_state;
    866 
    867     SET_ERROR_IF((target == GL_TEXTURE_EXTERNAL_OES &&
    868             !isValidTextureExternalParam(pname, (GLenum)param)),
    869             GL_INVALID_ENUM);
    870 
    871     if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
    872         ctx->override2DTextureTarget(target);
    873         ctx->m_glTexParameteri_enc(ctx, GL_TEXTURE_2D, pname, param);
    874         ctx->restore2DTextureTarget();
    875     } else {
    876         ctx->m_glTexParameteri_enc(ctx, target, pname, param);
    877     }
    878 }
    879 
    880 void GLEncoder::s_glTexParameterx(void* self,
    881         GLenum target, GLenum pname, GLfixed param)
    882 {
    883     GLEncoder* ctx = (GLEncoder*)self;
    884     const GLClientState* state = ctx->m_state;
    885 
    886     SET_ERROR_IF((target == GL_TEXTURE_EXTERNAL_OES &&
    887             !isValidTextureExternalParam(pname, (GLenum)param)),
    888             GL_INVALID_ENUM);
    889 
    890     if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
    891         ctx->override2DTextureTarget(target);
    892         ctx->m_glTexParameterx_enc(ctx, GL_TEXTURE_2D, pname, param);
    893         ctx->restore2DTextureTarget();
    894     } else {
    895         ctx->m_glTexParameterx_enc(ctx, target, pname, param);
    896     }
    897 }
    898 
    899 void GLEncoder::s_glTexParameteriv(void* self,
    900         GLenum target, GLenum pname, const GLint* params)
    901 {
    902     GLEncoder* ctx = (GLEncoder*)self;
    903     const GLClientState* state = ctx->m_state;
    904 
    905     SET_ERROR_IF((target == GL_TEXTURE_EXTERNAL_OES &&
    906             !isValidTextureExternalParam(pname, (GLenum)params[0])),
    907             GL_INVALID_ENUM);
    908 
    909     if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
    910         ctx->override2DTextureTarget(target);
    911         ctx->m_glTexParameteriv_enc(ctx, GL_TEXTURE_2D, pname, params);
    912         ctx->restore2DTextureTarget();
    913     } else {
    914         ctx->m_glTexParameteriv_enc(ctx, target, pname, params);
    915     }
    916 }
    917 
    918 void GLEncoder::s_glTexParameterxv(void* self,
    919         GLenum target, GLenum pname, const GLfixed* params)
    920 {
    921     GLEncoder* ctx = (GLEncoder*)self;
    922     const GLClientState* state = ctx->m_state;
    923 
    924     SET_ERROR_IF((target == GL_TEXTURE_EXTERNAL_OES &&
    925             !isValidTextureExternalParam(pname, (GLenum)params[0])),
    926             GL_INVALID_ENUM);
    927 
    928     if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
    929         ctx->override2DTextureTarget(target);
    930         ctx->m_glTexParameterxv_enc(ctx, GL_TEXTURE_2D, pname, params);
    931         ctx->restore2DTextureTarget();
    932     } else {
    933         ctx->m_glTexParameterxv_enc(ctx, target, pname, params);
    934     }
    935 }
    936 
    937 void GLEncoder::override2DTextureTarget(GLenum target)
    938 {
    939     if ((target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) &&
    940         target != m_state->getPriorityEnabledTarget(GL_TEXTURE_2D)) {
    941             m_glBindTexture_enc(this, GL_TEXTURE_2D,
    942                     m_state->getBoundTexture(target));
    943     }
    944 }
    945 
    946 void GLEncoder::restore2DTextureTarget()
    947 {
    948     GLenum priorityTarget = m_state->getPriorityEnabledTarget(GL_TEXTURE_2D);
    949     m_glBindTexture_enc(this, GL_TEXTURE_2D,
    950             m_state->getBoundTexture(priorityTarget));
    951 }
    952 
    953 void GLEncoder::s_glGenFramebuffersOES(void* self,
    954         GLsizei n, GLuint* framebuffers) {
    955     GLEncoder* ctx = (GLEncoder*)self;
    956     GLClientState* state = ctx->m_state;
    957 
    958     SET_ERROR_IF(n < 0, GL_INVALID_VALUE);
    959 
    960     ctx->m_glGenFramebuffersOES_enc(self, n, framebuffers);
    961     state->addFramebuffers(n, framebuffers);
    962 }
    963 
    964 void GLEncoder::s_glDeleteFramebuffersOES(void* self,
    965         GLsizei n, const GLuint* framebuffers) {
    966     GLEncoder* ctx = (GLEncoder*)self;
    967     GLClientState* state = ctx->m_state;
    968 
    969     SET_ERROR_IF(n < 0, GL_INVALID_VALUE);
    970 
    971     ctx->m_glDeleteFramebuffersOES_enc(self, n, framebuffers);
    972     state->removeFramebuffers(n, framebuffers);
    973 }
    974 
    975 void GLEncoder::s_glBindFramebufferOES(void* self,
    976         GLenum target, GLuint framebuffer) {
    977     GLEncoder* ctx = (GLEncoder*)self;
    978     GLClientState* state = ctx->m_state;
    979 
    980     SET_ERROR_IF((target != GL_FRAMEBUFFER),
    981                  GL_INVALID_ENUM);
    982 
    983     state->bindFramebuffer(target, framebuffer);
    984 
    985     ctx->m_glBindFramebufferOES_enc(self, target, framebuffer);
    986 }
    987 
    988 void GLEncoder::s_glFramebufferTexture2DOES(void*self,
    989         GLenum target, GLenum attachment,
    990         GLenum textarget, GLuint texture, GLint level) {
    991     GLEncoder* ctx = (GLEncoder*)self;
    992     GLClientState* state = ctx->m_state;
    993 
    994     state->attachTextureObject(target, attachment, texture);
    995 
    996     ctx->m_glFramebufferTexture2DOES_enc(self, target, attachment, textarget, texture, level);
    997 }
    998 
    999 void GLEncoder::s_glFramebufferTexture2DMultisampleIMG(void* self,
   1000         GLenum target, GLenum attachment,
   1001         GLenum textarget, GLuint texture, GLint level, GLsizei samples) {
   1002     GLEncoder* ctx = (GLEncoder*)self;
   1003     GLClientState* state = ctx->m_state;
   1004 
   1005     state->attachTextureObject(target, attachment, texture);
   1006 
   1007     ctx->m_glFramebufferTexture2DMultisampleIMG_enc(self, target, attachment, textarget, texture, level, samples);
   1008 }
   1009 
   1010 void GLEncoder::s_glGetFramebufferAttachmentParameterivOES(void* self,
   1011         GLenum target, GLenum attachment, GLenum pname, GLint* params)
   1012 {
   1013     GLEncoder* ctx = (GLEncoder*)self;
   1014     const GLClientState* state = ctx->m_state;
   1015 
   1016     SET_ERROR_IF(state->boundFramebuffer(GL_FRAMEBUFFER) == 0,
   1017                  GL_INVALID_OPERATION);
   1018     SET_ERROR_IF((pname != GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE) &&
   1019                  (!state->attachmentHasObject(GL_FRAMEBUFFER, attachment)),
   1020                  GL_INVALID_ENUM);
   1021 
   1022     ctx->m_glGetFramebufferAttachmentParameterivOES_enc(self, target, attachment, pname, params);
   1023 }
   1024 
   1025 GLEncoder::GLEncoder(IOStream *stream, ChecksumCalculator *protocol)
   1026         : gl_encoder_context_t(stream, protocol)
   1027 {
   1028     m_initialized = false;
   1029     m_state = NULL;
   1030     m_error = GL_NO_ERROR;
   1031     m_num_compressedTextureFormats = 0;
   1032     m_compressedTextureFormats = NULL;
   1033 
   1034     // overrides;
   1035 #define OVERRIDE(name)  m_##name##_enc = this-> name ; this-> name = &s_##name
   1036 
   1037     OVERRIDE(glFlush);
   1038     OVERRIDE(glPixelStorei);
   1039     OVERRIDE(glVertexPointer);
   1040     OVERRIDE(glNormalPointer);
   1041     OVERRIDE(glColorPointer);
   1042     OVERRIDE(glPointSizePointerOES);
   1043     OVERRIDE(glClientActiveTexture);
   1044     OVERRIDE(glTexCoordPointer);
   1045     OVERRIDE(glMatrixIndexPointerOES);
   1046     OVERRIDE(glWeightPointerOES);
   1047 
   1048     OVERRIDE(glGetIntegerv);
   1049     OVERRIDE(glGetFloatv);
   1050     OVERRIDE(glGetBooleanv);
   1051     OVERRIDE(glGetFixedv);
   1052     OVERRIDE(glGetPointerv);
   1053 
   1054     OVERRIDE(glBindBuffer);
   1055     OVERRIDE(glBufferData);
   1056     OVERRIDE(glBufferSubData);
   1057     OVERRIDE(glDeleteBuffers);
   1058 
   1059     OVERRIDE(glEnableClientState);
   1060     OVERRIDE(glDisableClientState);
   1061     OVERRIDE(glIsEnabled);
   1062     OVERRIDE(glDrawArrays);
   1063     OVERRIDE(glDrawElements);
   1064 
   1065     this->glGetString = s_glGetString;
   1066     this->glFinish = s_glFinish;
   1067 
   1068     OVERRIDE(glGetError);
   1069 
   1070     OVERRIDE(glActiveTexture);
   1071     OVERRIDE(glBindTexture);
   1072     OVERRIDE(glDeleteTextures);
   1073     OVERRIDE(glDisable);
   1074     OVERRIDE(glEnable);
   1075     OVERRIDE(glGetTexParameterfv);
   1076     OVERRIDE(glGetTexParameteriv);
   1077     OVERRIDE(glGetTexParameterxv);
   1078     OVERRIDE(glTexParameterf);
   1079     OVERRIDE(glTexParameterfv);
   1080     OVERRIDE(glTexParameteri);
   1081     OVERRIDE(glTexParameterx);
   1082     OVERRIDE(glTexParameteriv);
   1083     OVERRIDE(glTexParameterxv);
   1084 
   1085     OVERRIDE(glGenFramebuffersOES);
   1086     OVERRIDE(glDeleteFramebuffersOES);
   1087     OVERRIDE(glBindFramebufferOES);
   1088     OVERRIDE(glFramebufferTexture2DOES);
   1089     OVERRIDE(glFramebufferTexture2DMultisampleIMG);
   1090     OVERRIDE(glGetFramebufferAttachmentParameterivOES);
   1091 }
   1092 
   1093 GLEncoder::~GLEncoder()
   1094 {
   1095     delete [] m_compressedTextureFormats;
   1096 }
   1097 
   1098 size_t GLEncoder::pixelDataSize(GLsizei width, GLsizei height, GLenum format, GLenum type, int pack)
   1099 {
   1100     assert(m_state != NULL);
   1101     return m_state->pixelDataSize(width, height, 1, format, type, pack);
   1102 }
   1103 
   1104 void GLEncoder::s_glFinish(void *self)
   1105 {
   1106     GLEncoder *ctx = (GLEncoder *)self;
   1107     ctx->glFinishRoundTrip(self);
   1108 }
   1109