Home | History | Annotate | Download | only in GLESv2_enc
      1 /*
      2 * Copyright (C) 2011 The Android Open Source Project
      3 *
      4 * Licensed under the Apache License, Version 2.0 (the "License");
      5 * you may not use this file except in compliance with the License.
      6 * You may obtain a copy of the License at
      7 *
      8 * http://www.apache.org/licenses/LICENSE-2.0
      9 *
     10 * Unless required by applicable law or agreed to in writing, software
     11 * distributed under the License is distributed on an "AS IS" BASIS,
     12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13 * See the License for the specific language governing permissions and
     14 * limitations under the License.
     15 */
     16 
     17 #include "GL2Encoder.h"
     18 #include "GLESv2Validation.h"
     19 
     20 #include <string>
     21 #include <map>
     22 
     23 #include <assert.h>
     24 #include <ctype.h>
     25 
     26 #include <GLES2/gl2.h>
     27 #include <GLES2/gl2ext.h>
     28 #include <GLES2/gl2platform.h>
     29 
     30 #include <GLES3/gl3.h>
     31 #include <GLES3/gl31.h>
     32 
     33 #ifndef MIN
     34 #define MIN(a, b) ((a) < (b) ? (a) : (b))
     35 #endif
     36 
     37 static GLubyte *gVendorString= (GLubyte *) "Android";
     38 static GLubyte *gRendererString= (GLubyte *) "Android HW-GLES 3.0";
     39 static GLubyte *gVersionString= (GLubyte *) "OpenGL ES 3.0";
     40 static GLubyte *gExtensionsString= (GLubyte *) "GL_OES_EGL_image_external ";
     41 
     42 #define SET_ERROR_IF(condition, err) if((condition)) { \
     43         ALOGE("%s:%s:%d GL error 0x%x\n", __FILE__, __FUNCTION__, __LINE__, err); \
     44         ctx->setError(err); \
     45         return; \
     46     }
     47 
     48 #define SET_ERROR_WITH_MESSAGE_IF(condition, err, generator, genargs) if ((condition)) { \
     49         std::string msg = generator genargs; \
     50         ALOGE("%s:%s:%d GL error 0x%x\n" \
     51               "Info: %s\n", __FILE__, __FUNCTION__, __LINE__, err, msg.c_str()); \
     52         ctx->setError(err); \
     53         return; \
     54     } \
     55 
     56 #define RET_AND_SET_ERROR_IF(condition, err, ret) if((condition)) { \
     57         ALOGE("%s:%s:%d GL error 0x%x\n", __FILE__, __FUNCTION__, __LINE__, err); \
     58         ctx->setError(err);  \
     59         return ret; \
     60     } \
     61 
     62 #define RET_AND_SET_ERROR_WITH_MESSAGE_IF(condition, err, ret, generator, genargs) if((condition)) { \
     63         std::string msg = generator genargs; \
     64         ALOGE("%s:%s:%d GL error 0x%x\n" \
     65               "Info: %s\n", __FILE__, __FUNCTION__, __LINE__, err, msg.c_str()); \
     66         ctx->setError(err);   \
     67         return ret; \
     68     } \
     69 
     70 GL2Encoder::GL2Encoder(IOStream *stream, ChecksumCalculator *protocol)
     71         : gl2_encoder_context_t(stream, protocol)
     72 {
     73     m_currMajorVersion = 2;
     74     m_currMinorVersion = 0;
     75     m_initialized = false;
     76     m_state = NULL;
     77     m_error = GL_NO_ERROR;
     78     m_num_compressedTextureFormats = 0;
     79     m_max_cubeMapTextureSize = 0;
     80     m_max_renderBufferSize = 0;
     81     m_max_textureSize = 0;
     82     m_max_3d_textureSize = 0;
     83     m_max_vertexAttribStride = 0;
     84     m_compressedTextureFormats = NULL;
     85 
     86     m_ssbo_offset_align = 0;
     87     m_ubo_offset_align = 0;
     88 
     89     m_drawCallFlushCount = 0;
     90     m_primitiveRestartEnabled = false;
     91     m_primitiveRestartIndex = 0;
     92 
     93     // overrides
     94 #define OVERRIDE(name)  m_##name##_enc = this-> name ; this-> name = &s_##name
     95 #define OVERRIDE_CUSTOM(name)  this-> name = &s_##name
     96 #define OVERRIDEWITH(name, target)  do { \
     97     m_##target##_enc = this-> target; \
     98     this-> target = &s_##name; \
     99 } while(0)
    100 #define OVERRIDEOES(name) OVERRIDEWITH(name, name##OES)
    101 
    102     OVERRIDE(glFlush);
    103     OVERRIDE(glPixelStorei);
    104     OVERRIDE(glGetString);
    105     OVERRIDE(glBindBuffer);
    106     OVERRIDE(glBufferData);
    107     OVERRIDE(glBufferSubData);
    108     OVERRIDE(glDeleteBuffers);
    109     OVERRIDE(glDrawArrays);
    110     OVERRIDE(glDrawElements);
    111     OVERRIDE(glGetIntegerv);
    112     OVERRIDE(glGetFloatv);
    113     OVERRIDE(glGetBooleanv);
    114     OVERRIDE(glVertexAttribPointer);
    115     OVERRIDE(glEnableVertexAttribArray);
    116     OVERRIDE(glDisableVertexAttribArray);
    117     OVERRIDE(glGetVertexAttribiv);
    118     OVERRIDE(glGetVertexAttribfv);
    119     OVERRIDE(glGetVertexAttribPointerv);
    120 
    121     this->glShaderBinary = &s_glShaderBinary;
    122     this->glShaderSource = &s_glShaderSource;
    123     this->glFinish = &s_glFinish;
    124 
    125     OVERRIDE(glGetError);
    126     OVERRIDE(glLinkProgram);
    127     OVERRIDE(glDeleteProgram);
    128     OVERRIDE(glGetUniformiv);
    129     OVERRIDE(glGetUniformfv);
    130     OVERRIDE(glCreateProgram);
    131     OVERRIDE(glCreateShader);
    132     OVERRIDE(glDeleteShader);
    133     OVERRIDE(glAttachShader);
    134     OVERRIDE(glDetachShader);
    135     OVERRIDE(glGetAttachedShaders);
    136     OVERRIDE(glGetShaderSource);
    137     OVERRIDE(glGetShaderInfoLog);
    138     OVERRIDE(glGetProgramInfoLog);
    139 
    140     OVERRIDE(glGetUniformLocation);
    141     OVERRIDE(glUseProgram);
    142 
    143     OVERRIDE(glUniform1f);
    144     OVERRIDE(glUniform1fv);
    145     OVERRIDE(glUniform1i);
    146     OVERRIDE(glUniform1iv);
    147     OVERRIDE(glUniform2f);
    148     OVERRIDE(glUniform2fv);
    149     OVERRIDE(glUniform2i);
    150     OVERRIDE(glUniform2iv);
    151     OVERRIDE(glUniform3f);
    152     OVERRIDE(glUniform3fv);
    153     OVERRIDE(glUniform3i);
    154     OVERRIDE(glUniform3iv);
    155     OVERRIDE(glUniform4f);
    156     OVERRIDE(glUniform4fv);
    157     OVERRIDE(glUniform4i);
    158     OVERRIDE(glUniform4iv);
    159     OVERRIDE(glUniformMatrix2fv);
    160     OVERRIDE(glUniformMatrix3fv);
    161     OVERRIDE(glUniformMatrix4fv);
    162 
    163     OVERRIDE(glActiveTexture);
    164     OVERRIDE(glBindTexture);
    165     OVERRIDE(glDeleteTextures);
    166     OVERRIDE(glGetTexParameterfv);
    167     OVERRIDE(glGetTexParameteriv);
    168     OVERRIDE(glTexParameterf);
    169     OVERRIDE(glTexParameterfv);
    170     OVERRIDE(glTexParameteri);
    171     OVERRIDE(glTexParameteriv);
    172     OVERRIDE(glTexImage2D);
    173     OVERRIDE(glTexSubImage2D);
    174     OVERRIDE(glCopyTexImage2D);
    175 
    176     OVERRIDE(glGenRenderbuffers);
    177     OVERRIDE(glDeleteRenderbuffers);
    178     OVERRIDE(glBindRenderbuffer);
    179     OVERRIDE(glRenderbufferStorage);
    180     OVERRIDE(glFramebufferRenderbuffer);
    181 
    182     OVERRIDE(glGenFramebuffers);
    183     OVERRIDE(glDeleteFramebuffers);
    184     OVERRIDE(glBindFramebuffer);
    185     OVERRIDE(glFramebufferTexture2D);
    186     OVERRIDE(glFramebufferTexture3DOES);
    187     OVERRIDE(glGetFramebufferAttachmentParameteriv);
    188 
    189     OVERRIDE(glCheckFramebufferStatus);
    190 
    191     OVERRIDE(glGenVertexArrays);
    192     OVERRIDE(glDeleteVertexArrays);
    193     OVERRIDE(glBindVertexArray);
    194     OVERRIDEOES(glGenVertexArrays);
    195     OVERRIDEOES(glDeleteVertexArrays);
    196     OVERRIDEOES(glBindVertexArray);
    197 
    198     OVERRIDE_CUSTOM(glMapBufferRange);
    199     OVERRIDE_CUSTOM(glUnmapBuffer);
    200     OVERRIDE_CUSTOM(glFlushMappedBufferRange);
    201 
    202     OVERRIDE(glCompressedTexImage2D);
    203     OVERRIDE(glCompressedTexSubImage2D);
    204 
    205     OVERRIDE(glBindBufferRange);
    206     OVERRIDE(glBindBufferBase);
    207 
    208     OVERRIDE(glCopyBufferSubData);
    209 
    210     OVERRIDE(glGetBufferParameteriv);
    211     OVERRIDE(glGetBufferParameteri64v);
    212     OVERRIDE(glGetBufferPointerv);
    213 
    214     OVERRIDE_CUSTOM(glGetUniformIndices);
    215 
    216     OVERRIDE(glUniform1ui);
    217     OVERRIDE(glUniform2ui);
    218     OVERRIDE(glUniform3ui);
    219     OVERRIDE(glUniform4ui);
    220     OVERRIDE(glUniform1uiv);
    221     OVERRIDE(glUniform2uiv);
    222     OVERRIDE(glUniform3uiv);
    223     OVERRIDE(glUniform4uiv);
    224     OVERRIDE(glUniformMatrix2x3fv);
    225     OVERRIDE(glUniformMatrix3x2fv);
    226     OVERRIDE(glUniformMatrix2x4fv);
    227     OVERRIDE(glUniformMatrix4x2fv);
    228     OVERRIDE(glUniformMatrix3x4fv);
    229     OVERRIDE(glUniformMatrix4x3fv);
    230 
    231     OVERRIDE(glGetUniformuiv);
    232     OVERRIDE(glGetActiveUniformBlockiv);
    233 
    234     OVERRIDE(glGetVertexAttribIiv);
    235     OVERRIDE(glGetVertexAttribIuiv);
    236 
    237     OVERRIDE_CUSTOM(glVertexAttribIPointer);
    238 
    239     OVERRIDE(glVertexAttribDivisor);
    240 
    241     OVERRIDE(glRenderbufferStorageMultisample);
    242     OVERRIDE(glDrawBuffers);
    243     OVERRIDE(glReadBuffer);
    244     OVERRIDE(glFramebufferTextureLayer);
    245     OVERRIDE(glTexStorage2D);
    246 
    247     OVERRIDE_CUSTOM(glTransformFeedbackVaryings);
    248     OVERRIDE(glBeginTransformFeedback);
    249     OVERRIDE(glEndTransformFeedback);
    250     OVERRIDE(glPauseTransformFeedback);
    251     OVERRIDE(glResumeTransformFeedback);
    252 
    253     OVERRIDE(glTexImage3D);
    254     OVERRIDE(glTexSubImage3D);
    255     OVERRIDE(glTexStorage3D);
    256     OVERRIDE(glCompressedTexImage3D);
    257     OVERRIDE(glCompressedTexSubImage3D);
    258 
    259     OVERRIDE(glDrawArraysInstanced);
    260     OVERRIDE_CUSTOM(glDrawElementsInstanced);
    261     OVERRIDE_CUSTOM(glDrawRangeElements);
    262 
    263     OVERRIDE_CUSTOM(glGetStringi);
    264     OVERRIDE(glGetProgramBinary);
    265     OVERRIDE(glReadPixels);
    266 
    267     OVERRIDE(glEnable);
    268     OVERRIDE(glDisable);
    269     OVERRIDE(glClearBufferiv);
    270     OVERRIDE(glClearBufferuiv);
    271     OVERRIDE(glClearBufferfv);
    272     OVERRIDE(glBlitFramebuffer);
    273     OVERRIDE_CUSTOM(glGetInternalformativ);
    274 
    275     OVERRIDE(glGenerateMipmap);
    276 
    277     OVERRIDE(glBindSampler);
    278 
    279     OVERRIDE_CUSTOM(glFenceSync);
    280     OVERRIDE_CUSTOM(glClientWaitSync);
    281     OVERRIDE_CUSTOM(glWaitSync);
    282     OVERRIDE_CUSTOM(glDeleteSync);
    283     OVERRIDE_CUSTOM(glIsSync);
    284     OVERRIDE_CUSTOM(glGetSynciv);
    285 
    286     OVERRIDE(glGetIntegeri_v);
    287     OVERRIDE(glGetInteger64i_v);
    288     OVERRIDE(glGetInteger64v);
    289     OVERRIDE(glGetBooleani_v);
    290 
    291     OVERRIDE(glGetShaderiv);
    292 
    293     OVERRIDE(glActiveShaderProgram);
    294     OVERRIDE_CUSTOM(glCreateShaderProgramv);
    295     OVERRIDE(glProgramUniform1f);
    296     OVERRIDE(glProgramUniform1fv);
    297     OVERRIDE(glProgramUniform1i);
    298     OVERRIDE(glProgramUniform1iv);
    299     OVERRIDE(glProgramUniform1ui);
    300     OVERRIDE(glProgramUniform1uiv);
    301     OVERRIDE(glProgramUniform2f);
    302     OVERRIDE(glProgramUniform2fv);
    303     OVERRIDE(glProgramUniform2i);
    304     OVERRIDE(glProgramUniform2iv);
    305     OVERRIDE(glProgramUniform2ui);
    306     OVERRIDE(glProgramUniform2uiv);
    307     OVERRIDE(glProgramUniform3f);
    308     OVERRIDE(glProgramUniform3fv);
    309     OVERRIDE(glProgramUniform3i);
    310     OVERRIDE(glProgramUniform3iv);
    311     OVERRIDE(glProgramUniform3ui);
    312     OVERRIDE(glProgramUniform3uiv);
    313     OVERRIDE(glProgramUniform4f);
    314     OVERRIDE(glProgramUniform4fv);
    315     OVERRIDE(glProgramUniform4i);
    316     OVERRIDE(glProgramUniform4iv);
    317     OVERRIDE(glProgramUniform4ui);
    318     OVERRIDE(glProgramUniform4uiv);
    319     OVERRIDE(glProgramUniformMatrix2fv);
    320     OVERRIDE(glProgramUniformMatrix2x3fv);
    321     OVERRIDE(glProgramUniformMatrix2x4fv);
    322     OVERRIDE(glProgramUniformMatrix3fv);
    323     OVERRIDE(glProgramUniformMatrix3x2fv);
    324     OVERRIDE(glProgramUniformMatrix3x4fv);
    325     OVERRIDE(glProgramUniformMatrix4fv);
    326     OVERRIDE(glProgramUniformMatrix4x2fv);
    327     OVERRIDE(glProgramUniformMatrix4x3fv);
    328 
    329     OVERRIDE(glProgramParameteri);
    330     OVERRIDE(glUseProgramStages);
    331     OVERRIDE(glBindProgramPipeline);
    332 
    333     OVERRIDE(glGetProgramResourceiv);
    334     OVERRIDE(glGetProgramResourceIndex);
    335     OVERRIDE(glGetProgramResourceLocation);
    336     OVERRIDE(glGetProgramResourceName);
    337     OVERRIDE(glGetProgramPipelineInfoLog);
    338 
    339     OVERRIDE(glVertexAttribFormat);
    340     OVERRIDE(glVertexAttribIFormat);
    341     OVERRIDE(glVertexBindingDivisor);
    342     OVERRIDE(glVertexAttribBinding);
    343     OVERRIDE(glBindVertexBuffer);
    344 
    345     OVERRIDE_CUSTOM(glDrawArraysIndirect);
    346     OVERRIDE_CUSTOM(glDrawElementsIndirect);
    347 
    348     OVERRIDE(glTexStorage2DMultisample);
    349 }
    350 
    351 GL2Encoder::~GL2Encoder()
    352 {
    353     delete m_compressedTextureFormats;
    354 }
    355 
    356 GLenum GL2Encoder::s_glGetError(void * self)
    357 {
    358     GL2Encoder *ctx = (GL2Encoder *)self;
    359     GLenum err = ctx->getError();
    360     if(err != GL_NO_ERROR) {
    361         ctx->m_glGetError_enc(ctx); // also clear host error
    362         ctx->setError(GL_NO_ERROR);
    363         return err;
    364     }
    365 
    366     return ctx->m_glGetError_enc(self);
    367 }
    368 
    369 class GL2Encoder::ErrorUpdater {
    370 public:
    371     ErrorUpdater(GL2Encoder* ctx) :
    372         mCtx(ctx),
    373         guest_error(ctx->getError()),
    374         host_error(ctx->m_glGetError_enc(ctx)) {
    375             // Preserve any existing GL error in the guest:
    376             // OpenGL ES 3.0.5 spec:
    377             // The command enum GetError( void ); is used to obtain error information.
    378             // Each detectable error is assigned a numeric code. When an error is
    379             // detected, a flag is set and the code is recorded. Further errors, if
    380             // they occur, do not affect this recorded code. When GetError is called,
    381             // the code is returned and the flag is cleared, so that a further error
    382             // will again record its code. If a call to GetError returns NO_ERROR, then
    383             // there has been no detectable error since the last call to GetError (or
    384             // since the GL was initialized).
    385             if (guest_error == GL_NO_ERROR) {
    386                 guest_error = host_error;
    387             }
    388         }
    389 
    390     GLenum getHostErrorAndUpdate() {
    391         host_error = mCtx->m_glGetError_enc(mCtx);
    392         if (guest_error == GL_NO_ERROR) {
    393             guest_error = host_error;
    394         }
    395         return host_error;
    396     }
    397 
    398     void updateGuestErrorState() {
    399         mCtx->setError(guest_error);
    400     }
    401 
    402 private:
    403     GL2Encoder* mCtx;
    404     GLenum guest_error;
    405     GLenum host_error;
    406 };
    407 
    408 template<class T>
    409 class GL2Encoder::ScopedQueryUpdate {
    410 public:
    411     ScopedQueryUpdate(GL2Encoder* ctx, uint32_t bytes, T* target) :
    412         mCtx(ctx),
    413         mBuf(bytes, 0),
    414         mTarget(target),
    415         mErrorUpdater(ctx) {
    416     }
    417     T* hostStagingBuffer() {
    418         return (T*)&mBuf[0];
    419     }
    420     ~ScopedQueryUpdate() {
    421         GLint hostError = mErrorUpdater.getHostErrorAndUpdate();
    422         if (hostError == GL_NO_ERROR) {
    423             memcpy(mTarget, &mBuf[0], mBuf.size());
    424         }
    425         mErrorUpdater.updateGuestErrorState();
    426     }
    427 private:
    428     GL2Encoder* mCtx;
    429     std::vector<char> mBuf;
    430     T* mTarget;
    431     ErrorUpdater mErrorUpdater;
    432 };
    433 
    434 void GL2Encoder::safe_glGetBooleanv(GLenum param, GLboolean* val) {
    435     ScopedQueryUpdate<GLboolean> query(this, glUtilsParamSize(param) * sizeof(GLboolean), val);
    436     m_glGetBooleanv_enc(this, param, query.hostStagingBuffer());
    437 }
    438 
    439 void GL2Encoder::safe_glGetFloatv(GLenum param, GLfloat* val) {
    440     ScopedQueryUpdate<GLfloat> query(this, glUtilsParamSize(param) * sizeof(GLfloat), val);
    441     m_glGetFloatv_enc(this, param, query.hostStagingBuffer());
    442 }
    443 
    444 void GL2Encoder::safe_glGetIntegerv(GLenum param, GLint* val) {
    445     ScopedQueryUpdate<GLint> query(this, glUtilsParamSize(param) * sizeof(GLint), val);
    446     m_glGetIntegerv_enc(this, param, query.hostStagingBuffer());
    447 }
    448 
    449 void GL2Encoder::safe_glGetInteger64v(GLenum param, GLint64* val) {
    450     ScopedQueryUpdate<GLint64> query(this, glUtilsParamSize(param) * sizeof(GLint64), val);
    451     m_glGetInteger64v_enc(this, param, query.hostStagingBuffer());
    452 }
    453 
    454 void GL2Encoder::safe_glGetIntegeri_v(GLenum param, GLuint index, GLint* val) {
    455     ScopedQueryUpdate<GLint> query(this, sizeof(GLint), val);
    456     m_glGetIntegeri_v_enc(this, param, index, query.hostStagingBuffer());
    457 }
    458 
    459 void GL2Encoder::safe_glGetInteger64i_v(GLenum param, GLuint index, GLint64* val) {
    460     ScopedQueryUpdate<GLint64> query(this, sizeof(GLint64), val);
    461     m_glGetInteger64i_v_enc(this, param, index, query.hostStagingBuffer());
    462 }
    463 
    464 void GL2Encoder::safe_glGetBooleani_v(GLenum param, GLuint index, GLboolean* val) {
    465     ScopedQueryUpdate<GLboolean> query(this, sizeof(GLboolean), val);
    466     m_glGetBooleani_v_enc(this, param, index, query.hostStagingBuffer());
    467 }
    468 
    469 void GL2Encoder::s_glFlush(void *self)
    470 {
    471     GL2Encoder *ctx = (GL2Encoder *) self;
    472     ctx->m_glFlush_enc(self);
    473     ctx->m_stream->flush();
    474 }
    475 
    476 const GLubyte *GL2Encoder::s_glGetString(void *self, GLenum name)
    477 {
    478     GL2Encoder *ctx = (GL2Encoder *)self;
    479 
    480     GLubyte *retval =  (GLubyte *) "";
    481     RET_AND_SET_ERROR_IF(
    482         name != GL_VENDOR &&
    483         name != GL_RENDERER &&
    484         name != GL_VERSION &&
    485         name != GL_EXTENSIONS,
    486         GL_INVALID_ENUM,
    487         retval);
    488     switch(name) {
    489     case GL_VENDOR:
    490         retval = gVendorString;
    491         break;
    492     case GL_RENDERER:
    493         retval = gRendererString;
    494         break;
    495     case GL_VERSION:
    496         retval = gVersionString;
    497         break;
    498     case GL_EXTENSIONS:
    499         retval = gExtensionsString;
    500         break;
    501     }
    502     return retval;
    503 }
    504 
    505 void GL2Encoder::s_glPixelStorei(void *self, GLenum param, GLint value)
    506 {
    507     GL2Encoder *ctx = (GL2Encoder *)self;
    508     SET_ERROR_IF(!GLESv2Validation::pixelStoreParam(ctx, param), GL_INVALID_ENUM);
    509     SET_ERROR_IF(!GLESv2Validation::pixelStoreValue(param, value), GL_INVALID_VALUE);
    510     ctx->m_glPixelStorei_enc(ctx, param, value);
    511     assert(ctx->m_state != NULL);
    512     ctx->m_state->setPixelStore(param, value);
    513 }
    514 void GL2Encoder::s_glBindBuffer(void *self, GLenum target, GLuint id)
    515 {
    516     GL2Encoder *ctx = (GL2Encoder *) self;
    517     assert(ctx->m_state != NULL);
    518     ctx->m_state->bindBuffer(target, id);
    519     ctx->m_state->addBuffer(id);
    520     // TODO set error state if needed;
    521     ctx->m_glBindBuffer_enc(self, target, id);
    522 }
    523 
    524 void GL2Encoder::s_glBufferData(void * self, GLenum target, GLsizeiptr size, const GLvoid * data, GLenum usage)
    525 {
    526     GL2Encoder *ctx = (GL2Encoder *) self;
    527     SET_ERROR_IF(!GLESv2Validation::bufferTarget(ctx, target), GL_INVALID_ENUM);
    528     GLuint bufferId = ctx->m_state->getBuffer(target);
    529     SET_ERROR_IF(bufferId==0, GL_INVALID_OPERATION);
    530     SET_ERROR_IF(size<0, GL_INVALID_VALUE);
    531 
    532     ctx->m_shared->updateBufferData(bufferId, size, (void*)data);
    533     ctx->m_shared->setBufferUsage(bufferId, usage);
    534     ctx->m_glBufferData_enc(self, target, size, data, usage);
    535 }
    536 
    537 void GL2Encoder::s_glBufferSubData(void * self, GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid * data)
    538 {
    539     GL2Encoder *ctx = (GL2Encoder *) self;
    540     SET_ERROR_IF(!GLESv2Validation::bufferTarget(ctx, target), GL_INVALID_ENUM);
    541     GLuint bufferId = ctx->m_state->getBuffer(target);
    542     SET_ERROR_IF(bufferId==0, GL_INVALID_OPERATION);
    543     SET_ERROR_IF(ctx->isBufferTargetMapped(target), GL_INVALID_OPERATION);
    544 
    545     GLenum res = ctx->m_shared->subUpdateBufferData(bufferId, offset, size, (void*)data);
    546     SET_ERROR_IF(res, res);
    547 
    548     ctx->m_glBufferSubData_enc(self, target, offset, size, data);
    549 }
    550 
    551 void GL2Encoder::s_glGenBuffers(void* self, GLsizei n, GLuint* buffers) {
    552     GL2Encoder *ctx = (GL2Encoder *) self;
    553     SET_ERROR_IF(n<0, GL_INVALID_VALUE);
    554     ctx->m_glGenBuffers_enc(self, n, buffers);
    555     for (int i = 0; i < n; i++) {
    556         ctx->m_state->addBuffer(buffers[i]);
    557     }
    558 }
    559 
    560 void GL2Encoder::s_glDeleteBuffers(void * self, GLsizei n, const GLuint * buffers)
    561 {
    562     GL2Encoder *ctx = (GL2Encoder *) self;
    563     SET_ERROR_IF(n<0, GL_INVALID_VALUE);
    564     for (int i=0; i<n; i++) {
    565         // Technically if the buffer is mapped, we should unmap it, but we won't
    566         // use it anymore after this :)
    567         ctx->m_shared->deleteBufferData(buffers[i]);
    568         ctx->m_state->unBindBuffer(buffers[i]);
    569         ctx->m_state->removeBuffer(buffers[i]);
    570         ctx->m_glDeleteBuffers_enc(self,1,&buffers[i]);
    571     }
    572 }
    573 
    574 static bool isValidVertexAttribIndex(void *self, GLuint indx)
    575 {
    576     GL2Encoder *ctx = (GL2Encoder *)self;
    577     GLint maxIndex;
    578     ctx->glGetIntegerv(self, GL_MAX_VERTEX_ATTRIBS, &maxIndex);
    579     return indx < maxIndex;
    580 }
    581 
    582 #define VALIDATE_VERTEX_ATTRIB_INDEX(index) \
    583     SET_ERROR_WITH_MESSAGE_IF( \
    584             !isValidVertexAttribIndex(self, index), GL_INVALID_VALUE, \
    585             GLESv2Validation::vertexAttribIndexRangeErrorMsg, (ctx, index)); \
    586 
    587 void GL2Encoder::s_glVertexAttribPointer(void *self, GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid * ptr)
    588 {
    589     GL2Encoder *ctx = (GL2Encoder *)self;
    590     assert(ctx->m_state != NULL);
    591     VALIDATE_VERTEX_ATTRIB_INDEX(indx);
    592     SET_ERROR_IF((size < 1 || size > 4), GL_INVALID_VALUE);
    593     SET_ERROR_IF(!GLESv2Validation::vertexAttribType(ctx, type), GL_INVALID_ENUM);
    594     SET_ERROR_IF(stride < 0, GL_INVALID_VALUE);
    595     SET_ERROR_IF((type == GL_INT_2_10_10_10_REV ||
    596                   type == GL_UNSIGNED_INT_2_10_10_10_REV) &&
    597                  size != 4,
    598                  GL_INVALID_OPERATION);
    599     ctx->m_state->setVertexAttribBinding(indx, indx);
    600     ctx->m_state->setVertexAttribFormat(indx, size, type, normalized, 0, false);
    601 
    602     GLsizei effectiveStride = stride;
    603     if (stride == 0) {
    604         effectiveStride = glSizeof(type) * size;
    605         switch (type) {
    606             case GL_INT_2_10_10_10_REV:
    607             case GL_UNSIGNED_INT_2_10_10_10_REV:
    608                 effectiveStride /= 4;
    609                 break;
    610             default:
    611                 break;
    612         }
    613     }
    614 
    615     ctx->m_state->bindIndexedBuffer(0, indx, ctx->m_state->currentArrayVbo(), (uintptr_t)ptr, 0, stride, effectiveStride);
    616 
    617     if (ctx->m_state->currentArrayVbo() != 0) {
    618         ctx->glVertexAttribPointerOffset(ctx, indx, size, type, normalized, stride, (uintptr_t)ptr);
    619     } else {
    620         SET_ERROR_IF(ctx->m_state->currentVertexArrayObject() != 0 && ptr, GL_INVALID_OPERATION);
    621         // wait for client-array handler
    622     }
    623 }
    624 
    625 void GL2Encoder::s_glGetIntegerv(void *self, GLenum param, GLint *ptr)
    626 {
    627     GL2Encoder *ctx = (GL2Encoder *) self;
    628     assert(ctx->m_state != NULL);
    629     GLClientState* state = ctx->m_state;
    630 
    631     switch (param) {
    632     case GL_MAJOR_VERSION:
    633         *ptr = ctx->m_deviceMajorVersion;
    634         break;
    635     case GL_MINOR_VERSION:
    636         *ptr = ctx->m_deviceMinorVersion;
    637         break;
    638     case GL_NUM_SHADER_BINARY_FORMATS:
    639         *ptr = 0;
    640         break;
    641     case GL_SHADER_BINARY_FORMATS:
    642         // do nothing
    643         break;
    644 
    645     case GL_COMPRESSED_TEXTURE_FORMATS: {
    646         GLint *compressedTextureFormats = ctx->getCompressedTextureFormats();
    647         if (ctx->m_num_compressedTextureFormats > 0 &&
    648                 compressedTextureFormats != NULL) {
    649             memcpy(ptr, compressedTextureFormats,
    650                     ctx->m_num_compressedTextureFormats * sizeof(GLint));
    651         }
    652         break;
    653     }
    654 
    655     case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS:
    656     case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:
    657     case GL_MAX_TEXTURE_IMAGE_UNITS:
    658         ctx->safe_glGetIntegerv(param, ptr);
    659         *ptr = MIN(*ptr, GLClientState::MAX_TEXTURE_UNITS);
    660         break;
    661 
    662     case GL_TEXTURE_BINDING_2D:
    663         *ptr = state->getBoundTexture(GL_TEXTURE_2D);
    664         break;
    665     case GL_TEXTURE_BINDING_EXTERNAL_OES:
    666         *ptr = state->getBoundTexture(GL_TEXTURE_EXTERNAL_OES);
    667         break;
    668 
    669     case GL_MAX_VERTEX_ATTRIBS:
    670         if (!ctx->m_state->getClientStateParameter<GLint>(param, ptr)) {
    671             ctx->safe_glGetIntegerv(param, ptr);
    672             ctx->m_state->setMaxVertexAttribs(*ptr);
    673         }
    674         break;
    675     case GL_MAX_VERTEX_ATTRIB_STRIDE:
    676         if (ctx->m_max_vertexAttribStride != 0) {
    677             *ptr = ctx->m_max_vertexAttribStride;
    678         } else {
    679             ctx->safe_glGetIntegerv(param, ptr);
    680             ctx->m_max_vertexAttribStride = *ptr;
    681         }
    682         break;
    683     case GL_MAX_CUBE_MAP_TEXTURE_SIZE:
    684         if (ctx->m_max_cubeMapTextureSize != 0) {
    685             *ptr = ctx->m_max_cubeMapTextureSize;
    686         } else {
    687             ctx->safe_glGetIntegerv(param, ptr);
    688             ctx->m_max_cubeMapTextureSize = *ptr;
    689         }
    690         break;
    691     case GL_MAX_RENDERBUFFER_SIZE:
    692         if (ctx->m_max_renderBufferSize != 0) {
    693             *ptr = ctx->m_max_renderBufferSize;
    694         } else {
    695             ctx->safe_glGetIntegerv(param, ptr);
    696             ctx->m_max_renderBufferSize = *ptr;
    697         }
    698         break;
    699     case GL_MAX_TEXTURE_SIZE:
    700         if (ctx->m_max_textureSize != 0) {
    701             *ptr = ctx->m_max_textureSize;
    702         } else {
    703             ctx->safe_glGetIntegerv(param, ptr);
    704             ctx->m_max_textureSize = *ptr;
    705         }
    706         break;
    707     case GL_MAX_3D_TEXTURE_SIZE:
    708         if (ctx->m_max_3d_textureSize != 0) {
    709             *ptr = ctx->m_max_3d_textureSize;
    710         } else {
    711             ctx->safe_glGetIntegerv(param, ptr);
    712             ctx->m_max_3d_textureSize = *ptr;
    713         }
    714         break;
    715     case GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT:
    716         if (ctx->m_ssbo_offset_align != 0) {
    717             *ptr = ctx->m_ssbo_offset_align;
    718         } else {
    719             ctx->safe_glGetIntegerv(param, ptr);
    720             ctx->m_ssbo_offset_align = *ptr;
    721         }
    722         break;
    723     case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT:
    724         if (ctx->m_ubo_offset_align != 0) {
    725             *ptr = ctx->m_ubo_offset_align;
    726         } else {
    727             ctx->safe_glGetIntegerv(param, ptr);
    728             ctx->m_ubo_offset_align = *ptr;
    729         }
    730         break;
    731     // Desktop OpenGL can allow a mindboggling # samples per pixel (such as 64).
    732     // Limit to 4 (spec minimum) to keep dEQP tests from timing out.
    733     case GL_MAX_SAMPLES:
    734     case GL_MAX_COLOR_TEXTURE_SAMPLES:
    735     case GL_MAX_INTEGER_SAMPLES:
    736     case GL_MAX_DEPTH_TEXTURE_SAMPLES:
    737         *ptr = 4;
    738         break;
    739     // Checks for version-incompatible enums.
    740     // Not allowed in vanilla ES 2.0.
    741     case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:
    742     case GL_MAX_UNIFORM_BUFFER_BINDINGS:
    743         SET_ERROR_IF(ctx->majorVersion() < 3, GL_INVALID_ENUM);
    744         ctx->safe_glGetIntegerv(param, ptr);
    745         break;
    746     case GL_MAX_COLOR_ATTACHMENTS:
    747     case GL_MAX_DRAW_BUFFERS:
    748         SET_ERROR_IF(ctx->majorVersion() < 3 &&
    749                      !ctx->hasExtension("GL_EXT_draw_buffers"), GL_INVALID_ENUM);
    750         ctx->safe_glGetIntegerv(param, ptr);
    751         break;
    752     // Not allowed in ES 3.0.
    753     case GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS:
    754     case GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS:
    755     case GL_MAX_VERTEX_ATTRIB_BINDINGS:
    756         SET_ERROR_IF(ctx->majorVersion() < 3 ||
    757                      (ctx->majorVersion() == 3 &&
    758                       ctx->minorVersion() == 0), GL_INVALID_ENUM);
    759         ctx->safe_glGetIntegerv(param, ptr);
    760         break;
    761     default:
    762         if (!ctx->m_state->getClientStateParameter<GLint>(param, ptr)) {
    763             ctx->safe_glGetIntegerv(param, ptr);
    764         }
    765         break;
    766     }
    767 }
    768 
    769 
    770 void GL2Encoder::s_glGetFloatv(void *self, GLenum param, GLfloat *ptr)
    771 {
    772     GL2Encoder *ctx = (GL2Encoder *)self;
    773     assert(ctx->m_state != NULL);
    774     GLClientState* state = ctx->m_state;
    775 
    776     switch (param) {
    777     case GL_NUM_SHADER_BINARY_FORMATS:
    778         *ptr = 0;
    779         break;
    780     case GL_SHADER_BINARY_FORMATS:
    781         // do nothing
    782         break;
    783 
    784     case GL_COMPRESSED_TEXTURE_FORMATS: {
    785         GLint *compressedTextureFormats = ctx->getCompressedTextureFormats();
    786         if (ctx->m_num_compressedTextureFormats > 0 &&
    787                 compressedTextureFormats != NULL) {
    788             for (int i = 0; i < ctx->m_num_compressedTextureFormats; i++) {
    789                 ptr[i] = (GLfloat) compressedTextureFormats[i];
    790             }
    791         }
    792         break;
    793     }
    794 
    795     case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS:
    796     case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:
    797     case GL_MAX_TEXTURE_IMAGE_UNITS:
    798         ctx->safe_glGetFloatv(param, ptr);
    799         *ptr = MIN(*ptr, (GLfloat)GLClientState::MAX_TEXTURE_UNITS);
    800         break;
    801 
    802     case GL_TEXTURE_BINDING_2D:
    803         *ptr = (GLfloat)state->getBoundTexture(GL_TEXTURE_2D);
    804         break;
    805     case GL_TEXTURE_BINDING_EXTERNAL_OES:
    806         *ptr = (GLfloat)state->getBoundTexture(GL_TEXTURE_EXTERNAL_OES);
    807         break;
    808 
    809     default:
    810         if (!ctx->m_state->getClientStateParameter<GLfloat>(param, ptr)) {
    811             ctx->safe_glGetFloatv(param, ptr);
    812         }
    813         break;
    814     }
    815 }
    816 
    817 
    818 void GL2Encoder::s_glGetBooleanv(void *self, GLenum param, GLboolean *ptr)
    819 {
    820     GL2Encoder *ctx = (GL2Encoder *)self;
    821     assert(ctx->m_state != NULL);
    822     GLClientState* state = ctx->m_state;
    823 
    824     switch (param) {
    825     case GL_NUM_SHADER_BINARY_FORMATS:
    826         *ptr = GL_FALSE;
    827         break;
    828     case GL_SHADER_BINARY_FORMATS:
    829         // do nothing
    830         break;
    831 
    832     case GL_COMPRESSED_TEXTURE_FORMATS: {
    833         GLint *compressedTextureFormats = ctx->getCompressedTextureFormats();
    834         if (ctx->m_num_compressedTextureFormats > 0 &&
    835                 compressedTextureFormats != NULL) {
    836             for (int i = 0; i < ctx->m_num_compressedTextureFormats; i++) {
    837                 ptr[i] = compressedTextureFormats[i] != 0 ? GL_TRUE : GL_FALSE;
    838             }
    839         }
    840         break;
    841     }
    842 
    843     case GL_TEXTURE_BINDING_2D:
    844         *ptr = state->getBoundTexture(GL_TEXTURE_2D) != 0 ? GL_TRUE : GL_FALSE;
    845         break;
    846     case GL_TEXTURE_BINDING_EXTERNAL_OES:
    847         *ptr = state->getBoundTexture(GL_TEXTURE_EXTERNAL_OES) != 0
    848                 ? GL_TRUE : GL_FALSE;
    849         break;
    850 
    851     default:
    852         if (!ctx->m_state->getClientStateParameter<GLboolean>(param, ptr)) {
    853             ctx->safe_glGetBooleanv(param, ptr);
    854         }
    855         *ptr = (*ptr != 0) ? GL_TRUE : GL_FALSE;
    856         break;
    857     }
    858 }
    859 
    860 
    861 void GL2Encoder::s_glEnableVertexAttribArray(void *self, GLuint index)
    862 {
    863     GL2Encoder *ctx = (GL2Encoder *)self;
    864     assert(ctx->m_state);
    865     VALIDATE_VERTEX_ATTRIB_INDEX(index);
    866     ctx->m_glEnableVertexAttribArray_enc(ctx, index);
    867     ctx->m_state->enable(index, 1);
    868 }
    869 
    870 void GL2Encoder::s_glDisableVertexAttribArray(void *self, GLuint index)
    871 {
    872     GL2Encoder *ctx = (GL2Encoder *)self;
    873     assert(ctx->m_state);
    874     VALIDATE_VERTEX_ATTRIB_INDEX(index);
    875     ctx->m_glDisableVertexAttribArray_enc(ctx, index);
    876     ctx->m_state->enable(index, 0);
    877 }
    878 
    879 
    880 void GL2Encoder::s_glGetVertexAttribiv(void *self, GLuint index, GLenum pname, GLint *params)
    881 {
    882     GL2Encoder *ctx = (GL2Encoder *)self;
    883     assert(ctx->m_state);
    884     GLint maxIndex;
    885     ctx->glGetIntegerv(self, GL_MAX_VERTEX_ATTRIBS, &maxIndex);
    886     SET_ERROR_IF(!(index < maxIndex), GL_INVALID_VALUE);
    887 
    888     if (!ctx->m_state->getVertexAttribParameter<GLint>(index, pname, params)) {
    889         ctx->m_glGetVertexAttribiv_enc(self, index, pname, params);
    890     }
    891 }
    892 
    893 void GL2Encoder::s_glGetVertexAttribfv(void *self, GLuint index, GLenum pname, GLfloat *params)
    894 {
    895     GL2Encoder *ctx = (GL2Encoder *)self;
    896     assert(ctx->m_state);
    897     GLint maxIndex;
    898     ctx->glGetIntegerv(self, GL_MAX_VERTEX_ATTRIBS, &maxIndex);
    899     SET_ERROR_IF(!(index < maxIndex), GL_INVALID_VALUE);
    900 
    901     if (!ctx->m_state->getVertexAttribParameter<GLfloat>(index, pname, params)) {
    902         ctx->m_glGetVertexAttribfv_enc(self, index, pname, params);
    903     }
    904 }
    905 
    906 void GL2Encoder::s_glGetVertexAttribPointerv(void *self, GLuint index, GLenum pname, GLvoid **pointer)
    907 {
    908     GL2Encoder *ctx = (GL2Encoder *)self;
    909     if (ctx->m_state == NULL) return;
    910     GLint maxIndex;
    911     ctx->glGetIntegerv(self, GL_MAX_VERTEX_ATTRIBS, &maxIndex);
    912     SET_ERROR_IF(!(index < maxIndex), GL_INVALID_VALUE);
    913     SET_ERROR_IF(pname != GL_VERTEX_ATTRIB_ARRAY_POINTER, GL_INVALID_ENUM);
    914     (void)pname;
    915 
    916     *pointer = (GLvoid*)(ctx->m_state->getCurrAttributeBindingInfo(index).offset);
    917 }
    918 
    919 void GL2Encoder::calcIndexRange(const void* indices,
    920                                 GLenum type,
    921                                 GLsizei count,
    922                                 int* minIndex_out,
    923                                 int* maxIndex_out) {
    924     switch(type) {
    925     case GL_BYTE:
    926     case GL_UNSIGNED_BYTE:
    927         GLUtils::minmaxExcept(
    928                 (unsigned char *)indices, count,
    929                 minIndex_out, maxIndex_out,
    930                 m_primitiveRestartEnabled, GLUtils::primitiveRestartIndex<unsigned char>());
    931         break;
    932     case GL_SHORT:
    933     case GL_UNSIGNED_SHORT:
    934         GLUtils::minmaxExcept(
    935                 (unsigned short *)indices, count,
    936                 minIndex_out, maxIndex_out,
    937                 m_primitiveRestartEnabled, GLUtils::primitiveRestartIndex<unsigned short>());
    938         break;
    939     case GL_INT:
    940     case GL_UNSIGNED_INT:
    941         GLUtils::minmaxExcept(
    942                 (unsigned int *)indices, count,
    943                 minIndex_out, maxIndex_out,
    944                 m_primitiveRestartEnabled, GLUtils::primitiveRestartIndex<unsigned int>());
    945         break;
    946     default:
    947         ALOGE("unsupported index buffer type %d\n", type);
    948     }
    949 }
    950 
    951 void* GL2Encoder::recenterIndices(const void* src,
    952                                   GLenum type,
    953                                   GLsizei count,
    954                                   int minIndex) {
    955 
    956     void* adjustedIndices = (void*)src;
    957 
    958     if (minIndex != 0) {
    959         adjustedIndices = m_fixedBuffer.alloc(glSizeof(type) * count);
    960         switch(type) {
    961         case GL_BYTE:
    962         case GL_UNSIGNED_BYTE:
    963             GLUtils::shiftIndicesExcept(
    964                     (unsigned char *)src,
    965                     (unsigned char *)adjustedIndices,
    966                     count, -minIndex,
    967                     m_primitiveRestartEnabled,
    968                     (unsigned char)m_primitiveRestartIndex);
    969             break;
    970         case GL_SHORT:
    971         case GL_UNSIGNED_SHORT:
    972             GLUtils::shiftIndicesExcept(
    973                     (unsigned short *)src,
    974                     (unsigned short *)adjustedIndices,
    975                     count, -minIndex,
    976                     m_primitiveRestartEnabled,
    977                     (unsigned short)m_primitiveRestartIndex);
    978             break;
    979         case GL_INT:
    980         case GL_UNSIGNED_INT:
    981             GLUtils::shiftIndicesExcept(
    982                     (unsigned int *)src,
    983                     (unsigned int *)adjustedIndices,
    984                     count, -minIndex,
    985                     m_primitiveRestartEnabled,
    986                     (unsigned int)m_primitiveRestartIndex);
    987             break;
    988         default:
    989             ALOGE("unsupported index buffer type %d\n", type);
    990         }
    991     }
    992 
    993     return adjustedIndices;
    994 }
    995 
    996 void GL2Encoder::getBufferIndexRange(BufferData* buf,
    997                                      const void* dataWithOffset,
    998                                      GLenum type,
    999                                      size_t count,
   1000                                      size_t offset,
   1001                                      int* minIndex_out,
   1002                                      int* maxIndex_out) {
   1003 
   1004     if (buf->m_indexRangeCache.findRange(
   1005                 type, offset, count,
   1006                 m_primitiveRestartEnabled,
   1007                 minIndex_out,
   1008                 maxIndex_out)) {
   1009         return;
   1010     }
   1011 
   1012     calcIndexRange(dataWithOffset, type, count, minIndex_out, maxIndex_out);
   1013 
   1014     buf->m_indexRangeCache.addRange(
   1015             type, offset, count, m_primitiveRestartEnabled,
   1016             *minIndex_out, *maxIndex_out);
   1017 
   1018     ALOGV("%s: got range [%u %u] pr? %d", __FUNCTION__, *minIndex_out, *maxIndex_out, m_primitiveRestartEnabled);
   1019 }
   1020 
   1021 // For detecting legacy usage of glVertexAttribPointer
   1022 void GL2Encoder::getVBOUsage(bool* hasClientArrays, bool* hasVBOs) const {
   1023     if (hasClientArrays) *hasClientArrays = false;
   1024     if (hasVBOs) *hasVBOs = false;
   1025 
   1026     for (int i = 0; i < m_state->nLocations(); i++) {
   1027         const GLClientState::VertexAttribState& state = m_state->getState(i);
   1028         if (state.enabled) {
   1029             const GLClientState::BufferBinding& curr_binding = m_state->getCurrAttributeBindingInfo(i);
   1030             GLuint bufferObject = curr_binding.buffer;
   1031             if (bufferObject == 0 && curr_binding.offset && hasClientArrays) {
   1032                 *hasClientArrays = true;
   1033             }
   1034             if (bufferObject != 0 && hasVBOs) {
   1035                 *hasVBOs = true;
   1036             }
   1037         }
   1038     }
   1039 }
   1040 
   1041 void GL2Encoder::sendVertexAttributes(GLint first, GLsizei count, bool hasClientArrays, GLsizei primcount)
   1042 {
   1043     assert(m_state);
   1044 
   1045     GLuint currentVao = m_state->currentVertexArrayObject();
   1046     GLuint lastBoundVbo = m_state->currentArrayVbo();
   1047     for (int i = 0; i < m_state->nLocations(); i++) {
   1048         bool enableDirty;
   1049         const GLClientState::VertexAttribState& state = m_state->getStateAndEnableDirty(i, &enableDirty);
   1050 
   1051         if (!enableDirty && !state.enabled) {
   1052             continue;
   1053         }
   1054 
   1055         if (state.enabled) {
   1056             const GLClientState::BufferBinding& curr_binding = m_state->getCurrAttributeBindingInfo(i);
   1057             GLuint bufferObject = curr_binding.buffer;
   1058             if (hasClientArrays && lastBoundVbo != bufferObject) {
   1059                 this->m_glBindBuffer_enc(this, GL_ARRAY_BUFFER, bufferObject);
   1060                 lastBoundVbo = bufferObject;
   1061             }
   1062 
   1063             int divisor = curr_binding.divisor;
   1064             int stride = curr_binding.stride;
   1065             int effectiveStride = curr_binding.effectiveStride;
   1066             uintptr_t offset = curr_binding.offset;
   1067 
   1068             int firstIndex = effectiveStride * first;
   1069             if (firstIndex && divisor && !primcount) {
   1070                 // If firstIndex != 0 according to effectiveStride * first,
   1071                 // it needs to be adjusted if a divisor has been specified,
   1072                 // even if we are not in glDraw***Instanced.
   1073                 firstIndex = 0;
   1074             }
   1075 
   1076             if (bufferObject == 0) {
   1077                 unsigned int datalen = state.elementSize * count;
   1078                 if (divisor && primcount) {
   1079                     ALOGV("%s: divisor for att %d: %d, w/ stride %d (effective stride %d) size %d type 0x%x) datalen %u",
   1080                             __FUNCTION__, i, divisor, state.stride, effectiveStride, state.elementSize, state.type, datalen);
   1081                     int actual_count = std::max(1, (int)((primcount + divisor - 1) / divisor));
   1082                     datalen = state.elementSize * actual_count;
   1083                     ALOGV("%s: actual datalen %u", __FUNCTION__, datalen);
   1084                 }
   1085                 if (state.elementSize == 0) {
   1086                     // The vertex attribute array is uninitialized. Abandon it.
   1087                     ALOGE("a vertex attribute array is uninitialized. Skipping corresponding vertex attribute.");
   1088                     this->m_glDisableVertexAttribArray_enc(this, i);
   1089                     continue;
   1090                 }
   1091                 m_glEnableVertexAttribArray_enc(this, i);
   1092 
   1093                 if (datalen && (!offset || !((unsigned char*)offset + firstIndex))) {
   1094                     ALOGD("%s: bad offset / len!!!!!", __FUNCTION__);
   1095                     continue;
   1096                 }
   1097                 if (state.isInt) {
   1098                     this->glVertexAttribIPointerDataAEMU(this, i, state.size, state.type, stride, (unsigned char *)offset + firstIndex, datalen);
   1099                 } else {
   1100                     this->glVertexAttribPointerData(this, i, state.size, state.type, state.normalized, stride, (unsigned char *)offset + firstIndex, datalen);
   1101                 }
   1102             } else {
   1103                 const BufferData* buf = m_shared->getBufferData(bufferObject);
   1104                 // The following expression actually means bufLen = stride*count;
   1105                 // But the last element doesn't have to fill up the whole stride.
   1106                 // So it becomes the current form.
   1107                 unsigned int bufLen = effectiveStride * (count ? (count - 1) : 0) + state.elementSize;
   1108                 if (divisor && primcount) {
   1109                     int actual_count = std::max(1, (int)((primcount + divisor - 1) / divisor));
   1110                     bufLen = effectiveStride * (actual_count ? (actual_count - 1) : 0) + state.elementSize;
   1111                 }
   1112                 if (buf && firstIndex >= 0 && firstIndex + bufLen <= buf->m_size) {
   1113                     if (hasClientArrays) {
   1114                         m_glEnableVertexAttribArray_enc(this, i);
   1115                         if (state.isInt) {
   1116                             this->glVertexAttribIPointerOffsetAEMU(this, i, state.size, state.type, stride, offset + firstIndex);
   1117                         } else {
   1118                             this->glVertexAttribPointerOffset(this, i, state.size, state.type, state.normalized, stride, offset + firstIndex);
   1119                         }
   1120                     }
   1121                 } else {
   1122                     ALOGE("a vertex attribute index out of boundary is detected. Skipping corresponding vertex attribute. buf=%p", buf);
   1123                     if (buf) {
   1124                         ALOGE("Out of bounds vertex attribute info: "
   1125                                 "clientArray? %d attribute %d vbo %u allocedBufferSize %u bufferDataSpecified? %d wantedStart %u wantedEnd %u",
   1126                                 hasClientArrays, i, bufferObject, buf->m_size, buf != NULL, firstIndex, firstIndex + bufLen);
   1127                     }
   1128                     m_glDisableVertexAttribArray_enc(this, i);
   1129                 }
   1130             }
   1131         } else {
   1132             if (hasClientArrays) {
   1133                 this->m_glDisableVertexAttribArray_enc(this, i);
   1134             }
   1135         }
   1136     }
   1137 
   1138     if (hasClientArrays && lastBoundVbo != m_state->currentArrayVbo()) {
   1139         this->m_glBindBuffer_enc(this, GL_ARRAY_BUFFER, m_state->currentArrayVbo());
   1140     }
   1141 }
   1142 
   1143 void GL2Encoder::flushDrawCall() {
   1144     // This used to be every other draw call, but
   1145     // now that we are using real GPU buffers on host,
   1146     // set this to every 200 draw calls
   1147     // (tuned on z840 linux NVIDIA Quadro K2200)
   1148     if (m_drawCallFlushCount % 200 == 0) {
   1149         m_stream->flush();
   1150     }
   1151     m_drawCallFlushCount++;
   1152 }
   1153 
   1154 static bool isValidDrawMode(GLenum mode)
   1155 {
   1156     bool retval = false;
   1157     switch (mode) {
   1158     case GL_POINTS:
   1159     case GL_LINE_STRIP:
   1160     case GL_LINE_LOOP:
   1161     case GL_LINES:
   1162     case GL_TRIANGLE_STRIP:
   1163     case GL_TRIANGLE_FAN:
   1164     case GL_TRIANGLES:
   1165         retval = true;
   1166     }
   1167     return retval;
   1168 }
   1169 
   1170 void GL2Encoder::s_glDrawArrays(void *self, GLenum mode, GLint first, GLsizei count)
   1171 {
   1172     GL2Encoder *ctx = (GL2Encoder *)self;
   1173     assert(ctx->m_state != NULL);
   1174     SET_ERROR_IF(!isValidDrawMode(mode), GL_INVALID_ENUM);
   1175     SET_ERROR_IF(count < 0, GL_INVALID_VALUE);
   1176 
   1177     bool has_client_vertex_arrays = false;
   1178     bool has_indirect_arrays = false;
   1179     ctx->getVBOUsage(&has_client_vertex_arrays,
   1180                      &has_indirect_arrays);
   1181 
   1182     if (has_client_vertex_arrays ||
   1183         (!has_client_vertex_arrays &&
   1184          !has_indirect_arrays)) {
   1185         ctx->sendVertexAttributes(first, count, true);
   1186         ctx->m_glDrawArrays_enc(ctx, mode, 0, count);
   1187     } else {
   1188         ctx->sendVertexAttributes(0, count, false);
   1189         ctx->m_glDrawArrays_enc(ctx, mode, first, count);
   1190     }
   1191 }
   1192 
   1193 
   1194 void GL2Encoder::s_glDrawElements(void *self, GLenum mode, GLsizei count, GLenum type, const void *indices)
   1195 {
   1196 
   1197     GL2Encoder *ctx = (GL2Encoder *)self;
   1198     assert(ctx->m_state != NULL);
   1199     SET_ERROR_IF(!isValidDrawMode(mode), GL_INVALID_ENUM);
   1200     SET_ERROR_IF(count < 0, GL_INVALID_VALUE);
   1201     SET_ERROR_IF(!(type == GL_UNSIGNED_BYTE || type == GL_UNSIGNED_SHORT || type == GL_UNSIGNED_INT), GL_INVALID_ENUM);
   1202     SET_ERROR_IF(ctx->m_state->getTransformFeedbackActiveUnpaused(), GL_INVALID_OPERATION);
   1203 
   1204     bool has_client_vertex_arrays = false;
   1205     bool has_indirect_arrays = false;
   1206     int nLocations = ctx->m_state->nLocations();
   1207     GLintptr offset = 0;
   1208 
   1209     ctx->getVBOUsage(&has_client_vertex_arrays, &has_indirect_arrays);
   1210 
   1211     if (!has_client_vertex_arrays && !has_indirect_arrays) {
   1212         // ALOGW("glDrawElements: no vertex arrays / buffers bound to the command\n");
   1213         GLenum status = ctx->m_glCheckFramebufferStatus_enc(self, GL_FRAMEBUFFER);
   1214         SET_ERROR_IF(status != GL_FRAMEBUFFER_COMPLETE, GL_INVALID_FRAMEBUFFER_OPERATION);
   1215     }
   1216 
   1217     BufferData* buf = NULL;
   1218     int minIndex = 0, maxIndex = 0;
   1219 
   1220     // For validation/immediate index array purposes,
   1221     // we need the min/max vertex index of the index array.
   1222     // If the VBO != 0, this may not be the first time we have
   1223     // used this particular index buffer. getBufferIndexRange
   1224     // can more quickly get min/max vertex index by
   1225     // caching previous results.
   1226     if (ctx->m_state->currentIndexVbo() != 0) {
   1227         buf = ctx->m_shared->getBufferData(ctx->m_state->currentIndexVbo());
   1228         offset = (GLintptr)indices;
   1229         indices = (void*)((GLintptr)buf->m_fixedBuffer.ptr() + (GLintptr)indices);
   1230         ctx->getBufferIndexRange(buf,
   1231                                  indices,
   1232                                  type,
   1233                                  (size_t)count,
   1234                                  (size_t)offset,
   1235                                  &minIndex, &maxIndex);
   1236     } else {
   1237         // In this case, the |indices| field holds a real
   1238         // array, so calculate the indices now. They will
   1239         // also be needed to know how much data to
   1240         // transfer to host.
   1241         ctx->calcIndexRange(indices,
   1242                             type,
   1243                             count,
   1244                             &minIndex,
   1245                             &maxIndex);
   1246     }
   1247 
   1248     bool adjustIndices = true;
   1249     if (ctx->m_state->currentIndexVbo() != 0) {
   1250         if (!has_client_vertex_arrays) {
   1251             ctx->sendVertexAttributes(0, maxIndex + 1, false);
   1252             ctx->m_glBindBuffer_enc(self, GL_ELEMENT_ARRAY_BUFFER, ctx->m_state->currentIndexVbo());
   1253             ctx->glDrawElementsOffset(ctx, mode, count, type, offset);
   1254             ctx->flushDrawCall();
   1255             adjustIndices = false;
   1256         } else {
   1257             BufferData * buf = ctx->m_shared->getBufferData(ctx->m_state->currentIndexVbo());
   1258             ctx->m_glBindBuffer_enc(self, GL_ELEMENT_ARRAY_BUFFER, 0);
   1259         }
   1260     }
   1261     if (adjustIndices) {
   1262         void *adjustedIndices =
   1263             ctx->recenterIndices(indices,
   1264                                  type,
   1265                                  count,
   1266                                  minIndex);
   1267 
   1268         if (has_indirect_arrays || 1) {
   1269             ctx->sendVertexAttributes(minIndex, maxIndex - minIndex + 1, true);
   1270             ctx->glDrawElementsData(ctx, mode, count, type, adjustedIndices,
   1271                                     count * glSizeof(type));
   1272             // XXX - OPTIMIZATION (see the other else branch) should be implemented
   1273             if(!has_indirect_arrays) {
   1274                 //ALOGD("unoptimized drawelements !!!\n");
   1275             }
   1276         } else {
   1277             // we are all direct arrays and immidate mode index array -
   1278             // rebuild the arrays and the index array;
   1279             ALOGE("glDrawElements: direct index & direct buffer data - will be implemented in later versions;\n");
   1280         }
   1281     }
   1282 }
   1283 
   1284 
   1285 GLint * GL2Encoder::getCompressedTextureFormats()
   1286 {
   1287     if (m_compressedTextureFormats == NULL) {
   1288         this->glGetIntegerv(this, GL_NUM_COMPRESSED_TEXTURE_FORMATS,
   1289                             &m_num_compressedTextureFormats);
   1290         if (m_num_compressedTextureFormats > 0) {
   1291             // get number of texture formats;
   1292             m_compressedTextureFormats = new GLint[m_num_compressedTextureFormats];
   1293             this->glGetCompressedTextureFormats(this, m_num_compressedTextureFormats, m_compressedTextureFormats);
   1294         }
   1295     }
   1296     return m_compressedTextureFormats;
   1297 }
   1298 
   1299 // Replace uses of samplerExternalOES with sampler2D, recording the names of
   1300 // modified shaders in data. Also remove
   1301 //   #extension GL_OES_EGL_image_external : require
   1302 // statements.
   1303 //
   1304 // This implementation assumes the input has already been pre-processed. If not,
   1305 // a few cases will be mishandled:
   1306 //
   1307 // 1. "mySampler" will be incorrectly recorded as being a samplerExternalOES in
   1308 //    the following code:
   1309 //      #if 1
   1310 //      uniform sampler2D mySampler;
   1311 //      #else
   1312 //      uniform samplerExternalOES mySampler;
   1313 //      #endif
   1314 //
   1315 // 2. Comments that look like sampler declarations will be incorrectly modified
   1316 //    and recorded:
   1317 //      // samplerExternalOES hahaFooledYou
   1318 //
   1319 // 3. However, GLSL ES does not have a concatentation operator, so things like
   1320 //    this (valid in C) are invalid and not a problem:
   1321 //      #define SAMPLER(TYPE, NAME) uniform sampler#TYPE NAME
   1322 //      SAMPLER(ExternalOES, mySampler);
   1323 //
   1324 static bool replaceSamplerExternalWith2D(char* const str, ShaderData* const data)
   1325 {
   1326     static const char STR_HASH_EXTENSION[] = "#extension";
   1327     static const char STR_GL_OES_EGL_IMAGE_EXTERNAL[] = "GL_OES_EGL_image_external";
   1328     static const char STR_SAMPLER_EXTERNAL_OES[] = "samplerExternalOES";
   1329     static const char STR_SAMPLER2D_SPACE[]      = "sampler2D         ";
   1330 
   1331     // -- overwrite all "#extension GL_OES_EGL_image_external : xxx" statements
   1332     char* c = str;
   1333     while ((c = strstr(c, STR_HASH_EXTENSION))) {
   1334         char* start = c;
   1335         c += sizeof(STR_HASH_EXTENSION)-1;
   1336         while (isspace(*c) && *c != '\0') {
   1337             c++;
   1338         }
   1339         if (strncmp(c, STR_GL_OES_EGL_IMAGE_EXTERNAL,
   1340                 sizeof(STR_GL_OES_EGL_IMAGE_EXTERNAL)-1) == 0)
   1341         {
   1342             // #extension statements are terminated by end of line
   1343             c = start;
   1344             while (*c != '\0' && *c != '\r' && *c != '\n') {
   1345                 *c++ = ' ';
   1346             }
   1347         }
   1348     }
   1349 
   1350     // -- replace "samplerExternalOES" with "sampler2D" and record name
   1351     c = str;
   1352     while ((c = strstr(c, STR_SAMPLER_EXTERNAL_OES))) {
   1353         // Make sure "samplerExternalOES" isn't a substring of a larger token
   1354         if (c == str || !isspace(*(c-1))) {
   1355             c++;
   1356             continue;
   1357         }
   1358         char* sampler_start = c;
   1359         c += sizeof(STR_SAMPLER_EXTERNAL_OES)-1;
   1360         if (!isspace(*c) && *c != '\0') {
   1361             continue;
   1362         }
   1363 
   1364         // capture sampler name
   1365         while (isspace(*c) && *c != '\0') {
   1366             c++;
   1367         }
   1368         if (!isalpha(*c) && *c != '_') {
   1369             // not an identifier
   1370             return false;
   1371         }
   1372         char* name_start = c;
   1373         do {
   1374             c++;
   1375         } while (isalnum(*c) || *c == '_');
   1376         data->samplerExternalNames.push_back(
   1377                 android::String8(name_start, c - name_start));
   1378 
   1379         // memcpy instead of strcpy since we don't want the NUL terminator
   1380         memcpy(sampler_start, STR_SAMPLER2D_SPACE, sizeof(STR_SAMPLER2D_SPACE)-1);
   1381     }
   1382 
   1383     return true;
   1384 }
   1385 
   1386 void GL2Encoder::s_glShaderBinary(void *self, GLsizei n, const GLuint *shaders, GLenum binaryformat, const void* binary, GLsizei length)
   1387 {
   1388     GL2Encoder* ctx = (GL2Encoder*)self;
   1389     // Although it is not supported, need to set proper error code.
   1390     SET_ERROR_IF(1, GL_INVALID_ENUM);
   1391 }
   1392 
   1393 void GL2Encoder::s_glShaderSource(void *self, GLuint shader, GLsizei count, const GLchar * const *string, const GLint *length)
   1394 {
   1395     GL2Encoder* ctx = (GL2Encoder*)self;
   1396     ShaderData* shaderData = ctx->m_shared->getShaderData(shader);
   1397     SET_ERROR_IF(!ctx->m_shared->isShaderOrProgramObject(shader), GL_INVALID_VALUE);
   1398     SET_ERROR_IF(!shaderData, GL_INVALID_OPERATION);
   1399     SET_ERROR_IF((count<0), GL_INVALID_VALUE);
   1400 
   1401     // Track original sources---they may be translated in the backend
   1402     std::vector<std::string> orig_sources;
   1403     for (int i = 0; i < count; i++) {
   1404         orig_sources.push_back(std::string((const char*)(string[i])));
   1405     }
   1406     shaderData->sources = orig_sources;
   1407 
   1408     int len = glUtilsCalcShaderSourceLen((char**)string, (GLint*)length, count);
   1409     char *str = new char[len + 1];
   1410     glUtilsPackStrings(str, (char**)string, (GLint*)length, count);
   1411 
   1412     // TODO: pre-process str before calling replaceSamplerExternalWith2D().
   1413     // Perhaps we can borrow Mesa's pre-processor?
   1414 
   1415     if (!replaceSamplerExternalWith2D(str, shaderData)) {
   1416         delete[] str;
   1417         ctx->setError(GL_OUT_OF_MEMORY);
   1418         return;
   1419     }
   1420     ctx->glShaderString(ctx, shader, str, len + 1);
   1421     delete[] str;
   1422 }
   1423 
   1424 void GL2Encoder::s_glFinish(void *self)
   1425 {
   1426     GL2Encoder *ctx = (GL2Encoder *)self;
   1427     ctx->glFinishRoundTrip(self);
   1428 }
   1429 
   1430 void GL2Encoder::s_glLinkProgram(void * self, GLuint program)
   1431 {
   1432     GL2Encoder *ctx = (GL2Encoder *)self;
   1433     bool isProgram = ctx->m_shared->isProgram(program);
   1434     SET_ERROR_IF(!isProgram && !ctx->m_shared->isShader(program), GL_INVALID_VALUE);
   1435     SET_ERROR_IF(!isProgram, GL_INVALID_OPERATION);
   1436 
   1437     ctx->m_glLinkProgram_enc(self, program);
   1438 
   1439     GLint linkStatus = 0;
   1440     ctx->glGetProgramiv(self, program, GL_LINK_STATUS, &linkStatus);
   1441     if (!linkStatus) {
   1442         return;
   1443     }
   1444 
   1445     //get number of active uniforms in the program
   1446     GLint numUniforms=0;
   1447     ctx->glGetProgramiv(self, program, GL_ACTIVE_UNIFORMS, &numUniforms);
   1448     ctx->m_shared->initProgramData(program,numUniforms);
   1449 
   1450     //get the length of the longest uniform name
   1451     GLint maxLength=0;
   1452     ctx->glGetProgramiv(self, program, GL_ACTIVE_UNIFORM_MAX_LENGTH, &maxLength);
   1453 
   1454     GLint size;
   1455     GLenum type;
   1456     GLchar *name = new GLchar[maxLength+1];
   1457     GLint location;
   1458     //for each active uniform, get its size and starting location.
   1459     for (GLint i=0 ; i<numUniforms ; ++i)
   1460     {
   1461         ctx->glGetActiveUniform(self, program, i, maxLength, NULL, &size, &type, name);
   1462         location = ctx->m_glGetUniformLocation_enc(self, program, name);
   1463         ctx->m_shared->setProgramIndexInfo(program, i, location, size, type, name);
   1464     }
   1465     ctx->m_shared->setupLocationShiftWAR(program);
   1466 
   1467     delete[] name;
   1468 }
   1469 
   1470 void GL2Encoder::s_glDeleteProgram(void *self, GLuint program)
   1471 {
   1472     GL2Encoder *ctx = (GL2Encoder*)self;
   1473     ctx->m_glDeleteProgram_enc(self, program);
   1474 
   1475     ctx->m_shared->deleteProgramData(program);
   1476 }
   1477 
   1478 void GL2Encoder::s_glGetUniformiv(void *self, GLuint program, GLint location, GLint* params)
   1479 {
   1480     GL2Encoder *ctx = (GL2Encoder*)self;
   1481     SET_ERROR_IF(!ctx->m_shared->isShaderOrProgramObject(program), GL_INVALID_VALUE);
   1482     SET_ERROR_IF(!ctx->m_shared->isProgram(program), GL_INVALID_OPERATION);
   1483     SET_ERROR_IF(!ctx->m_shared->isProgramInitialized(program), GL_INVALID_OPERATION);
   1484     GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
   1485     SET_ERROR_IF(ctx->m_shared->getProgramUniformType(program,hostLoc)==0, GL_INVALID_OPERATION);
   1486     ctx->m_glGetUniformiv_enc(self, program, hostLoc, params);
   1487 }
   1488 void GL2Encoder::s_glGetUniformfv(void *self, GLuint program, GLint location, GLfloat* params)
   1489 {
   1490     GL2Encoder *ctx = (GL2Encoder*)self;
   1491     SET_ERROR_IF(!ctx->m_shared->isShaderOrProgramObject(program), GL_INVALID_VALUE);
   1492     SET_ERROR_IF(!ctx->m_shared->isProgram(program), GL_INVALID_OPERATION);
   1493     SET_ERROR_IF(!ctx->m_shared->isProgramInitialized(program), GL_INVALID_OPERATION);
   1494     GLint hostLoc = ctx->m_shared->locationWARAppToHost(program,location);
   1495     SET_ERROR_IF(ctx->m_shared->getProgramUniformType(program,hostLoc)==0, GL_INVALID_OPERATION);
   1496     ctx->m_glGetUniformfv_enc(self, program, hostLoc, params);
   1497 }
   1498 
   1499 GLuint GL2Encoder::s_glCreateProgram(void * self)
   1500 {
   1501     GL2Encoder *ctx = (GL2Encoder*)self;
   1502     GLuint program = ctx->m_glCreateProgram_enc(self);
   1503     if (program!=0)
   1504         ctx->m_shared->addProgramData(program);
   1505     return program;
   1506 }
   1507 
   1508 GLuint GL2Encoder::s_glCreateShader(void *self, GLenum shaderType)
   1509 {
   1510     GL2Encoder *ctx = (GL2Encoder*)self;
   1511     RET_AND_SET_ERROR_IF(!GLESv2Validation::shaderType(ctx, shaderType), GL_INVALID_ENUM, 0);
   1512     GLuint shader = ctx->m_glCreateShader_enc(self, shaderType);
   1513     if (shader != 0) {
   1514         if (!ctx->m_shared->addShaderData(shader)) {
   1515             ctx->m_glDeleteShader_enc(self, shader);
   1516             return 0;
   1517         }
   1518     }
   1519     return shader;
   1520 }
   1521 
   1522 void GL2Encoder::s_glGetAttachedShaders(void *self, GLuint program, GLsizei maxCount,
   1523         GLsizei* count, GLuint* shaders)
   1524 {
   1525     GL2Encoder *ctx = (GL2Encoder*)self;
   1526     SET_ERROR_IF(maxCount < 0, GL_INVALID_VALUE);
   1527     ctx->m_glGetAttachedShaders_enc(self, program, maxCount, count, shaders);
   1528 }
   1529 
   1530 void GL2Encoder::s_glGetShaderSource(void *self, GLuint shader, GLsizei bufsize,
   1531             GLsizei* length, GLchar* source)
   1532 {
   1533     GL2Encoder *ctx = (GL2Encoder*)self;
   1534     SET_ERROR_IF(bufsize < 0, GL_INVALID_VALUE);
   1535     ctx->m_glGetShaderSource_enc(self, shader, bufsize, length, source);
   1536     ShaderData* shaderData = ctx->m_shared->getShaderData(shader);
   1537     if (shaderData) {
   1538         std::string returned;
   1539         int curr_len = 0;
   1540         for (int i = 0; i < shaderData->sources.size(); i++) {
   1541             if (curr_len + shaderData->sources[i].size() < bufsize - 1) {
   1542                 returned += shaderData->sources[i];
   1543             } else {
   1544                 returned += shaderData->sources[i].substr(0, bufsize - 1 - curr_len);
   1545                 break;
   1546             }
   1547         }
   1548         memcpy(source, returned.substr(0, bufsize - 1).c_str(), bufsize);
   1549     }
   1550 }
   1551 
   1552 void GL2Encoder::s_glGetShaderInfoLog(void *self, GLuint shader, GLsizei bufsize,
   1553         GLsizei* length, GLchar* infolog)
   1554 {
   1555     GL2Encoder *ctx = (GL2Encoder*)self;
   1556     SET_ERROR_IF(bufsize < 0, GL_INVALID_VALUE);
   1557     ctx->m_glGetShaderInfoLog_enc(self, shader, bufsize, length, infolog);
   1558 }
   1559 
   1560 void GL2Encoder::s_glGetProgramInfoLog(void *self, GLuint program, GLsizei bufsize,
   1561         GLsizei* length, GLchar* infolog)
   1562 {
   1563     GL2Encoder *ctx = (GL2Encoder*)self;
   1564     SET_ERROR_IF(bufsize < 0, GL_INVALID_VALUE);
   1565     ctx->m_glGetProgramInfoLog_enc(self, program, bufsize, length, infolog);
   1566 }
   1567 
   1568 void GL2Encoder::s_glDeleteShader(void *self, GLenum shader)
   1569 {
   1570     GL2Encoder *ctx = (GL2Encoder*)self;
   1571     ctx->m_glDeleteShader_enc(self,shader);
   1572     ctx->m_shared->unrefShaderData(shader);
   1573 }
   1574 
   1575 void GL2Encoder::s_glAttachShader(void *self, GLuint program, GLuint shader)
   1576 {
   1577     GL2Encoder *ctx = (GL2Encoder*)self;
   1578     ctx->m_glAttachShader_enc(self, program, shader);
   1579     ctx->m_shared->attachShader(program, shader);
   1580 }
   1581 
   1582 void GL2Encoder::s_glDetachShader(void *self, GLuint program, GLuint shader)
   1583 {
   1584     GL2Encoder *ctx = (GL2Encoder*)self;
   1585     ctx->m_glDetachShader_enc(self, program, shader);
   1586     ctx->m_shared->detachShader(program, shader);
   1587 }
   1588 
   1589 int sArrIndexOfUniformExpr(const char* name, int* err) {
   1590     *err = 0;
   1591     int arrIndex = 0;
   1592     int namelen = strlen(name);
   1593     if (name[namelen-1] == ']') {
   1594         const char *brace = strrchr(name,'[');
   1595         if (!brace || sscanf(brace+1,"%d",&arrIndex) != 1) {
   1596             *err = 1; return 0;
   1597         }
   1598     }
   1599     return arrIndex;
   1600 }
   1601 
   1602 int GL2Encoder::s_glGetUniformLocation(void *self, GLuint program, const GLchar *name)
   1603 {
   1604     if (!name) return -1;
   1605 
   1606     GL2Encoder *ctx = (GL2Encoder*)self;
   1607 
   1608     // if we need the uniform location WAR
   1609     // parse array index from the end of the name string
   1610     int arrIndex = 0;
   1611     bool needLocationWAR = ctx->m_shared->needUniformLocationWAR(program);
   1612     if (needLocationWAR) {
   1613         int err;
   1614         arrIndex = sArrIndexOfUniformExpr(name, &err);
   1615         if (err) return -1;
   1616     }
   1617 
   1618     int hostLoc = ctx->m_glGetUniformLocation_enc(self, program, name);
   1619     if (hostLoc >= 0 && needLocationWAR) {
   1620         return ctx->m_shared->locationWARHostToApp(program, hostLoc, arrIndex);
   1621     }
   1622     return hostLoc;
   1623 }
   1624 
   1625 bool GL2Encoder::updateHostTexture2DBinding(GLenum texUnit, GLenum newTarget)
   1626 {
   1627     if (newTarget != GL_TEXTURE_2D && newTarget != GL_TEXTURE_EXTERNAL_OES)
   1628         return false;
   1629 
   1630     m_state->setActiveTextureUnit(texUnit);
   1631 
   1632     GLenum oldTarget = m_state->getPriorityEnabledTarget(GL_TEXTURE_2D);
   1633     if (newTarget != oldTarget) {
   1634         if (newTarget == GL_TEXTURE_EXTERNAL_OES) {
   1635             m_state->disableTextureTarget(GL_TEXTURE_2D);
   1636             m_state->enableTextureTarget(GL_TEXTURE_EXTERNAL_OES);
   1637         } else {
   1638             m_state->disableTextureTarget(GL_TEXTURE_EXTERNAL_OES);
   1639             m_state->enableTextureTarget(GL_TEXTURE_2D);
   1640         }
   1641         m_glActiveTexture_enc(this, texUnit);
   1642         m_glBindTexture_enc(this, GL_TEXTURE_2D,
   1643                 m_state->getBoundTexture(newTarget));
   1644         return true;
   1645     }
   1646 
   1647     return false;
   1648 }
   1649 
   1650 void GL2Encoder::updateHostTexture2DBindingsFromProgramData(GLuint program) {
   1651     GL2Encoder *ctx = this;
   1652     GLClientState* state = ctx->m_state;
   1653     GLSharedGroupPtr shared = ctx->m_shared;
   1654 
   1655     GLenum origActiveTexture = state->getActiveTextureUnit();
   1656     GLenum hostActiveTexture = origActiveTexture;
   1657     GLint samplerIdx = -1;
   1658     GLint samplerVal;
   1659     GLenum samplerTarget;
   1660     while ((samplerIdx = shared->getNextSamplerUniform(program, samplerIdx, &samplerVal, &samplerTarget)) != -1) {
   1661         if (samplerVal < 0 || samplerVal >= GLClientState::MAX_TEXTURE_UNITS)
   1662             continue;
   1663         if (ctx->updateHostTexture2DBinding(GL_TEXTURE0 + samplerVal,
   1664                     samplerTarget))
   1665         {
   1666             hostActiveTexture = GL_TEXTURE0 + samplerVal;
   1667         }
   1668     }
   1669     state->setActiveTextureUnit(origActiveTexture);
   1670     if (hostActiveTexture != origActiveTexture) {
   1671         ctx->m_glActiveTexture_enc(ctx, origActiveTexture);
   1672     }
   1673 }
   1674 
   1675 void GL2Encoder::s_glUseProgram(void *self, GLuint program)
   1676 {
   1677     GL2Encoder *ctx = (GL2Encoder*)self;
   1678     GLSharedGroupPtr shared = ctx->m_shared;
   1679 
   1680     SET_ERROR_IF(program && !shared->isShaderOrProgramObject(program), GL_INVALID_VALUE);
   1681     SET_ERROR_IF(program && !shared->isProgram(program), GL_INVALID_OPERATION);
   1682 
   1683     ctx->m_glUseProgram_enc(self, program);
   1684     ctx->m_state->setCurrentProgram(program);
   1685     ctx->m_state->setCurrentShaderProgram(program);
   1686 
   1687     ctx->updateHostTexture2DBindingsFromProgramData(program);
   1688 }
   1689 
   1690 void GL2Encoder::s_glUniform1f(void *self , GLint location, GLfloat x)
   1691 {
   1692     GL2Encoder *ctx = (GL2Encoder*)self;
   1693     GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
   1694     ctx->m_glUniform1f_enc(self, hostLoc, x);
   1695 }
   1696 
   1697 void GL2Encoder::s_glUniform1fv(void *self , GLint location, GLsizei count, const GLfloat* v)
   1698 {
   1699     GL2Encoder *ctx = (GL2Encoder*)self;
   1700     GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
   1701     ctx->m_glUniform1fv_enc(self, hostLoc, count, v);
   1702 }
   1703 
   1704 void GL2Encoder::s_glUniform1i(void *self , GLint location, GLint x)
   1705 {
   1706     GL2Encoder *ctx = (GL2Encoder*)self;
   1707     GLClientState* state = ctx->m_state;
   1708     GLSharedGroupPtr shared = ctx->m_shared;
   1709 
   1710     GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
   1711     ctx->m_glUniform1i_enc(self, hostLoc, x);
   1712 
   1713     GLenum target;
   1714     if (shared->setSamplerUniform(state->currentShaderProgram(), location, x, &target)) {
   1715         GLenum origActiveTexture = state->getActiveTextureUnit();
   1716         if (ctx->updateHostTexture2DBinding(GL_TEXTURE0 + x, target)) {
   1717             ctx->m_glActiveTexture_enc(self, origActiveTexture);
   1718         }
   1719         state->setActiveTextureUnit(origActiveTexture);
   1720     }
   1721 }
   1722 
   1723 void GL2Encoder::s_glUniform1iv(void *self , GLint location, GLsizei count, const GLint* v)
   1724 {
   1725     GL2Encoder *ctx = (GL2Encoder*)self;
   1726     GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
   1727     ctx->m_glUniform1iv_enc(self, hostLoc, count, v);
   1728 }
   1729 
   1730 void GL2Encoder::s_glUniform2f(void *self , GLint location, GLfloat x, GLfloat y)
   1731 {
   1732     GL2Encoder *ctx = (GL2Encoder*)self;
   1733     GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
   1734     ctx->m_glUniform2f_enc(self, hostLoc, x, y);
   1735 }
   1736 
   1737 void GL2Encoder::s_glUniform2fv(void *self , GLint location, GLsizei count, const GLfloat* v)
   1738 {
   1739     GL2Encoder *ctx = (GL2Encoder*)self;
   1740     GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
   1741     ctx->m_glUniform2fv_enc(self, hostLoc, count, v);
   1742 }
   1743 
   1744 void GL2Encoder::s_glUniform2i(void *self , GLint location, GLint x, GLint y)
   1745 {
   1746     GL2Encoder *ctx = (GL2Encoder*)self;
   1747     GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
   1748     ctx->m_glUniform2i_enc(self, hostLoc, x, y);
   1749 }
   1750 
   1751 void GL2Encoder::s_glUniform2iv(void *self , GLint location, GLsizei count, const GLint* v)
   1752 {
   1753     GL2Encoder *ctx = (GL2Encoder*)self;
   1754     GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
   1755     ctx->m_glUniform2iv_enc(self, hostLoc, count, v);
   1756 }
   1757 
   1758 void GL2Encoder::s_glUniform3f(void *self , GLint location, GLfloat x, GLfloat y, GLfloat z)
   1759 {
   1760     GL2Encoder *ctx = (GL2Encoder*)self;
   1761     GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
   1762     ctx->m_glUniform3f_enc(self, hostLoc, x, y, z);
   1763 }
   1764 
   1765 void GL2Encoder::s_glUniform3fv(void *self , GLint location, GLsizei count, const GLfloat* v)
   1766 {
   1767     GL2Encoder *ctx = (GL2Encoder*)self;
   1768     GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
   1769     ctx->m_glUniform3fv_enc(self, hostLoc, count, v);
   1770 }
   1771 
   1772 void GL2Encoder::s_glUniform3i(void *self , GLint location, GLint x, GLint y, GLint z)
   1773 {
   1774     GL2Encoder *ctx = (GL2Encoder*)self;
   1775     GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
   1776     ctx->m_glUniform3i_enc(self, hostLoc, x, y, z);
   1777 }
   1778 
   1779 void GL2Encoder::s_glUniform3iv(void *self , GLint location, GLsizei count, const GLint* v)
   1780 {
   1781     GL2Encoder *ctx = (GL2Encoder*)self;
   1782     GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
   1783     ctx->m_glUniform3iv_enc(self, hostLoc, count, v);
   1784 }
   1785 
   1786 void GL2Encoder::s_glUniform4f(void *self , GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
   1787 {
   1788     GL2Encoder *ctx = (GL2Encoder*)self;
   1789     GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
   1790     ctx->m_glUniform4f_enc(self, hostLoc, x, y, z, w);
   1791 }
   1792 
   1793 void GL2Encoder::s_glUniform4fv(void *self , GLint location, GLsizei count, const GLfloat* v)
   1794 {
   1795     GL2Encoder *ctx = (GL2Encoder*)self;
   1796     GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
   1797     ctx->m_glUniform4fv_enc(self, hostLoc, count, v);
   1798 }
   1799 
   1800 void GL2Encoder::s_glUniform4i(void *self , GLint location, GLint x, GLint y, GLint z, GLint w)
   1801 {
   1802     GL2Encoder *ctx = (GL2Encoder*)self;
   1803     GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
   1804     ctx->m_glUniform4i_enc(self, hostLoc, x, y, z, w);
   1805 }
   1806 
   1807 void GL2Encoder::s_glUniform4iv(void *self , GLint location, GLsizei count, const GLint* v)
   1808 {
   1809     GL2Encoder *ctx = (GL2Encoder*)self;
   1810     GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
   1811     ctx->m_glUniform4iv_enc(self, hostLoc, count, v);
   1812 }
   1813 
   1814 void GL2Encoder::s_glUniformMatrix2fv(void *self , GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
   1815 {
   1816     GL2Encoder *ctx = (GL2Encoder*)self;
   1817     GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
   1818     ctx->m_glUniformMatrix2fv_enc(self, hostLoc, count, transpose, value);
   1819 }
   1820 
   1821 void GL2Encoder::s_glUniformMatrix3fv(void *self , GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
   1822 {
   1823     GL2Encoder *ctx = (GL2Encoder*)self;
   1824     GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
   1825     ctx->m_glUniformMatrix3fv_enc(self, hostLoc, count, transpose, value);
   1826 }
   1827 
   1828 void GL2Encoder::s_glUniformMatrix4fv(void *self , GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
   1829 {
   1830     GL2Encoder *ctx = (GL2Encoder*)self;
   1831     GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
   1832     ctx->m_glUniformMatrix4fv_enc(self, hostLoc, count, transpose, value);
   1833 }
   1834 
   1835 void GL2Encoder::s_glActiveTexture(void* self, GLenum texture)
   1836 {
   1837     GL2Encoder* ctx = (GL2Encoder*)self;
   1838     GLClientState* state = ctx->m_state;
   1839     GLenum err;
   1840 
   1841     SET_ERROR_IF((err = state->setActiveTextureUnit(texture)) != GL_NO_ERROR, err);
   1842 
   1843     ctx->m_glActiveTexture_enc(ctx, texture);
   1844 }
   1845 
   1846 void GL2Encoder::s_glBindTexture(void* self, GLenum target, GLuint texture)
   1847 {
   1848     GL2Encoder* ctx = (GL2Encoder*)self;
   1849     GLClientState* state = ctx->m_state;
   1850     GLenum err;
   1851     GLboolean firstUse;
   1852 
   1853     SET_ERROR_IF(!GLESv2Validation::textureTarget(ctx, target), GL_INVALID_ENUM);
   1854     SET_ERROR_IF((err = state->bindTexture(target, texture, &firstUse)) != GL_NO_ERROR, err);
   1855 
   1856     if (target != GL_TEXTURE_2D && target != GL_TEXTURE_EXTERNAL_OES) {
   1857         ctx->m_glBindTexture_enc(ctx, target, texture);
   1858         return;
   1859     }
   1860 
   1861     GLenum priorityTarget = state->getPriorityEnabledTarget(GL_TEXTURE_2D);
   1862 
   1863     if (target == GL_TEXTURE_EXTERNAL_OES && firstUse) {
   1864         ctx->m_glBindTexture_enc(ctx, GL_TEXTURE_2D, texture);
   1865         ctx->m_glTexParameteri_enc(ctx, GL_TEXTURE_2D,
   1866                 GL_TEXTURE_MIN_FILTER, GL_LINEAR);
   1867         ctx->m_glTexParameteri_enc(ctx, GL_TEXTURE_2D,
   1868                 GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
   1869         ctx->m_glTexParameteri_enc(ctx, GL_TEXTURE_2D,
   1870                 GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
   1871 
   1872         if (target != priorityTarget) {
   1873             ctx->m_glBindTexture_enc(ctx, GL_TEXTURE_2D,
   1874                     state->getBoundTexture(GL_TEXTURE_2D));
   1875         }
   1876     }
   1877 
   1878     if (target == priorityTarget) {
   1879         ctx->m_glBindTexture_enc(ctx, GL_TEXTURE_2D, texture);
   1880     }
   1881 }
   1882 
   1883 void GL2Encoder::s_glDeleteTextures(void* self, GLsizei n, const GLuint* textures)
   1884 {
   1885     GL2Encoder* ctx = (GL2Encoder*)self;
   1886     GLClientState* state = ctx->m_state;
   1887 
   1888     state->deleteTextures(n, textures);
   1889     ctx->m_glDeleteTextures_enc(ctx, n, textures);
   1890 }
   1891 
   1892 void GL2Encoder::s_glGetTexParameterfv(void* self,
   1893         GLenum target, GLenum pname, GLfloat* params)
   1894 {
   1895     GL2Encoder* ctx = (GL2Encoder*)self;
   1896     const GLClientState* state = ctx->m_state;
   1897 
   1898     if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
   1899         ctx->override2DTextureTarget(target);
   1900         ctx->m_glGetTexParameterfv_enc(ctx, GL_TEXTURE_2D, pname, params);
   1901         ctx->restore2DTextureTarget(target);
   1902     } else {
   1903         ctx->m_glGetTexParameterfv_enc(ctx, target, pname, params);
   1904     }
   1905 }
   1906 
   1907 void GL2Encoder::s_glGetTexParameteriv(void* self,
   1908         GLenum target, GLenum pname, GLint* params)
   1909 {
   1910     GL2Encoder* ctx = (GL2Encoder*)self;
   1911     const GLClientState* state = ctx->m_state;
   1912 
   1913     switch (pname) {
   1914     case GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES:
   1915         *params = 1;
   1916         break;
   1917 
   1918     default:
   1919         if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
   1920             ctx->override2DTextureTarget(target);
   1921             ctx->m_glGetTexParameteriv_enc(ctx, GL_TEXTURE_2D, pname, params);
   1922             ctx->restore2DTextureTarget(target);
   1923         } else {
   1924             ctx->m_glGetTexParameteriv_enc(ctx, target, pname, params);
   1925         }
   1926         break;
   1927     }
   1928 }
   1929 
   1930 static bool isValidTextureExternalParam(GLenum pname, GLenum param)
   1931 {
   1932     switch (pname) {
   1933     case GL_TEXTURE_MIN_FILTER:
   1934     case GL_TEXTURE_MAG_FILTER:
   1935         return param == GL_NEAREST || param == GL_LINEAR;
   1936 
   1937     case GL_TEXTURE_WRAP_S:
   1938     case GL_TEXTURE_WRAP_T:
   1939         return param == GL_CLAMP_TO_EDGE;
   1940 
   1941     default:
   1942         return true;
   1943     }
   1944 }
   1945 
   1946 void GL2Encoder::s_glTexParameterf(void* self,
   1947         GLenum target, GLenum pname, GLfloat param)
   1948 {
   1949     GL2Encoder* ctx = (GL2Encoder*)self;
   1950     const GLClientState* state = ctx->m_state;
   1951 
   1952     SET_ERROR_IF((target == GL_TEXTURE_EXTERNAL_OES &&
   1953             !isValidTextureExternalParam(pname, (GLenum)param)),
   1954             GL_INVALID_ENUM);
   1955 
   1956     if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
   1957         ctx->override2DTextureTarget(target);
   1958         ctx->m_glTexParameterf_enc(ctx, GL_TEXTURE_2D, pname, param);
   1959         ctx->restore2DTextureTarget(target);
   1960     } else {
   1961         ctx->m_glTexParameterf_enc(ctx, target, pname, param);
   1962     }
   1963 }
   1964 
   1965 void GL2Encoder::s_glTexParameterfv(void* self,
   1966         GLenum target, GLenum pname, const GLfloat* params)
   1967 {
   1968     GL2Encoder* ctx = (GL2Encoder*)self;
   1969     const GLClientState* state = ctx->m_state;
   1970 
   1971     SET_ERROR_IF((target == GL_TEXTURE_EXTERNAL_OES &&
   1972             !isValidTextureExternalParam(pname, (GLenum)params[0])),
   1973             GL_INVALID_ENUM);
   1974 
   1975     if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
   1976         ctx->override2DTextureTarget(target);
   1977         ctx->m_glTexParameterfv_enc(ctx, GL_TEXTURE_2D, pname, params);
   1978         ctx->restore2DTextureTarget(target);
   1979     } else {
   1980         ctx->m_glTexParameterfv_enc(ctx, target, pname, params);
   1981     }
   1982 }
   1983 
   1984 void GL2Encoder::s_glTexParameteri(void* self,
   1985         GLenum target, GLenum pname, GLint param)
   1986 {
   1987     GL2Encoder* ctx = (GL2Encoder*)self;
   1988     const GLClientState* state = ctx->m_state;
   1989 
   1990     SET_ERROR_IF((target == GL_TEXTURE_EXTERNAL_OES &&
   1991             !isValidTextureExternalParam(pname, (GLenum)param)),
   1992             GL_INVALID_ENUM);
   1993 
   1994     if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
   1995         ctx->override2DTextureTarget(target);
   1996         ctx->m_glTexParameteri_enc(ctx, GL_TEXTURE_2D, pname, param);
   1997         ctx->restore2DTextureTarget(target);
   1998     } else {
   1999         ctx->m_glTexParameteri_enc(ctx, target, pname, param);
   2000     }
   2001 }
   2002 
   2003 static int ilog2(uint32_t x) {
   2004     int p = 0;
   2005     while ((1 << p) < x)
   2006         p++;
   2007     return p;
   2008 }
   2009 
   2010 void GL2Encoder::s_glTexImage2D(void* self, GLenum target, GLint level,
   2011         GLint internalformat, GLsizei width, GLsizei height, GLint border,
   2012         GLenum format, GLenum type, const GLvoid* pixels)
   2013 {
   2014     GL2Encoder* ctx = (GL2Encoder*)self;
   2015     GLClientState* state = ctx->m_state;
   2016 
   2017     SET_ERROR_IF(!GLESv2Validation::textureTarget(ctx, target), GL_INVALID_ENUM);
   2018     SET_ERROR_IF(!GLESv2Validation::pixelType(ctx, type), GL_INVALID_ENUM);
   2019     SET_ERROR_IF(!GLESv2Validation::pixelFormat(ctx, format), GL_INVALID_ENUM);
   2020     // If unpack buffer is nonzero, verify unmapped state.
   2021     SET_ERROR_IF(ctx->isBufferTargetMapped(GL_PIXEL_UNPACK_BUFFER), GL_INVALID_OPERATION);
   2022 
   2023     GLint max_texture_size;
   2024     GLint max_cube_map_texture_size;
   2025     ctx->glGetIntegerv(ctx, GL_MAX_TEXTURE_SIZE, &max_texture_size);
   2026     ctx->glGetIntegerv(ctx, GL_MAX_CUBE_MAP_TEXTURE_SIZE, &max_cube_map_texture_size);
   2027     SET_ERROR_IF(level < 0, GL_INVALID_VALUE);
   2028     SET_ERROR_IF(level > ilog2(max_texture_size), GL_INVALID_VALUE);
   2029     SET_ERROR_IF((target == GL_TEXTURE_CUBE_MAP) &&
   2030                  (level > ilog2(max_cube_map_texture_size)), GL_INVALID_VALUE);
   2031     SET_ERROR_IF(width < 0 || height < 0, GL_INVALID_VALUE);
   2032     SET_ERROR_IF(width > max_texture_size, GL_INVALID_VALUE);
   2033     SET_ERROR_IF(height > max_texture_size, GL_INVALID_VALUE);
   2034     SET_ERROR_IF(GLESv2Validation::isCubeMapTarget(target) && width > max_cube_map_texture_size, GL_INVALID_VALUE);
   2035     SET_ERROR_IF(GLESv2Validation::isCubeMapTarget(target) && height > max_cube_map_texture_size, GL_INVALID_VALUE);
   2036     SET_ERROR_IF(border != 0, GL_INVALID_VALUE);
   2037     // If unpack buffer is nonzero, verify buffer data fits and is evenly divisible by the type.
   2038     SET_ERROR_IF(ctx->boundBuffer(GL_PIXEL_UNPACK_BUFFER) &&
   2039                  ctx->getBufferData(GL_PIXEL_UNPACK_BUFFER) &&
   2040                  (ctx->m_state->pboNeededDataSize(width, height, 1, format, type, 0) >
   2041                   ctx->getBufferData(GL_PIXEL_UNPACK_BUFFER)->m_size),
   2042                  GL_INVALID_OPERATION);
   2043     SET_ERROR_IF(ctx->boundBuffer(GL_PIXEL_UNPACK_BUFFER) &&
   2044                  ctx->getBufferData(GL_PIXEL_UNPACK_BUFFER) &&
   2045                  (ctx->getBufferData(GL_PIXEL_UNPACK_BUFFER)->m_size %
   2046                   glSizeof(type)),
   2047                  GL_INVALID_OPERATION);
   2048     SET_ERROR_IF(ctx->boundBuffer(GL_PIXEL_UNPACK_BUFFER) &&
   2049                  ctx->getBufferData(GL_PIXEL_UNPACK_BUFFER) &&
   2050                  ((uintptr_t)pixels % glSizeof(type)),
   2051                  GL_INVALID_OPERATION);
   2052     SET_ERROR_IF(state->isBoundTextureImmutableFormat(target), GL_INVALID_OPERATION);
   2053 
   2054     GLenum stateTarget = target;
   2055     if (target == GL_TEXTURE_CUBE_MAP_POSITIVE_X ||
   2056         target == GL_TEXTURE_CUBE_MAP_POSITIVE_Y ||
   2057         target == GL_TEXTURE_CUBE_MAP_POSITIVE_Z ||
   2058         target == GL_TEXTURE_CUBE_MAP_NEGATIVE_X ||
   2059         target == GL_TEXTURE_CUBE_MAP_NEGATIVE_Y ||
   2060         target == GL_TEXTURE_CUBE_MAP_NEGATIVE_Z)
   2061         stateTarget = GL_TEXTURE_CUBE_MAP;
   2062 
   2063     state->setBoundTextureInternalFormat(stateTarget, internalformat);
   2064     state->setBoundTextureFormat(stateTarget, format);
   2065     state->setBoundTextureType(stateTarget, type);
   2066     state->setBoundTextureDims(stateTarget, level, width, height, 1);
   2067 
   2068     if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
   2069         ctx->override2DTextureTarget(target);
   2070     }
   2071 
   2072     if (ctx->boundBuffer(GL_PIXEL_UNPACK_BUFFER)) {
   2073         ctx->glTexImage2DOffsetAEMU(
   2074                 ctx, target, level, internalformat,
   2075                 width, height, border,
   2076                 format, type, (uintptr_t)pixels);
   2077     } else {
   2078         ctx->m_glTexImage2D_enc(
   2079                 ctx, target, level, internalformat,
   2080                 width, height, border,
   2081                 format, type, pixels);
   2082     }
   2083 
   2084     if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
   2085         ctx->restore2DTextureTarget(target);
   2086     }
   2087 }
   2088 
   2089 void GL2Encoder::s_glTexSubImage2D(void* self, GLenum target, GLint level,
   2090         GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format,
   2091         GLenum type, const GLvoid* pixels)
   2092 {
   2093     GL2Encoder* ctx = (GL2Encoder*)self;
   2094     GLClientState* state = ctx->m_state;
   2095 
   2096     SET_ERROR_IF(!GLESv2Validation::textureTarget(ctx, target), GL_INVALID_ENUM);
   2097     SET_ERROR_IF(!GLESv2Validation::pixelType(ctx, type), GL_INVALID_ENUM);
   2098     SET_ERROR_IF(!GLESv2Validation::pixelFormat(ctx, format), GL_INVALID_ENUM);
   2099     // If unpack buffer is nonzero, verify unmapped state.
   2100     SET_ERROR_IF(ctx->isBufferTargetMapped(GL_PIXEL_UNPACK_BUFFER), GL_INVALID_OPERATION);
   2101 
   2102     GLint max_texture_size;
   2103     GLint max_cube_map_texture_size;
   2104     ctx->glGetIntegerv(ctx, GL_MAX_TEXTURE_SIZE, &max_texture_size);
   2105     ctx->glGetIntegerv(ctx, GL_MAX_CUBE_MAP_TEXTURE_SIZE, &max_cube_map_texture_size);
   2106     SET_ERROR_IF(level < 0, GL_INVALID_VALUE);
   2107     SET_ERROR_IF(level > ilog2(max_texture_size), GL_INVALID_VALUE);
   2108     SET_ERROR_IF(GLESv2Validation::isCubeMapTarget(target) &&
   2109                  level > ilog2(max_cube_map_texture_size), GL_INVALID_VALUE);
   2110     SET_ERROR_IF(width < 0 || height < 0, GL_INVALID_VALUE);
   2111     SET_ERROR_IF(xoffset < 0 || yoffset < 0, GL_INVALID_VALUE);
   2112 
   2113     GLuint tex = state->getBoundTexture(target);
   2114     GLsizei neededWidth = xoffset + width;
   2115     GLsizei neededHeight = yoffset + height;
   2116     GLsizei neededDepth = 1;
   2117 
   2118     if (tex && !state->queryTexEGLImageBacked(tex)) {
   2119         SET_ERROR_IF(
   2120                 (neededWidth > state->queryTexWidth(level, tex) ||
   2121                  neededHeight > state->queryTexHeight(level, tex) ||
   2122                  neededDepth > state->queryTexDepth(level, tex)),
   2123                 GL_INVALID_VALUE);
   2124     }
   2125 
   2126     // If unpack buffer is nonzero, verify buffer data fits and is evenly divisible by the type.
   2127     SET_ERROR_IF(ctx->boundBuffer(GL_PIXEL_UNPACK_BUFFER) &&
   2128                  ctx->getBufferData(GL_PIXEL_UNPACK_BUFFER) &&
   2129                  (state->pboNeededDataSize(width, height, 1, format, type, 0) >
   2130                   ctx->getBufferData(GL_PIXEL_UNPACK_BUFFER)->m_size),
   2131                  GL_INVALID_OPERATION);
   2132     SET_ERROR_IF(ctx->boundBuffer(GL_PIXEL_UNPACK_BUFFER) &&
   2133                  ctx->getBufferData(GL_PIXEL_UNPACK_BUFFER) &&
   2134                  (ctx->getBufferData(GL_PIXEL_UNPACK_BUFFER)->m_size %
   2135                   glSizeof(type)),
   2136                  GL_INVALID_OPERATION);
   2137     SET_ERROR_IF(!ctx->boundBuffer(GL_PIXEL_UNPACK_BUFFER) && !pixels, GL_INVALID_OPERATION);
   2138 
   2139     if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
   2140         ctx->override2DTextureTarget(target);
   2141     }
   2142 
   2143     if (ctx->boundBuffer(GL_PIXEL_UNPACK_BUFFER)) {
   2144         ctx->glTexSubImage2DOffsetAEMU(
   2145                 ctx, target, level,
   2146                 xoffset, yoffset, width, height,
   2147                 format, type, (uintptr_t)pixels);
   2148     } else {
   2149         ctx->m_glTexSubImage2D_enc(ctx, target, level, xoffset, yoffset, width,
   2150                 height, format, type, pixels);
   2151     }
   2152 
   2153     if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
   2154         ctx->restore2DTextureTarget(target);
   2155     }
   2156 }
   2157 
   2158 void GL2Encoder::s_glCopyTexImage2D(void* self, GLenum target, GLint level,
   2159         GLenum internalformat, GLint x, GLint y,
   2160         GLsizei width, GLsizei height, GLint border)
   2161 {
   2162     GL2Encoder* ctx = (GL2Encoder*)self;
   2163     GLClientState* state = ctx->m_state;
   2164 
   2165     SET_ERROR_IF(ctx->glCheckFramebufferStatus(ctx, GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE,
   2166                  GL_INVALID_FRAMEBUFFER_OPERATION);
   2167     // This is needed to work around underlying OpenGL drivers
   2168     // (such as those feeding some some AMD GPUs) that expect
   2169     // positive components of cube maps to be defined _before_
   2170     // the negative components (otherwise a segfault occurs).
   2171     GLenum extraTarget =
   2172         state->copyTexImageLuminanceCubeMapAMDWorkaround
   2173             (target, level, internalformat);
   2174 
   2175     if (extraTarget) {
   2176         ctx->m_glCopyTexImage2D_enc(ctx, extraTarget, level, internalformat,
   2177                                     x, y, width, height, border);
   2178     }
   2179 
   2180     ctx->m_glCopyTexImage2D_enc(ctx, target, level, internalformat,
   2181                                 x, y, width, height, border);
   2182 
   2183     state->setBoundTextureInternalFormat(target, internalformat);
   2184     state->setBoundTextureDims(target, level, width, height, 1);
   2185 }
   2186 
   2187 void GL2Encoder::s_glTexParameteriv(void* self,
   2188         GLenum target, GLenum pname, const GLint* params)
   2189 {
   2190     GL2Encoder* ctx = (GL2Encoder*)self;
   2191     const GLClientState* state = ctx->m_state;
   2192 
   2193     SET_ERROR_IF((target == GL_TEXTURE_EXTERNAL_OES &&
   2194             !isValidTextureExternalParam(pname, (GLenum)params[0])),
   2195             GL_INVALID_ENUM);
   2196 
   2197     if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
   2198         ctx->override2DTextureTarget(target);
   2199         ctx->m_glTexParameteriv_enc(ctx, GL_TEXTURE_2D, pname, params);
   2200         ctx->restore2DTextureTarget(target);
   2201     } else {
   2202         ctx->m_glTexParameteriv_enc(ctx, target, pname, params);
   2203     }
   2204 }
   2205 
   2206 bool GL2Encoder::texture2DNeedsOverride(GLenum target) const {
   2207     return (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) &&
   2208            target != m_state->getPriorityEnabledTarget(GL_TEXTURE_2D);
   2209 }
   2210 
   2211 void GL2Encoder::override2DTextureTarget(GLenum target)
   2212 {
   2213     if (texture2DNeedsOverride(target)) {
   2214         m_glBindTexture_enc(this, GL_TEXTURE_2D,
   2215                 m_state->getBoundTexture(target));
   2216     }
   2217 }
   2218 
   2219 void GL2Encoder::restore2DTextureTarget(GLenum target)
   2220 {
   2221     if (texture2DNeedsOverride(target)) {
   2222         GLuint priorityEnabledBoundTexture =
   2223                 m_state->getBoundTexture(
   2224                     m_state->getPriorityEnabledTarget(GL_TEXTURE_2D));
   2225         GLuint texture2DBoundTexture =
   2226                 m_state->getBoundTexture(GL_TEXTURE_2D);
   2227         if (!priorityEnabledBoundTexture) {
   2228             m_glBindTexture_enc(this, GL_TEXTURE_2D, texture2DBoundTexture);
   2229         } else {
   2230             m_glBindTexture_enc(this, GL_TEXTURE_2D, priorityEnabledBoundTexture);
   2231         }
   2232     }
   2233 }
   2234 
   2235 void GL2Encoder::associateEGLImage(GLenum target, GLeglImageOES eglImage) {
   2236     m_state->setBoundEGLImage(target, eglImage);
   2237 }
   2238 
   2239 
   2240 GLuint GL2Encoder::boundBuffer(GLenum target) const {
   2241     return m_state->getBuffer(target);
   2242 }
   2243 
   2244 BufferData* GL2Encoder::getBufferData(GLenum target) const {
   2245     GLuint bufferId = m_state->getBuffer(target);
   2246     if (!bufferId) return NULL;
   2247     return m_shared->getBufferData(bufferId);
   2248 }
   2249 
   2250 BufferData* GL2Encoder::getBufferDataById(GLuint bufferId) const {
   2251     if (!bufferId) return NULL;
   2252     return m_shared->getBufferData(bufferId);
   2253 }
   2254 
   2255 bool GL2Encoder::isBufferMapped(GLuint buffer) const {
   2256     return m_shared->getBufferData(buffer)->m_mapped;
   2257 }
   2258 
   2259 bool GL2Encoder::isBufferTargetMapped(GLenum target) const {
   2260     BufferData* buf = getBufferData(target);
   2261     if (!buf) return false;
   2262     return buf->m_mapped;
   2263 }
   2264 
   2265 void GL2Encoder::s_glGenRenderbuffers(void* self,
   2266         GLsizei n, GLuint* renderbuffers) {
   2267     GL2Encoder* ctx = (GL2Encoder*)self;
   2268     GLClientState* state = ctx->m_state;
   2269 
   2270     SET_ERROR_IF(n < 0, GL_INVALID_VALUE);
   2271 
   2272     ctx->m_glGenFramebuffers_enc(self, n, renderbuffers);
   2273     state->addRenderbuffers(n, renderbuffers);
   2274 }
   2275 
   2276 void GL2Encoder::s_glDeleteRenderbuffers(void* self,
   2277         GLsizei n, const GLuint* renderbuffers) {
   2278     GL2Encoder* ctx = (GL2Encoder*)self;
   2279     GLClientState* state = ctx->m_state;
   2280 
   2281     SET_ERROR_IF(n < 0, GL_INVALID_VALUE);
   2282 
   2283     ctx->m_glDeleteRenderbuffers_enc(self, n, renderbuffers);
   2284 
   2285     // Nope, lets just leak those for now.
   2286     // The spec has an *amazingly* convoluted set of conditions for when
   2287     // render buffers are actually deleted:
   2288     // glDeleteRenderbuffers deletes the n renderbuffer objects whose names are stored in the array addressed by renderbuffers. Unused names in renderbuffers that have been marked as used for the purposes of glGenRenderbuffers are marked as unused again. The name zero is reserved by the GL and is silently ignored, should it occur in renderbuffers, as are other unused names. Once a renderbuffer object is deleted, its name is again unused and it has no contents. If a renderbuffer that is currently bound to the target GL_RENDERBUFFER is deleted, it is as though glBindRenderbuffer had been executed with a target of GL_RENDERBUFFER and a name of zero.
   2289     //
   2290     // If a renderbuffer object is attached to one or more attachment points in the currently bound framebuffer, then it as if glFramebufferRenderbuffer had been called, with a renderbuffer of zero for each attachment point to which this image was attached in the currently bound framebuffer. In other words, this renderbuffer object is first detached from all attachment ponits in the currently bound framebuffer. ***Note that the renderbuffer image is specifically not detached from any non-bound framebuffers***
   2291     //
   2292     // So, just detach this one from the bound FBO, and ignore the rest.
   2293     for (int i = 0; i < n; i++) {
   2294         state->detachRbo(renderbuffers[i]);
   2295     }
   2296     // state->removeRenderbuffers(n, renderbuffers);
   2297 }
   2298 
   2299 void GL2Encoder::s_glBindRenderbuffer(void* self,
   2300         GLenum target, GLuint renderbuffer) {
   2301     GL2Encoder* ctx = (GL2Encoder*)self;
   2302     GLClientState* state = ctx->m_state;
   2303 
   2304     SET_ERROR_IF((target != GL_RENDERBUFFER),
   2305                  GL_INVALID_ENUM);
   2306 
   2307     ctx->m_glBindRenderbuffer_enc(self, target, renderbuffer);
   2308     state->bindRenderbuffer(target, renderbuffer);
   2309 }
   2310 
   2311 void GL2Encoder::s_glRenderbufferStorage(void* self,
   2312         GLenum target, GLenum internalformat,
   2313         GLsizei width, GLsizei height) {
   2314     GL2Encoder* ctx = (GL2Encoder*) self;
   2315     GLClientState* state = ctx->m_state;
   2316 
   2317     SET_ERROR_IF(target != GL_RENDERBUFFER, GL_INVALID_ENUM);
   2318     SET_ERROR_IF(
   2319         !GLESv2Validation::rboFormat(ctx, internalformat),
   2320         GL_INVALID_ENUM);
   2321 
   2322     state->setBoundRenderbufferFormat(internalformat);
   2323     state->setBoundRenderbufferSamples(0);
   2324 
   2325     ctx->m_glRenderbufferStorage_enc(self, target, internalformat,
   2326                                      width, height);
   2327 }
   2328 
   2329 void GL2Encoder::s_glFramebufferRenderbuffer(void* self,
   2330         GLenum target, GLenum attachment,
   2331         GLenum renderbuffertarget, GLuint renderbuffer) {
   2332     GL2Encoder* ctx = (GL2Encoder*)self;
   2333     GLClientState* state = ctx->m_state;
   2334 
   2335     SET_ERROR_IF(!GLESv2Validation::framebufferTarget(ctx, target), GL_INVALID_ENUM);
   2336     SET_ERROR_IF(!GLESv2Validation::framebufferAttachment(ctx, attachment), GL_INVALID_ENUM);
   2337     state->attachRbo(target, attachment, renderbuffer);
   2338 
   2339     ctx->m_glFramebufferRenderbuffer_enc(self, target, attachment, renderbuffertarget, renderbuffer);
   2340 }
   2341 
   2342 void GL2Encoder::s_glGenFramebuffers(void* self,
   2343         GLsizei n, GLuint* framebuffers) {
   2344     GL2Encoder* ctx = (GL2Encoder*)self;
   2345     GLClientState* state = ctx->m_state;
   2346 
   2347     SET_ERROR_IF(n < 0, GL_INVALID_VALUE);
   2348 
   2349     ctx->m_glGenFramebuffers_enc(self, n, framebuffers);
   2350     state->addFramebuffers(n, framebuffers);
   2351 }
   2352 
   2353 void GL2Encoder::s_glDeleteFramebuffers(void* self,
   2354         GLsizei n, const GLuint* framebuffers) {
   2355     GL2Encoder* ctx = (GL2Encoder*)self;
   2356     GLClientState* state = ctx->m_state;
   2357 
   2358     SET_ERROR_IF(n < 0, GL_INVALID_VALUE);
   2359 
   2360     ctx->m_glDeleteFramebuffers_enc(self, n, framebuffers);
   2361     state->removeFramebuffers(n, framebuffers);
   2362 }
   2363 
   2364 void GL2Encoder::s_glBindFramebuffer(void* self,
   2365         GLenum target, GLuint framebuffer) {
   2366     GL2Encoder* ctx = (GL2Encoder*)self;
   2367     GLClientState* state = ctx->m_state;
   2368 
   2369     SET_ERROR_IF(!GLESv2Validation::framebufferTarget(ctx, target), GL_INVALID_ENUM);
   2370 
   2371     state->bindFramebuffer(target, framebuffer);
   2372 
   2373     ctx->m_glBindFramebuffer_enc(self, target, framebuffer);
   2374 }
   2375 
   2376 void GL2Encoder::s_glFramebufferTexture2D(void* self,
   2377         GLenum target, GLenum attachment,
   2378         GLenum textarget, GLuint texture, GLint level) {
   2379     GL2Encoder* ctx = (GL2Encoder*)self;
   2380     GLClientState* state = ctx->m_state;
   2381 
   2382     SET_ERROR_IF(!GLESv2Validation::framebufferTarget(ctx, target), GL_INVALID_ENUM);
   2383     SET_ERROR_IF(!GLESv2Validation::framebufferAttachment(ctx, attachment), GL_INVALID_ENUM);
   2384     state->attachTextureObject(target, attachment, texture);
   2385 
   2386     ctx->m_glFramebufferTexture2D_enc(self, target, attachment, textarget, texture, level);
   2387 }
   2388 
   2389 void GL2Encoder::s_glFramebufferTexture3DOES(void* self,
   2390         GLenum target, GLenum attachment,
   2391         GLenum textarget, GLuint texture, GLint level, GLint zoffset) {
   2392     GL2Encoder* ctx = (GL2Encoder*)self;
   2393     GLClientState* state = ctx->m_state;
   2394 
   2395     state->attachTextureObject(target, attachment, texture);
   2396 
   2397     ctx->m_glFramebufferTexture3DOES_enc(self, target, attachment, textarget, texture, level, zoffset);
   2398 }
   2399 
   2400 void GL2Encoder::s_glGetFramebufferAttachmentParameteriv(void* self,
   2401         GLenum target, GLenum attachment, GLenum pname, GLint* params) {
   2402     GL2Encoder* ctx = (GL2Encoder*)self;
   2403     const GLClientState* state = ctx->m_state;
   2404     SET_ERROR_IF(!GLESv2Validation::framebufferTarget(ctx, target), GL_INVALID_ENUM);
   2405     SET_ERROR_IF(pname != GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME &&
   2406                  pname != GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE &&
   2407                  !state->attachmentHasObject(target, attachment),
   2408                  GL_INVALID_OPERATION);
   2409     SET_ERROR_IF((pname == GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL ||
   2410                   pname == GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE ||
   2411                   pname == GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER) &&
   2412                  (!state->attachmentHasObject(target, attachment) ||
   2413                   state->getBoundFramebufferAttachmentType(target, attachment) !=
   2414                   FBO_ATTACHMENT_TEXTURE),
   2415                  !state->attachmentHasObject(target, attachment) ?
   2416                  GL_INVALID_OPERATION : GL_INVALID_ENUM);
   2417     SET_ERROR_IF(attachment == GL_DEPTH_STENCIL_ATTACHMENT &&
   2418                  pname == GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME &&
   2419                  (state->objectOfAttachment(target, GL_DEPTH_ATTACHMENT) !=
   2420                   state->objectOfAttachment(target, GL_STENCIL_ATTACHMENT)),
   2421                  GL_INVALID_OPERATION);
   2422     SET_ERROR_IF(state->boundFramebuffer(target) &&
   2423                  (attachment == GL_BACK ||
   2424                   attachment == GL_FRONT),
   2425                  GL_INVALID_OPERATION);
   2426     ctx->m_glGetFramebufferAttachmentParameteriv_enc(self, target, attachment, pname, params);
   2427 }
   2428 
   2429 bool GL2Encoder::isCompleteFbo(GLenum target, const GLClientState* state,
   2430                                GLenum attachment) const {
   2431     FboFormatInfo fbo_format_info;
   2432     state->getBoundFramebufferFormat(target, attachment, &fbo_format_info);
   2433 
   2434     bool res;
   2435     switch (fbo_format_info.type) {
   2436     case FBO_ATTACHMENT_RENDERBUFFER:
   2437         switch (fbo_format_info.rb_format) {
   2438         case GL_R16F:
   2439         case GL_RG16F:
   2440         case GL_RGBA16F:
   2441         case GL_R32F:
   2442         case GL_RG32F:
   2443         case GL_RGBA32F:
   2444         case GL_R11F_G11F_B10F:
   2445             res = majorVersion() >= 3 && hasExtension("GL_EXT_color_buffer_float");
   2446             break;
   2447         case GL_RGB16F:
   2448             res = majorVersion() >= 3 && hasExtension("GL_EXT_color_buffer_half_float");
   2449             break;
   2450         case GL_STENCIL_INDEX8:
   2451             if (attachment == GL_STENCIL_ATTACHMENT) {
   2452                 res = true;
   2453             } else {
   2454                 res = false;
   2455             }
   2456             break;
   2457         default:
   2458             res = true;
   2459         }
   2460         break;
   2461     case FBO_ATTACHMENT_TEXTURE:
   2462         switch (fbo_format_info.tex_internalformat) {
   2463         case GL_R16F:
   2464         case GL_RG16F:
   2465         case GL_RGBA16F:
   2466         case GL_R32F:
   2467         case GL_RG32F:
   2468         case GL_RGBA32F:
   2469         case GL_R11F_G11F_B10F:
   2470             res = majorVersion() >= 3 && hasExtension("GL_EXT_color_buffer_float");
   2471             break;
   2472         case GL_RGB16F:
   2473             res = majorVersion() >= 3 && hasExtension("GL_EXT_color_buffer_half_float");
   2474             break;
   2475         case GL_RED:
   2476         case GL_RG:
   2477         case GL_SRGB8:
   2478         case GL_RGB32UI:
   2479         case GL_RGB16UI:
   2480         case GL_RGB8UI:
   2481         case GL_RGB32I:
   2482         case GL_RGB16I:
   2483         case GL_RGB8I:
   2484         case GL_R8_SNORM:
   2485         case GL_RG8_SNORM:
   2486         case GL_RGB8_SNORM:
   2487         case GL_RGBA8_SNORM:
   2488             res = false;
   2489             break;
   2490         // No float/half-float formats allowed for RGB(A)
   2491         case GL_RGB:
   2492         case GL_RGBA:
   2493             switch (fbo_format_info.tex_type) {
   2494             case GL_FLOAT:
   2495             case GL_HALF_FLOAT_OES:
   2496             case GL_UNSIGNED_INT_10F_11F_11F_REV:
   2497             case GL_UNSIGNED_INT_2_10_10_10_REV:
   2498                 res = false;
   2499                 break;
   2500             default:
   2501                 res = true;
   2502             }
   2503             break;
   2504         default:
   2505             res = true;
   2506         }
   2507         break;
   2508     case FBO_ATTACHMENT_NONE:
   2509         res = true;
   2510         break;
   2511     default:
   2512         res = true;
   2513     }
   2514     return res;
   2515 }
   2516 
   2517 bool GL2Encoder::checkFramebufferCompleteness(GLenum target, const GLClientState* state) const {
   2518     bool res = true;
   2519 
   2520     for (int i = 0; i < state->getMaxColorAttachments(); i++) {
   2521         res = res && isCompleteFbo(target, state, glUtilsColorAttachmentName(i));
   2522     }
   2523 
   2524     res = res && isCompleteFbo(target, state, GL_DEPTH_ATTACHMENT);
   2525     res = res && isCompleteFbo(target, state, GL_STENCIL_ATTACHMENT);
   2526 
   2527     return res;
   2528 }
   2529 
   2530 GLenum GL2Encoder::s_glCheckFramebufferStatus(void* self, GLenum target) {
   2531     GL2Encoder* ctx = (GL2Encoder*)self;
   2532     GLClientState* state = ctx->m_state;
   2533 
   2534     bool fboCompleteByCodec =
   2535         ctx->checkFramebufferCompleteness(target, state);
   2536 
   2537     if (!fboCompleteByCodec) {
   2538         state->setCheckFramebufferStatus(target, GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT);
   2539         return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
   2540     } else {
   2541         // double check with underlying opengl to avoid craziness.
   2542         GLenum host_checkstatus = ctx->m_glCheckFramebufferStatus_enc(self, target);
   2543         state->setCheckFramebufferStatus(target, host_checkstatus);
   2544         if (host_checkstatus == GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS) return GL_FRAMEBUFFER_COMPLETE;
   2545         return host_checkstatus;
   2546     }
   2547 }
   2548 
   2549 void GL2Encoder::s_glGenVertexArrays(void* self, GLsizei n, GLuint* arrays) {
   2550     GL2Encoder* ctx = (GL2Encoder*)self;
   2551     GLClientState* state = ctx->m_state;
   2552     SET_ERROR_IF(n < 0, GL_INVALID_VALUE);
   2553 
   2554     ctx->m_glGenVertexArrays_enc(self, n, arrays);
   2555     for (int i = 0; i < n; i++) {
   2556         ALOGV("%s: gen vao %u", __FUNCTION__, arrays[i]);
   2557     }
   2558     state->addVertexArrayObjects(n, arrays);
   2559 }
   2560 
   2561 void GL2Encoder::s_glDeleteVertexArrays(void* self, GLsizei n, const GLuint* arrays) {
   2562     GL2Encoder* ctx = (GL2Encoder*)self;
   2563     GLClientState* state = ctx->m_state;
   2564     SET_ERROR_IF(n < 0, GL_INVALID_VALUE);
   2565 
   2566     ctx->m_glDeleteVertexArrays_enc(self, n, arrays);
   2567     for (int i = 0; i < n; i++) {
   2568         ALOGV("%s: delete vao %u", __FUNCTION__, arrays[i]);
   2569     }
   2570     state->removeVertexArrayObjects(n, arrays);
   2571 }
   2572 
   2573 void GL2Encoder::s_glBindVertexArray(void* self, GLuint array) {
   2574     ALOGV("%s: call. array=%u\n", __FUNCTION__, array);
   2575     GL2Encoder* ctx = (GL2Encoder*)self;
   2576     GLClientState* state = ctx->m_state;
   2577     SET_ERROR_IF(!state->isVertexArrayObject(array), GL_INVALID_OPERATION);
   2578     ctx->m_glBindVertexArray_enc(self, array);
   2579     state->setVertexArrayObject(array);
   2580 }
   2581 
   2582 void* GL2Encoder::s_glMapBufferRange(void* self, GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access) {
   2583     GL2Encoder* ctx = (GL2Encoder*)self;
   2584     GLClientState* state = ctx->m_state;
   2585 
   2586     // begin validation (lots)
   2587 
   2588     RET_AND_SET_ERROR_IF(!GLESv2Validation::bufferTarget(ctx, target), GL_INVALID_ENUM, NULL);
   2589 
   2590     GLuint boundBuffer = ctx->m_state->getBuffer(target);
   2591 
   2592     RET_AND_SET_ERROR_IF(boundBuffer == 0, GL_INVALID_OPERATION, NULL);
   2593 
   2594     BufferData* buf = ctx->m_shared->getBufferData(boundBuffer);
   2595     RET_AND_SET_ERROR_IF(!buf, GL_INVALID_VALUE, NULL);
   2596 
   2597     GLsizeiptr bufferDataSize = buf->m_size;
   2598 
   2599     RET_AND_SET_ERROR_IF(offset < 0, GL_INVALID_VALUE, NULL);
   2600     RET_AND_SET_ERROR_IF(length < 0, GL_INVALID_VALUE, NULL);
   2601     RET_AND_SET_ERROR_IF(offset + length > bufferDataSize, GL_INVALID_VALUE, NULL);
   2602     RET_AND_SET_ERROR_IF(access & ~GLESv2Validation::allBufferMapAccessFlags, GL_INVALID_VALUE, NULL);
   2603 
   2604     RET_AND_SET_ERROR_IF(buf->m_mapped, GL_INVALID_OPERATION, NULL);
   2605     RET_AND_SET_ERROR_IF(!(access & (GL_MAP_READ_BIT | GL_MAP_WRITE_BIT)), GL_INVALID_OPERATION, NULL);
   2606     RET_AND_SET_ERROR_IF(
   2607         (access & GL_MAP_READ_BIT) &&
   2608              ((access & GL_MAP_INVALIDATE_RANGE_BIT) ||
   2609               (access & GL_MAP_INVALIDATE_BUFFER_BIT) ||
   2610               (access & GL_MAP_UNSYNCHRONIZED_BIT) ||
   2611               (access & GL_MAP_FLUSH_EXPLICIT_BIT)), GL_INVALID_OPERATION, NULL);
   2612 
   2613     // end validation; actually do stuff now
   2614 
   2615     buf->m_mapped = true;
   2616     buf->m_mappedAccess = access;
   2617     buf->m_mappedOffset = offset;
   2618     buf->m_mappedLength = length;
   2619 
   2620     char* todo = (char*)buf->m_fixedBuffer.ptr() + offset;
   2621     ctx->glMapBufferRangeAEMU(
   2622             ctx, target,
   2623             offset, length,
   2624             access,
   2625             todo);
   2626 
   2627     return todo;
   2628 }
   2629 
   2630 GLboolean GL2Encoder::s_glUnmapBuffer(void* self, GLenum target) {
   2631     GL2Encoder* ctx = (GL2Encoder*)self;
   2632     GLClientState* state = ctx->m_state;
   2633 
   2634     RET_AND_SET_ERROR_IF(!GLESv2Validation::bufferTarget(ctx, target), GL_INVALID_ENUM, GL_FALSE);
   2635 
   2636     GLuint boundBuffer = ctx->m_state->getBuffer(target);
   2637 
   2638     RET_AND_SET_ERROR_IF(boundBuffer == 0, GL_INVALID_OPERATION, GL_FALSE);
   2639 
   2640     BufferData* buf = ctx->m_shared->getBufferData(boundBuffer);
   2641     RET_AND_SET_ERROR_IF(!buf, GL_INVALID_VALUE, GL_FALSE);
   2642     RET_AND_SET_ERROR_IF(!buf->m_mapped, GL_INVALID_OPERATION, GL_FALSE);
   2643 
   2644     if (buf->m_mappedAccess & GL_MAP_WRITE_BIT) {
   2645         // invalide index range cache here
   2646         if (buf->m_mappedAccess & GL_MAP_INVALIDATE_BUFFER_BIT) {
   2647             buf->m_indexRangeCache.invalidateRange(0, buf->m_size);
   2648         } else {
   2649             buf->m_indexRangeCache.invalidateRange(buf->m_mappedOffset, buf->m_mappedLength);
   2650         }
   2651     }
   2652 
   2653     GLboolean host_res = GL_TRUE;
   2654 
   2655     ctx->glUnmapBufferAEMU(
   2656             ctx, target,
   2657             buf->m_mappedOffset,
   2658             buf->m_mappedLength,
   2659             buf->m_mappedAccess,
   2660             (void*)((char*)buf->m_fixedBuffer.ptr() + buf->m_mappedOffset),
   2661             &host_res);
   2662 
   2663     buf->m_mapped = false;
   2664     buf->m_mappedAccess = 0;
   2665     buf->m_mappedOffset = 0;
   2666     buf->m_mappedLength = 0;
   2667 
   2668     return host_res;
   2669 }
   2670 
   2671 void GL2Encoder::s_glFlushMappedBufferRange(void* self, GLenum target, GLintptr offset, GLsizeiptr length) {
   2672     GL2Encoder* ctx = (GL2Encoder*)self;
   2673     GLClientState* state = ctx->m_state;
   2674 
   2675     SET_ERROR_IF(!GLESv2Validation::bufferTarget(ctx, target), GL_INVALID_ENUM);
   2676 
   2677     GLuint boundBuffer = ctx->m_state->getBuffer(target);
   2678     SET_ERROR_IF(!boundBuffer, GL_INVALID_OPERATION);
   2679 
   2680     BufferData* buf = ctx->m_shared->getBufferData(boundBuffer);
   2681     SET_ERROR_IF(!buf, GL_INVALID_VALUE);
   2682     SET_ERROR_IF(!buf->m_mapped, GL_INVALID_OPERATION);
   2683     SET_ERROR_IF(!(buf->m_mappedAccess & GL_MAP_FLUSH_EXPLICIT_BIT), GL_INVALID_OPERATION);
   2684 
   2685     SET_ERROR_IF(offset < 0, GL_INVALID_VALUE);
   2686     SET_ERROR_IF(length < 0, GL_INVALID_VALUE);
   2687     SET_ERROR_IF(offset + length > buf->m_mappedLength, GL_INVALID_VALUE);
   2688 
   2689     GLintptr totalOffset = buf->m_mappedOffset + offset;
   2690 
   2691     buf->m_indexRangeCache.invalidateRange(totalOffset, length);
   2692 
   2693     ctx->glFlushMappedBufferRangeAEMU(
   2694             ctx, target,
   2695             totalOffset,
   2696             length,
   2697             buf->m_mappedAccess,
   2698             (void*)((char*)buf->m_fixedBuffer.ptr() + totalOffset));
   2699 }
   2700 
   2701 void GL2Encoder::s_glCompressedTexImage2D(void* self, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid* data) {
   2702     GL2Encoder* ctx = (GL2Encoder*)self;
   2703     GLClientState* state = ctx->m_state;
   2704 
   2705     SET_ERROR_IF(!GLESv2Validation::textureTarget(ctx, target), GL_INVALID_ENUM);
   2706     // Filter compressed formats support.
   2707     SET_ERROR_IF(!GLESv2Validation::supportedCompressedFormat(ctx, internalformat), GL_INVALID_ENUM);
   2708     // Verify level <= log2(GL_MAX_TEXTURE_SIZE).
   2709     GLint max_texture_size;
   2710     GLint max_cube_map_texture_size;
   2711     ctx->glGetIntegerv(ctx, GL_MAX_TEXTURE_SIZE, &max_texture_size);
   2712     ctx->glGetIntegerv(ctx, GL_MAX_CUBE_MAP_TEXTURE_SIZE, &max_cube_map_texture_size);
   2713     SET_ERROR_IF(level < 0, GL_INVALID_VALUE);
   2714     SET_ERROR_IF(level > ilog2(max_texture_size), GL_INVALID_VALUE);
   2715     SET_ERROR_IF(level > ilog2(max_cube_map_texture_size), GL_INVALID_VALUE);
   2716     SET_ERROR_IF(width > max_texture_size, GL_INVALID_VALUE);
   2717     SET_ERROR_IF(height > max_texture_size, GL_INVALID_VALUE);
   2718     SET_ERROR_IF(border, GL_INVALID_VALUE);
   2719     // If unpack buffer is nonzero, verify unmapped state.
   2720     SET_ERROR_IF(ctx->isBufferTargetMapped(GL_PIXEL_UNPACK_BUFFER), GL_INVALID_OPERATION);
   2721     SET_ERROR_IF(width < 0 || height < 0, GL_INVALID_VALUE);
   2722     // If unpack buffer is nonzero, verify buffer data fits.
   2723     SET_ERROR_IF(ctx->boundBuffer(GL_PIXEL_UNPACK_BUFFER) &&
   2724                  ctx->getBufferData(GL_PIXEL_UNPACK_BUFFER) &&
   2725                  (imageSize > ctx->getBufferData(GL_PIXEL_UNPACK_BUFFER)->m_size),
   2726                  GL_INVALID_OPERATION);
   2727     // TODO: Fix:
   2728     // If |imageSize| is inconsistent with compressed dimensions.
   2729     // SET_ERROR_IF(GLESv2Validation::compressedTexImageSize(internalformat, width, height, 1) != imageSize, GL_INVALID_VALUE);
   2730 
   2731     GLenum stateTarget = target;
   2732     if (target == GL_TEXTURE_CUBE_MAP_POSITIVE_X ||
   2733         target == GL_TEXTURE_CUBE_MAP_POSITIVE_Y ||
   2734         target == GL_TEXTURE_CUBE_MAP_POSITIVE_Z ||
   2735         target == GL_TEXTURE_CUBE_MAP_NEGATIVE_X ||
   2736         target == GL_TEXTURE_CUBE_MAP_NEGATIVE_Y ||
   2737         target == GL_TEXTURE_CUBE_MAP_NEGATIVE_Z)
   2738         stateTarget = GL_TEXTURE_CUBE_MAP;
   2739     state->setBoundTextureInternalFormat(stateTarget, (GLint)internalformat);
   2740     state->setBoundTextureDims(stateTarget, level, width, height, 1);
   2741 
   2742     if (ctx->boundBuffer(GL_PIXEL_UNPACK_BUFFER)) {
   2743         ctx->glCompressedTexImage2DOffsetAEMU(
   2744                 ctx, target, level, internalformat,
   2745                 width, height, border,
   2746                 imageSize, (uintptr_t)data);
   2747     } else {
   2748         ctx->m_glCompressedTexImage2D_enc(
   2749                 ctx, target, level, internalformat,
   2750                 width, height, border,
   2751                 imageSize, data);
   2752     }
   2753 }
   2754 
   2755 void GL2Encoder::s_glCompressedTexSubImage2D(void* self, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid* data) {
   2756     GL2Encoder* ctx = (GL2Encoder*)self;
   2757     GLClientState* state = ctx->m_state;
   2758 
   2759     SET_ERROR_IF(!GLESv2Validation::textureTarget(ctx, target), GL_INVALID_ENUM);
   2760     // If unpack buffer is nonzero, verify unmapped state.
   2761     SET_ERROR_IF(ctx->isBufferTargetMapped(GL_PIXEL_UNPACK_BUFFER), GL_INVALID_OPERATION);
   2762     GLint max_texture_size;
   2763     GLint max_cube_map_texture_size;
   2764     ctx->glGetIntegerv(ctx, GL_MAX_TEXTURE_SIZE, &max_texture_size);
   2765     ctx->glGetIntegerv(ctx, GL_MAX_CUBE_MAP_TEXTURE_SIZE, &max_cube_map_texture_size);
   2766     SET_ERROR_IF(level < 0, GL_INVALID_VALUE);
   2767     SET_ERROR_IF(level > ilog2(max_texture_size), GL_INVALID_VALUE);
   2768     SET_ERROR_IF(level > ilog2(max_cube_map_texture_size), GL_INVALID_VALUE);
   2769     SET_ERROR_IF(width < 0 || height < 0, GL_INVALID_VALUE);
   2770     // If unpack buffer is nonzero, verify buffer data fits.
   2771     SET_ERROR_IF(ctx->boundBuffer(GL_PIXEL_UNPACK_BUFFER) &&
   2772                  ctx->getBufferData(GL_PIXEL_UNPACK_BUFFER) &&
   2773                  (imageSize > ctx->getBufferData(GL_PIXEL_UNPACK_BUFFER)->m_size),
   2774                  GL_INVALID_OPERATION);
   2775     SET_ERROR_IF(xoffset < 0 || yoffset < 0, GL_INVALID_VALUE);
   2776 
   2777     if (ctx->boundBuffer(GL_PIXEL_UNPACK_BUFFER)) {
   2778         ctx->glCompressedTexSubImage2DOffsetAEMU(
   2779                 ctx, target, level,
   2780                 xoffset, yoffset,
   2781                 width, height, format,
   2782                 imageSize, (uintptr_t)data);
   2783     } else {
   2784         ctx->m_glCompressedTexSubImage2D_enc(
   2785                 ctx, target, level,
   2786                 xoffset, yoffset,
   2787                 width, height, format,
   2788                 imageSize, data);
   2789     }
   2790 }
   2791 
   2792 void GL2Encoder::s_glBindBufferRange(void* self, GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size) {
   2793     GL2Encoder* ctx = (GL2Encoder*)self;
   2794     GLClientState* state = ctx->m_state;
   2795 
   2796     SET_ERROR_IF(!GLESv2Validation::bufferTarget(ctx, target), GL_INVALID_ENUM);
   2797 
   2798     // Only works with certain targets
   2799     SET_ERROR_IF(
   2800         !(target == GL_ATOMIC_COUNTER_BUFFER ||
   2801           target == GL_SHADER_STORAGE_BUFFER ||
   2802           target == GL_TRANSFORM_FEEDBACK_BUFFER ||
   2803           target == GL_UNIFORM_BUFFER),
   2804         GL_INVALID_ENUM);
   2805 
   2806     // Can't exceed range
   2807     SET_ERROR_IF(index < 0 ||
   2808                  index >= state->getMaxIndexedBufferBindings(target),
   2809                  GL_INVALID_VALUE);
   2810     SET_ERROR_IF(buffer && size <= 0, GL_INVALID_VALUE);
   2811     SET_ERROR_IF((target == GL_ATOMIC_COUNTER_BUFFER ||
   2812                   target == GL_TRANSFORM_FEEDBACK_BUFFER) &&
   2813                  (size % 4 || offset % 4),
   2814                  GL_INVALID_VALUE);
   2815 
   2816     GLint ssbo_offset_align, ubo_offset_align;
   2817     ctx->s_glGetIntegerv(ctx, GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT, &ssbo_offset_align);
   2818     ctx->s_glGetIntegerv(ctx, GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT, &ubo_offset_align);
   2819     SET_ERROR_IF(target == GL_SHADER_STORAGE_BUFFER &&
   2820                  offset % ssbo_offset_align,
   2821                  GL_INVALID_VALUE);
   2822     SET_ERROR_IF(target == GL_UNIFORM_BUFFER &&
   2823                  offset % ubo_offset_align,
   2824                  GL_INVALID_VALUE);
   2825 
   2826     state->bindBuffer(target, buffer);
   2827     ctx->m_state->addBuffer(buffer);
   2828     state->bindIndexedBuffer(target, index, buffer, offset, size, 0, 0);
   2829     ctx->m_glBindBufferRange_enc(self, target, index, buffer, offset, size);
   2830 }
   2831 
   2832 void GL2Encoder::s_glBindBufferBase(void* self, GLenum target, GLuint index, GLuint buffer) {
   2833     GL2Encoder* ctx = (GL2Encoder*)self;
   2834     GLClientState* state = ctx->m_state;
   2835 
   2836     SET_ERROR_IF(!GLESv2Validation::bufferTarget(ctx, target), GL_INVALID_ENUM);
   2837 
   2838     // Only works with certain targets
   2839     SET_ERROR_IF(
   2840         !(target == GL_ATOMIC_COUNTER_BUFFER ||
   2841           target == GL_SHADER_STORAGE_BUFFER ||
   2842           target == GL_TRANSFORM_FEEDBACK_BUFFER ||
   2843           target == GL_UNIFORM_BUFFER),
   2844         GL_INVALID_ENUM);
   2845     // Can't exceed range
   2846     SET_ERROR_IF(index < 0 ||
   2847                  index >= state->getMaxIndexedBufferBindings(target),
   2848                  GL_INVALID_VALUE);
   2849 
   2850     state->bindBuffer(target, buffer);
   2851     ctx->m_state->addBuffer(buffer);
   2852     BufferData* buf = ctx->getBufferDataById(buffer);
   2853     state->bindIndexedBuffer(target, index, buffer, 0, buf ? buf->m_size : 0, 0, 0);
   2854     ctx->m_glBindBufferBase_enc(self, target, index, buffer);
   2855 }
   2856 
   2857 void GL2Encoder::s_glCopyBufferSubData(void *self , GLenum readtarget, GLenum writetarget, GLintptr readoffset, GLintptr writeoffset, GLsizeiptr size) {
   2858     GL2Encoder* ctx = (GL2Encoder*)self;
   2859     GLClientState* state = ctx->m_state;
   2860 
   2861     SET_ERROR_IF(!GLESv2Validation::bufferTarget(ctx, readtarget), GL_INVALID_ENUM);
   2862     SET_ERROR_IF(!GLESv2Validation::bufferTarget(ctx, writetarget), GL_INVALID_ENUM);
   2863     SET_ERROR_IF((readtarget == GL_ATOMIC_COUNTER_BUFFER ||
   2864                   readtarget == GL_DISPATCH_INDIRECT_BUFFER ||
   2865                   readtarget == GL_DRAW_INDIRECT_BUFFER ||
   2866                   readtarget == GL_SHADER_STORAGE_BUFFER), GL_INVALID_ENUM);
   2867     SET_ERROR_IF((writetarget == GL_ATOMIC_COUNTER_BUFFER ||
   2868                   writetarget == GL_DISPATCH_INDIRECT_BUFFER ||
   2869                   writetarget == GL_DRAW_INDIRECT_BUFFER ||
   2870                   writetarget == GL_SHADER_STORAGE_BUFFER), GL_INVALID_ENUM);
   2871     SET_ERROR_IF(!ctx->boundBuffer(readtarget), GL_INVALID_OPERATION);
   2872     SET_ERROR_IF(!ctx->boundBuffer(writetarget), GL_INVALID_OPERATION);
   2873     SET_ERROR_IF(ctx->isBufferTargetMapped(readtarget), GL_INVALID_OPERATION);
   2874     SET_ERROR_IF(ctx->isBufferTargetMapped(writetarget), GL_INVALID_OPERATION);
   2875     SET_ERROR_IF(readoffset < 0, GL_INVALID_VALUE);
   2876     SET_ERROR_IF(writeoffset < 0, GL_INVALID_VALUE);
   2877     SET_ERROR_IF(size < 0, GL_INVALID_VALUE);
   2878     SET_ERROR_IF(
   2879         ctx->getBufferData(readtarget) &&
   2880         (readoffset + size > ctx->getBufferData(readtarget)->m_size),
   2881         GL_INVALID_VALUE);
   2882     SET_ERROR_IF(
   2883         ctx->getBufferData(writetarget) &&
   2884         (writeoffset + size > ctx->getBufferData(writetarget)->m_size),
   2885         GL_INVALID_VALUE);
   2886     SET_ERROR_IF(readtarget == writetarget &&
   2887                  !((writeoffset >= readoffset + size) ||
   2888                    (readoffset >= writeoffset + size)),
   2889                  GL_INVALID_VALUE);
   2890 
   2891     ctx->m_glCopyBufferSubData_enc(self, readtarget, writetarget, readoffset, writeoffset, size);
   2892 }
   2893 
   2894 void GL2Encoder::s_glGetBufferParameteriv(void* self, GLenum target, GLenum pname, GLint* params) {
   2895     GL2Encoder* ctx = (GL2Encoder*)self;
   2896 
   2897     SET_ERROR_IF(!GLESv2Validation::bufferTarget(ctx, target), GL_INVALID_ENUM);
   2898     SET_ERROR_IF(
   2899         target != GL_ARRAY_BUFFER &&
   2900         target != GL_ELEMENT_ARRAY_BUFFER &&
   2901         target != GL_COPY_READ_BUFFER &&
   2902         target != GL_COPY_WRITE_BUFFER &&
   2903         target != GL_PIXEL_PACK_BUFFER &&
   2904         target != GL_PIXEL_UNPACK_BUFFER &&
   2905         target != GL_TRANSFORM_FEEDBACK_BUFFER &&
   2906         target != GL_UNIFORM_BUFFER,
   2907         GL_INVALID_ENUM);
   2908     SET_ERROR_IF(!GLESv2Validation::bufferParam(ctx, pname), GL_INVALID_ENUM);
   2909     SET_ERROR_IF(!ctx->boundBuffer(target), GL_INVALID_OPERATION);
   2910     SET_ERROR_IF(pname != GL_BUFFER_ACCESS_FLAGS &&
   2911                  pname != GL_BUFFER_MAPPED &&
   2912                  pname != GL_BUFFER_SIZE &&
   2913                  pname != GL_BUFFER_USAGE &&
   2914                  pname != GL_BUFFER_MAP_LENGTH &&
   2915                  pname != GL_BUFFER_MAP_OFFSET,
   2916                  GL_INVALID_ENUM);
   2917 
   2918     if (!params) return;
   2919 
   2920     BufferData* buf = ctx->getBufferData(target);
   2921 
   2922     switch (pname) {
   2923         case GL_BUFFER_ACCESS_FLAGS:
   2924             *params = buf ? buf->m_mappedAccess : 0;
   2925             break;
   2926         case GL_BUFFER_MAPPED:
   2927             *params = buf ? (buf->m_mapped ? GL_TRUE : GL_FALSE) : GL_FALSE;
   2928             break;
   2929         case GL_BUFFER_SIZE:
   2930             *params = buf ? buf->m_size : 0;
   2931             break;
   2932         case GL_BUFFER_USAGE:
   2933             *params = buf ? buf->m_usage : GL_STATIC_DRAW;
   2934             break;
   2935         case GL_BUFFER_MAP_LENGTH:
   2936             *params = buf ? buf->m_mappedLength : 0;
   2937             break;
   2938         case GL_BUFFER_MAP_OFFSET:
   2939             *params = buf ? buf->m_mappedOffset : 0;
   2940             break;
   2941         default:
   2942             break;
   2943     }
   2944 }
   2945 
   2946 void GL2Encoder::s_glGetBufferParameteri64v(void* self, GLenum target, GLenum pname, GLint64* params) {
   2947     GL2Encoder* ctx = (GL2Encoder*)self;
   2948 
   2949     SET_ERROR_IF(!GLESv2Validation::bufferTarget(ctx, target), GL_INVALID_ENUM);
   2950     SET_ERROR_IF(
   2951         target != GL_ARRAY_BUFFER &&
   2952         target != GL_ELEMENT_ARRAY_BUFFER &&
   2953         target != GL_COPY_READ_BUFFER &&
   2954         target != GL_COPY_WRITE_BUFFER &&
   2955         target != GL_PIXEL_PACK_BUFFER &&
   2956         target != GL_PIXEL_UNPACK_BUFFER &&
   2957         target != GL_TRANSFORM_FEEDBACK_BUFFER &&
   2958         target != GL_UNIFORM_BUFFER,
   2959         GL_INVALID_ENUM);
   2960     SET_ERROR_IF(!GLESv2Validation::bufferParam(ctx, pname), GL_INVALID_ENUM);
   2961     SET_ERROR_IF(!ctx->boundBuffer(target), GL_INVALID_OPERATION);
   2962     SET_ERROR_IF(pname != GL_BUFFER_ACCESS_FLAGS &&
   2963                  pname != GL_BUFFER_MAPPED &&
   2964                  pname != GL_BUFFER_SIZE &&
   2965                  pname != GL_BUFFER_USAGE &&
   2966                  pname != GL_BUFFER_MAP_LENGTH &&
   2967                  pname != GL_BUFFER_MAP_OFFSET,
   2968                  GL_INVALID_ENUM);
   2969 
   2970     if (!params) return;
   2971 
   2972     BufferData* buf = ctx->getBufferData(target);
   2973 
   2974     switch (pname) {
   2975         case GL_BUFFER_ACCESS_FLAGS:
   2976             *params = buf ? buf->m_mappedAccess : 0;
   2977             break;
   2978         case GL_BUFFER_MAPPED:
   2979             *params = buf ? (buf->m_mapped ? GL_TRUE : GL_FALSE) : GL_FALSE;
   2980             break;
   2981         case GL_BUFFER_SIZE:
   2982             *params = buf ? buf->m_size : 0;
   2983             break;
   2984         case GL_BUFFER_USAGE:
   2985             *params = buf ? buf->m_usage : GL_STATIC_DRAW;
   2986             break;
   2987         case GL_BUFFER_MAP_LENGTH:
   2988             *params = buf ? buf->m_mappedLength : 0;
   2989             break;
   2990         case GL_BUFFER_MAP_OFFSET:
   2991             *params = buf ? buf->m_mappedOffset : 0;
   2992             break;
   2993         default:
   2994             break;
   2995     }
   2996 }
   2997 
   2998 void GL2Encoder::s_glGetBufferPointerv(void* self, GLenum target, GLenum pname, GLvoid** params) {
   2999     GL2Encoder* ctx = (GL2Encoder*)self;
   3000     SET_ERROR_IF(!GLESv2Validation::bufferTarget(ctx, target), GL_INVALID_ENUM);
   3001     SET_ERROR_IF(
   3002         target == GL_ATOMIC_COUNTER_BUFFER ||
   3003         target == GL_DISPATCH_INDIRECT_BUFFER ||
   3004         target == GL_DRAW_INDIRECT_BUFFER ||
   3005         target == GL_SHADER_STORAGE_BUFFER,
   3006         GL_INVALID_ENUM);
   3007     SET_ERROR_IF(pname != GL_BUFFER_MAP_POINTER, GL_INVALID_ENUM);
   3008     SET_ERROR_IF(!ctx->boundBuffer(target), GL_INVALID_OPERATION);
   3009     if (!params) return;
   3010 
   3011     BufferData* buf = ctx->getBufferData(target);
   3012 
   3013     if (!buf || !buf->m_mapped) { *params = NULL; return; }
   3014 
   3015     *params = (GLvoid*)((char*)buf->m_fixedBuffer.ptr() + buf->m_mappedOffset);
   3016 }
   3017 
   3018 static const char* const kNameDelimiter = ";";
   3019 
   3020 static std::string packVarNames(GLsizei count, const char** names, GLint* err_out) {
   3021 
   3022 #define VALIDATE(cond, err) if (cond) { *err_out = err; return packed; } \
   3023 
   3024     std::string packed;
   3025     // validate the array of char[]'s
   3026     const char* currName;
   3027     for (GLsizei i = 0; i < count; i++) {
   3028         currName = names[i];
   3029         VALIDATE(!currName, GL_INVALID_OPERATION);
   3030         // check if has reasonable size
   3031         size_t len = strlen(currName);
   3032         VALIDATE(!len, GL_INVALID_OPERATION);
   3033         // check for our delimiter, which if present
   3034         // in the name, means an invalid name anyway.
   3035         VALIDATE(strstr(currName, kNameDelimiter),
   3036                  GL_INVALID_OPERATION);
   3037         packed += currName;
   3038         packed += ";";
   3039     }
   3040 
   3041     *err_out = GL_NO_ERROR;
   3042     return packed;
   3043 }
   3044 
   3045 void GL2Encoder::s_glGetUniformIndices(void* self, GLuint program, GLsizei uniformCount, const GLchar ** uniformNames, GLuint* uniformIndices) {
   3046     GL2Encoder* ctx = (GL2Encoder*)self;
   3047 
   3048     if (!uniformCount) return;
   3049 
   3050     GLint err = GL_NO_ERROR;
   3051     std::string packed = packVarNames(uniformCount, (const char**)uniformNames, &err);
   3052     SET_ERROR_IF(err != GL_NO_ERROR, GL_INVALID_OPERATION);
   3053 
   3054     bool needLocationWAR = ctx->m_shared->needUniformLocationWAR(program);
   3055     std::vector<int> arrIndices;
   3056     for (size_t i = 0; i < uniformCount; i++) {
   3057         int err;
   3058         arrIndices.push_back(sArrIndexOfUniformExpr(uniformNames[i], &err));
   3059         if (err) {
   3060             ALOGE("%s: invalid uniform name %s!", __FUNCTION__, uniformNames[i]);
   3061             return;
   3062         }
   3063     }
   3064 
   3065     ctx->glGetUniformIndicesAEMU(ctx, program, uniformCount, (const GLchar*)&packed[0], packed.size() + 1, uniformIndices);
   3066 
   3067     for (int i = 0; i < uniformCount; i++) {
   3068         if (uniformIndices[i] >= 0 && needLocationWAR) {
   3069             uniformIndices[i] =
   3070                 ctx->m_shared->locationWARHostToApp(program, uniformIndices[i], arrIndices[i]);
   3071         }
   3072     }
   3073 }
   3074 
   3075 void GL2Encoder::s_glUniform1ui(void* self, GLint location, GLuint v0) {
   3076     GL2Encoder *ctx = (GL2Encoder*)self;
   3077     GLClientState* state = ctx->m_state;
   3078     GLSharedGroupPtr shared = ctx->m_shared;
   3079 
   3080     GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
   3081     ctx->m_glUniform1ui_enc(self, hostLoc, v0);
   3082 
   3083     GLenum target;
   3084     if (shared->setSamplerUniform(state->currentShaderProgram(), location, v0, &target)) {
   3085         GLenum origActiveTexture = state->getActiveTextureUnit();
   3086         if (ctx->updateHostTexture2DBinding(GL_TEXTURE0 + v0, target)) {
   3087             ctx->m_glActiveTexture_enc(self, origActiveTexture);
   3088         }
   3089         state->setActiveTextureUnit(origActiveTexture);
   3090     }
   3091 }
   3092 
   3093 void GL2Encoder::s_glUniform2ui(void* self, GLint location, GLuint v0, GLuint v1) {
   3094     GL2Encoder *ctx = (GL2Encoder*)self;
   3095     GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
   3096     ctx->m_glUniform2ui_enc(self, hostLoc, v0, v1);
   3097 }
   3098 
   3099 void GL2Encoder::s_glUniform3ui(void* self, GLint location, GLuint v0, GLuint v1, GLuint v2) {
   3100     GL2Encoder *ctx = (GL2Encoder*)self;
   3101     GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
   3102     ctx->m_glUniform3ui_enc(self, hostLoc, v0, v1, v2);
   3103 }
   3104 
   3105 void GL2Encoder::s_glUniform4ui(void* self, GLint location, GLint v0, GLuint v1, GLuint v2, GLuint v3) {
   3106     GL2Encoder *ctx = (GL2Encoder*)self;
   3107     GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
   3108     ctx->m_glUniform4ui_enc(self, hostLoc, v0, v1, v2, v3);
   3109 }
   3110 
   3111 void GL2Encoder::s_glUniform1uiv(void* self, GLint location, GLsizei count, const GLuint *value) {
   3112     GL2Encoder *ctx = (GL2Encoder*)self;
   3113     GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
   3114     ctx->m_glUniform1uiv_enc(self, hostLoc, count, value);
   3115 }
   3116 
   3117 void GL2Encoder::s_glUniform2uiv(void* self, GLint location, GLsizei count, const GLuint *value) {
   3118     GL2Encoder *ctx = (GL2Encoder*)self;
   3119     GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
   3120     ctx->m_glUniform2uiv_enc(self, hostLoc, count, value);
   3121 }
   3122 
   3123 void GL2Encoder::s_glUniform3uiv(void* self, GLint location, GLsizei count, const GLuint *value) {
   3124     GL2Encoder *ctx = (GL2Encoder*)self;
   3125     GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
   3126     ctx->m_glUniform3uiv_enc(self, hostLoc, count, value);
   3127 }
   3128 
   3129 void GL2Encoder::s_glUniform4uiv(void* self, GLint location, GLsizei count, const GLuint *value) {
   3130     GL2Encoder *ctx = (GL2Encoder*)self;
   3131     GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
   3132     ctx->m_glUniform4uiv_enc(self, hostLoc, count, value);
   3133 }
   3134 
   3135 void GL2Encoder::s_glUniformMatrix2x3fv(void* self, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) {
   3136     GL2Encoder *ctx = (GL2Encoder*)self;
   3137     GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
   3138     ctx->m_glUniformMatrix2x3fv_enc(self, hostLoc, count, transpose, value);
   3139 }
   3140 
   3141 void GL2Encoder::s_glUniformMatrix3x2fv(void* self, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) {
   3142     GL2Encoder *ctx = (GL2Encoder*)self;
   3143     GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
   3144     ctx->m_glUniformMatrix3x2fv_enc(self, hostLoc, count, transpose, value);
   3145 }
   3146 
   3147 void GL2Encoder::s_glUniformMatrix2x4fv(void* self, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) {
   3148     GL2Encoder *ctx = (GL2Encoder*)self;
   3149     GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
   3150     ctx->m_glUniformMatrix2x4fv_enc(self, hostLoc, count, transpose, value);
   3151 }
   3152 
   3153 void GL2Encoder::s_glUniformMatrix4x2fv(void* self, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) {
   3154     GL2Encoder *ctx = (GL2Encoder*)self;
   3155     GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
   3156     ctx->m_glUniformMatrix4x2fv_enc(self, hostLoc, count, transpose, value);
   3157 }
   3158 
   3159 void GL2Encoder::s_glUniformMatrix3x4fv(void* self, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) {
   3160     GL2Encoder *ctx = (GL2Encoder*)self;
   3161     GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
   3162     ctx->m_glUniformMatrix3x4fv_enc(self, hostLoc, count, transpose, value);
   3163 }
   3164 
   3165 void GL2Encoder::s_glUniformMatrix4x3fv(void* self, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) {
   3166     GL2Encoder *ctx = (GL2Encoder*)self;
   3167     GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
   3168     ctx->m_glUniformMatrix4x3fv_enc(self, hostLoc, count, transpose, value);
   3169 }
   3170 
   3171 void GL2Encoder::s_glGetUniformuiv(void* self, GLuint program, GLint location, GLuint* params) {
   3172     GL2Encoder *ctx = (GL2Encoder*)self;
   3173     SET_ERROR_IF(!ctx->m_shared->isShaderOrProgramObject(program), GL_INVALID_VALUE);
   3174     SET_ERROR_IF(!ctx->m_shared->isProgram(program), GL_INVALID_OPERATION);
   3175     SET_ERROR_IF(!ctx->m_shared->isProgramInitialized(program), GL_INVALID_OPERATION);
   3176     GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
   3177     SET_ERROR_IF(ctx->m_shared->getProgramUniformType(program,hostLoc)==0, GL_INVALID_OPERATION);
   3178     ctx->m_glGetUniformuiv_enc(self, program, hostLoc, params);
   3179 }
   3180 
   3181 void GL2Encoder::s_glGetActiveUniformBlockiv(void* self, GLuint program, GLuint uniformBlockIndex, GLenum pname, GLint* params) {
   3182     GL2Encoder* ctx = (GL2Encoder*)self;
   3183     GLClientState* state = ctx->m_state;
   3184 
   3185     // refresh client state's # active uniforms in this block
   3186     if (pname == GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES) {
   3187         // TODO if worth it: cache uniform count and other params,
   3188         // invalidate on program relinking.
   3189         GLint numActiveUniforms;
   3190         ctx->m_glGetActiveUniformBlockiv_enc(ctx,
   3191                 program, uniformBlockIndex,
   3192                 GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS,
   3193                 &numActiveUniforms);
   3194         ctx->m_state->setNumActiveUniformsInUniformBlock(
   3195                 program, uniformBlockIndex, numActiveUniforms);
   3196     }
   3197 
   3198     ctx->m_glGetActiveUniformBlockiv_enc(ctx,
   3199             program, uniformBlockIndex,
   3200             pname, params);
   3201 }
   3202 
   3203 void GL2Encoder::s_glGetVertexAttribIiv(void* self, GLuint index, GLenum pname, GLint* params) {
   3204     GL2Encoder *ctx = (GL2Encoder *)self;
   3205     assert(ctx->m_state);
   3206     GLint maxIndex;
   3207     ctx->glGetIntegerv(self, GL_MAX_VERTEX_ATTRIBS, &maxIndex);
   3208     SET_ERROR_IF(!(index < maxIndex), GL_INVALID_VALUE);
   3209 
   3210     if (!ctx->m_state->getVertexAttribParameter<GLint>(index, pname, params)) {
   3211         ctx->m_glGetVertexAttribIiv_enc(self, index, pname, params);
   3212     }
   3213 }
   3214 
   3215 void GL2Encoder::s_glGetVertexAttribIuiv(void* self, GLuint index, GLenum pname, GLuint* params) {
   3216     GL2Encoder *ctx = (GL2Encoder *)self;
   3217     assert(ctx->m_state);
   3218     GLint maxIndex;
   3219     ctx->glGetIntegerv(self, GL_MAX_VERTEX_ATTRIBS, &maxIndex);
   3220     SET_ERROR_IF(!(index < maxIndex), GL_INVALID_VALUE);
   3221 
   3222     if (!ctx->m_state->getVertexAttribParameter<GLuint>(index, pname, params)) {
   3223         ctx->m_glGetVertexAttribIuiv_enc(self, index, pname, params);
   3224     }
   3225 }
   3226 
   3227 void GL2Encoder::s_glVertexAttribIPointer(void* self, GLuint index, GLint size, GLenum type, GLsizei stride, const GLvoid* pointer) {
   3228     GL2Encoder *ctx = (GL2Encoder *)self;
   3229     assert(ctx->m_state != NULL);
   3230     VALIDATE_VERTEX_ATTRIB_INDEX(index);
   3231     SET_ERROR_IF((size < 1 || size > 4), GL_INVALID_VALUE);
   3232     SET_ERROR_IF(
   3233         !(type == GL_BYTE ||
   3234           type == GL_UNSIGNED_BYTE ||
   3235           type == GL_SHORT ||
   3236           type == GL_UNSIGNED_SHORT ||
   3237           type == GL_INT ||
   3238           type == GL_UNSIGNED_INT),
   3239         GL_INVALID_ENUM);
   3240     SET_ERROR_IF(stride < 0, GL_INVALID_VALUE);
   3241 
   3242     ctx->m_state->setVertexAttribBinding(index, index);
   3243     ctx->m_state->setVertexAttribFormat(index, size, type, false, 0, true);
   3244     GLsizei effectiveStride = stride;
   3245     if (stride == 0) {
   3246         effectiveStride = glSizeof(type) * size;
   3247     }
   3248     ctx->m_state->bindIndexedBuffer(0, index, ctx->m_state->currentArrayVbo(), (uintptr_t)pointer, 0, stride, effectiveStride);
   3249 
   3250     if (ctx->m_state->currentArrayVbo() != 0) {
   3251         ctx->glVertexAttribIPointerOffsetAEMU(ctx, index, size, type, stride, (uintptr_t)pointer);
   3252     } else {
   3253         SET_ERROR_IF(ctx->m_state->currentVertexArrayObject() != 0 && pointer, GL_INVALID_OPERATION);
   3254         // wait for client-array handler
   3255     }
   3256 }
   3257 
   3258 void GL2Encoder::s_glVertexAttribDivisor(void* self, GLuint index, GLuint divisor) {
   3259     GL2Encoder *ctx = (GL2Encoder *)self;
   3260     assert(ctx->m_state != NULL);
   3261     VALIDATE_VERTEX_ATTRIB_INDEX(index);
   3262     ctx->m_state->setVertexAttribBinding(index, index);
   3263     ctx->m_state->setVertexBindingDivisor(index, divisor);
   3264     ctx->m_glVertexAttribDivisor_enc(ctx, index, divisor);
   3265 }
   3266 
   3267 void GL2Encoder::s_glRenderbufferStorageMultisample(void* self,
   3268         GLenum target, GLsizei samples, GLenum internalformat,
   3269         GLsizei width, GLsizei height) {
   3270     GL2Encoder *ctx = (GL2Encoder *)self;
   3271     GLClientState* state = ctx->m_state;
   3272 
   3273     SET_ERROR_IF(target != GL_RENDERBUFFER, GL_INVALID_ENUM);
   3274     SET_ERROR_IF(!GLESv2Validation::rboFormat(ctx, internalformat), GL_INVALID_ENUM);
   3275 
   3276     GLint max_samples;
   3277     ctx->s_glGetInternalformativ(ctx, target, internalformat, GL_SAMPLES, 1, &max_samples);
   3278     SET_ERROR_IF(samples > max_samples, GL_INVALID_OPERATION);
   3279 
   3280     state->setBoundRenderbufferFormat(internalformat);
   3281     state->setBoundRenderbufferSamples(samples);
   3282     ctx->m_glRenderbufferStorageMultisample_enc(
   3283             self, target, samples, internalformat, width, height);
   3284 }
   3285 
   3286 void GL2Encoder::s_glDrawBuffers(void* self, GLsizei n, const GLenum* bufs) {
   3287     GL2Encoder* ctx = (GL2Encoder*)self;
   3288     SET_ERROR_IF(!ctx->m_state->boundFramebuffer(GL_DRAW_FRAMEBUFFER) && n > 1, GL_INVALID_OPERATION);
   3289     SET_ERROR_IF(n < 0 || n > ctx->m_state->getMaxDrawBuffers(), GL_INVALID_VALUE);
   3290     for (int i = 0; i < n; i++) {
   3291         SET_ERROR_IF(
   3292             bufs[i] != GL_NONE &&
   3293             bufs[i] != GL_BACK &&
   3294             glUtilsColorAttachmentIndex(bufs[i]) == -1,
   3295             GL_INVALID_ENUM);
   3296         SET_ERROR_IF(
   3297             !ctx->m_state->boundFramebuffer(GL_DRAW_FRAMEBUFFER) &&
   3298             glUtilsColorAttachmentIndex(bufs[i]) != -1,
   3299             GL_INVALID_OPERATION);
   3300         SET_ERROR_IF(
   3301             ctx->m_state->boundFramebuffer(GL_DRAW_FRAMEBUFFER) &&
   3302             ((glUtilsColorAttachmentIndex(bufs[i]) != -1 &&
   3303               glUtilsColorAttachmentIndex(bufs[i]) != i) ||
   3304              (glUtilsColorAttachmentIndex(bufs[i]) == -1 &&
   3305               bufs[i] != GL_NONE)),
   3306             GL_INVALID_OPERATION);
   3307     }
   3308 
   3309     ctx->m_glDrawBuffers_enc(ctx, n, bufs);
   3310 }
   3311 
   3312 void GL2Encoder::s_glReadBuffer(void* self, GLenum src) {
   3313     GL2Encoder* ctx = (GL2Encoder*)self;
   3314 
   3315     SET_ERROR_IF(
   3316         glUtilsColorAttachmentIndex(src) != -1 &&
   3317          (glUtilsColorAttachmentIndex(src) >=
   3318          ctx->m_state->getMaxColorAttachments()),
   3319         GL_INVALID_OPERATION);
   3320     SET_ERROR_IF(
   3321         src != GL_NONE &&
   3322         src != GL_BACK &&
   3323         src > GL_COLOR_ATTACHMENT0 &&
   3324         src < GL_DEPTH_ATTACHMENT &&
   3325         (src - GL_COLOR_ATTACHMENT0) >
   3326         ctx->m_state->getMaxColorAttachments(),
   3327         GL_INVALID_OPERATION);
   3328     SET_ERROR_IF(
   3329         src != GL_NONE &&
   3330         src != GL_BACK &&
   3331         glUtilsColorAttachmentIndex(src) == -1,
   3332         GL_INVALID_ENUM);
   3333     SET_ERROR_IF(
   3334         !ctx->m_state->boundFramebuffer(GL_READ_FRAMEBUFFER) &&
   3335         src != GL_NONE &&
   3336         src != GL_BACK,
   3337         GL_INVALID_OPERATION);
   3338     SET_ERROR_IF(
   3339         ctx->m_state->boundFramebuffer(GL_READ_FRAMEBUFFER) &&
   3340         src != GL_NONE &&
   3341         glUtilsColorAttachmentIndex(src) == -1,
   3342         GL_INVALID_OPERATION);
   3343 
   3344     ctx->m_glReadBuffer_enc(ctx, src);
   3345 }
   3346 
   3347 void GL2Encoder::s_glFramebufferTextureLayer(void* self, GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer) {
   3348     GL2Encoder* ctx = (GL2Encoder*)self;
   3349     GLClientState* state = ctx->m_state;
   3350 
   3351     SET_ERROR_IF(!GLESv2Validation::framebufferTarget(ctx, target), GL_INVALID_ENUM);
   3352     SET_ERROR_IF(!GLESv2Validation::framebufferAttachment(ctx, attachment), GL_INVALID_ENUM);
   3353     GLenum lastBoundTarget = state->queryTexLastBoundTarget(texture);
   3354     SET_ERROR_IF(lastBoundTarget != GL_TEXTURE_2D_ARRAY &&
   3355                  lastBoundTarget != GL_TEXTURE_3D,
   3356                  GL_INVALID_OPERATION);
   3357     state->attachTextureObject(target, attachment, texture);
   3358 
   3359     GLint max3DTextureSize;
   3360     ctx->glGetIntegerv(ctx, GL_MAX_3D_TEXTURE_SIZE, &max3DTextureSize);
   3361     SET_ERROR_IF(
   3362             layer >= max3DTextureSize,
   3363             GL_INVALID_VALUE);
   3364 
   3365     ctx->m_glFramebufferTextureLayer_enc(self, target, attachment, texture, level, layer);
   3366 }
   3367 
   3368 void GL2Encoder::s_glTexStorage2D(void* self, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height) {
   3369     GL2Encoder* ctx = (GL2Encoder*)self;
   3370     GLClientState* state = ctx->m_state;
   3371 
   3372     SET_ERROR_IF(
   3373         target != GL_TEXTURE_2D &&
   3374         target != GL_TEXTURE_CUBE_MAP,
   3375         GL_INVALID_ENUM);
   3376     SET_ERROR_IF(!GLESv2Validation::pixelInternalFormat(internalformat), GL_INVALID_ENUM);
   3377     SET_ERROR_IF(!state->getBoundTexture(target), GL_INVALID_OPERATION);
   3378     SET_ERROR_IF(levels < 1 || width < 1 || height < 1, GL_INVALID_VALUE);
   3379     SET_ERROR_IF(levels > ilog2((uint32_t)std::max(width, height)) + 1,
   3380                  GL_INVALID_OPERATION);
   3381     SET_ERROR_IF(state->isBoundTextureImmutableFormat(target), GL_INVALID_OPERATION);
   3382 
   3383     state->setBoundTextureInternalFormat(target, internalformat);
   3384     state->setBoundTextureDims(target, -1, width, height, 1);
   3385     state->setBoundTextureImmutableFormat(target);
   3386     ctx->m_glTexStorage2D_enc(ctx, target, levels, internalformat, width, height);
   3387 }
   3388 
   3389 void GL2Encoder::s_glTransformFeedbackVaryings(void* self, GLuint program, GLsizei count, const char** varyings, GLenum bufferMode) {
   3390     GL2Encoder* ctx = (GL2Encoder*)self;
   3391 
   3392     SET_ERROR_IF(!ctx->m_shared->isProgram(program), GL_INVALID_VALUE);
   3393 
   3394     GLint maxCount = 0;
   3395     ctx->glGetIntegerv(ctx, GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS, &maxCount);
   3396 
   3397     SET_ERROR_IF(
   3398         bufferMode == GL_SEPARATE_ATTRIBS &&
   3399         maxCount < count,
   3400         GL_INVALID_VALUE);
   3401     SET_ERROR_IF(
   3402         bufferMode != GL_INTERLEAVED_ATTRIBS &&
   3403         bufferMode != GL_SEPARATE_ATTRIBS,
   3404         GL_INVALID_ENUM);
   3405 
   3406     if (!count) return;
   3407 
   3408     GLint err = GL_NO_ERROR;
   3409     std::string packed = packVarNames(count, varyings, &err);
   3410     SET_ERROR_IF(err != GL_NO_ERROR, GL_INVALID_OPERATION);
   3411 
   3412     ctx->glTransformFeedbackVaryingsAEMU(ctx, program, count, (const char*)&packed[0], packed.size() + 1, bufferMode);
   3413 }
   3414 
   3415 void GL2Encoder::s_glBeginTransformFeedback(void* self, GLenum primitiveMode) {
   3416     GL2Encoder* ctx = (GL2Encoder*)self;
   3417     GLClientState* state = ctx->m_state;
   3418     ctx->m_glBeginTransformFeedback_enc(ctx, primitiveMode);
   3419     state->setTransformFeedbackActiveUnpaused(true);
   3420 }
   3421 
   3422 void GL2Encoder::s_glEndTransformFeedback(void* self) {
   3423     GL2Encoder* ctx = (GL2Encoder*)self;
   3424     GLClientState* state = ctx->m_state;
   3425     ctx->m_glEndTransformFeedback_enc(ctx);
   3426     state->setTransformFeedbackActiveUnpaused(false);
   3427 }
   3428 
   3429 void GL2Encoder::s_glPauseTransformFeedback(void* self) {
   3430     GL2Encoder* ctx = (GL2Encoder*)self;
   3431     GLClientState* state = ctx->m_state;
   3432     ctx->m_glPauseTransformFeedback_enc(ctx);
   3433     state->setTransformFeedbackActiveUnpaused(false);
   3434 }
   3435 
   3436 void GL2Encoder::s_glResumeTransformFeedback(void* self) {
   3437     GL2Encoder* ctx = (GL2Encoder*)self;
   3438     GLClientState* state = ctx->m_state;
   3439     ctx->m_glResumeTransformFeedback_enc(ctx);
   3440     state->setTransformFeedbackActiveUnpaused(true);
   3441 }
   3442 
   3443 void GL2Encoder::s_glTexImage3D(void* self, GLenum target, GLint level, GLint internalFormat,
   3444                                GLsizei width, GLsizei height, GLsizei depth,
   3445                                GLint border, GLenum format, GLenum type, const GLvoid* data) {
   3446     GL2Encoder* ctx = (GL2Encoder*)self;
   3447     GLClientState* state = ctx->m_state;
   3448 
   3449     SET_ERROR_IF(target != GL_TEXTURE_3D &&
   3450                  target != GL_TEXTURE_2D_ARRAY,
   3451                  GL_INVALID_ENUM);
   3452     SET_ERROR_IF(!GLESv2Validation::pixelType(ctx, type), GL_INVALID_ENUM);
   3453     SET_ERROR_IF(!GLESv2Validation::pixelFormat(ctx, format), GL_INVALID_ENUM);
   3454 
   3455     // If unpack buffer is nonzero, verify unmapped state.
   3456     SET_ERROR_IF(ctx->isBufferTargetMapped(GL_PIXEL_UNPACK_BUFFER), GL_INVALID_OPERATION);
   3457 
   3458     GLint max_texture_size;
   3459     GLint max_3d_texture_size;
   3460     ctx->glGetIntegerv(ctx, GL_MAX_TEXTURE_SIZE, &max_texture_size);
   3461     ctx->glGetIntegerv(ctx, GL_MAX_3D_TEXTURE_SIZE, &max_3d_texture_size);
   3462     SET_ERROR_IF(level < 0, GL_INVALID_VALUE);
   3463     SET_ERROR_IF(level > ilog2(max_texture_size), GL_INVALID_VALUE);
   3464     SET_ERROR_IF(level > ilog2(max_3d_texture_size), GL_INVALID_VALUE);
   3465 
   3466     SET_ERROR_IF(width < 0 || height < 0 || depth < 0, GL_INVALID_VALUE);
   3467     SET_ERROR_IF(width > GL_MAX_TEXTURE_SIZE, GL_INVALID_VALUE);
   3468     SET_ERROR_IF(height > GL_MAX_TEXTURE_SIZE, GL_INVALID_VALUE);
   3469     SET_ERROR_IF(depth > GL_MAX_TEXTURE_SIZE, GL_INVALID_VALUE);
   3470     SET_ERROR_IF(width > GL_MAX_3D_TEXTURE_SIZE, GL_INVALID_VALUE);
   3471     SET_ERROR_IF(height > GL_MAX_3D_TEXTURE_SIZE, GL_INVALID_VALUE);
   3472     SET_ERROR_IF(depth > GL_MAX_3D_TEXTURE_SIZE, GL_INVALID_VALUE);
   3473     SET_ERROR_IF(border != 0, GL_INVALID_VALUE);
   3474     // If unpack buffer is nonzero, verify buffer data fits and is evenly divisible by the type.
   3475     SET_ERROR_IF(ctx->boundBuffer(GL_PIXEL_UNPACK_BUFFER) &&
   3476                  ctx->getBufferData(GL_PIXEL_UNPACK_BUFFER) &&
   3477                  (ctx->m_state->pboNeededDataSize(width, height, depth, format, type, 0) >
   3478                   ctx->getBufferData(GL_PIXEL_UNPACK_BUFFER)->m_size),
   3479                  GL_INVALID_OPERATION);
   3480     SET_ERROR_IF(ctx->boundBuffer(GL_PIXEL_UNPACK_BUFFER) &&
   3481                  ctx->getBufferData(GL_PIXEL_UNPACK_BUFFER) &&
   3482                  (ctx->getBufferData(GL_PIXEL_UNPACK_BUFFER)->m_size %
   3483                   glSizeof(type)),
   3484                  GL_INVALID_OPERATION);
   3485     SET_ERROR_IF(state->isBoundTextureImmutableFormat(target), GL_INVALID_OPERATION);
   3486 
   3487     state->setBoundTextureInternalFormat(target, internalFormat);
   3488     state->setBoundTextureFormat(target, format);
   3489     state->setBoundTextureType(target, type);
   3490     state->setBoundTextureDims(target, level, width, height, depth);
   3491 
   3492     if (ctx->boundBuffer(GL_PIXEL_UNPACK_BUFFER)) {
   3493         ctx->glTexImage3DOffsetAEMU(
   3494                 ctx, target, level, internalFormat,
   3495                 width, height, depth,
   3496                 border, format, type, (uintptr_t)data);
   3497     } else {
   3498         ctx->m_glTexImage3D_enc(ctx,
   3499                 target, level, internalFormat,
   3500                 width, height, depth,
   3501                 border, format, type, data);
   3502     }
   3503 }
   3504 
   3505 void GL2Encoder::s_glTexSubImage3D(void* self, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid* data) {
   3506     GL2Encoder* ctx = (GL2Encoder*)self;
   3507     GLClientState* state = ctx->m_state;
   3508 
   3509     SET_ERROR_IF(target != GL_TEXTURE_3D &&
   3510                  target != GL_TEXTURE_2D_ARRAY,
   3511                  GL_INVALID_ENUM);
   3512     SET_ERROR_IF(!GLESv2Validation::pixelType(ctx, type), GL_INVALID_ENUM);
   3513     SET_ERROR_IF(!GLESv2Validation::pixelFormat(ctx, format), GL_INVALID_ENUM);
   3514     // If unpack buffer is nonzero, verify unmapped state.
   3515     SET_ERROR_IF(ctx->isBufferTargetMapped(GL_PIXEL_UNPACK_BUFFER), GL_INVALID_OPERATION);
   3516     GLint max_texture_size;
   3517     GLint max_3d_texture_size;
   3518     ctx->glGetIntegerv(ctx, GL_MAX_TEXTURE_SIZE, &max_texture_size);
   3519     ctx->glGetIntegerv(ctx, GL_MAX_3D_TEXTURE_SIZE, &max_3d_texture_size);
   3520     SET_ERROR_IF(level < 0, GL_INVALID_VALUE);
   3521     SET_ERROR_IF(level > ilog2(max_texture_size), GL_INVALID_VALUE);
   3522     SET_ERROR_IF(level > ilog2(max_3d_texture_size), GL_INVALID_VALUE);
   3523     SET_ERROR_IF(width < 0 || height < 0 || depth < 0, GL_INVALID_VALUE);
   3524     SET_ERROR_IF(xoffset < 0 || yoffset < 0 || zoffset < 0, GL_INVALID_VALUE);
   3525     GLuint tex = state->getBoundTexture(target);
   3526     GLsizei neededWidth = xoffset + width;
   3527     GLsizei neededHeight = yoffset + height;
   3528     GLsizei neededDepth = zoffset + depth;
   3529 
   3530     SET_ERROR_IF(tex &&
   3531                  (neededWidth > state->queryTexWidth(level, tex) ||
   3532                   neededHeight > state->queryTexHeight(level, tex) ||
   3533                   neededDepth > state->queryTexDepth(level, tex)),
   3534                  GL_INVALID_VALUE);
   3535     // If unpack buffer is nonzero, verify buffer data fits and is evenly divisible by the type.
   3536     SET_ERROR_IF(ctx->boundBuffer(GL_PIXEL_UNPACK_BUFFER) &&
   3537                  ctx->getBufferData(GL_PIXEL_UNPACK_BUFFER) &&
   3538                  (ctx->m_state->pboNeededDataSize(width, height, depth, format, type, 0) >
   3539                   ctx->getBufferData(GL_PIXEL_UNPACK_BUFFER)->m_size),
   3540                  GL_INVALID_OPERATION);
   3541     SET_ERROR_IF(ctx->boundBuffer(GL_PIXEL_UNPACK_BUFFER) &&
   3542                  ctx->getBufferData(GL_PIXEL_UNPACK_BUFFER) &&
   3543                  (ctx->getBufferData(GL_PIXEL_UNPACK_BUFFER)->m_size %
   3544                   glSizeof(type)),
   3545                  GL_INVALID_OPERATION);
   3546     SET_ERROR_IF(!ctx->boundBuffer(GL_PIXEL_UNPACK_BUFFER) && !data, GL_INVALID_OPERATION);
   3547     SET_ERROR_IF(xoffset < 0 || yoffset < 0 || zoffset < 0, GL_INVALID_VALUE);
   3548 
   3549     if (ctx->boundBuffer(GL_PIXEL_UNPACK_BUFFER)) {
   3550         ctx->glTexSubImage3DOffsetAEMU(ctx,
   3551                 target, level,
   3552                 xoffset, yoffset, zoffset,
   3553                 width, height, depth,
   3554                 format, type, (uintptr_t)data);
   3555     } else {
   3556         ctx->m_glTexSubImage3D_enc(ctx,
   3557                 target, level,
   3558                 xoffset, yoffset, zoffset,
   3559                 width, height, depth,
   3560                 format, type, data);
   3561     }
   3562 }
   3563 
   3564 void GL2Encoder::s_glCompressedTexImage3D(void* self, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid* data) {
   3565     GL2Encoder* ctx = (GL2Encoder*)self;
   3566     GLClientState* state = ctx->m_state;
   3567 
   3568     // Filter compressed formats support.
   3569     SET_ERROR_IF(!GLESv2Validation::supportedCompressedFormat(ctx, internalformat), GL_INVALID_ENUM);
   3570     // If unpack buffer is nonzero, verify unmapped state.
   3571     SET_ERROR_IF(ctx->isBufferTargetMapped(GL_PIXEL_UNPACK_BUFFER), GL_INVALID_OPERATION);
   3572     SET_ERROR_IF(width < 0 || height < 0 || depth < 0, GL_INVALID_VALUE);
   3573     SET_ERROR_IF(border, GL_INVALID_VALUE);
   3574     // If unpack buffer is nonzero, verify buffer data fits.
   3575     SET_ERROR_IF(ctx->boundBuffer(GL_PIXEL_UNPACK_BUFFER) &&
   3576                  ctx->getBufferData(GL_PIXEL_UNPACK_BUFFER) &&
   3577                  (imageSize > ctx->getBufferData(GL_PIXEL_UNPACK_BUFFER)->m_size),
   3578                  GL_INVALID_OPERATION);
   3579     // TODO: Fix:
   3580     // If |imageSize| is too small for compressed dimensions.
   3581     // SET_ERROR_IF(GLESv2Validation::compressedTexImageSize(internalformat, width, height, depth) > imageSize, GL_INVALID_VALUE);
   3582     state->setBoundTextureInternalFormat(target, (GLint)internalformat);
   3583     state->setBoundTextureDims(target, level, width, height, depth);
   3584 
   3585     if (ctx->boundBuffer(GL_PIXEL_UNPACK_BUFFER)) {
   3586         ctx->glCompressedTexImage3DOffsetAEMU(
   3587                 ctx, target, level, internalformat,
   3588                 width, height, depth, border,
   3589                 imageSize, (uintptr_t)data);
   3590     } else {
   3591         ctx->m_glCompressedTexImage3D_enc(
   3592                 ctx, target, level, internalformat,
   3593                 width, height, depth, border,
   3594                 imageSize, data);
   3595     }
   3596 }
   3597 
   3598 void GL2Encoder::s_glCompressedTexSubImage3D(void* self, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid* data) {
   3599     GL2Encoder* ctx = (GL2Encoder*)self;
   3600     GLClientState* state = ctx->m_state;
   3601 
   3602     SET_ERROR_IF(!GLESv2Validation::textureTarget(ctx, target), GL_INVALID_ENUM);
   3603     // If unpack buffer is nonzero, verify unmapped state.
   3604     SET_ERROR_IF(ctx->isBufferTargetMapped(GL_PIXEL_UNPACK_BUFFER), GL_INVALID_OPERATION);
   3605     SET_ERROR_IF(width < 0 || height < 0 || depth < 0, GL_INVALID_VALUE);
   3606     // If unpack buffer is nonzero, verify buffer data fits.
   3607     SET_ERROR_IF(ctx->boundBuffer(GL_PIXEL_UNPACK_BUFFER) &&
   3608                  ctx->getBufferData(GL_PIXEL_UNPACK_BUFFER) &&
   3609                  (imageSize > ctx->getBufferData(GL_PIXEL_UNPACK_BUFFER)->m_size),
   3610                  GL_INVALID_OPERATION);
   3611     SET_ERROR_IF(xoffset < 0 || yoffset < 0 || zoffset < 0, GL_INVALID_VALUE);
   3612 
   3613     if (ctx->boundBuffer(GL_PIXEL_UNPACK_BUFFER)) {
   3614         ctx->glCompressedTexSubImage3DOffsetAEMU(
   3615                 ctx, target, level,
   3616                 xoffset, yoffset, zoffset,
   3617                 width, height, depth,
   3618                 format, imageSize, (uintptr_t)data);
   3619     } else {
   3620         ctx->m_glCompressedTexSubImage3D_enc(
   3621                 ctx, target, level,
   3622                 xoffset, yoffset, zoffset,
   3623                 width, height, depth,
   3624                 format, imageSize, data);
   3625 
   3626     }
   3627 }
   3628 
   3629 void GL2Encoder::s_glTexStorage3D(void* self, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth) {
   3630     GL2Encoder* ctx = (GL2Encoder*)self;
   3631     GLClientState* state = ctx->m_state;
   3632     SET_ERROR_IF(target != GL_TEXTURE_3D &&
   3633                  target != GL_TEXTURE_2D_ARRAY,
   3634                  GL_INVALID_ENUM);
   3635     SET_ERROR_IF(!GLESv2Validation::pixelInternalFormat(internalformat), GL_INVALID_ENUM);
   3636     SET_ERROR_IF(!state->getBoundTexture(target), GL_INVALID_OPERATION);
   3637     SET_ERROR_IF(levels < 1 || width < 1 || height < 1, GL_INVALID_VALUE);
   3638     SET_ERROR_IF(target == GL_TEXTURE_3D && (levels > ilog2((uint32_t)std::max(width, std::max(height, depth))) + 1),
   3639                  GL_INVALID_OPERATION);
   3640     SET_ERROR_IF(target == GL_TEXTURE_2D_ARRAY && (levels > ilog2((uint32_t)std::max(width, height)) + 1),
   3641                  GL_INVALID_OPERATION);
   3642     SET_ERROR_IF(state->isBoundTextureImmutableFormat(target), GL_INVALID_OPERATION);
   3643 
   3644     state->setBoundTextureInternalFormat(target, internalformat);
   3645     state->setBoundTextureDims(target, -1, width, height, depth);
   3646     state->setBoundTextureImmutableFormat(target);
   3647     ctx->m_glTexStorage3D_enc(ctx, target, levels, internalformat, width, height, depth);
   3648     state->setBoundTextureImmutableFormat(target);
   3649 }
   3650 
   3651 void GL2Encoder::s_glDrawArraysInstanced(void* self, GLenum mode, GLint first, GLsizei count, GLsizei primcount) {
   3652     GL2Encoder *ctx = (GL2Encoder *)self;
   3653     assert(ctx->m_state != NULL);
   3654     SET_ERROR_IF(!isValidDrawMode(mode), GL_INVALID_ENUM);
   3655     SET_ERROR_IF(count < 0, GL_INVALID_VALUE);
   3656 
   3657     bool has_client_vertex_arrays = false;
   3658     bool has_indirect_arrays = false;
   3659     ctx->getVBOUsage(&has_client_vertex_arrays,
   3660                      &has_indirect_arrays);
   3661 
   3662     if (has_client_vertex_arrays ||
   3663         (!has_client_vertex_arrays &&
   3664          !has_indirect_arrays)) {
   3665         ctx->sendVertexAttributes(first, count, true, primcount);
   3666         ctx->m_glDrawArraysInstanced_enc(ctx, mode, 0, count, primcount);
   3667     } else {
   3668         ctx->sendVertexAttributes(0, count, false, primcount);
   3669         ctx->m_glDrawArraysInstanced_enc(ctx, mode, first, count, primcount);
   3670     }
   3671     ctx->m_stream->flush();
   3672 }
   3673 
   3674 void GL2Encoder::s_glDrawElementsInstanced(void* self, GLenum mode, GLsizei count, GLenum type, const void* indices, GLsizei primcount)
   3675 {
   3676 
   3677     GL2Encoder *ctx = (GL2Encoder *)self;
   3678     assert(ctx->m_state != NULL);
   3679     SET_ERROR_IF(!isValidDrawMode(mode), GL_INVALID_ENUM);
   3680     SET_ERROR_IF(count < 0, GL_INVALID_VALUE);
   3681     SET_ERROR_IF(!(type == GL_UNSIGNED_BYTE || type == GL_UNSIGNED_SHORT || type == GL_UNSIGNED_INT), GL_INVALID_ENUM);
   3682     SET_ERROR_IF(ctx->m_state->getTransformFeedbackActiveUnpaused(), GL_INVALID_OPERATION);
   3683 
   3684     bool has_client_vertex_arrays = false;
   3685     bool has_indirect_arrays = false;
   3686     int nLocations = ctx->m_state->nLocations();
   3687     GLintptr offset = 0;
   3688 
   3689     ctx->getVBOUsage(&has_client_vertex_arrays, &has_indirect_arrays);
   3690 
   3691     if (!has_client_vertex_arrays && !has_indirect_arrays) {
   3692         // ALOGW("glDrawElements: no vertex arrays / buffers bound to the command\n");
   3693         GLenum status = ctx->m_glCheckFramebufferStatus_enc(self, GL_FRAMEBUFFER);
   3694         SET_ERROR_IF(status != GL_FRAMEBUFFER_COMPLETE, GL_INVALID_FRAMEBUFFER_OPERATION);
   3695     }
   3696 
   3697     BufferData* buf = NULL;
   3698     int minIndex = 0, maxIndex = 0;
   3699 
   3700     // For validation/immediate index array purposes,
   3701     // we need the min/max vertex index of the index array.
   3702     // If the VBO != 0, this may not be the first time we have
   3703     // used this particular index buffer. getBufferIndexRange
   3704     // can more quickly get min/max vertex index by
   3705     // caching previous results.
   3706     if (ctx->m_state->currentIndexVbo() != 0) {
   3707         buf = ctx->m_shared->getBufferData(ctx->m_state->currentIndexVbo());
   3708         offset = (GLintptr)indices;
   3709         indices = (void*)((GLintptr)buf->m_fixedBuffer.ptr() + (GLintptr)indices);
   3710         ctx->getBufferIndexRange(buf,
   3711                                  indices,
   3712                                  type,
   3713                                  (size_t)count,
   3714                                  (size_t)offset,
   3715                                  &minIndex, &maxIndex);
   3716     } else {
   3717         // In this case, the |indices| field holds a real
   3718         // array, so calculate the indices now. They will
   3719         // also be needed to know how much data to
   3720         // transfer to host.
   3721         ctx->calcIndexRange(indices,
   3722                             type,
   3723                             count,
   3724                             &minIndex,
   3725                             &maxIndex);
   3726     }
   3727 
   3728     bool adjustIndices = true;
   3729     if (ctx->m_state->currentIndexVbo() != 0) {
   3730         if (!has_client_vertex_arrays) {
   3731             ctx->sendVertexAttributes(0, maxIndex + 1, false, primcount);
   3732             ctx->m_glBindBuffer_enc(self, GL_ELEMENT_ARRAY_BUFFER, ctx->m_state->currentIndexVbo());
   3733             ctx->glDrawElementsInstancedOffsetAEMU(ctx, mode, count, type, offset, primcount);
   3734             ctx->flushDrawCall();
   3735             adjustIndices = false;
   3736         } else {
   3737             BufferData * buf = ctx->m_shared->getBufferData(ctx->m_state->currentIndexVbo());
   3738             ctx->m_glBindBuffer_enc(self, GL_ELEMENT_ARRAY_BUFFER, 0);
   3739         }
   3740     }
   3741     if (adjustIndices) {
   3742         void *adjustedIndices =
   3743             ctx->recenterIndices(indices,
   3744                                  type,
   3745                                  count,
   3746                                  minIndex);
   3747 
   3748         if (has_indirect_arrays || 1) {
   3749             ctx->sendVertexAttributes(minIndex, maxIndex - minIndex + 1, true, primcount);
   3750             ctx->glDrawElementsInstancedDataAEMU(ctx, mode, count, type, adjustedIndices, primcount, count * glSizeof(type));
   3751             ctx->m_stream->flush();
   3752             // XXX - OPTIMIZATION (see the other else branch) should be implemented
   3753             if(!has_indirect_arrays) {
   3754                 //ALOGD("unoptimized drawelements !!!\n");
   3755             }
   3756         } else {
   3757             // we are all direct arrays and immidate mode index array -
   3758             // rebuild the arrays and the index array;
   3759             ALOGE("glDrawElements: direct index & direct buffer data - will be implemented in later versions;\n");
   3760         }
   3761     }
   3762 }
   3763 
   3764 void GL2Encoder::s_glDrawRangeElements(void* self, GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void* indices)
   3765 {
   3766 
   3767     GL2Encoder *ctx = (GL2Encoder *)self;
   3768     assert(ctx->m_state != NULL);
   3769     SET_ERROR_IF(!isValidDrawMode(mode), GL_INVALID_ENUM);
   3770     SET_ERROR_IF(end < start, GL_INVALID_VALUE);
   3771     SET_ERROR_IF(count < 0, GL_INVALID_VALUE);
   3772     SET_ERROR_IF(!(type == GL_UNSIGNED_BYTE || type == GL_UNSIGNED_SHORT || type == GL_UNSIGNED_INT), GL_INVALID_ENUM);
   3773     SET_ERROR_IF(ctx->m_state->getTransformFeedbackActiveUnpaused(), GL_INVALID_OPERATION);
   3774 
   3775     bool has_client_vertex_arrays = false;
   3776     bool has_indirect_arrays = false;
   3777     int nLocations = ctx->m_state->nLocations();
   3778     GLintptr offset = 0;
   3779 
   3780     ctx->getVBOUsage(&has_client_vertex_arrays, &has_indirect_arrays);
   3781 
   3782     if (!has_client_vertex_arrays && !has_indirect_arrays) {
   3783         // ALOGW("glDrawElements: no vertex arrays / buffers bound to the command\n");
   3784         GLenum status = ctx->m_glCheckFramebufferStatus_enc(self, GL_FRAMEBUFFER);
   3785         SET_ERROR_IF(status != GL_FRAMEBUFFER_COMPLETE, GL_INVALID_FRAMEBUFFER_OPERATION);
   3786     }
   3787 
   3788     BufferData* buf = NULL;
   3789     int minIndex = 0, maxIndex = 0;
   3790 
   3791     // For validation/immediate index array purposes,
   3792     // we need the min/max vertex index of the index array.
   3793     // If the VBO != 0, this may not be the first time we have
   3794     // used this particular index buffer. getBufferIndexRange
   3795     // can more quickly get min/max vertex index by
   3796     // caching previous results.
   3797     if (ctx->m_state->currentIndexVbo() != 0) {
   3798         buf = ctx->m_shared->getBufferData(ctx->m_state->currentIndexVbo());
   3799         offset = (GLintptr)indices;
   3800         indices = (void*)((GLintptr)buf->m_fixedBuffer.ptr() + (GLintptr)indices);
   3801         ctx->getBufferIndexRange(buf,
   3802                                  indices,
   3803                                  type,
   3804                                  (size_t)count,
   3805                                  (size_t)offset,
   3806                                  &minIndex, &maxIndex);
   3807     } else {
   3808         // In this case, the |indices| field holds a real
   3809         // array, so calculate the indices now. They will
   3810         // also be needed to know how much data to
   3811         // transfer to host.
   3812         ctx->calcIndexRange(indices,
   3813                             type,
   3814                             count,
   3815                             &minIndex,
   3816                             &maxIndex);
   3817     }
   3818 
   3819     bool adjustIndices = true;
   3820     if (ctx->m_state->currentIndexVbo() != 0) {
   3821         if (!has_client_vertex_arrays) {
   3822             ctx->sendVertexAttributes(0, maxIndex + 1, false);
   3823             ctx->m_glBindBuffer_enc(self, GL_ELEMENT_ARRAY_BUFFER, ctx->m_state->currentIndexVbo());
   3824             ctx->glDrawElementsOffset(ctx, mode, count, type, offset);
   3825             ctx->flushDrawCall();
   3826             adjustIndices = false;
   3827         } else {
   3828             BufferData * buf = ctx->m_shared->getBufferData(ctx->m_state->currentIndexVbo());
   3829             ctx->m_glBindBuffer_enc(self, GL_ELEMENT_ARRAY_BUFFER, 0);
   3830         }
   3831     }
   3832     if (adjustIndices) {
   3833         void *adjustedIndices =
   3834             ctx->recenterIndices(indices,
   3835                                  type,
   3836                                  count,
   3837                                  minIndex);
   3838 
   3839         if (has_indirect_arrays || 1) {
   3840             ctx->sendVertexAttributes(minIndex, maxIndex - minIndex + 1, true);
   3841             ctx->glDrawElementsData(ctx, mode, count, type, adjustedIndices, count * glSizeof(type));
   3842             ctx->m_stream->flush();
   3843             // XXX - OPTIMIZATION (see the other else branch) should be implemented
   3844             if(!has_indirect_arrays) {
   3845                 //ALOGD("unoptimized drawelements !!!\n");
   3846             }
   3847         } else {
   3848             // we are all direct arrays and immidate mode index array -
   3849             // rebuild the arrays and the index array;
   3850             ALOGE("glDrawElements: direct index & direct buffer data - will be implemented in later versions;\n");
   3851         }
   3852     }
   3853 }
   3854 
   3855 // struct GLStringKey {
   3856 //     GLenum name;
   3857 //     GLuint index;
   3858 // };
   3859 //
   3860 // struct GLStringKeyCompare {
   3861 //     bool operator() (const GLStringKey& a,
   3862 //                      const GLStringKey& b) const {
   3863 //         if (a.name != b.name) return a.name < b.name;
   3864 //         if (a.index != b.index) return a.index < b.index;
   3865 //         return false;
   3866 //     }
   3867 // };
   3868 //
   3869 // typedef std::map<GLStringKey, std::string, GLStringKeyCompare> GLStringStore;
   3870 //
   3871 // static GLStringStore sGLStringStore;
   3872 // bool sGLStringStoreInitialized = false;
   3873 
   3874 const GLubyte* GL2Encoder::s_glGetStringi(void* self, GLenum name, GLuint index) {
   3875     GL2Encoder *ctx = (GL2Encoder *)self;
   3876     GLubyte *retval =  (GLubyte *) "";
   3877 
   3878     RET_AND_SET_ERROR_IF(
   3879         name != GL_VENDOR &&
   3880         name != GL_RENDERER &&
   3881         name != GL_VERSION &&
   3882         name != GL_EXTENSIONS,
   3883         GL_INVALID_ENUM,
   3884         retval);
   3885 
   3886     RET_AND_SET_ERROR_IF(
   3887         name == GL_VENDOR ||
   3888         name == GL_RENDERER ||
   3889         name == GL_VERSION ||
   3890         name == GL_EXTENSIONS &&
   3891         index != 0,
   3892         GL_INVALID_VALUE,
   3893         retval);
   3894 
   3895     switch (name) {
   3896     case GL_VENDOR:
   3897         retval = gVendorString;
   3898         break;
   3899     case GL_RENDERER:
   3900         retval = gRendererString;
   3901         break;
   3902     case GL_VERSION:
   3903         retval = gVersionString;
   3904         break;
   3905     case GL_EXTENSIONS:
   3906         retval = gExtensionsString;
   3907         break;
   3908     }
   3909 
   3910     return retval;
   3911 }
   3912 
   3913 void GL2Encoder::s_glGetProgramBinary(void* self, GLuint program, GLsizei bufSize, GLsizei* length, GLenum* binaryFormat, void* binary) {
   3914     GL2Encoder *ctx = (GL2Encoder *)self;
   3915 
   3916     SET_ERROR_IF(!ctx->m_shared->isProgram(program), GL_INVALID_OPERATION);
   3917 
   3918     GLint linkStatus = 0;
   3919     ctx->glGetProgramiv(self, program, GL_LINK_STATUS, &linkStatus);
   3920     GLint properLength = 0;
   3921     ctx->glGetProgramiv(self, program, GL_PROGRAM_BINARY_LENGTH, &properLength);
   3922 
   3923     SET_ERROR_IF(!linkStatus, GL_INVALID_OPERATION);
   3924     SET_ERROR_IF(bufSize < properLength, GL_INVALID_OPERATION);
   3925 
   3926     ctx->m_glGetProgramBinary_enc(ctx, program, bufSize, length, binaryFormat, binary);
   3927 }
   3928 
   3929 void GL2Encoder::s_glReadPixels(void* self, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels) {
   3930     GL2Encoder *ctx = (GL2Encoder *)self;
   3931 
   3932     SET_ERROR_IF(!GLESv2Validation::readPixelsFormat(format), GL_INVALID_ENUM);
   3933     SET_ERROR_IF(!GLESv2Validation::readPixelsType(type), GL_INVALID_ENUM);
   3934     SET_ERROR_IF(width < 0 || height < 0, GL_INVALID_VALUE);
   3935     SET_ERROR_IF(ctx->isBufferTargetMapped(GL_PIXEL_PACK_BUFFER), GL_INVALID_OPERATION);
   3936     SET_ERROR_IF(ctx->boundBuffer(GL_PIXEL_PACK_BUFFER) &&
   3937                  ctx->getBufferData(GL_PIXEL_PACK_BUFFER) &&
   3938                  (ctx->m_state->pboNeededDataSize(width, height, 1, format, type, 1) >
   3939                   ctx->getBufferData(GL_PIXEL_PACK_BUFFER)->m_size),
   3940                  GL_INVALID_OPERATION);
   3941     /*
   3942 GL_INVALID_OPERATION is generated if the readbuffer of the currently bound framebuffer is a fixed point normalized surface and format and type are neither GL_RGBA and GL_UNSIGNED_BYTE, respectively, nor the format/type pair returned by querying GL_IMPLEMENTATION_COLOR_READ_FORMAT and GL_IMPLEMENTATION_COLOR_READ_TYPE.
   3943 
   3944 GL_INVALID_OPERATION is generated if the readbuffer of the currently bound framebuffer is a floating point surface and format and type are neither GL_RGBA and GL_FLOAT, respectively, nor the format/type pair returned by querying GL_IMPLEMENTATION_COLOR_READ_FORMAT and GL_IMPLEMENTATION_COLOR_READ_TYPE.
   3945 
   3946 GL_INVALID_OPERATION is generated if the readbuffer of the currently bound framebuffer is a signed integer surface and format and type are neither GL_RGBA_INTEGER and GL_INT, respectively, nor the format/type pair returned by querying GL_IMPLEMENTATION_COLOR_READ_FORMAT and GL_IMPLEMENTATION_COLOR_READ_TYPE.
   3947 
   3948 GL_INVALID_OPERATION is generated if the readbuffer of the currently bound framebuffer is an unsigned integer surface and format and type are neither GL_RGBA_INTEGER and GL_UNSIGNED_INT, respectively, nor the format/type pair returned by querying GL_IMPLEMENTATION_COLOR_READ_FORMAT and GL_IMPLEMENTATION_COLOR_READ_TYPE.
   3949 */
   3950 
   3951     FboFormatInfo fbo_format_info;
   3952     ctx->m_state->getBoundFramebufferFormat(
   3953             GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, &fbo_format_info);
   3954     SET_ERROR_IF(
   3955         fbo_format_info.type == FBO_ATTACHMENT_TEXTURE &&
   3956         !GLESv2Validation::readPixelsFboFormatMatch(
   3957             format, type, fbo_format_info.tex_type),
   3958         GL_INVALID_OPERATION);
   3959 
   3960     if (ctx->boundBuffer(GL_PIXEL_PACK_BUFFER)) {
   3961         ctx->glReadPixelsOffsetAEMU(
   3962                 ctx, x, y, width, height,
   3963                 format, type, (uintptr_t)pixels);
   3964     } else {
   3965         ctx->m_glReadPixels_enc(
   3966                 ctx, x, y, width, height,
   3967                 format, type, pixels);
   3968     }
   3969 }
   3970 
   3971 // Track enabled state for some things like:
   3972 // - Primitive restart
   3973 void GL2Encoder::s_glEnable(void* self, GLenum what) {
   3974     GL2Encoder *ctx = (GL2Encoder *)self;
   3975 
   3976     switch (what) {
   3977     case GL_PRIMITIVE_RESTART_FIXED_INDEX:
   3978         ctx->m_primitiveRestartEnabled = true;
   3979         break;
   3980     }
   3981 
   3982     ctx->m_glEnable_enc(ctx, what);
   3983 }
   3984 
   3985 void GL2Encoder::s_glDisable(void* self, GLenum what) {
   3986     GL2Encoder *ctx = (GL2Encoder *)self;
   3987 
   3988     switch (what) {
   3989     case GL_PRIMITIVE_RESTART_FIXED_INDEX:
   3990         ctx->m_primitiveRestartEnabled = false;
   3991         break;
   3992     }
   3993 
   3994     ctx->m_glDisable_enc(ctx, what);
   3995 }
   3996 
   3997 void GL2Encoder::s_glClearBufferiv(void* self, GLenum buffer, GLint drawBuffer, const GLint * value) {
   3998     GL2Encoder *ctx = (GL2Encoder *)self;
   3999 
   4000     SET_ERROR_IF(buffer == GL_DEPTH || buffer == GL_DEPTH_STENCIL, GL_INVALID_ENUM);
   4001 
   4002     ctx->m_glClearBufferiv_enc(ctx, buffer, drawBuffer, value);
   4003 }
   4004 
   4005 void GL2Encoder::s_glClearBufferuiv(void* self, GLenum buffer, GLint drawBuffer, const GLuint * value) {
   4006     GL2Encoder *ctx = (GL2Encoder *)self;
   4007 
   4008     SET_ERROR_IF(buffer == GL_DEPTH || buffer == GL_STENCIL || buffer == GL_DEPTH_STENCIL, GL_INVALID_ENUM);
   4009 
   4010     ctx->m_glClearBufferuiv_enc(ctx, buffer, drawBuffer, value);
   4011 }
   4012 
   4013 void GL2Encoder::s_glClearBufferfv(void* self, GLenum buffer, GLint drawBuffer, const GLfloat * value) {
   4014     GL2Encoder *ctx = (GL2Encoder *)self;
   4015 
   4016     SET_ERROR_IF(buffer == GL_STENCIL || buffer == GL_DEPTH_STENCIL, GL_INVALID_ENUM);
   4017 
   4018     ctx->m_glClearBufferfv_enc(ctx, buffer, drawBuffer, value);
   4019 }
   4020 
   4021 void GL2Encoder::s_glBlitFramebuffer(void* self, GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter) {
   4022     GL2Encoder *ctx = (GL2Encoder *)self;
   4023     GLClientState* state = ctx->m_state;
   4024 
   4025     bool validateColor = mask | GL_COLOR_BUFFER_BIT;
   4026     bool validateDepth = mask | GL_DEPTH_BUFFER_BIT;
   4027     bool validateStencil = mask | GL_STENCIL_BUFFER_BIT;
   4028 
   4029     FboFormatInfo read_fbo_format_info;
   4030     FboFormatInfo draw_fbo_format_info;
   4031     if (validateColor) {
   4032         state->getBoundFramebufferFormat(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, &read_fbo_format_info);
   4033         state->getBoundFramebufferFormat(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, &draw_fbo_format_info);
   4034 
   4035         if (read_fbo_format_info.type == FBO_ATTACHMENT_TEXTURE &&
   4036             draw_fbo_format_info.type == FBO_ATTACHMENT_TEXTURE) {
   4037             SET_ERROR_IF(
   4038                     state->boundFramebuffer(GL_READ_FRAMEBUFFER) &&
   4039                     state->boundFramebuffer(GL_DRAW_FRAMEBUFFER) &&
   4040                     !GLESv2Validation::blitFramebufferFormat(
   4041                         read_fbo_format_info.tex_type,
   4042                         draw_fbo_format_info.tex_type),
   4043                     GL_INVALID_OPERATION);
   4044         }
   4045     }
   4046 
   4047     if (validateDepth) {
   4048         state->getBoundFramebufferFormat(GL_READ_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, &read_fbo_format_info);
   4049         state->getBoundFramebufferFormat(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, &draw_fbo_format_info);
   4050 
   4051         if (read_fbo_format_info.type == FBO_ATTACHMENT_RENDERBUFFER &&
   4052             draw_fbo_format_info.type == FBO_ATTACHMENT_RENDERBUFFER) {
   4053             SET_ERROR_IF(
   4054                     state->boundFramebuffer(GL_READ_FRAMEBUFFER) &&
   4055                     state->boundFramebuffer(GL_DRAW_FRAMEBUFFER) &&
   4056                     !GLESv2Validation::blitFramebufferFormat(
   4057                         read_fbo_format_info.rb_format,
   4058                         draw_fbo_format_info.rb_format),
   4059                     GL_INVALID_OPERATION);
   4060         }
   4061     }
   4062 
   4063     if (validateStencil) {
   4064         state->getBoundFramebufferFormat(GL_READ_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, &read_fbo_format_info);
   4065         state->getBoundFramebufferFormat(GL_DRAW_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, &draw_fbo_format_info);
   4066 
   4067         if (read_fbo_format_info.type == FBO_ATTACHMENT_RENDERBUFFER &&
   4068             draw_fbo_format_info.type == FBO_ATTACHMENT_RENDERBUFFER) {
   4069             SET_ERROR_IF(
   4070                     state->boundFramebuffer(GL_READ_FRAMEBUFFER) &&
   4071                     state->boundFramebuffer(GL_DRAW_FRAMEBUFFER) &&
   4072                     !GLESv2Validation::blitFramebufferFormat(
   4073                         read_fbo_format_info.rb_format,
   4074                         draw_fbo_format_info.rb_format),
   4075                     GL_INVALID_OPERATION);
   4076         }
   4077     }
   4078 
   4079     state->getBoundFramebufferFormat(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, &draw_fbo_format_info);
   4080     SET_ERROR_IF(
   4081             draw_fbo_format_info.type == FBO_ATTACHMENT_RENDERBUFFER &&
   4082             draw_fbo_format_info.rb_multisamples > 0,
   4083             GL_INVALID_OPERATION);
   4084     SET_ERROR_IF(
   4085             draw_fbo_format_info.type == FBO_ATTACHMENT_TEXTURE &&
   4086             draw_fbo_format_info.tex_multisamples > 0,
   4087             GL_INVALID_OPERATION);
   4088 
   4089     state->getBoundFramebufferFormat(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, &read_fbo_format_info);
   4090     SET_ERROR_IF(
   4091             read_fbo_format_info.type == FBO_ATTACHMENT_RENDERBUFFER &&
   4092             read_fbo_format_info.rb_multisamples > 0 &&
   4093             draw_fbo_format_info.type == FBO_ATTACHMENT_RENDERBUFFER &&
   4094             state->boundFramebuffer(GL_READ_FRAMEBUFFER) &&
   4095             state->boundFramebuffer(GL_DRAW_FRAMEBUFFER) &&
   4096             (read_fbo_format_info.rb_format !=
   4097              draw_fbo_format_info.rb_format),
   4098             GL_INVALID_OPERATION);
   4099     SET_ERROR_IF(
   4100             read_fbo_format_info.type == FBO_ATTACHMENT_RENDERBUFFER &&
   4101             read_fbo_format_info.rb_multisamples > 0 &&
   4102             draw_fbo_format_info.type == FBO_ATTACHMENT_RENDERBUFFER &&
   4103             (srcX0 != dstX0 || srcY0 != dstY0 ||
   4104              srcX1 != dstX1 || srcY1 != dstY1),
   4105             GL_INVALID_OPERATION);
   4106 
   4107 	ctx->m_glBlitFramebuffer_enc(ctx,
   4108             srcX0, srcY0, srcX1, srcY1,
   4109             dstX0, dstY0, dstX1, dstY1,
   4110             mask, filter);
   4111 }
   4112 
   4113 void GL2Encoder::s_glGetInternalformativ(void* self, GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint *params) {
   4114     GL2Encoder *ctx = (GL2Encoder *)self;
   4115 
   4116     SET_ERROR_IF(pname != GL_NUM_SAMPLE_COUNTS &&
   4117                  pname != GL_SAMPLES,
   4118                  GL_INVALID_ENUM);
   4119     SET_ERROR_IF(!GLESv2Validation::internalFormatTarget(ctx, target), GL_INVALID_ENUM);
   4120     SET_ERROR_IF(!GLESv2Validation::unsizedFormat(internalformat) &&
   4121                  !GLESv2Validation::colorRenderableFormat(ctx, internalformat) &&
   4122                  !GLESv2Validation::depthRenderableFormat(ctx, internalformat) &&
   4123                  !GLESv2Validation::stencilRenderableFormat(ctx, internalformat),
   4124                  GL_INVALID_ENUM);
   4125     SET_ERROR_IF(bufSize < 0, GL_INVALID_VALUE);
   4126 
   4127     if (bufSize < 1) return;
   4128 
   4129     // Desktop OpenGL can allow a mindboggling # samples per pixel (such as 64).
   4130     // Limit to 4 (spec minimum) to keep dEQP tests from timing out.
   4131     switch (pname) {
   4132         case GL_NUM_SAMPLE_COUNTS:
   4133             *params = 3;
   4134             break;
   4135         case GL_SAMPLES:
   4136             params[0] = 4;
   4137             if (bufSize > 1) params[1] = 2;
   4138             if (bufSize > 2) params[2] = 1;
   4139             break;
   4140         default:
   4141             break;
   4142     }
   4143 }
   4144 
   4145 void GL2Encoder::s_glGenerateMipmap(void* self, GLenum target) {
   4146     GL2Encoder *ctx = (GL2Encoder *)self;
   4147     GLClientState* state = ctx->m_state;
   4148 
   4149     SET_ERROR_IF(target != GL_TEXTURE_2D &&
   4150                  target != GL_TEXTURE_3D &&
   4151                  target != GL_TEXTURE_CUBE_MAP,
   4152                  GL_INVALID_ENUM);
   4153 
   4154     GLuint tex = state->getBoundTexture(target);
   4155     GLenum internalformat = state->queryTexInternalFormat(tex);
   4156     GLenum format = state->queryTexFormat(tex);
   4157 
   4158     SET_ERROR_IF(tex && GLESv2Validation::isCompressedFormat(internalformat),
   4159                  GL_INVALID_OPERATION);
   4160     SET_ERROR_IF(tex &&
   4161                  !GLESv2Validation::unsizedFormat(internalformat) &&
   4162                  !(GLESv2Validation::colorRenderableFormat(ctx, internalformat) &&
   4163                    GLESv2Validation::filterableTexFormat(ctx, internalformat)),
   4164                  GL_INVALID_OPERATION);
   4165 
   4166     ctx->m_glGenerateMipmap_enc(ctx, target);
   4167 }
   4168 
   4169 void GL2Encoder::s_glBindSampler(void* self, GLuint unit, GLuint sampler) {
   4170     GL2Encoder *ctx = (GL2Encoder *)self;
   4171     GLint maxCombinedUnits;
   4172     ctx->glGetIntegerv(ctx, GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &maxCombinedUnits);
   4173     SET_ERROR_IF(unit >= maxCombinedUnits, GL_INVALID_VALUE);
   4174 
   4175     ctx->m_glBindSampler_enc(ctx, unit, sampler);
   4176 }
   4177 
   4178 GLsync GL2Encoder::s_glFenceSync(void* self, GLenum condition, GLbitfield flags) {
   4179     GL2Encoder *ctx = (GL2Encoder *)self;
   4180     uint64_t syncHandle = ctx->glFenceSyncAEMU(ctx, condition, flags);
   4181     return (GLsync)(uintptr_t)syncHandle;
   4182 }
   4183 
   4184 GLenum GL2Encoder::s_glClientWaitSync(void* self, GLsync wait_on, GLbitfield flags, GLuint64 timeout) {
   4185     GL2Encoder *ctx = (GL2Encoder *)self;
   4186     return ctx->glClientWaitSyncAEMU(ctx, (uint64_t)(uintptr_t)wait_on, flags, timeout);
   4187 }
   4188 
   4189 void GL2Encoder::s_glWaitSync(void* self, GLsync wait_on, GLbitfield flags, GLuint64 timeout) {
   4190     GL2Encoder *ctx = (GL2Encoder *)self;
   4191     ctx->glWaitSyncAEMU(ctx, (uint64_t)(uintptr_t)wait_on, flags, timeout);
   4192 }
   4193 
   4194 void GL2Encoder::s_glDeleteSync(void* self, GLsync sync) {
   4195     GL2Encoder *ctx = (GL2Encoder *)self;
   4196 
   4197     if (!sync) return;
   4198 
   4199     ctx->glDeleteSyncAEMU(ctx, (uint64_t)(uintptr_t)sync);
   4200 }
   4201 
   4202 GLboolean GL2Encoder::s_glIsSync(void* self, GLsync sync) {
   4203     GL2Encoder *ctx = (GL2Encoder *)self;
   4204     return ctx->glIsSyncAEMU(ctx, (uint64_t)(uintptr_t)sync);
   4205 }
   4206 
   4207 void GL2Encoder::s_glGetSynciv(void* self, GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values) {
   4208     GL2Encoder *ctx = (GL2Encoder *)self;
   4209 
   4210     SET_ERROR_IF(bufSize < 0, GL_INVALID_VALUE);
   4211 
   4212     return ctx->glGetSyncivAEMU(ctx, (uint64_t)(uintptr_t)sync, pname, bufSize, length, values);
   4213 }
   4214 
   4215 #define LIMIT_CASE(target, lim) \
   4216     case target: \
   4217         ctx->glGetIntegerv(ctx, lim, &limit); \
   4218         SET_ERROR_IF(index < 0 || index >= limit, GL_INVALID_VALUE); \
   4219         break; \
   4220 
   4221 void GL2Encoder::s_glGetIntegeri_v(void* self, GLenum target, GLuint index, GLint* params) {
   4222     GL2Encoder *ctx = (GL2Encoder *)self;
   4223     GLClientState* state = ctx->m_state;
   4224 
   4225     GLint limit;
   4226 
   4227     switch (target) {
   4228     LIMIT_CASE(GL_TRANSFORM_FEEDBACK_BUFFER_BINDING, GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS)
   4229     LIMIT_CASE(GL_UNIFORM_BUFFER_BINDING, GL_MAX_UNIFORM_BUFFER_BINDINGS)
   4230     LIMIT_CASE(GL_ATOMIC_COUNTER_BUFFER_BINDING, GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS)
   4231     LIMIT_CASE(GL_SHADER_STORAGE_BUFFER_BINDING, GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS)
   4232     default:
   4233         break;
   4234     }
   4235 
   4236     const GLClientState::VertexAttribBindingVector& currBindings =
   4237         state->currentVertexBufferBindings();
   4238 
   4239     switch (target) {
   4240     case GL_VERTEX_BINDING_DIVISOR:
   4241     case GL_VERTEX_BINDING_OFFSET:
   4242     case GL_VERTEX_BINDING_STRIDE:
   4243     case GL_VERTEX_BINDING_BUFFER:
   4244         SET_ERROR_IF(index < 0 || index > currBindings.size(), GL_INVALID_VALUE);
   4245         break;
   4246     default:
   4247         break;
   4248     }
   4249 
   4250     switch (target) {
   4251     case GL_VERTEX_BINDING_DIVISOR:
   4252         *params = currBindings[index].divisor;
   4253         return;
   4254     case GL_VERTEX_BINDING_OFFSET:
   4255         *params = currBindings[index].offset;
   4256         return;
   4257     case GL_VERTEX_BINDING_STRIDE:
   4258         *params = currBindings[index].effectiveStride;
   4259         return;
   4260     case GL_VERTEX_BINDING_BUFFER:
   4261         *params = currBindings[index].buffer;
   4262         return;
   4263     default:
   4264         break;
   4265     }
   4266 
   4267     ctx->safe_glGetIntegeri_v(target, index, params);
   4268 }
   4269 
   4270 void GL2Encoder::s_glGetInteger64i_v(void* self, GLenum target, GLuint index, GLint64* params) {
   4271     GL2Encoder *ctx = (GL2Encoder *)self;
   4272     GLClientState* state = ctx->m_state;
   4273 
   4274     GLint limit;
   4275 
   4276     switch (target) {
   4277     LIMIT_CASE(GL_TRANSFORM_FEEDBACK_BUFFER_BINDING, GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS)
   4278     LIMIT_CASE(GL_UNIFORM_BUFFER_BINDING, GL_MAX_UNIFORM_BUFFER_BINDINGS)
   4279     LIMIT_CASE(GL_ATOMIC_COUNTER_BUFFER_BINDING, GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS)
   4280     LIMIT_CASE(GL_SHADER_STORAGE_BUFFER_BINDING, GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS)
   4281     default:
   4282         break;
   4283     }
   4284 
   4285     const GLClientState::VertexAttribBindingVector& currBindings =
   4286         state->currentVertexBufferBindings();
   4287 
   4288     switch (target) {
   4289     case GL_VERTEX_BINDING_DIVISOR:
   4290     case GL_VERTEX_BINDING_OFFSET:
   4291     case GL_VERTEX_BINDING_STRIDE:
   4292     case GL_VERTEX_BINDING_BUFFER:
   4293         SET_ERROR_IF(index < 0 || index > currBindings.size(), GL_INVALID_VALUE);
   4294         break;
   4295     default:
   4296         break;
   4297     }
   4298 
   4299     switch (target) {
   4300     case GL_VERTEX_BINDING_DIVISOR:
   4301         *params = currBindings[index].divisor;
   4302         return;
   4303     case GL_VERTEX_BINDING_OFFSET:
   4304         *params = currBindings[index].offset;
   4305         return;
   4306     case GL_VERTEX_BINDING_STRIDE:
   4307         *params = currBindings[index].effectiveStride;
   4308         return;
   4309     case GL_VERTEX_BINDING_BUFFER:
   4310         *params = currBindings[index].buffer;
   4311         return;
   4312     default:
   4313         break;
   4314     }
   4315 
   4316     ctx->safe_glGetInteger64i_v(target, index, params);
   4317 }
   4318 
   4319 void GL2Encoder::s_glGetInteger64v(void* self, GLenum param, GLint64* val) {
   4320     GL2Encoder *ctx = (GL2Encoder *)self;
   4321     ctx->safe_glGetInteger64v(param, val);
   4322 }
   4323 
   4324 void GL2Encoder::s_glGetBooleani_v(void* self, GLenum param, GLuint index, GLboolean* val) {
   4325     GL2Encoder *ctx = (GL2Encoder *)self;
   4326     ctx->safe_glGetBooleani_v(param, index, val);
   4327 }
   4328 
   4329 void GL2Encoder::s_glGetShaderiv(void* self, GLuint shader, GLenum pname, GLint* params) {
   4330     GL2Encoder *ctx = (GL2Encoder *)self;
   4331     ctx->m_glGetShaderiv_enc(self, shader, pname, params);
   4332     if (pname == GL_SHADER_SOURCE_LENGTH) {
   4333         ShaderData* shaderData = ctx->m_shared->getShaderData(shader);
   4334         if (shaderData) {
   4335             int totalLen = 0;
   4336             for (int i = 0; i < shaderData->sources.size(); i++) {
   4337                 totalLen += shaderData->sources[i].size();
   4338             }
   4339             if (totalLen != 0) {
   4340                 *params = totalLen + 1; // account for null terminator
   4341             }
   4342         }
   4343     }
   4344 }
   4345 
   4346 void GL2Encoder::s_glActiveShaderProgram(void* self, GLuint pipeline, GLuint program) {
   4347     GL2Encoder *ctx = (GL2Encoder*)self;
   4348     GLClientState* state = ctx->m_state;
   4349     GLSharedGroupPtr shared = ctx->m_shared;
   4350 
   4351     SET_ERROR_IF(!pipeline, GL_INVALID_OPERATION);
   4352     SET_ERROR_IF(program && !shared->isShaderOrProgramObject(program), GL_INVALID_VALUE);
   4353     SET_ERROR_IF(program && !shared->isProgram(program), GL_INVALID_OPERATION);
   4354 
   4355     ctx->m_glActiveShaderProgram_enc(ctx, pipeline, program);
   4356     if (!state->currentProgram()) {
   4357         state->setCurrentShaderProgram(program);
   4358     }
   4359 }
   4360 
   4361 GLuint GL2Encoder::s_glCreateShaderProgramv(void* self, GLenum type, GLsizei count, const char** strings) {
   4362 
   4363     GLint* length = NULL;
   4364     GL2Encoder* ctx = (GL2Encoder*)self;
   4365 
   4366     int len = glUtilsCalcShaderSourceLen((char**)strings, length, count);
   4367     char *str = new char[len + 1];
   4368     glUtilsPackStrings(str, (char**)strings, (GLint*)length, count);
   4369 
   4370     // Do GLSharedGroup and location WorkARound-specific initialization
   4371     // Phase 1: create a ShaderData and initialize with replaceSamplerExternalWith2D()
   4372     uint32_t spDataId = ctx->m_shared->addNewShaderProgramData();
   4373     ShaderProgramData* spData = ctx->m_shared->getShaderProgramDataById(spDataId);
   4374     ShaderData* sData = spData->shaderData;
   4375 
   4376     if (!replaceSamplerExternalWith2D(str, sData)) {
   4377         delete [] str;
   4378         ctx->setError(GL_OUT_OF_MEMORY);
   4379         ctx->m_shared->deleteShaderProgramDataById(spDataId);
   4380         return -1;
   4381     }
   4382 
   4383     GLuint res = ctx->glCreateShaderProgramvAEMU(ctx, type, count, str, len + 1);
   4384     delete [] str;
   4385 
   4386     // Phase 2: do glLinkProgram-related initialization for locationWorkARound
   4387     GLint linkStatus = 0;
   4388     ctx->glGetProgramiv(self, res, GL_LINK_STATUS ,&linkStatus);
   4389     if (!linkStatus) {
   4390         ctx->m_shared->deleteShaderProgramDataById(spDataId);
   4391         return -1;
   4392     }
   4393 
   4394     ctx->m_shared->associateGLShaderProgram(res, spDataId);
   4395 
   4396     GLint numUniforms = 0;
   4397     ctx->glGetProgramiv(self, res, GL_ACTIVE_UNIFORMS, &numUniforms);
   4398     ctx->m_shared->initShaderProgramData(res, numUniforms);
   4399 
   4400     GLint maxLength=0;
   4401     ctx->glGetProgramiv(self, res, GL_ACTIVE_UNIFORM_MAX_LENGTH, &maxLength);
   4402 
   4403     GLint size; GLenum uniformType; GLchar* name = new GLchar[maxLength + 1];
   4404 
   4405     for (GLint i = 0; i < numUniforms; ++i) {
   4406         ctx->glGetActiveUniform(self, res, i, maxLength, NULL, &size, &uniformType, name);
   4407         GLint location = ctx->m_glGetUniformLocation_enc(self, res, name);
   4408         ctx->m_shared->setShaderProgramIndexInfo(res, i, location, size, uniformType, name);
   4409     }
   4410 
   4411     ctx->m_shared->setupShaderProgramLocationShiftWAR(res);
   4412 
   4413     delete [] name;
   4414 
   4415     return res;
   4416 }
   4417 
   4418 void GL2Encoder::s_glProgramUniform1f(void* self, GLuint program, GLint location, GLfloat v0)
   4419 {
   4420     GL2Encoder *ctx = (GL2Encoder*)self;
   4421     GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
   4422     ctx->m_glProgramUniform1f_enc(self, program, hostLoc, v0);
   4423 }
   4424 
   4425 void GL2Encoder::s_glProgramUniform1fv(void* self, GLuint program, GLint location, GLsizei count, const GLfloat *value)
   4426 {
   4427     GL2Encoder *ctx = (GL2Encoder*)self;
   4428     GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
   4429     ctx->m_glProgramUniform1fv_enc(self, program, hostLoc, count, value);
   4430 }
   4431 
   4432 void GL2Encoder::s_glProgramUniform1i(void* self, GLuint program, GLint location, GLint v0)
   4433 {
   4434     GL2Encoder *ctx = (GL2Encoder*)self;
   4435     GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
   4436     ctx->m_glProgramUniform1i_enc(self, program, hostLoc, v0);
   4437 
   4438     GLClientState* state = ctx->m_state;
   4439     GLSharedGroupPtr shared = ctx->m_shared;
   4440     GLenum target;
   4441 
   4442     if (shared->setSamplerUniform(program, location, v0, &target)) {
   4443         GLenum origActiveTexture = state->getActiveTextureUnit();
   4444         if (ctx->updateHostTexture2DBinding(GL_TEXTURE0 + v0, target)) {
   4445             ctx->m_glActiveTexture_enc(self, origActiveTexture);
   4446         }
   4447         state->setActiveTextureUnit(origActiveTexture);
   4448     }
   4449 }
   4450 
   4451 void GL2Encoder::s_glProgramUniform1iv(void* self, GLuint program, GLint location, GLsizei count, const GLint *value)
   4452 {
   4453     GL2Encoder *ctx = (GL2Encoder*)self;
   4454     GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
   4455     ctx->m_glProgramUniform1iv_enc(self, program, hostLoc, count, value);
   4456 }
   4457 
   4458 void GL2Encoder::s_glProgramUniform1ui(void* self, GLuint program, GLint location, GLuint v0)
   4459 {
   4460     GL2Encoder *ctx = (GL2Encoder*)self;
   4461     GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
   4462     ctx->m_glProgramUniform1ui_enc(self, program, hostLoc, v0);
   4463 
   4464     GLClientState* state = ctx->m_state;
   4465     GLSharedGroupPtr shared = ctx->m_shared;
   4466     GLenum target;
   4467 
   4468     if (shared->setSamplerUniform(program, location, v0, &target)) {
   4469         GLenum origActiveTexture = state->getActiveTextureUnit();
   4470         if (ctx->updateHostTexture2DBinding(GL_TEXTURE0 + v0, target)) {
   4471             ctx->m_glActiveTexture_enc(self, origActiveTexture);
   4472         }
   4473         state->setActiveTextureUnit(origActiveTexture);
   4474     }
   4475 }
   4476 
   4477 void GL2Encoder::s_glProgramUniform1uiv(void* self, GLuint program, GLint location, GLsizei count, const GLuint *value)
   4478 {
   4479     GL2Encoder *ctx = (GL2Encoder*)self;
   4480     GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
   4481     ctx->m_glProgramUniform1uiv_enc(self, program, hostLoc, count, value);
   4482 }
   4483 
   4484 void GL2Encoder::s_glProgramUniform2f(void* self, GLuint program, GLint location, GLfloat v0, GLfloat v1)
   4485 {
   4486     GL2Encoder *ctx = (GL2Encoder*)self;
   4487     GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
   4488     ctx->m_glProgramUniform2f_enc(self, program, hostLoc, v0, v1);
   4489 }
   4490 
   4491 void GL2Encoder::s_glProgramUniform2fv(void* self, GLuint program, GLint location, GLsizei count, const GLfloat *value)
   4492 {
   4493     GL2Encoder *ctx = (GL2Encoder*)self;
   4494     GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
   4495     ctx->m_glProgramUniform2fv_enc(self, program, hostLoc, count, value);
   4496 }
   4497 
   4498 void GL2Encoder::s_glProgramUniform2i(void* self, GLuint program, GLint location, GLint v0, GLint v1)
   4499 {
   4500     GL2Encoder *ctx = (GL2Encoder*)self;
   4501     GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
   4502     ctx->m_glProgramUniform2i_enc(self, program, hostLoc, v0, v1);
   4503 }
   4504 
   4505 void GL2Encoder::s_glProgramUniform2iv(void* self, GLuint program, GLint location, GLsizei count, const GLint *value)
   4506 {
   4507     GL2Encoder *ctx = (GL2Encoder*)self;
   4508     GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
   4509     ctx->m_glProgramUniform2iv_enc(self, program, hostLoc, count, value);
   4510 }
   4511 
   4512 void GL2Encoder::s_glProgramUniform2ui(void* self, GLuint program, GLint location, GLint v0, GLuint v1)
   4513 {
   4514     GL2Encoder *ctx = (GL2Encoder*)self;
   4515     GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
   4516     ctx->m_glProgramUniform2ui_enc(self, program, hostLoc, v0, v1);
   4517 }
   4518 
   4519 void GL2Encoder::s_glProgramUniform2uiv(void* self, GLuint program, GLint location, GLsizei count, const GLuint *value)
   4520 {
   4521     GL2Encoder *ctx = (GL2Encoder*)self;
   4522     GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
   4523     ctx->m_glProgramUniform2uiv_enc(self, program, hostLoc, count, value);
   4524 }
   4525 
   4526 void GL2Encoder::s_glProgramUniform3f(void* self, GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2)
   4527 {
   4528     GL2Encoder *ctx = (GL2Encoder*)self;
   4529     GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
   4530     ctx->m_glProgramUniform3f_enc(self, program, hostLoc, v0, v1, v2);
   4531 }
   4532 
   4533 void GL2Encoder::s_glProgramUniform3fv(void* self, GLuint program, GLint location, GLsizei count, const GLfloat *value)
   4534 {
   4535     GL2Encoder *ctx = (GL2Encoder*)self;
   4536     GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
   4537     ctx->m_glProgramUniform3fv_enc(self, program, hostLoc, count, value);
   4538 }
   4539 
   4540 void GL2Encoder::s_glProgramUniform3i(void* self, GLuint program, GLint location, GLint v0, GLint v1, GLint v2)
   4541 {
   4542     GL2Encoder *ctx = (GL2Encoder*)self;
   4543     GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
   4544     ctx->m_glProgramUniform3i_enc(self, program, hostLoc, v0, v1, v2);
   4545 }
   4546 
   4547 void GL2Encoder::s_glProgramUniform3iv(void* self, GLuint program, GLint location, GLsizei count, const GLint *value)
   4548 {
   4549     GL2Encoder *ctx = (GL2Encoder*)self;
   4550     GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
   4551     ctx->m_glProgramUniform3iv_enc(self, program, hostLoc, count, value);
   4552 }
   4553 
   4554 void GL2Encoder::s_glProgramUniform3ui(void* self, GLuint program, GLint location, GLint v0, GLint v1, GLuint v2)
   4555 {
   4556     GL2Encoder *ctx = (GL2Encoder*)self;
   4557     GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
   4558     ctx->m_glProgramUniform3ui_enc(self, program, hostLoc, v0, v1, v2);
   4559 }
   4560 
   4561 void GL2Encoder::s_glProgramUniform3uiv(void* self, GLuint program, GLint location, GLsizei count, const GLuint *value)
   4562 {
   4563     GL2Encoder *ctx = (GL2Encoder*)self;
   4564     GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
   4565     ctx->m_glProgramUniform3uiv_enc(self, program, hostLoc, count, value);
   4566 }
   4567 
   4568 void GL2Encoder::s_glProgramUniform4f(void* self, GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3)
   4569 {
   4570     GL2Encoder *ctx = (GL2Encoder*)self;
   4571     GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
   4572     ctx->m_glProgramUniform4f_enc(self, program, hostLoc, v0, v1, v2, v3);
   4573 }
   4574 
   4575 void GL2Encoder::s_glProgramUniform4fv(void* self, GLuint program, GLint location, GLsizei count, const GLfloat *value)
   4576 {
   4577     GL2Encoder *ctx = (GL2Encoder*)self;
   4578     GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
   4579     ctx->m_glProgramUniform4fv_enc(self, program, hostLoc, count, value);
   4580 }
   4581 
   4582 void GL2Encoder::s_glProgramUniform4i(void* self, GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLint v3)
   4583 {
   4584     GL2Encoder *ctx = (GL2Encoder*)self;
   4585     GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
   4586     ctx->m_glProgramUniform4i_enc(self, program, hostLoc, v0, v1, v2, v3);
   4587 }
   4588 
   4589 void GL2Encoder::s_glProgramUniform4iv(void* self, GLuint program, GLint location, GLsizei count, const GLint *value)
   4590 {
   4591     GL2Encoder *ctx = (GL2Encoder*)self;
   4592     GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
   4593     ctx->m_glProgramUniform4iv_enc(self, program, hostLoc, count, value);
   4594 }
   4595 
   4596 void GL2Encoder::s_glProgramUniform4ui(void* self, GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLuint v3)
   4597 {
   4598     GL2Encoder *ctx = (GL2Encoder*)self;
   4599     GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
   4600     ctx->m_glProgramUniform4ui_enc(self, program, hostLoc, v0, v1, v2, v3);
   4601 }
   4602 
   4603 void GL2Encoder::s_glProgramUniform4uiv(void* self, GLuint program, GLint location, GLsizei count, const GLuint *value)
   4604 {
   4605     GL2Encoder *ctx = (GL2Encoder*)self;
   4606     GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
   4607     ctx->m_glProgramUniform4uiv_enc(self, program, hostLoc, count, value);
   4608 }
   4609 
   4610 void GL2Encoder::s_glProgramUniformMatrix2fv(void* self, GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
   4611 {
   4612     GL2Encoder *ctx = (GL2Encoder*)self;
   4613     GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
   4614     ctx->m_glProgramUniformMatrix2fv_enc(self, program, hostLoc, count, transpose, value);
   4615 }
   4616 
   4617 void GL2Encoder::s_glProgramUniformMatrix2x3fv(void* self, GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
   4618 {
   4619     GL2Encoder *ctx = (GL2Encoder*)self;
   4620     GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
   4621     ctx->m_glProgramUniformMatrix2x3fv_enc(self, program, hostLoc, count, transpose, value);
   4622 }
   4623 
   4624 void GL2Encoder::s_glProgramUniformMatrix2x4fv(void* self, GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
   4625 {
   4626     GL2Encoder *ctx = (GL2Encoder*)self;
   4627     GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
   4628     ctx->m_glProgramUniformMatrix2x4fv_enc(self, program, hostLoc, count, transpose, value);
   4629 }
   4630 
   4631 void GL2Encoder::s_glProgramUniformMatrix3fv(void* self, GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
   4632 {
   4633     GL2Encoder *ctx = (GL2Encoder*)self;
   4634     GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
   4635     ctx->m_glProgramUniformMatrix3fv_enc(self, program, hostLoc, count, transpose, value);
   4636 }
   4637 
   4638 void GL2Encoder::s_glProgramUniformMatrix3x2fv(void* self, GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
   4639 {
   4640     GL2Encoder *ctx = (GL2Encoder*)self;
   4641     GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
   4642     ctx->m_glProgramUniformMatrix3x2fv_enc(self, program, hostLoc, count, transpose, value);
   4643 }
   4644 
   4645 void GL2Encoder::s_glProgramUniformMatrix3x4fv(void* self, GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
   4646 {
   4647     GL2Encoder *ctx = (GL2Encoder*)self;
   4648     GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
   4649     ctx->m_glProgramUniformMatrix3x4fv_enc(self, program, hostLoc, count, transpose, value);
   4650 }
   4651 
   4652 void GL2Encoder::s_glProgramUniformMatrix4fv(void* self, GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
   4653 {
   4654     GL2Encoder *ctx = (GL2Encoder*)self;
   4655     GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
   4656     ctx->m_glProgramUniformMatrix4fv_enc(self, program, hostLoc, count, transpose, value);
   4657 }
   4658 
   4659 void GL2Encoder::s_glProgramUniformMatrix4x2fv(void* self, GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
   4660 {
   4661     GL2Encoder *ctx = (GL2Encoder*)self;
   4662     GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
   4663     ctx->m_glProgramUniformMatrix4x2fv_enc(self, program, hostLoc, count, transpose, value);
   4664 }
   4665 
   4666 void GL2Encoder::s_glProgramUniformMatrix4x3fv(void* self, GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
   4667 {
   4668     GL2Encoder *ctx = (GL2Encoder*)self;
   4669     GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
   4670     ctx->m_glProgramUniformMatrix4x3fv_enc(self, program, hostLoc, count, transpose, value);
   4671 }
   4672 
   4673 void GL2Encoder::s_glProgramParameteri(void* self, GLuint program, GLenum pname, GLint value) {
   4674     GL2Encoder* ctx = (GL2Encoder*)self;
   4675     ctx->m_glProgramParameteri_enc(self, program, pname, value);
   4676 }
   4677 
   4678 void GL2Encoder::s_glUseProgramStages(void *self, GLuint pipeline, GLbitfield stages, GLuint program)
   4679 {
   4680     GL2Encoder *ctx = (GL2Encoder*)self;
   4681     GLClientState* state = ctx->m_state;
   4682     GLSharedGroupPtr shared = ctx->m_shared;
   4683 
   4684     SET_ERROR_IF(!pipeline, GL_INVALID_OPERATION);
   4685     SET_ERROR_IF(program && !shared->isShaderOrProgramObject(program), GL_INVALID_VALUE);
   4686     SET_ERROR_IF(program && !shared->isProgram(program), GL_INVALID_OPERATION);
   4687 
   4688     ctx->m_glUseProgramStages_enc(self, pipeline, stages, program);
   4689     state->associateProgramWithPipeline(program, pipeline);
   4690 
   4691     // There is an active non-separable shader program in effect; no need to update external/2D bindings.
   4692     if (state->currentProgram()) {
   4693         return;
   4694     }
   4695 
   4696     // Otherwise, update host texture 2D bindings.
   4697     ctx->updateHostTexture2DBindingsFromProgramData(program);
   4698 }
   4699 
   4700 void GL2Encoder::s_glBindProgramPipeline(void* self, GLuint pipeline)
   4701 {
   4702     GL2Encoder *ctx = (GL2Encoder*)self;
   4703     GLClientState* state = ctx->m_state;
   4704 
   4705     ctx->m_glBindProgramPipeline_enc(self, pipeline);
   4706 
   4707     // There is an active non-separable shader program in effect; no need to update external/2D bindings.
   4708     if (!pipeline || state->currentProgram()) {
   4709         return;
   4710     }
   4711 
   4712     GLClientState::ProgramPipelineIterator it = state->programPipelineBegin();
   4713     for (; it != state->programPipelineEnd(); ++it) {
   4714         if (it->second == pipeline) {
   4715             ctx->updateHostTexture2DBindingsFromProgramData(it->first);
   4716         }
   4717     }
   4718 }
   4719 
   4720 void GL2Encoder::s_glGetProgramResourceiv(void* self, GLuint program, GLenum programInterface, GLuint index, GLsizei propCount, const GLenum * props, GLsizei bufSize, GLsizei * length, GLint * params) {
   4721     GL2Encoder *ctx = (GL2Encoder*)self;
   4722     SET_ERROR_IF(bufSize < 0, GL_INVALID_VALUE);
   4723     if (bufSize == 0) {
   4724         if (length) *length = 0;
   4725         return;
   4726     }
   4727 
   4728     // Avoid modifying |name| if |*length| < bufSize.
   4729     GLint* intermediate = new GLint[bufSize];
   4730     GLsizei* myLength = length ? length : new GLsizei;
   4731     bool needFreeLength = length == NULL;
   4732 
   4733     ctx->m_glGetProgramResourceiv_enc(self, program, programInterface, index, propCount, props, bufSize, myLength, intermediate);
   4734     GLsizei writtenInts = *myLength;
   4735     memcpy(params, intermediate, writtenInts * sizeof(GLint));
   4736 
   4737     delete [] intermediate;
   4738     if (needFreeLength)
   4739         delete myLength;
   4740 }
   4741 
   4742 GLuint GL2Encoder::s_glGetProgramResourceIndex(void* self, GLuint program, GLenum programInterface, const char* name) {
   4743     GL2Encoder *ctx = (GL2Encoder*)self;
   4744     return ctx->m_glGetProgramResourceIndex_enc(self, program, programInterface, name);
   4745 }
   4746 
   4747 GLint GL2Encoder::s_glGetProgramResourceLocation(void* self, GLuint program, GLenum programInterface, const char* name) {
   4748     GL2Encoder *ctx = (GL2Encoder*)self;
   4749     return ctx->m_glGetProgramResourceLocation_enc(self, program, programInterface, name);
   4750 }
   4751 
   4752 void GL2Encoder::s_glGetProgramResourceName(void* self, GLuint program, GLenum programInterface, GLuint index, GLsizei bufSize, GLsizei* length, char* name) {
   4753     GL2Encoder *ctx = (GL2Encoder*)self;
   4754     SET_ERROR_IF(bufSize < 0, GL_INVALID_VALUE);
   4755     if (bufSize == 0) {
   4756         if (length) *length = 0;
   4757         return;
   4758     }
   4759 
   4760     // Avoid modifying |name| if |*length| < bufSize.
   4761     char* intermediate = new char[bufSize];
   4762     GLsizei* myLength = length ? length : new GLsizei;
   4763     bool needFreeLength = length == NULL;
   4764 
   4765     ctx->m_glGetProgramResourceName_enc(self, program, programInterface, index, bufSize, myLength, intermediate);
   4766     GLsizei writtenStrLen = *myLength;
   4767     memcpy(name, intermediate, writtenStrLen + 1);
   4768 
   4769     delete [] intermediate;
   4770     if (needFreeLength)
   4771         delete myLength;
   4772 }
   4773 
   4774 void GL2Encoder::s_glGetProgramPipelineInfoLog(void* self, GLuint pipeline, GLsizei bufSize, GLsizei* length, GLchar* infoLog) {
   4775     GL2Encoder *ctx = (GL2Encoder*)self;
   4776     SET_ERROR_IF(bufSize < 0, GL_INVALID_VALUE);
   4777     if (bufSize == 0) {
   4778         if (length) *length = 0;
   4779         return;
   4780     }
   4781 
   4782     // Avoid modifying |infoLog| if |*length| < bufSize.
   4783     GLchar* intermediate = new GLchar[bufSize];
   4784     GLsizei* myLength = length ? length : new GLsizei;
   4785     bool needFreeLength = length == NULL;
   4786 
   4787     ctx->m_glGetProgramPipelineInfoLog_enc(self, pipeline, bufSize, myLength, intermediate);
   4788     GLsizei writtenStrLen = *myLength;
   4789     memcpy(infoLog, intermediate, writtenStrLen + 1);
   4790 
   4791     delete [] intermediate;
   4792     if (needFreeLength)
   4793         delete myLength;
   4794 }
   4795 
   4796 void GL2Encoder::s_glVertexAttribFormat(void* self, GLuint attribindex, GLint size, GLenum type, GLboolean normalized, GLuint relativeoffset) {
   4797     GL2Encoder *ctx = (GL2Encoder*)self;
   4798     GLClientState* state = ctx->m_state;
   4799 
   4800     VALIDATE_VERTEX_ATTRIB_INDEX(attribindex);
   4801     SET_ERROR_IF(!state->currentVertexArrayObject(), GL_INVALID_OPERATION);
   4802 
   4803     state->setVertexAttribFormat(attribindex, size, type, normalized, relativeoffset, false);
   4804     ctx->m_glVertexAttribFormat_enc(ctx, attribindex, size, type, normalized, relativeoffset);
   4805 }
   4806 
   4807 void GL2Encoder::s_glVertexAttribIFormat(void* self, GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset) {
   4808     GL2Encoder *ctx = (GL2Encoder*)self;
   4809     GLClientState* state = ctx->m_state;
   4810 
   4811     VALIDATE_VERTEX_ATTRIB_INDEX(attribindex);
   4812     SET_ERROR_IF(!state->currentVertexArrayObject(), GL_INVALID_OPERATION);
   4813 
   4814     state->setVertexAttribFormat(attribindex, size, type, GL_FALSE, relativeoffset, true);
   4815     ctx->m_glVertexAttribIFormat_enc(ctx, attribindex, size, type, relativeoffset);
   4816 }
   4817 
   4818 void GL2Encoder::s_glVertexBindingDivisor(void* self, GLuint bindingindex, GLuint divisor) {
   4819     GL2Encoder *ctx = (GL2Encoder*)self;
   4820     GLClientState* state = ctx->m_state;
   4821 
   4822     SET_ERROR_IF(!state->currentVertexArrayObject(), GL_INVALID_OPERATION);
   4823 
   4824     state->setVertexBindingDivisor(bindingindex, divisor);
   4825     ctx->m_glVertexBindingDivisor_enc(ctx, bindingindex, divisor);
   4826 }
   4827 
   4828 void GL2Encoder::s_glVertexAttribBinding(void* self, GLuint attribindex, GLuint bindingindex) {
   4829     GL2Encoder *ctx = (GL2Encoder*)self;
   4830     GLClientState* state = ctx->m_state;
   4831     VALIDATE_VERTEX_ATTRIB_INDEX(attribindex);
   4832     SET_ERROR_IF(!state->currentVertexArrayObject(), GL_INVALID_OPERATION);
   4833 
   4834     state->setVertexAttribBinding(attribindex, bindingindex);
   4835     ctx->m_glVertexAttribBinding_enc(ctx, attribindex, bindingindex);
   4836 }
   4837 
   4838 void GL2Encoder::s_glBindVertexBuffer(void* self, GLuint bindingindex, GLuint buffer, GLintptr offset, GLintptr stride) {
   4839     GL2Encoder *ctx = (GL2Encoder*)self;
   4840     GLClientState* state = ctx->m_state;
   4841 
   4842     SET_ERROR_IF(offset < 0, GL_INVALID_VALUE);
   4843 
   4844     GLint maxStride;
   4845     ctx->glGetIntegerv(ctx, GL_MAX_VERTEX_ATTRIB_STRIDE, &maxStride);
   4846     SET_ERROR_IF(stride < 0 || stride > maxStride, GL_INVALID_VALUE);
   4847 
   4848     SET_ERROR_IF(!state->currentVertexArrayObject(), GL_INVALID_OPERATION);
   4849 
   4850     state->bindIndexedBuffer(0, bindingindex, buffer, offset, 0, stride, stride);
   4851     ctx->m_glBindVertexBuffer_enc(ctx, bindingindex, buffer, offset, stride);
   4852 }
   4853 
   4854 void GL2Encoder::s_glDrawArraysIndirect(void* self, GLenum mode, const void* indirect) {
   4855     GL2Encoder *ctx = (GL2Encoder*)self;
   4856     GLClientState* state = ctx->m_state;
   4857 
   4858     bool hasClientArrays = false;
   4859     ctx->getVBOUsage(&hasClientArrays, NULL);
   4860 
   4861     SET_ERROR_IF(hasClientArrays, GL_INVALID_OPERATION);
   4862     SET_ERROR_IF(!state->currentVertexArrayObject(), GL_INVALID_OPERATION);
   4863     SET_ERROR_IF(!ctx->boundBuffer(GL_DRAW_INDIRECT_BUFFER), GL_INVALID_OPERATION);
   4864 
   4865     GLuint indirectStructSize = glUtilsIndirectStructSize(INDIRECT_COMMAND_DRAWARRAYS);
   4866     if (ctx->boundBuffer(GL_DRAW_INDIRECT_BUFFER)) {
   4867         // BufferData* buf = ctx->getBufferData(target);
   4868         // if (buf) {
   4869         //     SET_ERROR_IF((GLuint)(uintptr_t)indirect + indirectStructSize > buf->m_size, GL_INVALID_VALUE);
   4870         // }
   4871         ctx->glDrawArraysIndirectOffsetAEMU(ctx, mode, (uintptr_t)indirect);
   4872     } else {
   4873         // Client command structs are technically allowed in desktop OpenGL, but not in ES.
   4874         // This is purely for debug/dev purposes.
   4875         ctx->glDrawArraysIndirectDataAEMU(ctx, mode, indirect, indirectStructSize);
   4876     }
   4877 }
   4878 
   4879 void GL2Encoder::s_glDrawElementsIndirect(void* self, GLenum mode, GLenum type, const void* indirect) {
   4880     GL2Encoder *ctx = (GL2Encoder*)self;
   4881 
   4882     GLClientState* state = ctx->m_state;
   4883 
   4884     bool hasClientArrays = false;
   4885     ctx->getVBOUsage(&hasClientArrays, NULL);
   4886 
   4887     SET_ERROR_IF(hasClientArrays, GL_INVALID_OPERATION);
   4888     SET_ERROR_IF(!state->currentVertexArrayObject(), GL_INVALID_OPERATION);
   4889     SET_ERROR_IF(!ctx->boundBuffer(GL_DRAW_INDIRECT_BUFFER), GL_INVALID_OPERATION);
   4890 
   4891     SET_ERROR_IF(ctx->m_state->getTransformFeedbackActiveUnpaused(), GL_INVALID_OPERATION);
   4892 
   4893     GLuint indirectStructSize = glUtilsIndirectStructSize(INDIRECT_COMMAND_DRAWELEMENTS);
   4894     if (ctx->boundBuffer(GL_DRAW_INDIRECT_BUFFER)) {
   4895         // BufferData* buf = ctx->getBufferData(target);
   4896         // if (buf) {
   4897         //     SET_ERROR_IF((GLuint)(uintptr_t)indirect + indirectStructSize > buf->m_size, GL_INVALID_VALUE);
   4898         // }
   4899         ctx->glDrawElementsIndirectOffsetAEMU(ctx, mode, type, (uintptr_t)indirect);
   4900     } else {
   4901         // Client command structs are technically allowed in desktop OpenGL, but not in ES.
   4902         // This is purely for debug/dev purposes.
   4903         ctx->glDrawElementsIndirectDataAEMU(ctx, mode, type, indirect, indirectStructSize);
   4904     }
   4905 
   4906 }
   4907 
   4908 void GL2Encoder::s_glTexStorage2DMultisample(void* self, GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations) {
   4909     GL2Encoder *ctx = (GL2Encoder*)self;
   4910     GLClientState* state = ctx->m_state;
   4911 
   4912     SET_ERROR_IF(target != GL_TEXTURE_2D_MULTISAMPLE, GL_INVALID_ENUM);
   4913     SET_ERROR_IF(!GLESv2Validation::pixelInternalFormat(internalformat), GL_INVALID_ENUM);
   4914     SET_ERROR_IF(!state->getBoundTexture(target), GL_INVALID_OPERATION);
   4915     SET_ERROR_IF(width < 1 || height < 1, GL_INVALID_VALUE);
   4916     SET_ERROR_IF(state->isBoundTextureImmutableFormat(target), GL_INVALID_OPERATION);
   4917     GLint max_samples;
   4918     ctx->s_glGetInternalformativ(ctx, target, internalformat, GL_SAMPLES, 1, &max_samples);
   4919     SET_ERROR_IF(samples > max_samples, GL_INVALID_OPERATION);
   4920 
   4921     state->setBoundTextureInternalFormat(target, internalformat);
   4922     state->setBoundTextureDims(target, 0, width, height, 1);
   4923     state->setBoundTextureImmutableFormat(target);
   4924     state->setBoundTextureSamples(target, samples);
   4925 
   4926     ctx->m_glTexStorage2DMultisample_enc(ctx, target, samples, internalformat, width, height, fixedsamplelocations);
   4927 }
   4928 
   4929