• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
GL2Encoder(IOStream * stream,ChecksumCalculator * protocol)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 
~GL2Encoder()375 GL2Encoder::~GL2Encoder()
376 {
377     delete m_compressedTextureFormats;
378 }
379 
s_glGetError(void * self)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:
ErrorUpdater(GL2Encoder * ctx)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 
getHostErrorAndUpdate()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 
updateGuestErrorState()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:
ScopedQueryUpdate(GL2Encoder * ctx,uint32_t bytes,T * target)439     ScopedQueryUpdate(GL2Encoder* ctx, uint32_t bytes, T* target) :
440         mCtx(ctx),
441         mBuf(bytes, 0),
442         mTarget(target),
443         mErrorUpdater(ctx) {
444     }
hostStagingBuffer()445     T* hostStagingBuffer() {
446         return (T*)&mBuf[0];
447     }
~ScopedQueryUpdate()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 
safe_glGetBooleanv(GLenum param,GLboolean * val)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 
safe_glGetFloatv(GLenum param,GLfloat * val)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 
safe_glGetIntegerv(GLenum param,GLint * val)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 
safe_glGetInteger64v(GLenum param,GLint64 * val)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 
safe_glGetIntegeri_v(GLenum param,GLuint index,GLint * val)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 
safe_glGetInteger64i_v(GLenum param,GLuint index,GLint64 * val)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 
safe_glGetBooleani_v(GLenum param,GLuint index,GLboolean * val)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 
s_glFlush(void * self)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 
s_glGetString(void * self,GLenum name)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 
s_glPixelStorei(void * self,GLenum param,GLint value)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 }
s_glBindBuffer(void * self,GLenum target,GLuint id)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 
doBindBufferEncodeCached(GLenum target,GLuint id)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 
s_glBufferData(void * self,GLenum target,GLsizeiptr size,const GLvoid * data,GLenum usage)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 
s_glBufferSubData(void * self,GLenum target,GLintptr offset,GLsizeiptr size,const GLvoid * data)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 
s_glGenBuffers(void * self,GLsizei n,GLuint * buffers)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 
s_glDeleteBuffers(void * self,GLsizei n,const GLuint * buffers)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 
isValidVertexAttribIndex(void * self,GLuint indx)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 
s_glVertexAttribPointer(void * self,GLuint indx,GLint size,GLenum type,GLboolean normalized,GLsizei stride,const GLvoid * ptr)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 
s_glGetIntegerv(void * self,GLenum param,GLint * ptr)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 
s_glGetFloatv(void * self,GLenum param,GLfloat * ptr)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 
s_glGetBooleanv(void * self,GLenum param,GLboolean * ptr)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 
s_glEnableVertexAttribArray(void * self,GLuint index)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 
s_glDisableVertexAttribArray(void * self,GLuint index)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 
s_glGetVertexAttribiv(void * self,GLuint index,GLenum pname,GLint * params)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 
s_glGetVertexAttribfv(void * self,GLuint index,GLenum pname,GLfloat * params)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 
s_glGetVertexAttribPointerv(void * self,GLuint index,GLenum pname,GLvoid ** pointer)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 
calcIndexRange(const void * indices,GLenum type,GLsizei count,int * minIndex_out,int * maxIndex_out)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 
recenterIndices(const void * src,GLenum type,GLsizei count,int minIndex)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 
getBufferIndexRange(BufferData * buf,const void * dataWithOffset,GLenum type,size_t count,size_t offset,int * minIndex_out,int * maxIndex_out)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
getVBOUsage(bool * hasClientArrays,bool * hasVBOs) const1183 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 
sendVertexAttributes(GLint first,GLsizei count,bool hasClientArrays,GLsizei primcount)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 
flushDrawCall()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 
isValidDrawMode(GLenum mode)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 
s_glDrawArrays(void * self,GLenum mode,GLint first,GLsizei count)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 
s_glDrawElements(void * self,GLenum mode,GLsizei count,GLenum type,const void * indices)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 
s_glDrawArraysNullAEMU(void * self,GLenum mode,GLint first,GLsizei count)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 
s_glDrawElementsNullAEMU(void * self,GLenum mode,GLsizei count,GLenum type,const void * indices)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 
getCompressedTextureFormats()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 
getSamplerExternalAliases(char * str)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 
replaceExternalSamplerUniformDefinition(char * str,const std::string & samplerExternalType,ShaderData * data)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 
replaceSamplerExternalWith2D(char * const str,ShaderData * const data)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 
s_glShaderBinary(void * self,GLsizei n,const GLuint * shaders,GLenum binaryformat,const void * binary,GLsizei length)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 
s_glShaderSource(void * self,GLuint shader,GLsizei count,const GLchar * const * string,const GLint * length)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 
s_glFinish(void * self)1785 void GL2Encoder::s_glFinish(void *self)
1786 {
1787     GL2Encoder *ctx = (GL2Encoder *)self;
1788     ctx->glFinishRoundTrip(self);
1789 }
1790 
s_glLinkProgram(void * self,GLuint program)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 
s_glDeleteProgram(void * self,GLuint program)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 
s_glGetUniformiv(void * self,GLuint program,GLint location,GLint * params)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 }
s_glGetUniformfv(void * self,GLuint program,GLint location,GLfloat * params)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 
s_glCreateProgram(void * self)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 
s_glCreateShader(void * self,GLenum shaderType)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 
s_glGetAttachedShaders(void * self,GLuint program,GLsizei maxCount,GLsizei * count,GLuint * shaders)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 
s_glGetShaderSource(void * self,GLuint shader,GLsizei bufsize,GLsizei * length,GLchar * source)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 
s_glGetShaderInfoLog(void * self,GLuint shader,GLsizei bufsize,GLsizei * length,GLchar * infolog)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 
s_glGetProgramInfoLog(void * self,GLuint program,GLsizei bufsize,GLsizei * length,GLchar * infolog)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 
s_glDeleteShader(void * self,GLenum shader)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 
s_glAttachShader(void * self,GLuint program,GLuint shader)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 
s_glDetachShader(void * self,GLuint program,GLuint shader)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 
sArrIndexOfUniformExpr(const char * name,int * err)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 
s_glGetUniformLocation(void * self,GLuint program,const GLchar * name)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 
updateHostTexture2DBinding(GLenum texUnit,GLenum newTarget)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 
updateHostTexture2DBindingsFromProgramData(GLuint program)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 
s_glUseProgram(void * self,GLuint program)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 
s_glUniform1f(void * self,GLint location,GLfloat x)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 
s_glUniform1fv(void * self,GLint location,GLsizei count,const GLfloat * v)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 
s_glUniform1i(void * self,GLint location,GLint x)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 
s_glUniform1iv(void * self,GLint location,GLsizei count,const GLint * v)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 
s_glUniform2f(void * self,GLint location,GLfloat x,GLfloat y)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 
s_glUniform2fv(void * self,GLint location,GLsizei count,const GLfloat * v)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 
s_glUniform2i(void * self,GLint location,GLint x,GLint y)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 
s_glUniform2iv(void * self,GLint location,GLsizei count,const GLint * v)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 
s_glUniform3f(void * self,GLint location,GLfloat x,GLfloat y,GLfloat z)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 
s_glUniform3fv(void * self,GLint location,GLsizei count,const GLfloat * v)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 
s_glUniform3i(void * self,GLint location,GLint x,GLint y,GLint z)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 
s_glUniform3iv(void * self,GLint location,GLsizei count,const GLint * v)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 
s_glUniform4f(void * self,GLint location,GLfloat x,GLfloat y,GLfloat z,GLfloat w)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 
s_glUniform4fv(void * self,GLint location,GLsizei count,const GLfloat * v)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 
s_glUniform4i(void * self,GLint location,GLint x,GLint y,GLint z,GLint w)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 
s_glUniform4iv(void * self,GLint location,GLsizei count,const GLint * v)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 
s_glUniformMatrix2fv(void * self,GLint location,GLsizei count,GLboolean transpose,const GLfloat * value)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 
s_glUniformMatrix3fv(void * self,GLint location,GLsizei count,GLboolean transpose,const GLfloat * value)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 
s_glUniformMatrix4fv(void * self,GLint location,GLsizei count,GLboolean transpose,const GLfloat * value)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 
s_glActiveTexture(void * self,GLenum texture)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 
s_glBindTexture(void * self,GLenum target,GLuint texture)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 
s_glDeleteTextures(void * self,GLsizei n,const GLuint * textures)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 
s_glGetTexParameterfv(void * self,GLenum target,GLenum pname,GLfloat * params)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 
s_glGetTexParameteriv(void * self,GLenum target,GLenum pname,GLint * params)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 
isValidTextureExternalParam(GLenum pname,GLenum param)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 
s_glTexParameterf(void * self,GLenum target,GLenum pname,GLfloat param)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 
s_glTexParameterfv(void * self,GLenum target,GLenum pname,const GLfloat * params)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 
s_glTexParameteri(void * self,GLenum target,GLenum pname,GLint param)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 
ilog2(uint32_t x)2364 static int ilog2(uint32_t x) {
2365     int p = 0;
2366     while ((1 << p) < x)
2367         p++;
2368     return p;
2369 }
2370 
s_glTexImage2D(void * self,GLenum target,GLint level,GLint internalformat,GLsizei width,GLsizei height,GLint border,GLenum format,GLenum type,const GLvoid * pixels)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 
s_glTexSubImage2D(void * self,GLenum target,GLint level,GLint xoffset,GLint yoffset,GLsizei width,GLsizei height,GLenum format,GLenum type,const GLvoid * pixels)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 
s_glCopyTexImage2D(void * self,GLenum target,GLint level,GLenum internalformat,GLint x,GLint y,GLsizei width,GLsizei height,GLint border)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 
s_glTexParameteriv(void * self,GLenum target,GLenum pname,const GLint * params)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 
texture2DNeedsOverride(GLenum target) const2567 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 
override2DTextureTarget(GLenum target)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 
restore2DTextureTarget(GLenum target)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 
associateEGLImage(GLenum target,GLeglImageOES eglImage)2596 void GL2Encoder::associateEGLImage(GLenum target, GLeglImageOES eglImage) {
2597     m_state->setBoundEGLImage(target, eglImage);
2598 }
2599 
2600 
boundBuffer(GLenum target) const2601 GLuint GL2Encoder::boundBuffer(GLenum target) const {
2602     return m_state->getBuffer(target);
2603 }
2604 
getBufferData(GLenum target) const2605 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 
getBufferDataById(GLuint bufferId) const2611 BufferData* GL2Encoder::getBufferDataById(GLuint bufferId) const {
2612     if (!bufferId) return NULL;
2613     return m_shared->getBufferData(bufferId);
2614 }
2615 
isBufferMapped(GLuint buffer) const2616 bool GL2Encoder::isBufferMapped(GLuint buffer) const {
2617     return m_shared->getBufferData(buffer)->m_mapped;
2618 }
2619 
isBufferTargetMapped(GLenum target) const2620 bool GL2Encoder::isBufferTargetMapped(GLenum target) const {
2621     BufferData* buf = getBufferData(target);
2622     if (!buf) return false;
2623     return buf->m_mapped;
2624 }
2625 
s_glGenRenderbuffers(void * self,GLsizei n,GLuint * renderbuffers)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 
s_glDeleteRenderbuffers(void * self,GLsizei n,const GLuint * renderbuffers)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 
s_glBindRenderbuffer(void * self,GLenum target,GLuint renderbuffer)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 
s_glRenderbufferStorage(void * self,GLenum target,GLenum internalformat,GLsizei width,GLsizei height)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 
s_glFramebufferRenderbuffer(void * self,GLenum target,GLenum attachment,GLenum renderbuffertarget,GLuint renderbuffer)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 
s_glGenFramebuffers(void * self,GLsizei n,GLuint * framebuffers)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 
s_glDeleteFramebuffers(void * self,GLsizei n,const GLuint * framebuffers)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 
s_glBindFramebuffer(void * self,GLenum target,GLuint framebuffer)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 
s_glFramebufferTexture2D(void * self,GLenum target,GLenum attachment,GLenum textarget,GLuint texture,GLint level)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 
s_glFramebufferTexture3DOES(void * self,GLenum target,GLenum attachment,GLenum textarget,GLuint texture,GLint level,GLint zoffset)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 
s_glGetFramebufferAttachmentParameteriv(void * self,GLenum target,GLenum attachment,GLenum pname,GLint * params)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 
isCompleteFbo(GLenum target,const GLClientState * state,GLenum attachment) const2790 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 
checkFramebufferCompleteness(GLenum target,const GLClientState * state) const2878 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 
s_glCheckFramebufferStatus(void * self,GLenum target)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 
s_glGenVertexArrays(void * self,GLsizei n,GLuint * arrays)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 
s_glDeleteVertexArrays(void * self,GLsizei n,const GLuint * arrays)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 
s_glBindVertexArray(void * self,GLuint array)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 
s_glMapBufferOES(void * self,GLenum target,GLenum access)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 
s_glUnmapBufferOES(void * self,GLenum target)2958 GLboolean GL2Encoder::s_glUnmapBufferOES(void* self, GLenum target) {
2959     GL2Encoder* ctx = (GL2Encoder*)self;
2960 
2961     return ctx->glUnmapBuffer(ctx, target);
2962 }
2963 
s_glMapBufferRangeAEMUImpl(GL2Encoder * ctx,GLenum target,GLintptr offset,GLsizeiptr length,GLbitfield access,BufferData * buf)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 
s_glMapBufferRange(void * self,GLenum target,GLintptr offset,GLsizeiptr length,GLbitfield access)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 
s_glUnmapBuffer(void * self,GLenum target)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 
s_glFlushMappedBufferRange(void * self,GLenum target,GLintptr offset,GLsizeiptr length)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 
s_glCompressedTexImage2D(void * self,GLenum target,GLint level,GLenum internalformat,GLsizei width,GLsizei height,GLint border,GLsizei imageSize,const GLvoid * data)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 
s_glCompressedTexSubImage2D(void * self,GLenum target,GLint level,GLint xoffset,GLint yoffset,GLsizei width,GLsizei height,GLenum format,GLsizei imageSize,const GLvoid * data)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 
s_glBindBufferRange(void * self,GLenum target,GLuint index,GLuint buffer,GLintptr offset,GLsizeiptr size)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 
s_glBindBufferBase(void * self,GLenum target,GLuint index,GLuint buffer)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 
doIndexedBufferBindEncodeCached(IndexedBufferBindOp op,GLenum target,GLuint index,GLuint buffer,GLintptr offset,GLsizeiptr size,GLintptr stride,GLintptr effectiveStride)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 
s_glCopyBufferSubData(void * self,GLenum readtarget,GLenum writetarget,GLintptr readoffset,GLintptr writeoffset,GLsizeiptr size)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 
s_glGetBufferParameteriv(void * self,GLenum target,GLenum pname,GLint * params)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 
s_glGetBufferParameteri64v(void * self,GLenum target,GLenum pname,GLint64 * params)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 
s_glGetBufferPointerv(void * self,GLenum target,GLenum pname,GLvoid ** params)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 
packVarNames(GLsizei count,const char ** names,GLint * err_out)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 
s_glGetUniformIndices(void * self,GLuint program,GLsizei uniformCount,const GLchar ** uniformNames,GLuint * uniformIndices)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 
s_glUniform1ui(void * self,GLint location,GLuint v0)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 
s_glUniform2ui(void * self,GLint location,GLuint v0,GLuint v1)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 
s_glUniform3ui(void * self,GLint location,GLuint v0,GLuint v1,GLuint v2)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 
s_glUniform4ui(void * self,GLint location,GLint v0,GLuint v1,GLuint v2,GLuint v3)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 
s_glUniform1uiv(void * self,GLint location,GLsizei count,const GLuint * value)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 
s_glUniform2uiv(void * self,GLint location,GLsizei count,const GLuint * value)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 
s_glUniform3uiv(void * self,GLint location,GLsizei count,const GLuint * value)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 
s_glUniform4uiv(void * self,GLint location,GLsizei count,const GLuint * value)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 
s_glUniformMatrix2x3fv(void * self,GLint location,GLsizei count,GLboolean transpose,const GLfloat * value)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 
s_glUniformMatrix3x2fv(void * self,GLint location,GLsizei count,GLboolean transpose,const GLfloat * value)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 
s_glUniformMatrix2x4fv(void * self,GLint location,GLsizei count,GLboolean transpose,const GLfloat * value)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 
s_glUniformMatrix4x2fv(void * self,GLint location,GLsizei count,GLboolean transpose,const GLfloat * value)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 
s_glUniformMatrix3x4fv(void * self,GLint location,GLsizei count,GLboolean transpose,const GLfloat * value)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 
s_glUniformMatrix4x3fv(void * self,GLint location,GLsizei count,GLboolean transpose,const GLfloat * value)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 
s_glGetUniformuiv(void * self,GLuint program,GLint location,GLuint * params)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 
s_glGetActiveUniformBlockiv(void * self,GLuint program,GLuint uniformBlockIndex,GLenum pname,GLint * params)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 
s_glGetVertexAttribIiv(void * self,GLuint index,GLenum pname,GLint * params)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 
s_glGetVertexAttribIuiv(void * self,GLuint index,GLenum pname,GLuint * params)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 
s_glVertexAttribIPointer(void * self,GLuint index,GLint size,GLenum type,GLsizei stride,const GLvoid * pointer)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 
s_glVertexAttribDivisor(void * self,GLuint index,GLuint divisor)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 
s_glRenderbufferStorageMultisample(void * self,GLenum target,GLsizei samples,GLenum internalformat,GLsizei width,GLsizei height)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 
s_glDrawBuffers(void * self,GLsizei n,const GLenum * bufs)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 
s_glReadBuffer(void * self,GLenum src)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 
s_glFramebufferTextureLayer(void * self,GLenum target,GLenum attachment,GLuint texture,GLint level,GLint layer)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 
s_glTexStorage2D(void * self,GLenum target,GLsizei levels,GLenum internalformat,GLsizei width,GLsizei height)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 
s_glTransformFeedbackVaryings(void * self,GLuint program,GLsizei count,const char ** varyings,GLenum bufferMode)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 
s_glBeginTransformFeedback(void * self,GLenum primitiveMode)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 
s_glEndTransformFeedback(void * self)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 
s_glPauseTransformFeedback(void * self)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 
s_glResumeTransformFeedback(void * self)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 
s_glTexImage3D(void * self,GLenum target,GLint level,GLint internalFormat,GLsizei width,GLsizei height,GLsizei depth,GLint border,GLenum format,GLenum type,const GLvoid * data)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 
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)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 
s_glCompressedTexImage3D(void * self,GLenum target,GLint level,GLenum internalformat,GLsizei width,GLsizei height,GLsizei depth,GLint border,GLsizei imageSize,const GLvoid * data)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 
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)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 
s_glTexStorage3D(void * self,GLenum target,GLsizei levels,GLenum internalformat,GLsizei width,GLsizei height,GLsizei depth)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 
s_glDrawArraysInstanced(void * self,GLenum mode,GLint first,GLsizei count,GLsizei primcount)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 
s_glDrawElementsInstanced(void * self,GLenum mode,GLsizei count,GLenum type,const void * indices,GLsizei primcount)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 
s_glDrawRangeElements(void * self,GLenum mode,GLuint start,GLuint end,GLsizei count,GLenum type,const void * indices)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 
s_glGetStringi(void * self,GLenum name,GLuint index)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 
s_glGetProgramBinary(void * self,GLuint program,GLsizei bufSize,GLsizei * length,GLenum * binaryFormat,void * binary)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 
s_glReadPixels(void * self,GLint x,GLint y,GLsizei width,GLsizei height,GLenum format,GLenum type,GLvoid * pixels)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
s_glEnable(void * self,GLenum what)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 
s_glDisable(void * self,GLenum what)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 
s_glClearBufferiv(void * self,GLenum buffer,GLint drawBuffer,const GLint * value)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 
s_glClearBufferuiv(void * self,GLenum buffer,GLint drawBuffer,const GLuint * value)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 
s_glClearBufferfv(void * self,GLenum buffer,GLint drawBuffer,const GLfloat * value)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 
s_glBlitFramebuffer(void * self,GLint srcX0,GLint srcY0,GLint srcX1,GLint srcY1,GLint dstX0,GLint dstY0,GLint dstX1,GLint dstY1,GLbitfield mask,GLenum filter)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 
s_glGetInternalformativ(void * self,GLenum target,GLenum internalformat,GLenum pname,GLsizei bufSize,GLint * params)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 
s_glGenerateMipmap(void * self,GLenum target)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 
s_glBindSampler(void * self,GLuint unit,GLuint sampler)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 
doSamplerBindEncodeCached(GLuint unit,GLuint sampler)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 
s_glDeleteSamplers(void * self,GLsizei n,const GLuint * samplers)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 
s_glFenceSync(void * self,GLenum condition,GLbitfield flags)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 
s_glClientWaitSync(void * self,GLsync wait_on,GLbitfield flags,GLuint64 timeout)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 
s_glWaitSync(void * self,GLsync wait_on,GLbitfield flags,GLuint64 timeout)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 
s_glDeleteSync(void * self,GLsync sync)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 
s_glIsSync(void * self,GLsync sync)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 
s_glGetSynciv(void * self,GLsync sync,GLenum pname,GLsizei bufSize,GLsizei * length,GLint * values)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 
s_glGetIntegeri_v(void * self,GLenum target,GLuint index,GLint * params)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 
s_glGetInteger64i_v(void * self,GLenum target,GLuint index,GLint64 * params)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 
s_glGetInteger64v(void * self,GLenum param,GLint64 * val)4821 void GL2Encoder::s_glGetInteger64v(void* self, GLenum param, GLint64* val) {
4822     GL2Encoder *ctx = (GL2Encoder *)self;
4823     ctx->safe_glGetInteger64v(param, val);
4824 }
4825 
s_glGetBooleani_v(void * self,GLenum param,GLuint index,GLboolean * val)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 
s_glGetShaderiv(void * self,GLuint shader,GLenum pname,GLint * params)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 
s_glActiveShaderProgram(void * self,GLuint pipeline,GLuint program)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 
s_glCreateShaderProgramv(void * self,GLenum type,GLsizei count,const char ** strings)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 
s_glProgramUniform1f(void * self,GLuint program,GLint location,GLfloat v0)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 
s_glProgramUniform1fv(void * self,GLuint program,GLint location,GLsizei count,const GLfloat * value)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 
s_glProgramUniform1i(void * self,GLuint program,GLint location,GLint v0)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 
s_glProgramUniform1iv(void * self,GLuint program,GLint location,GLsizei count,const GLint * value)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 
s_glProgramUniform1ui(void * self,GLuint program,GLint location,GLuint v0)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 
s_glProgramUniform1uiv(void * self,GLuint program,GLint location,GLsizei count,const GLuint * value)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 
s_glProgramUniform2f(void * self,GLuint program,GLint location,GLfloat v0,GLfloat v1)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 
s_glProgramUniform2fv(void * self,GLuint program,GLint location,GLsizei count,const GLfloat * value)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 
s_glProgramUniform2i(void * self,GLuint program,GLint location,GLint v0,GLint v1)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 
s_glProgramUniform2iv(void * self,GLuint program,GLint location,GLsizei count,const GLint * value)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 
s_glProgramUniform2ui(void * self,GLuint program,GLint location,GLint v0,GLuint v1)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 
s_glProgramUniform2uiv(void * self,GLuint program,GLint location,GLsizei count,const GLuint * value)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 
s_glProgramUniform3f(void * self,GLuint program,GLint location,GLfloat v0,GLfloat v1,GLfloat v2)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 
s_glProgramUniform3fv(void * self,GLuint program,GLint location,GLsizei count,const GLfloat * value)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 
s_glProgramUniform3i(void * self,GLuint program,GLint location,GLint v0,GLint v1,GLint v2)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 
s_glProgramUniform3iv(void * self,GLuint program,GLint location,GLsizei count,const GLint * value)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 
s_glProgramUniform3ui(void * self,GLuint program,GLint location,GLint v0,GLint v1,GLuint v2)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 
s_glProgramUniform3uiv(void * self,GLuint program,GLint location,GLsizei count,const GLuint * value)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 
s_glProgramUniform4f(void * self,GLuint program,GLint location,GLfloat v0,GLfloat v1,GLfloat v2,GLfloat v3)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 
s_glProgramUniform4fv(void * self,GLuint program,GLint location,GLsizei count,const GLfloat * value)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 
s_glProgramUniform4i(void * self,GLuint program,GLint location,GLint v0,GLint v1,GLint v2,GLint v3)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 
s_glProgramUniform4iv(void * self,GLuint program,GLint location,GLsizei count,const GLint * value)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 
s_glProgramUniform4ui(void * self,GLuint program,GLint location,GLint v0,GLint v1,GLint v2,GLuint v3)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 
s_glProgramUniform4uiv(void * self,GLuint program,GLint location,GLsizei count,const GLuint * value)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 
s_glProgramUniformMatrix2fv(void * self,GLuint program,GLint location,GLsizei count,GLboolean transpose,const GLfloat * value)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 
s_glProgramUniformMatrix2x3fv(void * self,GLuint program,GLint location,GLsizei count,GLboolean transpose,const GLfloat * value)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 
s_glProgramUniformMatrix2x4fv(void * self,GLuint program,GLint location,GLsizei count,GLboolean transpose,const GLfloat * value)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 
s_glProgramUniformMatrix3fv(void * self,GLuint program,GLint location,GLsizei count,GLboolean transpose,const GLfloat * value)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 
s_glProgramUniformMatrix3x2fv(void * self,GLuint program,GLint location,GLsizei count,GLboolean transpose,const GLfloat * value)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 
s_glProgramUniformMatrix3x4fv(void * self,GLuint program,GLint location,GLsizei count,GLboolean transpose,const GLfloat * value)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 
s_glProgramUniformMatrix4fv(void * self,GLuint program,GLint location,GLsizei count,GLboolean transpose,const GLfloat * value)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 
s_glProgramUniformMatrix4x2fv(void * self,GLuint program,GLint location,GLsizei count,GLboolean transpose,const GLfloat * value)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 
s_glProgramUniformMatrix4x3fv(void * self,GLuint program,GLint location,GLsizei count,GLboolean transpose,const GLfloat * value)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 
s_glProgramParameteri(void * self,GLuint program,GLenum pname,GLint value)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 
s_glUseProgramStages(void * self,GLuint pipeline,GLbitfield stages,GLuint program)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 
s_glBindProgramPipeline(void * self,GLuint pipeline)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 
s_glGetProgramResourceiv(void * self,GLuint program,GLenum programInterface,GLuint index,GLsizei propCount,const GLenum * props,GLsizei bufSize,GLsizei * length,GLint * params)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 
s_glGetProgramResourceIndex(void * self,GLuint program,GLenum programInterface,const char * name)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 
s_glGetProgramResourceLocation(void * self,GLuint program,GLenum programInterface,const char * name)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 
s_glGetProgramResourceName(void * self,GLuint program,GLenum programInterface,GLuint index,GLsizei bufSize,GLsizei * length,char * name)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 
s_glGetProgramPipelineInfoLog(void * self,GLuint pipeline,GLsizei bufSize,GLsizei * length,GLchar * infoLog)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 
s_glVertexAttribFormat(void * self,GLuint attribindex,GLint size,GLenum type,GLboolean normalized,GLuint relativeoffset)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 
s_glVertexAttribIFormat(void * self,GLuint attribindex,GLint size,GLenum type,GLuint relativeoffset)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 
s_glVertexBindingDivisor(void * self,GLuint bindingindex,GLuint divisor)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 
s_glVertexAttribBinding(void * self,GLuint attribindex,GLuint bindingindex)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 
s_glBindVertexBuffer(void * self,GLuint bindingindex,GLuint buffer,GLintptr offset,GLintptr stride)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 
s_glDrawArraysIndirect(void * self,GLenum mode,const void * indirect)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 
s_glDrawElementsIndirect(void * self,GLenum mode,GLenum type,const void * indirect)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 
s_glTexStorage2DMultisample(void * self,GLenum target,GLsizei samples,GLenum internalformat,GLsizei width,GLsizei height,GLboolean fixedsamplelocations)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 
s_glGetGraphicsResetStatusEXT(void * self)5430 GLenum GL2Encoder::s_glGetGraphicsResetStatusEXT(void* self) {
5431     (void)self;
5432     return GL_NO_ERROR;
5433 }
5434 
s_glReadnPixelsEXT(void * self,GLint x,GLint y,GLsizei width,GLsizei height,GLenum format,GLenum type,GLsizei bufSize,GLvoid * pixels)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 
s_glGetnUniformfvEXT(void * self,GLuint program,GLint location,GLsizei bufSize,GLfloat * params)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 
s_glGetnUniformivEXT(void * self,GLuint program,GLint location,GLsizei bufSize,GLint * params)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