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