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 #include "GLESTextureUtils.h"
20 
21 #include <string>
22 #include <map>
23 
24 #include <assert.h>
25 #include <ctype.h>
26 
27 #include <GLES2/gl2.h>
28 #include <GLES2/gl2ext.h>
29 #include <GLES2/gl2platform.h>
30 
31 #include <GLES3/gl3.h>
32 #include <GLES3/gl31.h>
33 
34 #ifndef MIN
35 #define MIN(a, b) ((a) < (b) ? (a) : (b))
36 #endif
37 
38 static GLubyte *gVendorString= (GLubyte *) "Android";
39 static GLubyte *gRendererString= (GLubyte *) "Android HW-GLES 3.0";
40 static GLubyte *gVersionString= (GLubyte *) "OpenGL ES 3.0";
41 static GLubyte *gExtensionsString= (GLubyte *) "GL_OES_EGL_image_external ";
42 
43 #define SET_ERROR_IF(condition, err) if((condition)) { \
44         ALOGE("%s:%s:%d GL error 0x%x condition [%s]\n", __FILE__, __FUNCTION__, __LINE__, err, #condition); \
45         ctx->setError(err); \
46         return; \
47     }
48 
49 #define SET_ERROR_WITH_MESSAGE_IF(condition, err, generator, genargs) if ((condition)) { \
50         std::string msg = generator genargs; \
51         ALOGE("%s:%s:%d GL error 0x%x\n" \
52               "Info: %s\n", __FILE__, __FUNCTION__, __LINE__, err, msg.c_str()); \
53         ctx->setError(err); \
54         return; \
55     } \
56 
57 #define RET_AND_SET_ERROR_IF(condition, err, ret) if((condition)) { \
58         ALOGE("%s:%s:%d GL error 0x%x\n", __FILE__, __FUNCTION__, __LINE__, err); \
59         ctx->setError(err);  \
60         return ret; \
61     } \
62 
63 #define RET_AND_SET_ERROR_WITH_MESSAGE_IF(condition, err, ret, generator, genargs) if((condition)) { \
64         std::string msg = generator genargs; \
65         ALOGE("%s:%s:%d GL error 0x%x\n" \
66               "Info: %s\n", __FILE__, __FUNCTION__, __LINE__, err, msg.c_str()); \
67         ctx->setError(err);   \
68         return ret; \
69     } \
70 
GL2Encoder(IOStream * stream,ChecksumCalculator * protocol)71 GL2Encoder::GL2Encoder(IOStream *stream, ChecksumCalculator *protocol)
72         : gl2_encoder_context_t(stream, protocol)
73 {
74     m_currMajorVersion = 2;
75     m_currMinorVersion = 0;
76     m_hasAsyncUnmapBuffer = false;
77     m_hasSyncBufferData = false;
78     m_initialized = false;
79     m_noHostError = false;
80     m_state = NULL;
81     m_error = GL_NO_ERROR;
82 
83     m_num_compressedTextureFormats = 0;
84     m_max_combinedTextureImageUnits = 0;
85     m_max_vertexTextureImageUnits = 0;
86     m_max_array_texture_layers = 0;
87     m_max_textureImageUnits = 0;
88     m_max_cubeMapTextureSize = 0;
89     m_max_renderBufferSize = 0;
90     m_max_textureSize = 0;
91     m_max_3d_textureSize = 0;
92     m_max_vertexAttribStride = 0;
93 
94     m_max_transformFeedbackSeparateAttribs = 0;
95     m_max_uniformBufferBindings = 0;
96     m_max_colorAttachments = 0;
97     m_max_drawBuffers = 0;
98 
99     m_max_atomicCounterBufferBindings = 0;
100     m_max_shaderStorageBufferBindings = 0;
101     m_max_vertexAttribBindings = 0;
102 
103     m_textureBufferOffsetAlign = 0;
104 
105     m_compressedTextureFormats = NULL;
106 
107     m_ssbo_offset_align = 0;
108     m_ubo_offset_align = 0;
109 
110     m_drawCallFlushInterval = 800;
111     m_drawCallFlushCount = 0;
112     m_primitiveRestartEnabled = false;
113     m_primitiveRestartIndex = 0;
114 
115     // overrides
116 #define OVERRIDE(name)  m_##name##_enc = this-> name ; this-> name = &s_##name
117 #define OVERRIDE_CUSTOM(name)  this-> name = &s_##name
118 #define OVERRIDEWITH(name, target)  do { \
119     m_##target##_enc = this-> target; \
120     this-> target = &s_##name; \
121 } while(0)
122 #define OVERRIDEOES(name) OVERRIDEWITH(name, name##OES)
123 
124     OVERRIDE(glFlush);
125     OVERRIDE(glPixelStorei);
126     OVERRIDE(glGetString);
127     OVERRIDE(glBindBuffer);
128     OVERRIDE(glBufferData);
129     OVERRIDE(glBufferSubData);
130     OVERRIDE(glDeleteBuffers);
131     OVERRIDE(glDrawArrays);
132     OVERRIDE(glDrawElements);
133     OVERRIDE(glDrawArraysNullAEMU);
134     OVERRIDE(glDrawElementsNullAEMU);
135     OVERRIDE(glGetIntegerv);
136     OVERRIDE(glGetFloatv);
137     OVERRIDE(glGetBooleanv);
138     OVERRIDE(glVertexAttribPointer);
139     OVERRIDE(glEnableVertexAttribArray);
140     OVERRIDE(glDisableVertexAttribArray);
141     OVERRIDE(glGetVertexAttribiv);
142     OVERRIDE(glGetVertexAttribfv);
143     OVERRIDE(glGetVertexAttribPointerv);
144 
145     this->glShaderBinary = &s_glShaderBinary;
146     this->glShaderSource = &s_glShaderSource;
147     this->glFinish = &s_glFinish;
148 
149     OVERRIDE(glGetError);
150     OVERRIDE(glLinkProgram);
151     OVERRIDE(glDeleteProgram);
152     OVERRIDE(glGetUniformiv);
153     OVERRIDE(glGetUniformfv);
154     OVERRIDE(glCreateProgram);
155     OVERRIDE(glCreateShader);
156     OVERRIDE(glDeleteShader);
157     OVERRIDE(glAttachShader);
158     OVERRIDE(glDetachShader);
159     OVERRIDE(glGetAttachedShaders);
160     OVERRIDE(glGetShaderSource);
161     OVERRIDE(glGetShaderInfoLog);
162     OVERRIDE(glGetProgramInfoLog);
163 
164     OVERRIDE(glGetUniformLocation);
165     OVERRIDE(glUseProgram);
166 
167     OVERRIDE(glUniform1f);
168     OVERRIDE(glUniform1fv);
169     OVERRIDE(glUniform1i);
170     OVERRIDE(glUniform1iv);
171     OVERRIDE(glUniform2f);
172     OVERRIDE(glUniform2fv);
173     OVERRIDE(glUniform2i);
174     OVERRIDE(glUniform2iv);
175     OVERRIDE(glUniform3f);
176     OVERRIDE(glUniform3fv);
177     OVERRIDE(glUniform3i);
178     OVERRIDE(glUniform3iv);
179     OVERRIDE(glUniform4f);
180     OVERRIDE(glUniform4fv);
181     OVERRIDE(glUniform4i);
182     OVERRIDE(glUniform4iv);
183     OVERRIDE(glUniformMatrix2fv);
184     OVERRIDE(glUniformMatrix3fv);
185     OVERRIDE(glUniformMatrix4fv);
186 
187     OVERRIDE(glActiveTexture);
188     OVERRIDE(glBindTexture);
189     OVERRIDE(glDeleteTextures);
190     OVERRIDE(glGetTexParameterfv);
191     OVERRIDE(glGetTexParameteriv);
192     OVERRIDE(glTexParameterf);
193     OVERRIDE(glTexParameterfv);
194     OVERRIDE(glTexParameteri);
195     OVERRIDE(glTexParameteriv);
196     OVERRIDE(glTexImage2D);
197     OVERRIDE(glTexSubImage2D);
198     OVERRIDE(glCopyTexImage2D);
199     OVERRIDE(glTexBufferOES);
200     OVERRIDE(glTexBufferRangeOES);
201     OVERRIDE(glTexBufferEXT);
202     OVERRIDE(glTexBufferRangeEXT);
203 
204     OVERRIDE(glEnableiEXT);
205     OVERRIDE(glDisableiEXT);
206     OVERRIDE(glBlendEquationiEXT);
207     OVERRIDE(glBlendEquationSeparateiEXT);
208     OVERRIDE(glBlendFunciEXT);
209     OVERRIDE(glBlendFuncSeparateiEXT);
210     OVERRIDE(glColorMaskiEXT);
211     OVERRIDE(glIsEnablediEXT);
212 
213     OVERRIDE(glGenRenderbuffers);
214     OVERRIDE(glDeleteRenderbuffers);
215     OVERRIDE(glBindRenderbuffer);
216     OVERRIDE(glRenderbufferStorage);
217     OVERRIDE(glFramebufferRenderbuffer);
218 
219     OVERRIDE(glGenFramebuffers);
220     OVERRIDE(glDeleteFramebuffers);
221     OVERRIDE(glBindFramebuffer);
222     OVERRIDE(glFramebufferParameteri);
223     OVERRIDE(glFramebufferTexture2D);
224     OVERRIDE(glFramebufferTexture3DOES);
225     OVERRIDE(glGetFramebufferAttachmentParameteriv);
226 
227     OVERRIDE(glCheckFramebufferStatus);
228 
229     OVERRIDE(glGenVertexArrays);
230     OVERRIDE(glDeleteVertexArrays);
231     OVERRIDE(glBindVertexArray);
232     OVERRIDEOES(glGenVertexArrays);
233     OVERRIDEOES(glDeleteVertexArrays);
234     OVERRIDEOES(glBindVertexArray);
235 
236     OVERRIDE_CUSTOM(glMapBufferOES);
237     OVERRIDE_CUSTOM(glUnmapBufferOES);
238     OVERRIDE_CUSTOM(glMapBufferRange);
239     OVERRIDE_CUSTOM(glUnmapBuffer);
240     OVERRIDE_CUSTOM(glFlushMappedBufferRange);
241 
242     OVERRIDE(glCompressedTexImage2D);
243     OVERRIDE(glCompressedTexSubImage2D);
244 
245     OVERRIDE(glBindBufferRange);
246     OVERRIDE(glBindBufferBase);
247 
248     OVERRIDE(glCopyBufferSubData);
249 
250     OVERRIDE(glGetBufferParameteriv);
251     OVERRIDE(glGetBufferParameteri64v);
252     OVERRIDE(glGetBufferPointerv);
253 
254     OVERRIDE_CUSTOM(glGetUniformIndices);
255 
256     OVERRIDE(glUniform1ui);
257     OVERRIDE(glUniform2ui);
258     OVERRIDE(glUniform3ui);
259     OVERRIDE(glUniform4ui);
260     OVERRIDE(glUniform1uiv);
261     OVERRIDE(glUniform2uiv);
262     OVERRIDE(glUniform3uiv);
263     OVERRIDE(glUniform4uiv);
264     OVERRIDE(glUniformMatrix2x3fv);
265     OVERRIDE(glUniformMatrix3x2fv);
266     OVERRIDE(glUniformMatrix2x4fv);
267     OVERRIDE(glUniformMatrix4x2fv);
268     OVERRIDE(glUniformMatrix3x4fv);
269     OVERRIDE(glUniformMatrix4x3fv);
270 
271     OVERRIDE(glGetUniformuiv);
272     OVERRIDE(glGetActiveUniformBlockiv);
273 
274     OVERRIDE(glGetVertexAttribIiv);
275     OVERRIDE(glGetVertexAttribIuiv);
276 
277     OVERRIDE_CUSTOM(glVertexAttribIPointer);
278 
279     OVERRIDE(glVertexAttribDivisor);
280 
281     OVERRIDE(glRenderbufferStorageMultisample);
282     OVERRIDE(glDrawBuffers);
283     OVERRIDE(glReadBuffer);
284     OVERRIDE(glFramebufferTextureLayer);
285     OVERRIDE(glTexStorage2D);
286 
287     OVERRIDE_CUSTOM(glTransformFeedbackVaryings);
288     OVERRIDE(glBeginTransformFeedback);
289     OVERRIDE(glEndTransformFeedback);
290     OVERRIDE(glPauseTransformFeedback);
291     OVERRIDE(glResumeTransformFeedback);
292 
293     OVERRIDE(glTexImage3D);
294     OVERRIDE(glTexSubImage3D);
295     OVERRIDE(glTexStorage3D);
296     OVERRIDE(glCompressedTexImage3D);
297     OVERRIDE(glCompressedTexSubImage3D);
298 
299     OVERRIDE(glDrawArraysInstanced);
300     OVERRIDE_CUSTOM(glDrawElementsInstanced);
301     OVERRIDE_CUSTOM(glDrawRangeElements);
302 
303     OVERRIDE_CUSTOM(glGetStringi);
304     OVERRIDE(glGetProgramBinary);
305     OVERRIDE(glReadPixels);
306 
307     OVERRIDE(glEnable);
308     OVERRIDE(glDisable);
309     OVERRIDE(glClearBufferiv);
310     OVERRIDE(glClearBufferuiv);
311     OVERRIDE(glClearBufferfv);
312     OVERRIDE(glBlitFramebuffer);
313     OVERRIDE_CUSTOM(glGetInternalformativ);
314 
315     OVERRIDE(glGenerateMipmap);
316 
317     OVERRIDE(glBindSampler);
318     OVERRIDE(glDeleteSamplers);
319 
320     OVERRIDE_CUSTOM(glFenceSync);
321     OVERRIDE_CUSTOM(glClientWaitSync);
322     OVERRIDE_CUSTOM(glWaitSync);
323     OVERRIDE_CUSTOM(glDeleteSync);
324     OVERRIDE_CUSTOM(glIsSync);
325     OVERRIDE_CUSTOM(glGetSynciv);
326 
327     OVERRIDE(glGetIntegeri_v);
328     OVERRIDE(glGetInteger64i_v);
329     OVERRIDE(glGetInteger64v);
330     OVERRIDE(glGetBooleani_v);
331 
332     OVERRIDE(glGetShaderiv);
333 
334     OVERRIDE(glActiveShaderProgram);
335     OVERRIDE_CUSTOM(glCreateShaderProgramv);
336     OVERRIDE(glProgramUniform1f);
337     OVERRIDE(glProgramUniform1fv);
338     OVERRIDE(glProgramUniform1i);
339     OVERRIDE(glProgramUniform1iv);
340     OVERRIDE(glProgramUniform1ui);
341     OVERRIDE(glProgramUniform1uiv);
342     OVERRIDE(glProgramUniform2f);
343     OVERRIDE(glProgramUniform2fv);
344     OVERRIDE(glProgramUniform2i);
345     OVERRIDE(glProgramUniform2iv);
346     OVERRIDE(glProgramUniform2ui);
347     OVERRIDE(glProgramUniform2uiv);
348     OVERRIDE(glProgramUniform3f);
349     OVERRIDE(glProgramUniform3fv);
350     OVERRIDE(glProgramUniform3i);
351     OVERRIDE(glProgramUniform3iv);
352     OVERRIDE(glProgramUniform3ui);
353     OVERRIDE(glProgramUniform3uiv);
354     OVERRIDE(glProgramUniform4f);
355     OVERRIDE(glProgramUniform4fv);
356     OVERRIDE(glProgramUniform4i);
357     OVERRIDE(glProgramUniform4iv);
358     OVERRIDE(glProgramUniform4ui);
359     OVERRIDE(glProgramUniform4uiv);
360     OVERRIDE(glProgramUniformMatrix2fv);
361     OVERRIDE(glProgramUniformMatrix2x3fv);
362     OVERRIDE(glProgramUniformMatrix2x4fv);
363     OVERRIDE(glProgramUniformMatrix3fv);
364     OVERRIDE(glProgramUniformMatrix3x2fv);
365     OVERRIDE(glProgramUniformMatrix3x4fv);
366     OVERRIDE(glProgramUniformMatrix4fv);
367     OVERRIDE(glProgramUniformMatrix4x2fv);
368     OVERRIDE(glProgramUniformMatrix4x3fv);
369 
370     OVERRIDE(glProgramParameteri);
371     OVERRIDE(glUseProgramStages);
372     OVERRIDE(glBindProgramPipeline);
373 
374     OVERRIDE(glGetProgramResourceiv);
375     OVERRIDE(glGetProgramResourceIndex);
376     OVERRIDE(glGetProgramResourceLocation);
377     OVERRIDE(glGetProgramResourceName);
378     OVERRIDE(glGetProgramPipelineInfoLog);
379 
380     OVERRIDE(glVertexAttribFormat);
381     OVERRIDE(glVertexAttribIFormat);
382     OVERRIDE(glVertexBindingDivisor);
383     OVERRIDE(glVertexAttribBinding);
384     OVERRIDE(glBindVertexBuffer);
385 
386     OVERRIDE_CUSTOM(glDrawArraysIndirect);
387     OVERRIDE_CUSTOM(glDrawElementsIndirect);
388 
389     OVERRIDE(glTexStorage2DMultisample);
390 
391     OVERRIDE_CUSTOM(glGetGraphicsResetStatusEXT);
392     OVERRIDE_CUSTOM(glReadnPixelsEXT);
393     OVERRIDE_CUSTOM(glGetnUniformfvEXT);
394     OVERRIDE_CUSTOM(glGetnUniformivEXT);
395 
396     OVERRIDE(glInvalidateFramebuffer);
397     OVERRIDE(glInvalidateSubFramebuffer);
398 
399     OVERRIDE(glDispatchCompute);
400     OVERRIDE(glDispatchComputeIndirect);
401 
402     OVERRIDE(glGenTransformFeedbacks);
403     OVERRIDE(glDeleteTransformFeedbacks);
404     OVERRIDE(glGenSamplers);
405     OVERRIDE(glGenQueries);
406     OVERRIDE(glDeleteQueries);
407 
408     OVERRIDE(glBindTransformFeedback);
409     OVERRIDE(glBeginQuery);
410     OVERRIDE(glEndQuery);
411 
412     OVERRIDE(glClear);
413     OVERRIDE(glClearBufferfi);
414     OVERRIDE(glCopyTexSubImage2D);
415     OVERRIDE(glCopyTexSubImage3D);
416     OVERRIDE(glCompileShader);
417     OVERRIDE(glValidateProgram);
418     OVERRIDE(glProgramBinary);
419 
420     OVERRIDE(glGetSamplerParameterfv);
421     OVERRIDE(glGetSamplerParameteriv);
422     OVERRIDE(glSamplerParameterf);
423     OVERRIDE(glSamplerParameteri);
424     OVERRIDE(glSamplerParameterfv);
425     OVERRIDE(glSamplerParameteriv);
426 
427     OVERRIDE(glGetAttribLocation);
428 
429     OVERRIDE(glBindAttribLocation);
430     OVERRIDE(glUniformBlockBinding);
431     OVERRIDE(glGetTransformFeedbackVarying);
432     OVERRIDE(glScissor);
433     OVERRIDE(glDepthFunc);
434     OVERRIDE(glViewport);
435     OVERRIDE(glStencilFunc);
436     OVERRIDE(glStencilFuncSeparate);
437     OVERRIDE(glStencilOp);
438     OVERRIDE(glStencilOpSeparate);
439     OVERRIDE(glStencilMaskSeparate);
440     OVERRIDE(glBlendEquation);
441     OVERRIDE(glBlendEquationSeparate);
442     OVERRIDE(glBlendFunc);
443     OVERRIDE(glBlendFuncSeparate);
444     OVERRIDE(glCullFace);
445     OVERRIDE(glFrontFace);
446     OVERRIDE(glLineWidth);
447     OVERRIDE(glVertexAttrib1f);
448     OVERRIDE(glVertexAttrib2f);
449     OVERRIDE(glVertexAttrib3f);
450     OVERRIDE(glVertexAttrib4f);
451     OVERRIDE(glVertexAttrib1fv);
452     OVERRIDE(glVertexAttrib2fv);
453     OVERRIDE(glVertexAttrib3fv);
454     OVERRIDE(glVertexAttrib4fv);
455     OVERRIDE(glVertexAttribI4i);
456     OVERRIDE(glVertexAttribI4ui);
457     OVERRIDE(glVertexAttribI4iv);
458     OVERRIDE(glVertexAttribI4uiv);
459 
460     OVERRIDE(glGetShaderPrecisionFormat);
461     OVERRIDE(glGetProgramiv);
462     OVERRIDE(glGetActiveUniform);
463     OVERRIDE(glGetActiveUniformsiv);
464     OVERRIDE(glGetActiveUniformBlockName);
465     OVERRIDE(glGetActiveAttrib);
466     OVERRIDE(glGetRenderbufferParameteriv);
467     OVERRIDE(glGetQueryiv);
468     OVERRIDE(glGetQueryObjectuiv);
469     OVERRIDE(glIsEnabled);
470     OVERRIDE(glHint);
471 
472     OVERRIDE(glGetFragDataLocation);
473 
474     OVERRIDE(glStencilMask);
475     OVERRIDE(glClearStencil);
476 }
477 
~GL2Encoder()478 GL2Encoder::~GL2Encoder()
479 {
480     delete m_compressedTextureFormats;
481 }
482 
s_glGetError(void * self)483 GLenum GL2Encoder::s_glGetError(void * self)
484 {
485     GL2Encoder *ctx = (GL2Encoder *)self;
486     GLenum err = ctx->getError();
487     if(err != GL_NO_ERROR) {
488         if (!ctx->m_noHostError) {
489             ctx->m_glGetError_enc(ctx); // also clear host error
490         }
491         ctx->setError(GL_NO_ERROR);
492         return err;
493     }
494 
495     if (ctx->m_noHostError) {
496         return GL_NO_ERROR;
497     } else {
498         return ctx->m_glGetError_enc(self);
499     }
500 }
501 
502 class GL2Encoder::ErrorUpdater {
503 public:
ErrorUpdater(GL2Encoder * ctx)504     ErrorUpdater(GL2Encoder* ctx) :
505         mCtx(ctx),
506         guest_error(ctx->getError()),
507         host_error(ctx->m_glGetError_enc(ctx)) {
508             if (ctx->m_noHostError) {
509                 host_error = GL_NO_ERROR;
510             }
511             // Preserve any existing GL error in the guest:
512             // OpenGL ES 3.0.5 spec:
513             // The command enum GetError( void ); is used to obtain error information.
514             // Each detectable error is assigned a numeric code. When an error is
515             // detected, a flag is set and the code is recorded. Further errors, if
516             // they occur, do not affect this recorded code. When GetError is called,
517             // the code is returned and the flag is cleared, so that a further error
518             // will again record its code. If a call to GetError returns NO_ERROR, then
519             // there has been no detectable error since the last call to GetError (or
520             // since the GL was initialized).
521             if (guest_error == GL_NO_ERROR) {
522                 guest_error = host_error;
523             }
524         }
525 
getHostErrorAndUpdate()526     GLenum getHostErrorAndUpdate() {
527         host_error = mCtx->m_glGetError_enc(mCtx);
528         if (guest_error == GL_NO_ERROR) {
529             guest_error = host_error;
530         }
531         return host_error;
532     }
533 
updateGuestErrorState()534     void updateGuestErrorState() {
535         mCtx->setError(guest_error);
536     }
537 
538 private:
539     GL2Encoder* mCtx;
540     GLenum guest_error;
541     GLenum host_error;
542 };
543 
544 template<class T>
545 class GL2Encoder::ScopedQueryUpdate {
546 public:
ScopedQueryUpdate(GL2Encoder * ctx,uint32_t bytes,T * target)547     ScopedQueryUpdate(GL2Encoder* ctx, uint32_t bytes, T* target) :
548         mCtx(ctx),
549         mBuf(bytes, 0),
550         mTarget(target),
551         mErrorUpdater(ctx) {
552     }
hostStagingBuffer()553     T* hostStagingBuffer() {
554         return (T*)&mBuf[0];
555     }
~ScopedQueryUpdate()556     ~ScopedQueryUpdate() {
557         GLint hostError = mErrorUpdater.getHostErrorAndUpdate();
558         if (hostError == GL_NO_ERROR && mTarget) {
559             memcpy(mTarget, &mBuf[0], mBuf.size());
560         }
561         mErrorUpdater.updateGuestErrorState();
562     }
563 private:
564     GL2Encoder* mCtx;
565     std::vector<char> mBuf;
566     T* mTarget;
567     ErrorUpdater mErrorUpdater;
568 };
569 
safe_glGetBooleanv(GLenum param,GLboolean * val)570 void GL2Encoder::safe_glGetBooleanv(GLenum param, GLboolean* val) {
571     ScopedQueryUpdate<GLboolean> query(this, glUtilsParamSize(param) * sizeof(GLboolean), val);
572     m_glGetBooleanv_enc(this, param, query.hostStagingBuffer());
573 }
574 
safe_glGetFloatv(GLenum param,GLfloat * val)575 void GL2Encoder::safe_glGetFloatv(GLenum param, GLfloat* val) {
576     ScopedQueryUpdate<GLfloat> query(this, glUtilsParamSize(param) * sizeof(GLfloat), val);
577     m_glGetFloatv_enc(this, param, query.hostStagingBuffer());
578 }
579 
safe_glGetIntegerv(GLenum param,GLint * val)580 void GL2Encoder::safe_glGetIntegerv(GLenum param, GLint* val) {
581     ScopedQueryUpdate<GLint> query(this, glUtilsParamSize(param) * sizeof(GLint), val);
582     m_glGetIntegerv_enc(this, param, query.hostStagingBuffer());
583 }
584 
safe_glGetInteger64v(GLenum param,GLint64 * val)585 void GL2Encoder::safe_glGetInteger64v(GLenum param, GLint64* val) {
586     ScopedQueryUpdate<GLint64> query(this, glUtilsParamSize(param) * sizeof(GLint64), val);
587     m_glGetInteger64v_enc(this, param, query.hostStagingBuffer());
588 }
589 
safe_glGetIntegeri_v(GLenum param,GLuint index,GLint * val)590 void GL2Encoder::safe_glGetIntegeri_v(GLenum param, GLuint index, GLint* val) {
591     ScopedQueryUpdate<GLint> query(this, sizeof(GLint), val);
592     m_glGetIntegeri_v_enc(this, param, index, query.hostStagingBuffer());
593 }
594 
safe_glGetInteger64i_v(GLenum param,GLuint index,GLint64 * val)595 void GL2Encoder::safe_glGetInteger64i_v(GLenum param, GLuint index, GLint64* val) {
596     ScopedQueryUpdate<GLint64> query(this, sizeof(GLint64), val);
597     m_glGetInteger64i_v_enc(this, param, index, query.hostStagingBuffer());
598 }
599 
safe_glGetBooleani_v(GLenum param,GLuint index,GLboolean * val)600 void GL2Encoder::safe_glGetBooleani_v(GLenum param, GLuint index, GLboolean* val) {
601     ScopedQueryUpdate<GLboolean> query(this, sizeof(GLboolean), val);
602     m_glGetBooleani_v_enc(this, param, index, query.hostStagingBuffer());
603 }
604 
s_glFlush(void * self)605 void GL2Encoder::s_glFlush(void *self)
606 {
607     GL2Encoder *ctx = (GL2Encoder *) self;
608     ctx->m_glFlush_enc(self);
609     ctx->m_stream->flush();
610 }
611 
s_glGetString(void * self,GLenum name)612 const GLubyte *GL2Encoder::s_glGetString(void *self, GLenum name)
613 {
614     GL2Encoder *ctx = (GL2Encoder *)self;
615 
616     GLubyte *retval =  (GLubyte *) "";
617     RET_AND_SET_ERROR_IF(
618         name != GL_VENDOR &&
619         name != GL_RENDERER &&
620         name != GL_VERSION &&
621         name != GL_EXTENSIONS,
622         GL_INVALID_ENUM,
623         retval);
624     switch(name) {
625     case GL_VENDOR:
626         retval = gVendorString;
627         break;
628     case GL_RENDERER:
629         retval = gRendererString;
630         break;
631     case GL_VERSION:
632         retval = gVersionString;
633         break;
634     case GL_EXTENSIONS:
635         retval = gExtensionsString;
636         break;
637     }
638     return retval;
639 }
640 
s_glPixelStorei(void * self,GLenum param,GLint value)641 void GL2Encoder::s_glPixelStorei(void *self, GLenum param, GLint value)
642 {
643     GL2Encoder *ctx = (GL2Encoder *)self;
644     SET_ERROR_IF(!GLESv2Validation::pixelStoreParam(ctx, param), GL_INVALID_ENUM);
645     SET_ERROR_IF(!GLESv2Validation::pixelStoreValue(param, value), GL_INVALID_VALUE);
646     ctx->m_glPixelStorei_enc(ctx, param, value);
647     assert(ctx->m_state != NULL);
648     ctx->m_state->setPixelStore(param, value);
649 }
s_glBindBuffer(void * self,GLenum target,GLuint id)650 void GL2Encoder::s_glBindBuffer(void *self, GLenum target, GLuint id)
651 {
652     GL2Encoder *ctx = (GL2Encoder *) self;
653     assert(ctx->m_state != NULL);
654     SET_ERROR_IF(!GLESv2Validation::bufferTarget(ctx, target), GL_INVALID_ENUM);
655 
656     bool nop = ctx->m_state->isNonIndexedBindNoOp(target, id);
657 
658     if (nop) return;
659 
660     ctx->m_state->bindBuffer(target, id);
661     ctx->m_state->addBuffer(id);
662     ctx->m_glBindBuffer_enc(ctx, target, id);
663     ctx->m_state->setLastEncodedBufferBind(target, id);
664 }
665 
doBindBufferEncodeCached(GLenum target,GLuint id)666 void GL2Encoder::doBindBufferEncodeCached(GLenum target, GLuint id) {
667     bool encode = id != m_state->getLastEncodedBufferBind(target);
668 
669     if (encode) {
670         m_glBindBuffer_enc(this, target, id);
671     }
672 
673     m_state->setLastEncodedBufferBind(target, id);
674 }
675 
s_glBufferData(void * self,GLenum target,GLsizeiptr size,const GLvoid * data,GLenum usage)676 void GL2Encoder::s_glBufferData(void * self, GLenum target, GLsizeiptr size, const GLvoid * data, GLenum usage)
677 {
678     GL2Encoder *ctx = (GL2Encoder *) self;
679     SET_ERROR_IF(!GLESv2Validation::bufferTarget(ctx, target), GL_INVALID_ENUM);
680     GLuint bufferId = ctx->m_state->getBuffer(target);
681     SET_ERROR_IF(bufferId==0, GL_INVALID_OPERATION);
682     SET_ERROR_IF(size<0, GL_INVALID_VALUE);
683     SET_ERROR_IF(!GLESv2Validation::bufferUsage(ctx, usage), GL_INVALID_ENUM);
684 
685     ctx->m_shared->updateBufferData(bufferId, size, data);
686     ctx->m_shared->setBufferUsage(bufferId, usage);
687     if (ctx->m_hasSyncBufferData) {
688         ctx->glBufferDataSyncAEMU(self, target, size, data, usage);
689     } else {
690         ctx->m_glBufferData_enc(self, target, size, data, usage);
691     }
692 }
693 
s_glBufferSubData(void * self,GLenum target,GLintptr offset,GLsizeiptr size,const GLvoid * data)694 void GL2Encoder::s_glBufferSubData(void * self, GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid * data)
695 {
696     GL2Encoder *ctx = (GL2Encoder *) self;
697     SET_ERROR_IF(!GLESv2Validation::bufferTarget(ctx, target), GL_INVALID_ENUM);
698     GLuint bufferId = ctx->m_state->getBuffer(target);
699     SET_ERROR_IF(bufferId==0, GL_INVALID_OPERATION);
700     SET_ERROR_IF(ctx->isBufferTargetMapped(target), GL_INVALID_OPERATION);
701 
702     GLenum res = ctx->m_shared->subUpdateBufferData(bufferId, offset, size, data);
703     SET_ERROR_IF(res, res);
704 
705     ctx->m_glBufferSubData_enc(self, target, offset, size, data);
706 }
707 
s_glGenBuffers(void * self,GLsizei n,GLuint * buffers)708 void GL2Encoder::s_glGenBuffers(void* self, GLsizei n, GLuint* buffers) {
709     GL2Encoder *ctx = (GL2Encoder *) self;
710     SET_ERROR_IF(n<0, GL_INVALID_VALUE);
711     ctx->m_glGenBuffers_enc(self, n, buffers);
712     for (int i = 0; i < n; i++) {
713         ctx->m_state->addBuffer(buffers[i]);
714     }
715 }
716 
s_glDeleteBuffers(void * self,GLsizei n,const GLuint * buffers)717 void GL2Encoder::s_glDeleteBuffers(void * self, GLsizei n, const GLuint * buffers)
718 {
719     GL2Encoder *ctx = (GL2Encoder *) self;
720     SET_ERROR_IF(n<0, GL_INVALID_VALUE);
721     for (int i=0; i<n; i++) {
722         // Technically if the buffer is mapped, we should unmap it, but we won't
723         // use it anymore after this :)
724         ctx->m_shared->deleteBufferData(buffers[i]);
725         ctx->m_state->unBindBuffer(buffers[i]);
726         ctx->m_state->removeBuffer(buffers[i]);
727         ctx->m_glDeleteBuffers_enc(self,1,&buffers[i]);
728     }
729 }
730 
731 #define VALIDATE_VERTEX_ATTRIB_INDEX(index) \
732     SET_ERROR_IF(index >= CODEC_MAX_VERTEX_ATTRIBUTES, GL_INVALID_VALUE); \
733 
s_glVertexAttribPointer(void * self,GLuint indx,GLint size,GLenum type,GLboolean normalized,GLsizei stride,const GLvoid * ptr)734 void GL2Encoder::s_glVertexAttribPointer(void *self, GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid * ptr)
735 {
736     GL2Encoder *ctx = (GL2Encoder *)self;
737     assert(ctx->m_state != NULL);
738     VALIDATE_VERTEX_ATTRIB_INDEX(indx);
739     SET_ERROR_IF((size < 1 || size > 4), GL_INVALID_VALUE);
740     SET_ERROR_IF(!GLESv2Validation::vertexAttribType(ctx, type), GL_INVALID_ENUM);
741     SET_ERROR_IF(stride < 0, GL_INVALID_VALUE);
742     SET_ERROR_IF((type == GL_INT_2_10_10_10_REV ||
743                   type == GL_UNSIGNED_INT_2_10_10_10_REV) &&
744                  size != 4,
745                  GL_INVALID_OPERATION);
746     ctx->m_state->setVertexAttribBinding(indx, indx);
747     ctx->m_state->setVertexAttribFormat(indx, size, type, normalized, 0, false);
748 
749     GLsizei effectiveStride = stride;
750     if (stride == 0) {
751         effectiveStride = glSizeof(type) * size;
752         switch (type) {
753             case GL_INT_2_10_10_10_REV:
754             case GL_UNSIGNED_INT_2_10_10_10_REV:
755                 effectiveStride /= 4;
756                 break;
757             default:
758                 break;
759         }
760     }
761 
762     ctx->m_state->bindIndexedBuffer(0, indx, ctx->m_state->currentArrayVbo(), (uintptr_t)ptr, 0, stride, effectiveStride);
763 
764     if (ctx->m_state->currentArrayVbo() != 0) {
765         ctx->glVertexAttribPointerOffset(ctx, indx, size, type, normalized, stride, (uintptr_t)ptr);
766     } else {
767         SET_ERROR_IF(ctx->m_state->currentVertexArrayObject() != 0 && ptr, GL_INVALID_OPERATION);
768         // wait for client-array handler
769     }
770 }
771 
s_glGetIntegerv(void * self,GLenum param,GLint * ptr)772 void GL2Encoder::s_glGetIntegerv(void *self, GLenum param, GLint *ptr)
773 {
774     GL2Encoder *ctx = (GL2Encoder *) self;
775     GLClientState* state = ctx->m_state;
776 
777     switch (param) {
778     case GL_NUM_EXTENSIONS:
779         *ptr = (int)ctx->m_currExtensionsArray.size();
780         break;
781     case GL_MAJOR_VERSION:
782         *ptr = ctx->m_deviceMajorVersion;
783         break;
784     case GL_MINOR_VERSION:
785         *ptr = ctx->m_deviceMinorVersion;
786         break;
787     case GL_NUM_SHADER_BINARY_FORMATS:
788         *ptr = 0;
789         break;
790     case GL_SHADER_BINARY_FORMATS:
791         // do nothing
792         break;
793 
794     case GL_COMPRESSED_TEXTURE_FORMATS: {
795         GLint *compressedTextureFormats = ctx->getCompressedTextureFormats();
796         if (ctx->m_num_compressedTextureFormats > 0 &&
797                 compressedTextureFormats != NULL) {
798             memcpy(ptr, compressedTextureFormats,
799                     ctx->m_num_compressedTextureFormats * sizeof(GLint));
800         }
801         break;
802     }
803 
804     case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS:
805         if (ctx->m_max_combinedTextureImageUnits != 0) {
806             *ptr = ctx->m_max_combinedTextureImageUnits;
807         } else {
808             ctx->safe_glGetIntegerv(param, ptr);
809             ctx->m_max_combinedTextureImageUnits = *ptr;
810         }
811         break;
812     case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:
813         if (ctx->m_max_vertexTextureImageUnits != 0) {
814             *ptr = ctx->m_max_vertexTextureImageUnits;
815         } else {
816             ctx->safe_glGetIntegerv(param, ptr);
817             ctx->m_max_vertexTextureImageUnits = *ptr;
818         }
819         break;
820     case GL_MAX_ARRAY_TEXTURE_LAYERS:
821         if (ctx->m_max_array_texture_layers != 0) {
822             *ptr = ctx->m_max_array_texture_layers;
823         } else {
824             ctx->safe_glGetIntegerv(param, ptr);
825             ctx->m_max_array_texture_layers = *ptr;
826         }
827         break;
828     case GL_MAX_TEXTURE_IMAGE_UNITS:
829         if (ctx->m_max_textureImageUnits != 0) {
830             *ptr = ctx->m_max_textureImageUnits;
831         } else {
832             ctx->safe_glGetIntegerv(param, ptr);
833             ctx->m_max_textureImageUnits = *ptr;
834         }
835         break;
836     case GL_TEXTURE_BINDING_2D:
837         if (!state) return;
838         *ptr = state->getBoundTexture(GL_TEXTURE_2D);
839         break;
840     case GL_TEXTURE_BINDING_EXTERNAL_OES:
841         if (!state) return;
842         *ptr = state->getBoundTexture(GL_TEXTURE_EXTERNAL_OES);
843         break;
844     case GL_MAX_VERTEX_ATTRIBS:
845         *ptr = CODEC_MAX_VERTEX_ATTRIBUTES;
846         break;
847     case GL_MAX_VERTEX_ATTRIB_STRIDE:
848         if (ctx->m_max_vertexAttribStride != 0) {
849             *ptr = ctx->m_max_vertexAttribStride;
850         } else {
851             ctx->safe_glGetIntegerv(param, ptr);
852             ctx->m_max_vertexAttribStride = *ptr;
853         }
854         break;
855     case GL_MAX_CUBE_MAP_TEXTURE_SIZE:
856         if (ctx->m_max_cubeMapTextureSize != 0) {
857             *ptr = ctx->m_max_cubeMapTextureSize;
858         } else {
859             ctx->safe_glGetIntegerv(param, ptr);
860             ctx->m_max_cubeMapTextureSize = *ptr;
861         }
862         break;
863     case GL_MAX_RENDERBUFFER_SIZE:
864         if (ctx->m_max_renderBufferSize != 0) {
865             *ptr = ctx->m_max_renderBufferSize;
866         } else {
867             ctx->safe_glGetIntegerv(param, ptr);
868             ctx->m_max_renderBufferSize = *ptr;
869         }
870         break;
871     case GL_MAX_TEXTURE_SIZE:
872         if (ctx->m_max_textureSize != 0) {
873             *ptr = ctx->m_max_textureSize;
874         } else {
875             ctx->safe_glGetIntegerv(param, ptr);
876             ctx->m_max_textureSize = *ptr;
877             if (ctx->m_max_textureSize > 0) {
878                 uint32_t current = 1;
879                 while (current < ctx->m_max_textureSize) {
880                     ++ctx->m_log2MaxTextureSize;
881                     current = current << 1;
882                 }
883             }
884         }
885         break;
886     case GL_MAX_3D_TEXTURE_SIZE:
887         if (ctx->m_max_3d_textureSize != 0) {
888             *ptr = ctx->m_max_3d_textureSize;
889         } else {
890             ctx->safe_glGetIntegerv(param, ptr);
891             ctx->m_max_3d_textureSize = *ptr;
892         }
893         break;
894     case GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT:
895         if (ctx->m_ssbo_offset_align != 0) {
896             *ptr = ctx->m_ssbo_offset_align;
897         } else {
898             ctx->safe_glGetIntegerv(param, ptr);
899             ctx->m_ssbo_offset_align = *ptr;
900         }
901         break;
902     case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT:
903         if (ctx->m_ubo_offset_align != 0) {
904             *ptr = ctx->m_ubo_offset_align;
905         } else {
906             ctx->safe_glGetIntegerv(param, ptr);
907             ctx->m_ubo_offset_align = *ptr;
908         }
909         break;
910     // Desktop OpenGL can allow a mindboggling # samples per pixel (such as 64).
911     // Limit to 4 (spec minimum) to keep dEQP tests from timing out.
912     case GL_MAX_SAMPLES:
913     case GL_MAX_COLOR_TEXTURE_SAMPLES:
914     case GL_MAX_INTEGER_SAMPLES:
915     case GL_MAX_DEPTH_TEXTURE_SAMPLES:
916         *ptr = 4;
917         break;
918     // Checks for version-incompatible enums.
919     // Not allowed in vanilla ES 2.0.
920     case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:
921         SET_ERROR_IF(ctx->majorVersion() < 3, GL_INVALID_ENUM);
922         if (ctx->m_max_transformFeedbackSeparateAttribs != 0) {
923             *ptr = ctx->m_max_transformFeedbackSeparateAttribs;
924         } else {
925             ctx->safe_glGetIntegerv(param, ptr);
926             ctx->m_max_transformFeedbackSeparateAttribs = *ptr;
927         }
928         break;
929     case GL_MAX_UNIFORM_BUFFER_BINDINGS:
930         SET_ERROR_IF(ctx->majorVersion() < 3, GL_INVALID_ENUM);
931         if (ctx->m_max_uniformBufferBindings != 0) {
932             *ptr = ctx->m_max_uniformBufferBindings;
933         } else {
934             ctx->safe_glGetIntegerv(param, ptr);
935             ctx->m_max_uniformBufferBindings = *ptr;
936         }
937         break;
938     case GL_TEXTURE_BUFFER_OFFSET_ALIGNMENT_OES:
939         SET_ERROR_IF(!ctx->es32Plus() && !ctx->getExtensions().textureBufferAny(), GL_INVALID_ENUM);
940         if(ctx->m_textureBufferOffsetAlign != 0) {
941             *ptr = ctx->m_textureBufferOffsetAlign;
942         } else {
943             ctx->safe_glGetIntegerv(param, ptr);
944             ctx->m_textureBufferOffsetAlign = *ptr;
945         }
946         break;
947     case GL_MAX_COLOR_ATTACHMENTS:
948         SET_ERROR_IF(ctx->majorVersion() < 3 &&
949                      !ctx->hasExtension("GL_EXT_draw_buffers"), GL_INVALID_ENUM);
950         if (ctx->m_max_colorAttachments != 0) {
951             *ptr = ctx->m_max_colorAttachments;
952         } else {
953             ctx->safe_glGetIntegerv(param, ptr);
954             ctx->m_max_colorAttachments = *ptr;
955         }
956         break;
957     case GL_MAX_DRAW_BUFFERS:
958         SET_ERROR_IF(ctx->majorVersion() < 3 &&
959                      !ctx->hasExtension("GL_EXT_draw_buffers"), GL_INVALID_ENUM);
960         if (ctx->m_max_drawBuffers != 0) {
961             *ptr = ctx->m_max_drawBuffers;
962         } else {
963             ctx->safe_glGetIntegerv(param, ptr);
964             ctx->m_max_drawBuffers = *ptr;
965         }
966         break;
967     // Not allowed in ES 3.0.
968     case GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS:
969         SET_ERROR_IF(ctx->majorVersion() < 3 ||
970                      (ctx->majorVersion() == 3 &&
971                       ctx->minorVersion() == 0), GL_INVALID_ENUM);
972         if (ctx->m_max_atomicCounterBufferBindings != 0) {
973             *ptr = ctx->m_max_atomicCounterBufferBindings;
974         } else {
975             ctx->safe_glGetIntegerv(param, ptr);
976             ctx->m_max_atomicCounterBufferBindings = *ptr;
977         }
978         break;
979     case GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS:
980         SET_ERROR_IF(ctx->majorVersion() < 3 ||
981                      (ctx->majorVersion() == 3 &&
982                       ctx->minorVersion() == 0), GL_INVALID_ENUM);
983         if (ctx->m_max_shaderStorageBufferBindings != 0) {
984             *ptr = ctx->m_max_shaderStorageBufferBindings;
985         } else {
986             ctx->safe_glGetIntegerv(param, ptr);
987             ctx->m_max_shaderStorageBufferBindings = *ptr;
988         }
989         break;
990     case GL_MAX_VERTEX_ATTRIB_BINDINGS:
991         SET_ERROR_IF(ctx->majorVersion() < 3 ||
992                      (ctx->majorVersion() == 3 &&
993                       ctx->minorVersion() == 0), GL_INVALID_ENUM);
994         if (ctx->m_max_vertexAttribBindings != 0) {
995             *ptr = ctx->m_max_vertexAttribBindings;
996         } else {
997             ctx->safe_glGetIntegerv(param, ptr);
998             ctx->m_max_vertexAttribBindings = *ptr;
999         }
1000         break;
1001     case GL_RESET_NOTIFICATION_STRATEGY_EXT:
1002         // BUG: 121414786
1003         *ptr = GL_LOSE_CONTEXT_ON_RESET_EXT;
1004         break;
1005     default:
1006         if (!state) return;
1007         if (!state->getClientStateParameter<GLint>(param, ptr)) {
1008             ctx->safe_glGetIntegerv(param, ptr);
1009         }
1010         break;
1011     }
1012 }
1013 
1014 
s_glGetFloatv(void * self,GLenum param,GLfloat * ptr)1015 void GL2Encoder::s_glGetFloatv(void *self, GLenum param, GLfloat *ptr)
1016 {
1017     GL2Encoder *ctx = (GL2Encoder *)self;
1018     GLClientState* state = ctx->m_state;
1019 
1020     switch (param) {
1021     case GL_NUM_SHADER_BINARY_FORMATS:
1022         *ptr = 0;
1023         break;
1024     case GL_SHADER_BINARY_FORMATS:
1025         // do nothing
1026         break;
1027 
1028     case GL_COMPRESSED_TEXTURE_FORMATS: {
1029         GLint *compressedTextureFormats = ctx->getCompressedTextureFormats();
1030         if (ctx->m_num_compressedTextureFormats > 0 &&
1031                 compressedTextureFormats != NULL) {
1032             for (int i = 0; i < ctx->m_num_compressedTextureFormats; i++) {
1033                 ptr[i] = (GLfloat) compressedTextureFormats[i];
1034             }
1035         }
1036         break;
1037     }
1038 
1039     case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS:
1040     case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:
1041     case GL_MAX_TEXTURE_IMAGE_UNITS:
1042     case GL_MAX_VERTEX_ATTRIBS:
1043     case GL_MAX_VERTEX_ATTRIB_STRIDE:
1044     case GL_MAX_CUBE_MAP_TEXTURE_SIZE:
1045     case GL_MAX_RENDERBUFFER_SIZE:
1046     case GL_MAX_TEXTURE_SIZE:
1047     case GL_MAX_3D_TEXTURE_SIZE:
1048     case GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT:
1049     case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT:
1050     case GL_MAX_SAMPLES:
1051     case GL_MAX_COLOR_TEXTURE_SAMPLES:
1052     case GL_MAX_INTEGER_SAMPLES:
1053     case GL_MAX_DEPTH_TEXTURE_SAMPLES:
1054     case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:
1055     case GL_MAX_UNIFORM_BUFFER_BINDINGS:
1056     case GL_MAX_COLOR_ATTACHMENTS:
1057     case GL_MAX_DRAW_BUFFERS:
1058     case GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS:
1059     case GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS:
1060     case GL_MAX_VERTEX_ATTRIB_BINDINGS:
1061     case GL_TEXTURE_BINDING_2D:
1062     case GL_TEXTURE_BINDING_EXTERNAL_OES: {
1063         GLint res;
1064         s_glGetIntegerv(ctx, param, &res);
1065         *ptr = (GLfloat)res;
1066         break;
1067     }
1068 
1069     default:
1070         if (!state) return;
1071         if (!state->getClientStateParameter<GLfloat>(param, ptr)) {
1072             ctx->safe_glGetFloatv(param, ptr);
1073         }
1074         break;
1075     }
1076 }
1077 
1078 
s_glGetBooleanv(void * self,GLenum param,GLboolean * ptr)1079 void GL2Encoder::s_glGetBooleanv(void *self, GLenum param, GLboolean *ptr)
1080 {
1081     GL2Encoder *ctx = (GL2Encoder *)self;
1082     GLClientState* state = ctx->m_state;
1083 
1084     switch (param) {
1085     case GL_NUM_SHADER_BINARY_FORMATS:
1086         *ptr = GL_FALSE;
1087         break;
1088     case GL_SHADER_BINARY_FORMATS:
1089         // do nothing
1090         break;
1091 
1092     case GL_COMPRESSED_TEXTURE_FORMATS: {
1093         GLint *compressedTextureFormats = ctx->getCompressedTextureFormats();
1094         if (ctx->m_num_compressedTextureFormats > 0 &&
1095                 compressedTextureFormats != NULL) {
1096             for (int i = 0; i < ctx->m_num_compressedTextureFormats; i++) {
1097                 ptr[i] = compressedTextureFormats[i] != 0 ? GL_TRUE : GL_FALSE;
1098             }
1099         }
1100         break;
1101     }
1102 
1103     case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS:
1104     case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:
1105     case GL_MAX_TEXTURE_IMAGE_UNITS:
1106     case GL_MAX_VERTEX_ATTRIBS:
1107     case GL_MAX_VERTEX_ATTRIB_STRIDE:
1108     case GL_MAX_CUBE_MAP_TEXTURE_SIZE:
1109     case GL_MAX_RENDERBUFFER_SIZE:
1110     case GL_MAX_TEXTURE_SIZE:
1111     case GL_MAX_3D_TEXTURE_SIZE:
1112     case GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT:
1113     case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT:
1114     case GL_MAX_SAMPLES:
1115     case GL_MAX_COLOR_TEXTURE_SAMPLES:
1116     case GL_MAX_INTEGER_SAMPLES:
1117     case GL_MAX_DEPTH_TEXTURE_SAMPLES:
1118     case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:
1119     case GL_MAX_UNIFORM_BUFFER_BINDINGS:
1120     case GL_MAX_COLOR_ATTACHMENTS:
1121     case GL_MAX_DRAW_BUFFERS:
1122     case GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS:
1123     case GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS:
1124     case GL_MAX_VERTEX_ATTRIB_BINDINGS:
1125     case GL_TEXTURE_BINDING_2D:
1126     case GL_TEXTURE_BINDING_EXTERNAL_OES: {
1127         GLint res;
1128         s_glGetIntegerv(ctx, param, &res);
1129         *ptr = res == 0 ? GL_FALSE : GL_TRUE;
1130         break;
1131     }
1132 
1133     default:
1134         if (!state) return;
1135         {
1136             GLint intVal;
1137             if (!state->getClientStateParameter<GLint>(param, &intVal)) {
1138                 ctx->safe_glGetBooleanv(param, ptr);
1139             } else {
1140                 *ptr = (intVal != 0) ? GL_TRUE : GL_FALSE;
1141             }
1142         }
1143         break;
1144     }
1145 }
1146 
1147 
s_glEnableVertexAttribArray(void * self,GLuint index)1148 void GL2Encoder::s_glEnableVertexAttribArray(void *self, GLuint index)
1149 {
1150     GL2Encoder *ctx = (GL2Encoder *)self;
1151     assert(ctx->m_state);
1152     VALIDATE_VERTEX_ATTRIB_INDEX(index);
1153     ctx->m_glEnableVertexAttribArray_enc(ctx, index);
1154     ctx->m_state->enable(index, 1);
1155 }
1156 
s_glDisableVertexAttribArray(void * self,GLuint index)1157 void GL2Encoder::s_glDisableVertexAttribArray(void *self, GLuint index)
1158 {
1159     GL2Encoder *ctx = (GL2Encoder *)self;
1160     assert(ctx->m_state);
1161     VALIDATE_VERTEX_ATTRIB_INDEX(index);
1162     ctx->m_glDisableVertexAttribArray_enc(ctx, index);
1163     ctx->m_state->enable(index, 0);
1164 }
1165 
1166 
s_glGetVertexAttribiv(void * self,GLuint index,GLenum pname,GLint * params)1167 void GL2Encoder::s_glGetVertexAttribiv(void *self, GLuint index, GLenum pname, GLint *params)
1168 {
1169     GL2Encoder *ctx = (GL2Encoder *)self;
1170     VALIDATE_VERTEX_ATTRIB_INDEX(index);
1171     SET_ERROR_IF(!GLESv2Validation::allowedGetVertexAttrib(pname), GL_INVALID_ENUM);
1172 
1173     if (!ctx->m_state->getVertexAttribParameter<GLint>(index, pname, params)) {
1174         ctx->m_glGetVertexAttribiv_enc(self, index, pname, params);
1175     }
1176 }
1177 
s_glGetVertexAttribfv(void * self,GLuint index,GLenum pname,GLfloat * params)1178 void GL2Encoder::s_glGetVertexAttribfv(void *self, GLuint index, GLenum pname, GLfloat *params)
1179 {
1180     GL2Encoder *ctx = (GL2Encoder *)self;
1181     VALIDATE_VERTEX_ATTRIB_INDEX(index);
1182     SET_ERROR_IF(!GLESv2Validation::allowedGetVertexAttrib(pname), GL_INVALID_ENUM);
1183 
1184     if (!ctx->m_state->getVertexAttribParameter<GLfloat>(index, pname, params)) {
1185         ctx->m_glGetVertexAttribfv_enc(self, index, pname, params);
1186     }
1187 }
1188 
s_glGetVertexAttribPointerv(void * self,GLuint index,GLenum pname,GLvoid ** pointer)1189 void GL2Encoder::s_glGetVertexAttribPointerv(void *self, GLuint index, GLenum pname, GLvoid **pointer)
1190 {
1191     GL2Encoder *ctx = (GL2Encoder *)self;
1192     if (ctx->m_state == NULL) return;
1193     VALIDATE_VERTEX_ATTRIB_INDEX(index);
1194     SET_ERROR_IF(pname != GL_VERTEX_ATTRIB_ARRAY_POINTER, GL_INVALID_ENUM);
1195     (void)pname;
1196 
1197     *pointer = (GLvoid*)(ctx->m_state->getCurrAttributeBindingInfo(index).offset);
1198 }
1199 
calcIndexRange(const void * indices,GLenum type,GLsizei count,int * minIndex_out,int * maxIndex_out)1200 void GL2Encoder::calcIndexRange(const void* indices,
1201                                 GLenum type,
1202                                 GLsizei count,
1203                                 int* minIndex_out,
1204                                 int* maxIndex_out) {
1205     switch(type) {
1206     case GL_BYTE:
1207     case GL_UNSIGNED_BYTE:
1208         GLUtils::minmaxExcept(
1209                 (unsigned char *)indices, count,
1210                 minIndex_out, maxIndex_out,
1211                 m_primitiveRestartEnabled, GLUtils::primitiveRestartIndex<unsigned char>());
1212         break;
1213     case GL_SHORT:
1214     case GL_UNSIGNED_SHORT:
1215         GLUtils::minmaxExcept(
1216                 (unsigned short *)indices, count,
1217                 minIndex_out, maxIndex_out,
1218                 m_primitiveRestartEnabled, GLUtils::primitiveRestartIndex<unsigned short>());
1219         break;
1220     case GL_INT:
1221     case GL_UNSIGNED_INT:
1222         GLUtils::minmaxExcept(
1223                 (unsigned int *)indices, count,
1224                 minIndex_out, maxIndex_out,
1225                 m_primitiveRestartEnabled, GLUtils::primitiveRestartIndex<unsigned int>());
1226         break;
1227     default:
1228         ALOGE("unsupported index buffer type %d\n", type);
1229     }
1230 }
1231 
recenterIndices(const void * src,GLenum type,GLsizei count,int minIndex)1232 void* GL2Encoder::recenterIndices(const void* src,
1233                                   GLenum type,
1234                                   GLsizei count,
1235                                   int minIndex) {
1236 
1237     void* adjustedIndices = (void*)src;
1238 
1239     if (minIndex != 0) {
1240         m_fixedBuffer.resize(glSizeof(type) * count);
1241         adjustedIndices = m_fixedBuffer.data();
1242         switch(type) {
1243         case GL_BYTE:
1244         case GL_UNSIGNED_BYTE:
1245             GLUtils::shiftIndicesExcept(
1246                     (unsigned char *)src,
1247                     (unsigned char *)adjustedIndices,
1248                     count, -minIndex,
1249                     m_primitiveRestartEnabled,
1250                     (unsigned char)m_primitiveRestartIndex);
1251             break;
1252         case GL_SHORT:
1253         case GL_UNSIGNED_SHORT:
1254             GLUtils::shiftIndicesExcept(
1255                     (unsigned short *)src,
1256                     (unsigned short *)adjustedIndices,
1257                     count, -minIndex,
1258                     m_primitiveRestartEnabled,
1259                     (unsigned short)m_primitiveRestartIndex);
1260             break;
1261         case GL_INT:
1262         case GL_UNSIGNED_INT:
1263             GLUtils::shiftIndicesExcept(
1264                     (unsigned int *)src,
1265                     (unsigned int *)adjustedIndices,
1266                     count, -minIndex,
1267                     m_primitiveRestartEnabled,
1268                     (unsigned int)m_primitiveRestartIndex);
1269             break;
1270         default:
1271             ALOGE("unsupported index buffer type %d\n", type);
1272         }
1273     }
1274 
1275     return adjustedIndices;
1276 }
1277 
getBufferIndexRange(BufferData * buf,const void * dataWithOffset,GLenum type,size_t count,size_t offset,int * minIndex_out,int * maxIndex_out)1278 void GL2Encoder::getBufferIndexRange(BufferData* buf,
1279                                      const void* dataWithOffset,
1280                                      GLenum type,
1281                                      size_t count,
1282                                      size_t offset,
1283                                      int* minIndex_out,
1284                                      int* maxIndex_out) {
1285 
1286     if (buf->m_indexRangeCache.findRange(
1287                 type, offset, count,
1288                 m_primitiveRestartEnabled,
1289                 minIndex_out,
1290                 maxIndex_out)) {
1291         return;
1292     }
1293 
1294     calcIndexRange(dataWithOffset, type, count, minIndex_out, maxIndex_out);
1295 
1296     buf->m_indexRangeCache.addRange(
1297             type, offset, count, m_primitiveRestartEnabled,
1298             *minIndex_out, *maxIndex_out);
1299 
1300     ALOGV("%s: got range [%u %u] pr? %d", __FUNCTION__, *minIndex_out, *maxIndex_out, m_primitiveRestartEnabled);
1301 }
1302 
1303 // For detecting legacy usage of glVertexAttribPointer
getVBOUsage(bool * hasClientArrays,bool * hasVBOs) const1304 void GL2Encoder::getVBOUsage(bool* hasClientArrays, bool* hasVBOs) const {
1305     if (hasClientArrays) *hasClientArrays = false;
1306     if (hasVBOs) *hasVBOs = false;
1307 
1308     m_state->getVBOUsage(hasClientArrays, hasVBOs);
1309 }
1310 
sendVertexAttributes(GLint first,GLsizei count,bool hasClientArrays,GLsizei primcount)1311 void GL2Encoder::sendVertexAttributes(GLint first, GLsizei count, bool hasClientArrays, GLsizei primcount)
1312 {
1313     assert(m_state);
1314 
1315     m_state->updateEnableDirtyArrayForDraw();
1316 
1317     GLuint lastBoundVbo = m_state->currentArrayVbo();
1318     const GLClientState::VAOState& vaoState = m_state->currentVaoState();
1319 
1320     for (int k = 0; k < vaoState.numAttributesNeedingUpdateForDraw; k++) {
1321         int i = vaoState.attributesNeedingUpdateForDraw[k];
1322 
1323         const GLClientState::VertexAttribState& state = vaoState.attribState[i];
1324 
1325         if (state.enabled) {
1326             const GLClientState::BufferBinding& curr_binding = m_state->getCurrAttributeBindingInfo(i);
1327             GLuint bufferObject = curr_binding.buffer;
1328             if (hasClientArrays && lastBoundVbo != bufferObject) {
1329                 doBindBufferEncodeCached(GL_ARRAY_BUFFER, bufferObject);
1330                 lastBoundVbo = bufferObject;
1331             }
1332 
1333             int divisor = curr_binding.divisor;
1334             int stride = curr_binding.stride;
1335             int effectiveStride = curr_binding.effectiveStride;
1336             uintptr_t offset = curr_binding.offset;
1337 
1338             int firstIndex = effectiveStride * first;
1339             if (firstIndex && divisor && !primcount) {
1340                 // If firstIndex != 0 according to effectiveStride * first,
1341                 // it needs to be adjusted if a divisor has been specified,
1342                 // even if we are not in glDraw***Instanced.
1343                 firstIndex = 0;
1344             }
1345 
1346             if (bufferObject == 0) {
1347                 unsigned int datalen = state.elementSize * count;
1348                 if (divisor) {
1349                     ALOGV("%s: divisor for att %d: %d, w/ stride %d (effective stride %d) size %d type 0x%x) datalen %u",
1350                             __FUNCTION__, i, divisor, state.stride, effectiveStride, state.elementSize, state.type, datalen);
1351                     int actual_count = std::max(1, (int)((primcount + divisor - 1) / divisor));
1352                     datalen = state.elementSize * actual_count;
1353                     ALOGV("%s: actual datalen %u", __FUNCTION__, datalen);
1354                 }
1355                 if (state.elementSize == 0) {
1356                     // The vertex attribute array is uninitialized. Abandon it.
1357                     this->m_glDisableVertexAttribArray_enc(this, i);
1358                     continue;
1359                 }
1360                 m_glEnableVertexAttribArray_enc(this, i);
1361 
1362                 if (datalen && (!offset || !((unsigned char*)offset + firstIndex))) {
1363                     continue;
1364                 }
1365 
1366                 unsigned char* data = (unsigned char*)offset + firstIndex;
1367                 if (!m_state->isAttribIndexUsedByProgram(i)) {
1368                     continue;
1369                 }
1370 
1371                 if (state.isInt) {
1372                     this->glVertexAttribIPointerDataAEMU(this, i, state.size, state.type, stride, data, datalen);
1373                 } else {
1374                     this->glVertexAttribPointerData(this, i, state.size, state.type, state.normalized, stride, data, datalen);
1375                 }
1376             } else {
1377                 const BufferData* buf = m_shared->getBufferData(bufferObject);
1378                 // The following expression actually means bufLen = stride*count;
1379                 // But the last element doesn't have to fill up the whole stride.
1380                 // So it becomes the current form.
1381                 unsigned int bufLen = effectiveStride * (count ? (count - 1) : 0) + state.elementSize;
1382                 if (divisor) {
1383                     int actual_count = std::max(1, (int)((primcount + divisor - 1) / divisor));
1384                     bufLen = effectiveStride * (actual_count ? (actual_count - 1) : 0) + state.elementSize;
1385                 }
1386                 if (buf && firstIndex >= 0 && firstIndex + bufLen <= buf->m_size) {
1387                     if (hasClientArrays) {
1388                         m_glEnableVertexAttribArray_enc(this, i);
1389                         if (firstIndex) {
1390                             if (state.isInt) {
1391                                 this->glVertexAttribIPointerOffsetAEMU(this, i, state.size, state.type, stride, offset + firstIndex);
1392                             } else {
1393                                 this->glVertexAttribPointerOffset(this, i, state.size, state.type, state.normalized, stride, offset + firstIndex);
1394                             }
1395                         }
1396                     }
1397                 } else {
1398                     if (m_state->isAttribIndexUsedByProgram(i)) {
1399                         ALOGE("a vertex attribute index out of boundary is detected. Skipping corresponding vertex attribute. buf=%p", buf);
1400                         if (buf) {
1401                             ALOGE("Out of bounds vertex attribute info: "
1402                                     "clientArray? %d attribute %d vbo %u allocedBufferSize %u bufferDataSpecified? %d wantedStart %u wantedEnd %u",
1403                                     hasClientArrays, i, bufferObject, (unsigned int)buf->m_size, buf != NULL, firstIndex, firstIndex + bufLen);
1404                         }
1405                         m_glDisableVertexAttribArray_enc(this, i);
1406                     }
1407                 }
1408             }
1409         } else {
1410             if (hasClientArrays) {
1411                 this->m_glDisableVertexAttribArray_enc(this, i);
1412             }
1413         }
1414     }
1415 
1416     if (hasClientArrays && lastBoundVbo != m_state->currentArrayVbo()) {
1417         doBindBufferEncodeCached(GL_ARRAY_BUFFER, m_state->currentArrayVbo());
1418     }
1419 }
1420 
flushDrawCall()1421 void GL2Encoder::flushDrawCall() {
1422     if (m_drawCallFlushCount % m_drawCallFlushInterval == 0) {
1423         m_stream->flush();
1424     }
1425     m_drawCallFlushCount++;
1426 }
1427 
isValidDrawMode(GLenum mode)1428 static bool isValidDrawMode(GLenum mode)
1429 {
1430     bool retval = false;
1431     switch (mode) {
1432     case GL_POINTS:
1433     case GL_LINE_STRIP:
1434     case GL_LINE_LOOP:
1435     case GL_LINES:
1436     case GL_TRIANGLE_STRIP:
1437     case GL_TRIANGLE_FAN:
1438     case GL_TRIANGLES:
1439         retval = true;
1440     }
1441     return retval;
1442 }
1443 
s_glDrawArrays(void * self,GLenum mode,GLint first,GLsizei count)1444 void GL2Encoder::s_glDrawArrays(void *self, GLenum mode, GLint first, GLsizei count)
1445 {
1446     GL2Encoder *ctx = (GL2Encoder *)self;
1447     assert(ctx->m_state != NULL);
1448     SET_ERROR_IF(!isValidDrawMode(mode), GL_INVALID_ENUM);
1449     SET_ERROR_IF(count < 0, GL_INVALID_VALUE);
1450     SET_ERROR_IF(ctx->m_state->checkFramebufferCompleteness(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE, GL_INVALID_FRAMEBUFFER_OPERATION);
1451 
1452     bool has_client_vertex_arrays = false;
1453     bool has_indirect_arrays = false;
1454     ctx->getVBOUsage(&has_client_vertex_arrays,
1455                      &has_indirect_arrays);
1456 
1457     if (has_client_vertex_arrays ||
1458         (!has_client_vertex_arrays &&
1459          !has_indirect_arrays)) {
1460         ctx->sendVertexAttributes(first, count, true);
1461         ctx->m_glDrawArrays_enc(ctx, mode, 0, count);
1462     } else {
1463         ctx->m_glDrawArrays_enc(ctx, mode, first, count);
1464     }
1465 
1466     ctx->m_state->postDraw();
1467 }
1468 
1469 
s_glDrawElements(void * self,GLenum mode,GLsizei count,GLenum type,const void * indices)1470 void GL2Encoder::s_glDrawElements(void *self, GLenum mode, GLsizei count, GLenum type, const void *indices)
1471 {
1472 
1473     GL2Encoder *ctx = (GL2Encoder *)self;
1474     assert(ctx->m_state != NULL);
1475     SET_ERROR_IF(!isValidDrawMode(mode), GL_INVALID_ENUM);
1476     SET_ERROR_IF(count < 0, GL_INVALID_VALUE);
1477     SET_ERROR_IF(!(type == GL_UNSIGNED_BYTE || type == GL_UNSIGNED_SHORT || type == GL_UNSIGNED_INT), GL_INVALID_ENUM);
1478     SET_ERROR_IF(ctx->m_state->getTransformFeedbackActiveUnpaused(), GL_INVALID_OPERATION);
1479     SET_ERROR_IF(ctx->m_state->checkFramebufferCompleteness(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE, GL_INVALID_FRAMEBUFFER_OPERATION);
1480 
1481     bool has_client_vertex_arrays = false;
1482     bool has_indirect_arrays = false;
1483     GLintptr offset = 0;
1484 
1485     ctx->getVBOUsage(&has_client_vertex_arrays, &has_indirect_arrays);
1486 
1487     if (!has_client_vertex_arrays && !has_indirect_arrays) {
1488         // ALOGW("glDrawElements: no vertex arrays / buffers bound to the command\n");
1489         GLenum status = ctx->glCheckFramebufferStatus(self, GL_FRAMEBUFFER);
1490         SET_ERROR_IF(status != GL_FRAMEBUFFER_COMPLETE, GL_INVALID_FRAMEBUFFER_OPERATION);
1491     }
1492 
1493     BufferData* buf = NULL;
1494     int minIndex = 0, maxIndex = 0;
1495 
1496     // For validation/immediate index array purposes,
1497     // we need the min/max vertex index of the index array.
1498     // If the VBO != 0, this may not be the first time we have
1499     // used this particular index buffer. getBufferIndexRange
1500     // can more quickly get min/max vertex index by
1501     // caching previous results.
1502     if (ctx->m_state->currentIndexVbo() != 0) {
1503         buf = ctx->m_shared->getBufferData(ctx->m_state->currentIndexVbo());
1504         offset = (GLintptr)indices;
1505         indices = &buf->m_fixedBuffer[offset];
1506         ctx->getBufferIndexRange(buf,
1507                                  indices,
1508                                  type,
1509                                  (size_t)count,
1510                                  (size_t)offset,
1511                                  &minIndex, &maxIndex);
1512     } else {
1513         // In this case, the |indices| field holds a real
1514         // array, so calculate the indices now. They will
1515         // also be needed to know how much data to
1516         // transfer to host.
1517         ctx->calcIndexRange(indices,
1518                             type,
1519                             count,
1520                             &minIndex,
1521                             &maxIndex);
1522     }
1523 
1524     if (count == 0) return;
1525 
1526     bool adjustIndices = true;
1527     if (ctx->m_state->currentIndexVbo() != 0) {
1528         if (!has_client_vertex_arrays) {
1529             ctx->doBindBufferEncodeCached(GL_ELEMENT_ARRAY_BUFFER, ctx->m_state->currentIndexVbo());
1530             ctx->glDrawElementsOffset(ctx, mode, count, type, offset);
1531             ctx->flushDrawCall();
1532             adjustIndices = false;
1533         } else {
1534             ctx->doBindBufferEncodeCached(GL_ELEMENT_ARRAY_BUFFER, 0);
1535         }
1536     }
1537     if (adjustIndices) {
1538         void *adjustedIndices =
1539             ctx->recenterIndices(indices,
1540                                  type,
1541                                  count,
1542                                  minIndex);
1543 
1544         if (has_indirect_arrays || 1) {
1545             ctx->sendVertexAttributes(minIndex, maxIndex - minIndex + 1, true);
1546             ctx->glDrawElementsData(ctx, mode, count, type, adjustedIndices,
1547                                     count * glSizeof(type));
1548             // XXX - OPTIMIZATION (see the other else branch) should be implemented
1549             if(!has_indirect_arrays) {
1550                 //ALOGD("unoptimized drawelements !!!\n");
1551             }
1552         } else {
1553             // we are all direct arrays and immidate mode index array -
1554             // rebuild the arrays and the index array;
1555             ALOGE("glDrawElements: direct index & direct buffer data - will be implemented in later versions;\n");
1556         }
1557     }
1558 
1559     ctx->m_state->postDraw();
1560 }
1561 
s_glDrawArraysNullAEMU(void * self,GLenum mode,GLint first,GLsizei count)1562 void GL2Encoder::s_glDrawArraysNullAEMU(void *self, GLenum mode, GLint first, GLsizei count)
1563 {
1564     GL2Encoder *ctx = (GL2Encoder *)self;
1565     assert(ctx->m_state != NULL);
1566     SET_ERROR_IF(!isValidDrawMode(mode), GL_INVALID_ENUM);
1567     SET_ERROR_IF(count < 0, GL_INVALID_VALUE);
1568     SET_ERROR_IF(ctx->m_state->checkFramebufferCompleteness(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE, GL_INVALID_FRAMEBUFFER_OPERATION);
1569 
1570     bool has_client_vertex_arrays = false;
1571     bool has_indirect_arrays = false;
1572     ctx->getVBOUsage(&has_client_vertex_arrays,
1573                      &has_indirect_arrays);
1574 
1575     if (has_client_vertex_arrays ||
1576         (!has_client_vertex_arrays &&
1577          !has_indirect_arrays)) {
1578         ctx->sendVertexAttributes(first, count, true);
1579         ctx->m_glDrawArraysNullAEMU_enc(ctx, mode, 0, count);
1580     } else {
1581         ctx->m_glDrawArraysNullAEMU_enc(ctx, mode, first, count);
1582     }
1583     ctx->flushDrawCall();
1584     ctx->m_state->postDraw();
1585 }
1586 
s_glDrawElementsNullAEMU(void * self,GLenum mode,GLsizei count,GLenum type,const void * indices)1587 void GL2Encoder::s_glDrawElementsNullAEMU(void *self, GLenum mode, GLsizei count, GLenum type, const void *indices)
1588 {
1589 
1590     GL2Encoder *ctx = (GL2Encoder *)self;
1591     assert(ctx->m_state != NULL);
1592     SET_ERROR_IF(!isValidDrawMode(mode), GL_INVALID_ENUM);
1593     SET_ERROR_IF(count < 0, GL_INVALID_VALUE);
1594     SET_ERROR_IF(!(type == GL_UNSIGNED_BYTE || type == GL_UNSIGNED_SHORT || type == GL_UNSIGNED_INT), GL_INVALID_ENUM);
1595     SET_ERROR_IF(ctx->m_state->getTransformFeedbackActiveUnpaused(), GL_INVALID_OPERATION);
1596     SET_ERROR_IF(ctx->m_state->checkFramebufferCompleteness(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE, GL_INVALID_FRAMEBUFFER_OPERATION);
1597 
1598     bool has_client_vertex_arrays = false;
1599     bool has_indirect_arrays = false;
1600     GLintptr offset = (GLintptr)indices;
1601 
1602     ctx->getVBOUsage(&has_client_vertex_arrays, &has_indirect_arrays);
1603 
1604     if (!has_client_vertex_arrays && !has_indirect_arrays) {
1605         // ALOGW("glDrawElements: no vertex arrays / buffers bound to the command\n");
1606         GLenum status = ctx->glCheckFramebufferStatus(self, GL_FRAMEBUFFER);
1607         SET_ERROR_IF(status != GL_FRAMEBUFFER_COMPLETE, GL_INVALID_FRAMEBUFFER_OPERATION);
1608     }
1609 
1610     BufferData* buf = NULL;
1611     int minIndex = 0, maxIndex = 0;
1612 
1613     // For validation/immediate index array purposes,
1614     // we need the min/max vertex index of the index array.
1615     // If the VBO != 0, this may not be the first time we have
1616     // used this particular index buffer. getBufferIndexRange
1617     // can more quickly get min/max vertex index by
1618     // caching previous results.
1619     if (ctx->m_state->currentIndexVbo() != 0) {
1620         if (!has_client_vertex_arrays && has_indirect_arrays) {
1621             // Don't do anything
1622         } else {
1623             buf = ctx->m_shared->getBufferData(ctx->m_state->currentIndexVbo());
1624             offset = (GLintptr)indices;
1625             indices = &buf->m_fixedBuffer[offset];
1626             ctx->getBufferIndexRange(buf,
1627                                      indices,
1628                                      type,
1629                                      (size_t)count,
1630                                      (size_t)offset,
1631                                      &minIndex, &maxIndex);
1632         }
1633     } else {
1634         // In this case, the |indices| field holds a real
1635         // array, so calculate the indices now. They will
1636         // also be needed to know how much data to
1637         // transfer to host.
1638         ctx->calcIndexRange(indices,
1639                             type,
1640                             count,
1641                             &minIndex,
1642                             &maxIndex);
1643     }
1644 
1645     if (count == 0) return;
1646 
1647     bool adjustIndices = true;
1648     if (ctx->m_state->currentIndexVbo() != 0) {
1649         if (!has_client_vertex_arrays) {
1650             ctx->doBindBufferEncodeCached(GL_ELEMENT_ARRAY_BUFFER, ctx->m_state->currentIndexVbo());
1651             ctx->glDrawElementsOffsetNullAEMU(ctx, mode, count, type, offset);
1652             ctx->flushDrawCall();
1653             adjustIndices = false;
1654         } else {
1655             ctx->m_glBindBuffer_enc(self, GL_ELEMENT_ARRAY_BUFFER, 0);
1656         }
1657     }
1658     if (adjustIndices) {
1659         void *adjustedIndices =
1660             ctx->recenterIndices(indices,
1661                                  type,
1662                                  count,
1663                                  minIndex);
1664 
1665         if (has_indirect_arrays || 1) {
1666             ctx->sendVertexAttributes(minIndex, maxIndex - minIndex + 1, true);
1667             ctx->glDrawElementsDataNullAEMU(ctx, mode, count, type, adjustedIndices,
1668                                     count * glSizeof(type));
1669             // XXX - OPTIMIZATION (see the other else branch) should be implemented
1670             if(!has_indirect_arrays) {
1671                 //ALOGD("unoptimized drawelements !!!\n");
1672             }
1673         } else {
1674             // we are all direct arrays and immidate mode index array -
1675             // rebuild the arrays and the index array;
1676             ALOGE("glDrawElementsNullAEMU: direct index & direct buffer data - will be implemented in later versions;\n");
1677         }
1678     }
1679     ctx->m_state->postDraw();
1680 }
1681 
getCompressedTextureFormats()1682 GLint * GL2Encoder::getCompressedTextureFormats()
1683 {
1684     if (m_compressedTextureFormats == NULL) {
1685         this->glGetIntegerv(this, GL_NUM_COMPRESSED_TEXTURE_FORMATS,
1686                             &m_num_compressedTextureFormats);
1687         if (m_num_compressedTextureFormats > 0) {
1688             // get number of texture formats;
1689             m_compressedTextureFormats = new GLint[m_num_compressedTextureFormats];
1690             this->glGetCompressedTextureFormats(this, m_num_compressedTextureFormats, m_compressedTextureFormats);
1691         }
1692     }
1693     return m_compressedTextureFormats;
1694 }
1695 
1696 // Replace uses of samplerExternalOES with sampler2D, recording the names of
1697 // modified shaders in data. Also remove
1698 //   #extension GL_OES_EGL_image_external : require
1699 //   #extension GL_OES_EGL_image_external_essl3 : require
1700 // statements.
1701 //
1702 // This implementation assumes the input has already been pre-processed. If not,
1703 // a few cases will be mishandled:
1704 //
1705 // 1. "mySampler" will be incorrectly recorded as being a samplerExternalOES in
1706 //    the following code:
1707 //      #if 1
1708 //      uniform sampler2D mySampler;
1709 //      #else
1710 //      uniform samplerExternalOES mySampler;
1711 //      #endif
1712 //
1713 // 2. Comments that look like sampler declarations will be incorrectly modified
1714 //    and recorded:
1715 //      // samplerExternalOES hahaFooledYou
1716 //
1717 // 3. However, GLSL ES does not have a concatentation operator, so things like
1718 //    this (valid in C) are invalid and not a problem:
1719 //      #define SAMPLER(TYPE, NAME) uniform sampler#TYPE NAME
1720 //      SAMPLER(ExternalOES, mySampler);
1721 //
1722 
1723 static const char STR_SAMPLER_EXTERNAL_OES[] = "samplerExternalOES";
1724 static const char STR_SAMPLER2D_SPACE[]      = "sampler2D         ";
1725 static const char STR_DEFINE[] = "#define";
1726 
getSamplerExternalAliases(char * str)1727 static std::vector<std::string> getSamplerExternalAliases(char* str) {
1728     std::vector<std::string> res;
1729 
1730     res.push_back(STR_SAMPLER_EXTERNAL_OES);
1731 
1732     // -- capture #define x samplerExternalOES
1733     char* c = str;
1734     while ((c = strstr(c, STR_DEFINE))) {
1735         // Don't push it if samplerExternalOES is not even there.
1736         char* samplerExternalOES_next = strstr(c, STR_SAMPLER_EXTERNAL_OES);
1737         if (!samplerExternalOES_next) break;
1738 
1739         bool prevIdent = false;
1740 
1741         std::vector<std::string> idents;
1742         std::string curr;
1743 
1744         while (*c != '\0') {
1745 
1746             if (isspace(*c)) {
1747                 if (prevIdent) {
1748                     idents.push_back(curr);
1749                     curr = "";
1750                 }
1751             }
1752 
1753             if (*c == '\n' || idents.size() == 3) break;
1754 
1755             if (isalpha(*c) || *c == '_') {
1756                 curr.push_back(*c);
1757                 prevIdent = true;
1758             }
1759 
1760             ++c;
1761         }
1762 
1763         if (idents.size() != 3) continue;
1764 
1765         const std::string& defineLhs = idents[1];
1766         const std::string& defineRhs = idents[2];
1767 
1768         if (defineRhs == STR_SAMPLER_EXTERNAL_OES) {
1769             res.push_back(defineLhs);
1770         }
1771 
1772         if (*c == '\0') break;
1773     }
1774 
1775     return res;
1776 }
1777 
replaceExternalSamplerUniformDefinition(char * str,const std::string & samplerExternalType,ShaderData * data)1778 static bool replaceExternalSamplerUniformDefinition(char* str, const std::string& samplerExternalType, ShaderData* data) {
1779     // -- replace "samplerExternalOES" with "sampler2D" and record name
1780     char* c = str;
1781     while ((c = strstr(c, samplerExternalType.c_str()))) {
1782         // Make sure "samplerExternalOES" isn't a substring of a larger token
1783         if (c == str || !isspace(*(c-1))) {
1784             c++;
1785             continue;
1786         }
1787         char* sampler_start = c;
1788         c += samplerExternalType.size();
1789         if (!isspace(*c) && *c != '\0' && *c != ';') {
1790             continue;
1791         } else {
1792             // capture sampler name
1793             while (isspace(*c) && *c != '\0') {
1794                 c++;
1795             }
1796         }
1797 
1798         if ((!isalpha(*c) && *c != '_') || *c == ';') {
1799             // not an identifier, but might have some effect anyway.
1800             if (samplerExternalType == STR_SAMPLER_EXTERNAL_OES) {
1801                 memcpy(sampler_start, STR_SAMPLER2D_SPACE, sizeof(STR_SAMPLER2D_SPACE)-1);
1802             }
1803         } else {
1804             char* name_start = c;
1805             do {
1806                 c++;
1807             } while (isalnum(*c) || *c == '_');
1808 
1809             size_t len = (size_t)(c - name_start);
1810             if (len) {
1811                 data->samplerExternalNames.push_back(
1812                         std::string(name_start, len));
1813             }
1814 
1815             // We only need to perform a string replacement for the original
1816             // occurrence of samplerExternalOES if a #define was used.
1817             //
1818             // The important part was to record the name in
1819             // |data->samplerExternalNames|.
1820             if (samplerExternalType == STR_SAMPLER_EXTERNAL_OES) {
1821                 memcpy(sampler_start, STR_SAMPLER2D_SPACE, sizeof(STR_SAMPLER2D_SPACE)-1);
1822             }
1823         }
1824     }
1825 
1826     return true;
1827 }
1828 
replaceSamplerExternalWith2D(char * const str,ShaderData * const data)1829 static bool replaceSamplerExternalWith2D(char* const str, ShaderData* const data)
1830 {
1831     static const char STR_HASH_EXTENSION[] = "#extension";
1832     static const char STR_GL_OES_EGL_IMAGE_EXTERNAL[] = "GL_OES_EGL_image_external";
1833     static const char STR_GL_OES_EGL_IMAGE_EXTERNAL_ESSL3[] = "GL_OES_EGL_image_external_essl3";
1834 
1835     // -- overwrite all "#extension GL_OES_EGL_image_external : xxx" statements
1836     char* c = str;
1837     while ((c = strstr(c, STR_HASH_EXTENSION))) {
1838         char* start = c;
1839         c += sizeof(STR_HASH_EXTENSION)-1;
1840         while (isspace(*c) && *c != '\0') {
1841             c++;
1842         }
1843 
1844         bool hasBaseImageExternal =
1845             !strncmp(c, STR_GL_OES_EGL_IMAGE_EXTERNAL,
1846                      sizeof(STR_GL_OES_EGL_IMAGE_EXTERNAL) - 1);
1847         bool hasEssl3ImageExternal =
1848             !strncmp(c, STR_GL_OES_EGL_IMAGE_EXTERNAL_ESSL3,
1849                      sizeof(STR_GL_OES_EGL_IMAGE_EXTERNAL_ESSL3) - 1);
1850 
1851         if (hasBaseImageExternal || hasEssl3ImageExternal)
1852         {
1853             // #extension statements are terminated by end of line
1854             c = start;
1855             while (*c != '\0' && *c != '\r' && *c != '\n') {
1856                 *c++ = ' ';
1857             }
1858         }
1859     }
1860 
1861     std::vector<std::string> samplerExternalAliases =
1862         getSamplerExternalAliases(str);
1863 
1864     for (size_t i = 0; i < samplerExternalAliases.size(); i++) {
1865         if (!replaceExternalSamplerUniformDefinition(
1866                 str, samplerExternalAliases[i], data))
1867             return false;
1868     }
1869 
1870     return true;
1871 }
1872 
s_glShaderBinary(void * self,GLsizei,const GLuint *,GLenum,const void *,GLsizei)1873 void GL2Encoder::s_glShaderBinary(void *self, GLsizei, const GLuint *, GLenum, const void*, GLsizei)
1874 {
1875     // Although it is not supported, need to set proper error code.
1876     GL2Encoder* ctx = (GL2Encoder*)self;
1877     SET_ERROR_IF(1, GL_INVALID_ENUM);
1878 }
1879 
s_glShaderSource(void * self,GLuint shader,GLsizei count,const GLchar * const * string,const GLint * length)1880 void GL2Encoder::s_glShaderSource(void *self, GLuint shader, GLsizei count, const GLchar * const *string, const GLint *length)
1881 {
1882     GL2Encoder* ctx = (GL2Encoder*)self;
1883     ShaderData* shaderData = ctx->m_shared->getShaderData(shader);
1884     SET_ERROR_IF(!ctx->m_shared->isShaderOrProgramObject(shader), GL_INVALID_VALUE);
1885     SET_ERROR_IF(!shaderData, GL_INVALID_OPERATION);
1886     SET_ERROR_IF((count<0), GL_INVALID_VALUE);
1887 
1888     // Track original sources---they may be translated in the backend
1889     std::vector<std::string> orig_sources;
1890     if (length) {
1891         for (int i = 0; i < count; i++) {
1892             // Each element in the length array may contain the length of the corresponding
1893             // string (the null character is not counted as part of the string length) or a
1894             // value less than 0 to indicate that the string is null terminated.
1895             if (length[i] >= 0) {
1896                 orig_sources.push_back(std::string((const char*)(string[i]),
1897                                                    (const char*)(string[i]) + length[i]));
1898             } else {
1899                 orig_sources.push_back(std::string((const char*)(string[i])));
1900             }
1901         }
1902     } else {
1903         for (int i = 0; i < count; i++) {
1904             orig_sources.push_back(std::string((const char*)(string[i])));
1905         }
1906     }
1907     shaderData->sources = orig_sources;
1908 
1909     int len = glUtilsCalcShaderSourceLen((char**)string, (GLint*)length, count);
1910     char *str = new char[len + 1];
1911     glUtilsPackStrings(str, (char**)string, (GLint*)length, count);
1912 
1913     // TODO: pre-process str before calling replaceSamplerExternalWith2D().
1914     // Perhaps we can borrow Mesa's pre-processor?
1915 
1916     if (!replaceSamplerExternalWith2D(str, shaderData)) {
1917         delete[] str;
1918         ctx->setError(GL_OUT_OF_MEMORY);
1919         return;
1920     }
1921     ctx->glShaderString(ctx, shader, str, len + 1);
1922     delete[] str;
1923 }
1924 
s_glFinish(void * self)1925 void GL2Encoder::s_glFinish(void *self)
1926 {
1927     GL2Encoder *ctx = (GL2Encoder *)self;
1928     ctx->glFinishRoundTrip(self);
1929 }
1930 
s_glLinkProgram(void * self,GLuint program)1931 void GL2Encoder::s_glLinkProgram(void * self, GLuint program)
1932 {
1933     GL2Encoder *ctx = (GL2Encoder *)self;
1934     bool isProgram = ctx->m_shared->isProgram(program);
1935     SET_ERROR_IF(!isProgram && !ctx->m_shared->isShader(program), GL_INVALID_VALUE);
1936     SET_ERROR_IF(!isProgram, GL_INVALID_OPERATION);
1937 
1938     if (program == ctx->m_state->currentProgram() ||
1939         (!ctx->m_state->currentProgram() &&
1940          (program == ctx->m_state->currentShaderProgram()))) {
1941         SET_ERROR_IF(ctx->m_state->getTransformFeedbackActive(), GL_INVALID_OPERATION);
1942     }
1943 
1944     ctx->m_glLinkProgram_enc(self, program);
1945 
1946     GLint linkStatus = 0;
1947     ctx->m_glGetProgramiv_enc(self, program, GL_LINK_STATUS, &linkStatus);
1948     ctx->m_shared->setProgramLinkStatus(program, linkStatus);
1949     if (!linkStatus) {
1950         return;
1951     }
1952 
1953     // get number of active uniforms and attributes in the program
1954     GLint numUniforms=0;
1955     GLint numAttributes=0;
1956     ctx->m_glGetProgramiv_enc(self, program, GL_ACTIVE_UNIFORMS, &numUniforms);
1957     ctx->m_glGetProgramiv_enc(self, program, GL_ACTIVE_ATTRIBUTES, &numAttributes);
1958     ctx->m_shared->initProgramData(program,numUniforms,numAttributes);
1959 
1960     //get the length of the longest uniform name
1961     GLint maxLength=0;
1962     GLint maxAttribLength=0;
1963     ctx->m_glGetProgramiv_enc(self, program, GL_ACTIVE_UNIFORM_MAX_LENGTH, &maxLength);
1964     ctx->m_glGetProgramiv_enc(self, program, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &maxAttribLength);
1965 
1966     GLint size;
1967     GLenum type;
1968     size_t bufLen = maxLength > maxAttribLength ? maxLength : maxAttribLength;
1969     GLchar *name = new GLchar[bufLen + 1];
1970     GLint location;
1971     //for each active uniform, get its size and starting location.
1972     for (GLint i=0 ; i<numUniforms ; ++i)
1973     {
1974         ctx->m_glGetActiveUniform_enc(self, program, i, maxLength, NULL, &size, &type, name);
1975         location = ctx->m_glGetUniformLocation_enc(self, program, name);
1976         ctx->m_shared->setProgramIndexInfo(program, i, location, size, type, name);
1977     }
1978 
1979     for (GLint i = 0; i < numAttributes; ++i) {
1980         ctx->m_glGetActiveAttrib_enc(self, program, i, maxAttribLength,  NULL, &size, &type, name);
1981         location = ctx->m_glGetAttribLocation_enc(self, program, name);
1982         ctx->m_shared->setProgramAttribInfo(program, i, location, size, type, name);
1983     }
1984 
1985     if (ctx->majorVersion() > 2) {
1986         GLint numBlocks;
1987         ctx->m_glGetProgramiv_enc(ctx, program, GL_ACTIVE_UNIFORM_BLOCKS, &numBlocks);
1988         ctx->m_shared->setActiveUniformBlockCountForProgram(program, numBlocks);
1989 
1990         GLint tfVaryingsCount;
1991         ctx->m_glGetProgramiv_enc(ctx, program, GL_TRANSFORM_FEEDBACK_VARYINGS, &tfVaryingsCount);
1992         ctx->m_shared->setTransformFeedbackVaryingsCountForProgram(program, tfVaryingsCount);
1993     }
1994 
1995     delete[] name;
1996 }
1997 
1998 #define VALIDATE_PROGRAM_NAME(program) \
1999     bool isShaderOrProgramObject = \
2000         ctx->m_shared->isShaderOrProgramObject(program); \
2001     bool isProgram = \
2002         ctx->m_shared->isProgram(program); \
2003     SET_ERROR_IF(!isShaderOrProgramObject, GL_INVALID_VALUE); \
2004     SET_ERROR_IF(!isProgram, GL_INVALID_OPERATION); \
2005 
2006 #define VALIDATE_PROGRAM_NAME_RET(program, ret) \
2007     bool isShaderOrProgramObject = \
2008         ctx->m_shared->isShaderOrProgramObject(program); \
2009     bool isProgram = \
2010         ctx->m_shared->isProgram(program); \
2011     RET_AND_SET_ERROR_IF(!isShaderOrProgramObject, GL_INVALID_VALUE, ret); \
2012     RET_AND_SET_ERROR_IF(!isProgram, GL_INVALID_OPERATION, ret); \
2013 
2014 #define VALIDATE_SHADER_NAME(shader) \
2015     bool isShaderOrProgramObject = \
2016         ctx->m_shared->isShaderOrProgramObject(shader); \
2017     bool isShader = \
2018         ctx->m_shared->isShader(shader); \
2019     SET_ERROR_IF(!isShaderOrProgramObject, GL_INVALID_VALUE); \
2020     SET_ERROR_IF(!isShader, GL_INVALID_OPERATION); \
2021 
s_glDeleteProgram(void * self,GLuint program)2022 void GL2Encoder::s_glDeleteProgram(void *self, GLuint program)
2023 {
2024     GL2Encoder *ctx = (GL2Encoder*)self;
2025 
2026     VALIDATE_PROGRAM_NAME(program);
2027 
2028     ctx->m_glDeleteProgram_enc(self, program);
2029 
2030     ctx->m_shared->deleteProgramData(program);
2031 }
2032 
s_glGetUniformiv(void * self,GLuint program,GLint location,GLint * params)2033 void GL2Encoder::s_glGetUniformiv(void *self, GLuint program, GLint location, GLint* params)
2034 {
2035     GL2Encoder *ctx = (GL2Encoder*)self;
2036     SET_ERROR_IF(!ctx->m_shared->isShaderOrProgramObject(program), GL_INVALID_VALUE);
2037     SET_ERROR_IF(!ctx->m_shared->isProgram(program), GL_INVALID_OPERATION);
2038     SET_ERROR_IF(!ctx->m_shared->isProgramInitialized(program), GL_INVALID_OPERATION);
2039     SET_ERROR_IF(ctx->m_shared->getProgramUniformType(program,location)==0, GL_INVALID_OPERATION);
2040     SET_ERROR_IF(!ctx->m_shared->isProgramUniformLocationValid(program,location), GL_INVALID_OPERATION);
2041     ctx->m_glGetUniformiv_enc(self, program, location, params);
2042 }
s_glGetUniformfv(void * self,GLuint program,GLint location,GLfloat * params)2043 void GL2Encoder::s_glGetUniformfv(void *self, GLuint program, GLint location, GLfloat* params)
2044 {
2045     GL2Encoder *ctx = (GL2Encoder*)self;
2046     SET_ERROR_IF(!ctx->m_shared->isShaderOrProgramObject(program), GL_INVALID_VALUE);
2047     SET_ERROR_IF(!ctx->m_shared->isProgram(program), GL_INVALID_OPERATION);
2048     SET_ERROR_IF(!ctx->m_shared->isProgramInitialized(program), GL_INVALID_OPERATION);
2049     SET_ERROR_IF(ctx->m_shared->getProgramUniformType(program,location)==0, GL_INVALID_OPERATION);
2050     SET_ERROR_IF(!ctx->m_shared->isProgramUniformLocationValid(program,location), GL_INVALID_OPERATION);
2051     ctx->m_glGetUniformfv_enc(self, program, location, params);
2052 }
2053 
s_glCreateProgram(void * self)2054 GLuint GL2Encoder::s_glCreateProgram(void * self)
2055 {
2056     GL2Encoder *ctx = (GL2Encoder*)self;
2057     GLuint program = ctx->m_glCreateProgram_enc(self);
2058     if (program!=0)
2059         ctx->m_shared->addProgramData(program);
2060     return program;
2061 }
2062 
s_glCreateShader(void * self,GLenum shaderType)2063 GLuint GL2Encoder::s_glCreateShader(void *self, GLenum shaderType)
2064 {
2065     GL2Encoder *ctx = (GL2Encoder*)self;
2066     RET_AND_SET_ERROR_IF(!GLESv2Validation::shaderType(ctx, shaderType), GL_INVALID_ENUM, 0);
2067     GLuint shader = ctx->m_glCreateShader_enc(self, shaderType);
2068     if (shader != 0) {
2069         if (!ctx->m_shared->addShaderData(shader, shaderType)) {
2070             ctx->m_glDeleteShader_enc(self, shader);
2071             return 0;
2072         }
2073     }
2074     return shader;
2075 }
2076 
s_glGetAttachedShaders(void * self,GLuint program,GLsizei maxCount,GLsizei * count,GLuint * shaders)2077 void GL2Encoder::s_glGetAttachedShaders(void *self, GLuint program, GLsizei maxCount,
2078         GLsizei* count, GLuint* shaders)
2079 {
2080     GL2Encoder *ctx = (GL2Encoder*)self;
2081     VALIDATE_PROGRAM_NAME(program);
2082     SET_ERROR_IF(maxCount < 0, GL_INVALID_VALUE);
2083     ctx->m_glGetAttachedShaders_enc(self, program, maxCount, count, shaders);
2084 }
2085 
s_glGetShaderSource(void * self,GLuint shader,GLsizei bufsize,GLsizei * length,GLchar * source)2086 void GL2Encoder::s_glGetShaderSource(void *self, GLuint shader, GLsizei bufsize,
2087             GLsizei* length, GLchar* source)
2088 {
2089     GL2Encoder *ctx = (GL2Encoder*)self;
2090     VALIDATE_SHADER_NAME(shader);
2091     SET_ERROR_IF(bufsize < 0, GL_INVALID_VALUE);
2092     ctx->m_glGetShaderSource_enc(self, shader, bufsize, length, source);
2093     ShaderData* shaderData = ctx->m_shared->getShaderData(shader);
2094     if (shaderData) {
2095         std::string returned;
2096         int curr_len = 0;
2097         for (int i = 0; i < shaderData->sources.size(); i++) {
2098             if (curr_len + shaderData->sources[i].size() < bufsize - 1) {
2099                 returned += shaderData->sources[i];
2100             } else {
2101                 returned += shaderData->sources[i].substr(0, bufsize - 1 - curr_len);
2102                 break;
2103             }
2104         }
2105         std::string ret = returned.substr(0, bufsize - 1);
2106 
2107         size_t toCopy = bufsize < (ret.size() + 1) ? bufsize : ret.size() + 1;
2108         memcpy(source, ret.c_str(), toCopy);
2109     }
2110 }
2111 
s_glGetShaderInfoLog(void * self,GLuint shader,GLsizei bufsize,GLsizei * length,GLchar * infolog)2112 void GL2Encoder::s_glGetShaderInfoLog(void *self, GLuint shader, GLsizei bufsize,
2113         GLsizei* length, GLchar* infolog)
2114 {
2115     GL2Encoder *ctx = (GL2Encoder*)self;
2116     VALIDATE_SHADER_NAME(shader);
2117     SET_ERROR_IF(bufsize < 0, GL_INVALID_VALUE);
2118     ctx->m_glGetShaderInfoLog_enc(self, shader, bufsize, length, infolog);
2119 }
2120 
s_glGetProgramInfoLog(void * self,GLuint program,GLsizei bufsize,GLsizei * length,GLchar * infolog)2121 void GL2Encoder::s_glGetProgramInfoLog(void *self, GLuint program, GLsizei bufsize,
2122         GLsizei* length, GLchar* infolog)
2123 {
2124     GL2Encoder *ctx = (GL2Encoder*)self;
2125     VALIDATE_PROGRAM_NAME(program);
2126     SET_ERROR_IF(bufsize < 0, GL_INVALID_VALUE);
2127     ctx->m_glGetProgramInfoLog_enc(self, program, bufsize, length, infolog);
2128 }
2129 
s_glDeleteShader(void * self,GLenum shader)2130 void GL2Encoder::s_glDeleteShader(void *self, GLenum shader)
2131 {
2132     GL2Encoder *ctx = (GL2Encoder*)self;
2133 
2134     bool isShaderOrProgramObject =
2135         ctx->m_shared->isShaderOrProgramObject(shader);
2136     bool isShader =
2137         ctx->m_shared->isShader(shader);
2138 
2139     SET_ERROR_IF(isShaderOrProgramObject && !isShader, GL_INVALID_OPERATION);
2140     SET_ERROR_IF(!isShaderOrProgramObject && !isShader, GL_INVALID_VALUE);
2141 
2142     ctx->m_glDeleteShader_enc(self,shader);
2143     ctx->m_shared->unrefShaderData(shader);
2144 }
2145 
s_glAttachShader(void * self,GLuint program,GLuint shader)2146 void GL2Encoder::s_glAttachShader(void *self, GLuint program, GLuint shader)
2147 {
2148     GL2Encoder *ctx = (GL2Encoder*)self;
2149     bool programIsShaderOrProgram = ctx->m_shared->isShaderOrProgramObject(program);
2150     bool programIsProgram = ctx->m_shared->isProgram(program);
2151     bool shaderIsShaderOrProgram = ctx->m_shared->isShaderOrProgramObject(shader);
2152     bool shaderIsShader = ctx->m_shared->isShader(shader);
2153 
2154     SET_ERROR_IF(!programIsShaderOrProgram, GL_INVALID_VALUE);
2155     SET_ERROR_IF(!shaderIsShaderOrProgram, GL_INVALID_VALUE);
2156     SET_ERROR_IF(!programIsProgram, GL_INVALID_OPERATION);
2157     SET_ERROR_IF(!shaderIsShader, GL_INVALID_OPERATION);
2158     SET_ERROR_IF(!ctx->m_shared->attachShader(program, shader), GL_INVALID_OPERATION);
2159 
2160     ctx->m_glAttachShader_enc(self, program, shader);
2161 }
2162 
s_glDetachShader(void * self,GLuint program,GLuint shader)2163 void GL2Encoder::s_glDetachShader(void *self, GLuint program, GLuint shader)
2164 {
2165     GL2Encoder *ctx = (GL2Encoder*)self;
2166 
2167     bool programIsShaderOrProgram = ctx->m_shared->isShaderOrProgramObject(program);
2168     bool programIsProgram = ctx->m_shared->isProgram(program);
2169     bool shaderIsShaderOrProgram = ctx->m_shared->isShaderOrProgramObject(shader);
2170     bool shaderIsShader = ctx->m_shared->isShader(shader);
2171 
2172     SET_ERROR_IF(!programIsShaderOrProgram, GL_INVALID_VALUE);
2173     SET_ERROR_IF(!shaderIsShaderOrProgram, GL_INVALID_VALUE);
2174     SET_ERROR_IF(!programIsProgram, GL_INVALID_OPERATION);
2175     SET_ERROR_IF(!shaderIsShader, GL_INVALID_OPERATION);
2176     SET_ERROR_IF(!ctx->m_shared->detachShader(program, shader), GL_INVALID_OPERATION);
2177 
2178     ctx->m_glDetachShader_enc(self, program, shader);
2179 }
2180 
sArrIndexOfUniformExpr(const char * name,int * err)2181 int sArrIndexOfUniformExpr(const char* name, int* err) {
2182     *err = 0;
2183     int arrIndex = 0;
2184     int namelen = strlen(name);
2185     if (name[namelen-1] == ']') {
2186         const char *brace = strrchr(name,'[');
2187         if (!brace || sscanf(brace+1,"%d",&arrIndex) != 1) {
2188             *err = 1; return 0;
2189         }
2190     }
2191     return arrIndex;
2192 }
2193 
s_glGetUniformLocation(void * self,GLuint program,const GLchar * name)2194 int GL2Encoder::s_glGetUniformLocation(void *self, GLuint program, const GLchar *name)
2195 {
2196     if (!name) return -1;
2197     GL2Encoder *ctx = (GL2Encoder*)self;
2198 
2199     bool isShaderOrProgramObject =
2200         ctx->m_shared->isShaderOrProgramObject(program);
2201     bool isProgram =
2202         ctx->m_shared->isProgram(program);
2203 
2204     RET_AND_SET_ERROR_IF(!isShaderOrProgramObject, GL_INVALID_VALUE, -1);
2205     RET_AND_SET_ERROR_IF(!isProgram, GL_INVALID_OPERATION, -1);
2206     RET_AND_SET_ERROR_IF(!ctx->m_shared->getProgramLinkStatus(program), GL_INVALID_OPERATION, -1);
2207 
2208     return ctx->m_glGetUniformLocation_enc(self, program, name);
2209 }
2210 
updateHostTexture2DBinding(GLenum texUnit,GLenum newTarget)2211 bool GL2Encoder::updateHostTexture2DBinding(GLenum texUnit, GLenum newTarget)
2212 {
2213     if (newTarget != GL_TEXTURE_2D && newTarget != GL_TEXTURE_EXTERNAL_OES)
2214         return false;
2215 
2216     m_state->setActiveTextureUnit(texUnit);
2217 
2218     GLenum oldTarget = m_state->getPriorityEnabledTarget(GL_TEXTURE_2D);
2219     if (newTarget != oldTarget) {
2220         if (newTarget == GL_TEXTURE_EXTERNAL_OES) {
2221             m_state->disableTextureTarget(GL_TEXTURE_2D);
2222             m_state->enableTextureTarget(GL_TEXTURE_EXTERNAL_OES);
2223         } else {
2224             m_state->disableTextureTarget(GL_TEXTURE_EXTERNAL_OES);
2225             m_state->enableTextureTarget(GL_TEXTURE_2D);
2226         }
2227         m_glActiveTexture_enc(this, texUnit);
2228         m_glBindTexture_enc(this, GL_TEXTURE_2D,
2229                 m_state->getBoundTexture(newTarget));
2230         return true;
2231     }
2232 
2233     return false;
2234 }
2235 
updateHostTexture2DBindingsFromProgramData(GLuint program)2236 void GL2Encoder::updateHostTexture2DBindingsFromProgramData(GLuint program) {
2237     GL2Encoder *ctx = this;
2238     GLClientState* state = ctx->m_state;
2239     GLSharedGroupPtr shared = ctx->m_shared;
2240 
2241     GLenum origActiveTexture = state->getActiveTextureUnit();
2242     GLenum hostActiveTexture = origActiveTexture;
2243     GLint samplerIdx = -1;
2244     GLint samplerVal;
2245     GLenum samplerTarget;
2246     while ((samplerIdx = shared->getNextSamplerUniform(program, samplerIdx, &samplerVal, &samplerTarget)) != -1) {
2247         if (samplerVal < 0 || samplerVal >= GLClientState::MAX_TEXTURE_UNITS)
2248             continue;
2249         if (ctx->updateHostTexture2DBinding(GL_TEXTURE0 + samplerVal,
2250                     samplerTarget))
2251         {
2252             hostActiveTexture = GL_TEXTURE0 + samplerVal;
2253         }
2254     }
2255     state->setActiveTextureUnit(origActiveTexture);
2256     if (hostActiveTexture != origActiveTexture) {
2257         ctx->m_glActiveTexture_enc(ctx, origActiveTexture);
2258     }
2259 }
2260 
s_glUseProgram(void * self,GLuint program)2261 void GL2Encoder::s_glUseProgram(void *self, GLuint program)
2262 {
2263     GL2Encoder *ctx = (GL2Encoder*)self;
2264     GLSharedGroupPtr shared = ctx->m_shared;
2265 
2266     SET_ERROR_IF(program && !shared->isShaderOrProgramObject(program), GL_INVALID_VALUE);
2267     SET_ERROR_IF(program && !shared->isProgram(program), GL_INVALID_OPERATION);
2268     SET_ERROR_IF(ctx->m_state->getTransformFeedbackActiveUnpaused(), GL_INVALID_OPERATION);
2269 
2270     ctx->m_glUseProgram_enc(self, program);
2271 
2272     GLuint currProgram = ctx->m_state->currentProgram();
2273     ctx->m_shared->onUseProgram(currProgram, program);
2274 
2275     ctx->m_state->setCurrentProgram(program);
2276     ctx->m_state->setCurrentShaderProgram(program);
2277     ctx->updateHostTexture2DBindingsFromProgramData(program);
2278 
2279     if (program) {
2280         ctx->m_state->currentUniformValidationInfo = ctx->m_shared->getUniformValidationInfo(program);
2281         ctx->m_state->currentAttribValidationInfo = ctx->m_shared->getAttribValidationInfo(program);
2282     }
2283 }
2284 
s_glUniform1f(void * self,GLint location,GLfloat x)2285 void GL2Encoder::s_glUniform1f(void *self , GLint location, GLfloat x)
2286 {
2287     GL2Encoder *ctx = (GL2Encoder*)self;
2288     ctx->m_state->validateUniform(true /* is float? */, false /* is unsigned? */, 1 /* columns */, 1 /* rows */, location, 1 /* count */, ctx->getErrorPtr());
2289     ctx->m_glUniform1f_enc(self, location, x);
2290 }
2291 
s_glUniform1fv(void * self,GLint location,GLsizei count,const GLfloat * v)2292 void GL2Encoder::s_glUniform1fv(void *self , GLint location, GLsizei count, const GLfloat* v)
2293 {
2294     GL2Encoder *ctx = (GL2Encoder*)self;
2295     ctx->m_state->validateUniform(true /* is float? */, false /* is unsigned? */, 1 /* columns */, 1 /* rows */, location, count /* count */, ctx->getErrorPtr());
2296     ctx->m_glUniform1fv_enc(self, location, count, v);
2297 }
2298 
s_glUniform1i(void * self,GLint location,GLint x)2299 void GL2Encoder::s_glUniform1i(void *self , GLint location, GLint x)
2300 {
2301     GL2Encoder *ctx = (GL2Encoder*)self;
2302     GLClientState* state = ctx->m_state;
2303     GLSharedGroupPtr shared = ctx->m_shared;
2304 
2305     ctx->m_state->validateUniform(false /* is float? */, false /* is unsigned? */, 1 /* columns */, 1 /* rows */, location, 1 /* count */, ctx->getErrorPtr());
2306 
2307     ctx->m_glUniform1i_enc(self, location, x);
2308 
2309     GLenum target;
2310     if (shared->setSamplerUniform(state->currentShaderProgram(), location, x, &target)) {
2311         GLenum origActiveTexture = state->getActiveTextureUnit();
2312         if (ctx->updateHostTexture2DBinding(GL_TEXTURE0 + x, target)) {
2313             ctx->m_glActiveTexture_enc(self, origActiveTexture);
2314         }
2315         state->setActiveTextureUnit(origActiveTexture);
2316     }
2317 }
2318 
s_glUniform1iv(void * self,GLint location,GLsizei count,const GLint * v)2319 void GL2Encoder::s_glUniform1iv(void *self , GLint location, GLsizei count, const GLint* v)
2320 {
2321     GL2Encoder *ctx = (GL2Encoder*)self;
2322     ctx->m_state->validateUniform(false /* is float? */, false /* is unsigned? */, 1 /* columns */, 1 /* rows */, location, count /* count */, ctx->getErrorPtr());
2323     ctx->m_glUniform1iv_enc(self, location, count, v);
2324 }
2325 
s_glUniform2f(void * self,GLint location,GLfloat x,GLfloat y)2326 void GL2Encoder::s_glUniform2f(void *self , GLint location, GLfloat x, GLfloat y)
2327 {
2328     GL2Encoder *ctx = (GL2Encoder*)self;
2329     ctx->m_state->validateUniform(true /* is float? */, false /* is unsigned? */, 2 /* columns */, 1 /* rows */, location, 1 /* count */, ctx->getErrorPtr());
2330     ctx->m_glUniform2f_enc(self, location, x, y);
2331 }
2332 
s_glUniform2fv(void * self,GLint location,GLsizei count,const GLfloat * v)2333 void GL2Encoder::s_glUniform2fv(void *self , GLint location, GLsizei count, const GLfloat* v)
2334 {
2335     GL2Encoder *ctx = (GL2Encoder*)self;
2336     ctx->m_state->validateUniform(true /* is float? */, false /* is unsigned? */, 2 /* columns */, 1 /* rows */, location, count /* count */, ctx->getErrorPtr());
2337     ctx->m_glUniform2fv_enc(self, location, count, v);
2338 }
2339 
s_glUniform2i(void * self,GLint location,GLint x,GLint y)2340 void GL2Encoder::s_glUniform2i(void *self , GLint location, GLint x, GLint y)
2341 {
2342     GL2Encoder *ctx = (GL2Encoder*)self;
2343     ctx->m_state->validateUniform(false /* is float? */, false /* is unsigned? */, 2 /* columns */, 1 /* rows */, location, 1 /* count */, ctx->getErrorPtr());
2344     ctx->m_glUniform2i_enc(self, location, x, y);
2345 }
2346 
s_glUniform2iv(void * self,GLint location,GLsizei count,const GLint * v)2347 void GL2Encoder::s_glUniform2iv(void *self , GLint location, GLsizei count, const GLint* v)
2348 {
2349     GL2Encoder *ctx = (GL2Encoder*)self;
2350     ctx->m_state->validateUniform(false /* is float? */, false /* is unsigned? */, 2 /* columns */, 1 /* rows */, location, count /* count */, ctx->getErrorPtr());
2351     ctx->m_glUniform2iv_enc(self, location, count, v);
2352 }
2353 
s_glUniform3f(void * self,GLint location,GLfloat x,GLfloat y,GLfloat z)2354 void GL2Encoder::s_glUniform3f(void *self , GLint location, GLfloat x, GLfloat y, GLfloat z)
2355 {
2356     GL2Encoder *ctx = (GL2Encoder*)self;
2357     ctx->m_state->validateUniform(true /* is float? */, false /* is unsigned? */, 3 /* columns */, 1 /* rows */, location, 1 /* count */, ctx->getErrorPtr());
2358     ctx->m_glUniform3f_enc(self, location, x, y, z);
2359 }
2360 
s_glUniform3fv(void * self,GLint location,GLsizei count,const GLfloat * v)2361 void GL2Encoder::s_glUniform3fv(void *self , GLint location, GLsizei count, const GLfloat* v)
2362 {
2363     GL2Encoder *ctx = (GL2Encoder*)self;
2364     ctx->m_state->validateUniform(true /* is float? */, false /* is unsigned? */, 3 /* columns */, 1 /* rows */, location, count /* count */, ctx->getErrorPtr());
2365     ctx->m_glUniform3fv_enc(self, location, count, v);
2366 }
2367 
s_glUniform3i(void * self,GLint location,GLint x,GLint y,GLint z)2368 void GL2Encoder::s_glUniform3i(void *self , GLint location, GLint x, GLint y, GLint z)
2369 {
2370     GL2Encoder *ctx = (GL2Encoder*)self;
2371     ctx->m_state->validateUniform(false /* is float? */, false /* is unsigned? */, 3 /* columns */, 1 /* rows */, location, 1 /* count */, ctx->getErrorPtr());
2372     ctx->m_glUniform3i_enc(self, location, x, y, z);
2373 }
2374 
s_glUniform3iv(void * self,GLint location,GLsizei count,const GLint * v)2375 void GL2Encoder::s_glUniform3iv(void *self , GLint location, GLsizei count, const GLint* v)
2376 {
2377     GL2Encoder *ctx = (GL2Encoder*)self;
2378     ctx->m_state->validateUniform(false /* is float? */, false /* is unsigned? */, 3 /* columns */, 1 /* rows */, location, count /* count */, ctx->getErrorPtr());
2379     ctx->m_glUniform3iv_enc(self, location, count, v);
2380 }
2381 
s_glUniform4f(void * self,GLint location,GLfloat x,GLfloat y,GLfloat z,GLfloat w)2382 void GL2Encoder::s_glUniform4f(void *self , GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
2383 {
2384     GL2Encoder *ctx = (GL2Encoder*)self;
2385     ctx->m_state->validateUniform(true /* is float? */, false /* is unsigned? */, 4 /* columns */, 1 /* rows */, location, 1 /* count */, ctx->getErrorPtr());
2386     ctx->m_glUniform4f_enc(self, location, x, y, z, w);
2387 }
2388 
s_glUniform4fv(void * self,GLint location,GLsizei count,const GLfloat * v)2389 void GL2Encoder::s_glUniform4fv(void *self , GLint location, GLsizei count, const GLfloat* v)
2390 {
2391     GL2Encoder *ctx = (GL2Encoder*)self;
2392     ctx->m_state->validateUniform(true /* is float? */, false /* is unsigned? */, 4 /* columns */, 1 /* rows */, location, count /* count */, ctx->getErrorPtr());
2393     ctx->m_glUniform4fv_enc(self, location, count, v);
2394 }
2395 
s_glUniform4i(void * self,GLint location,GLint x,GLint y,GLint z,GLint w)2396 void GL2Encoder::s_glUniform4i(void *self , GLint location, GLint x, GLint y, GLint z, GLint w)
2397 {
2398     GL2Encoder *ctx = (GL2Encoder*)self;
2399     ctx->m_state->validateUniform(false /* is float? */, false /* is unsigned? */, 4 /* columns */, 1 /* rows */, location, 1 /* count */, ctx->getErrorPtr());
2400     ctx->m_glUniform4i_enc(self, location, x, y, z, w);
2401 }
2402 
s_glUniform4iv(void * self,GLint location,GLsizei count,const GLint * v)2403 void GL2Encoder::s_glUniform4iv(void *self , GLint location, GLsizei count, const GLint* v)
2404 {
2405     GL2Encoder *ctx = (GL2Encoder*)self;
2406     ctx->m_state->validateUniform(false /* is float? */, false /* is unsigned? */, 4 /* columns */, 1 /* rows */, location, count /* count */, ctx->getErrorPtr());
2407     ctx->m_glUniform4iv_enc(self, location, count, v);
2408 }
2409 
s_glUniformMatrix2fv(void * self,GLint location,GLsizei count,GLboolean transpose,const GLfloat * value)2410 void GL2Encoder::s_glUniformMatrix2fv(void *self , GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
2411 {
2412     GL2Encoder *ctx = (GL2Encoder*)self;
2413     ctx->m_state->validateUniform(true /* is float? */, false /* is unsigned? */, 2 /* columns */, 2 /* rows */, location, count /* count */, ctx->getErrorPtr());
2414     ctx->m_glUniformMatrix2fv_enc(self, location, count, transpose, value);
2415 }
2416 
s_glUniformMatrix3fv(void * self,GLint location,GLsizei count,GLboolean transpose,const GLfloat * value)2417 void GL2Encoder::s_glUniformMatrix3fv(void *self , GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
2418 {
2419     GL2Encoder *ctx = (GL2Encoder*)self;
2420     ctx->m_state->validateUniform(true /* is float? */, false /* is unsigned? */, 3 /* columns */, 3 /* rows */, location, count /* count */, ctx->getErrorPtr());
2421     ctx->m_glUniformMatrix3fv_enc(self, location, count, transpose, value);
2422 }
2423 
s_glUniformMatrix4fv(void * self,GLint location,GLsizei count,GLboolean transpose,const GLfloat * value)2424 void GL2Encoder::s_glUniformMatrix4fv(void *self , GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
2425 {
2426     GL2Encoder *ctx = (GL2Encoder*)self;
2427     ctx->m_state->validateUniform(true /* is float? */, false /* is unsigned? */, 4 /* columns */, 4 /* rows */, location, count /* count */, ctx->getErrorPtr());
2428     ctx->m_glUniformMatrix4fv_enc(self, location, count, transpose, value);
2429 }
2430 
s_glActiveTexture(void * self,GLenum texture)2431 void GL2Encoder::s_glActiveTexture(void* self, GLenum texture)
2432 {
2433     GL2Encoder* ctx = (GL2Encoder*)self;
2434     GLClientState* state = ctx->m_state;
2435     GLenum err;
2436 
2437     GLint maxCombinedUnits;
2438     ctx->glGetIntegerv(ctx, GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &maxCombinedUnits);
2439 
2440     SET_ERROR_IF(texture - GL_TEXTURE0 > maxCombinedUnits - 1, GL_INVALID_ENUM);
2441     SET_ERROR_IF((err = state->setActiveTextureUnit(texture)) != GL_NO_ERROR, err);
2442 
2443     ctx->m_glActiveTexture_enc(ctx, texture);
2444 }
2445 
s_glBindTexture(void * self,GLenum target,GLuint texture)2446 void GL2Encoder::s_glBindTexture(void* self, GLenum target, GLuint texture)
2447 {
2448     GL2Encoder* ctx = (GL2Encoder*)self;
2449     GLClientState* state = ctx->m_state;
2450     GLenum err;
2451     GLboolean firstUse;
2452 
2453     SET_ERROR_IF(!GLESv2Validation::textureTarget(ctx, target), GL_INVALID_ENUM);
2454     SET_ERROR_IF((err = state->bindTexture(target, texture, &firstUse)) != GL_NO_ERROR, err);
2455 
2456     if (target != GL_TEXTURE_2D && target != GL_TEXTURE_EXTERNAL_OES) {
2457         ctx->m_glBindTexture_enc(ctx, target, texture);
2458         return;
2459     }
2460 
2461     GLenum priorityTarget = state->getPriorityEnabledTarget(GL_TEXTURE_2D);
2462 
2463     if (target == GL_TEXTURE_EXTERNAL_OES && firstUse) {
2464         ctx->m_glBindTexture_enc(ctx, GL_TEXTURE_2D, texture);
2465         ctx->m_glTexParameteri_enc(ctx, GL_TEXTURE_2D,
2466                 GL_TEXTURE_MIN_FILTER, GL_LINEAR);
2467         ctx->m_glTexParameteri_enc(ctx, GL_TEXTURE_2D,
2468                 GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
2469         ctx->m_glTexParameteri_enc(ctx, GL_TEXTURE_2D,
2470                 GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
2471 
2472         if (target != priorityTarget) {
2473             ctx->m_glBindTexture_enc(ctx, GL_TEXTURE_2D,
2474                     state->getBoundTexture(GL_TEXTURE_2D));
2475         }
2476     }
2477 
2478     if (target == priorityTarget) {
2479         ctx->m_glBindTexture_enc(ctx, GL_TEXTURE_2D, texture);
2480     }
2481 }
2482 
s_glDeleteTextures(void * self,GLsizei n,const GLuint * textures)2483 void GL2Encoder::s_glDeleteTextures(void* self, GLsizei n, const GLuint* textures)
2484 {
2485     GL2Encoder* ctx = (GL2Encoder*)self;
2486     GLClientState* state = ctx->m_state;
2487 
2488     state->deleteTextures(n, textures);
2489     ctx->m_glDeleteTextures_enc(ctx, n, textures);
2490 }
2491 
s_glGetTexParameterfv(void * self,GLenum target,GLenum pname,GLfloat * params)2492 void GL2Encoder::s_glGetTexParameterfv(void* self,
2493         GLenum target, GLenum pname, GLfloat* params)
2494 {
2495     GL2Encoder* ctx = (GL2Encoder*)self;
2496 
2497     SET_ERROR_IF(!GLESv2Validation::textureTarget(ctx, target), GL_INVALID_ENUM);
2498     SET_ERROR_IF(!GLESv2Validation::textureParams(ctx, pname), GL_INVALID_ENUM);
2499     if (!params) return;
2500 
2501     if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
2502         ctx->override2DTextureTarget(target);
2503         ctx->m_glGetTexParameterfv_enc(ctx, GL_TEXTURE_2D, pname, params);
2504         ctx->restore2DTextureTarget(target);
2505     } else {
2506         ctx->m_glGetTexParameterfv_enc(ctx, target, pname, params);
2507     }
2508 }
2509 
s_glGetTexParameteriv(void * self,GLenum target,GLenum pname,GLint * params)2510 void GL2Encoder::s_glGetTexParameteriv(void* self,
2511         GLenum target, GLenum pname, GLint* params)
2512 {
2513     GL2Encoder* ctx = (GL2Encoder*)self;
2514 
2515     SET_ERROR_IF(!GLESv2Validation::textureTarget(ctx, target), GL_INVALID_ENUM);
2516     SET_ERROR_IF(!GLESv2Validation::textureParams(ctx, pname), GL_INVALID_ENUM);
2517 
2518     if (!params) return;
2519 
2520     switch (pname) {
2521     case GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES:
2522         *params = 1;
2523         break;
2524 
2525     default:
2526         if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
2527             ctx->override2DTextureTarget(target);
2528             ctx->m_glGetTexParameteriv_enc(ctx, GL_TEXTURE_2D, pname, params);
2529             ctx->restore2DTextureTarget(target);
2530         } else {
2531             ctx->m_glGetTexParameteriv_enc(ctx, target, pname, params);
2532         }
2533         break;
2534     }
2535 }
2536 
isValidTextureExternalParam(GLenum pname,GLenum param)2537 static bool isValidTextureExternalParam(GLenum pname, GLenum param)
2538 {
2539     switch (pname) {
2540     case GL_TEXTURE_MIN_FILTER:
2541     case GL_TEXTURE_MAG_FILTER:
2542         return param == GL_NEAREST || param == GL_LINEAR;
2543 
2544     case GL_TEXTURE_WRAP_S:
2545     case GL_TEXTURE_WRAP_T:
2546         return param == GL_CLAMP_TO_EDGE;
2547 
2548     default:
2549         return true;
2550     }
2551 }
2552 
s_glTexParameterf(void * self,GLenum target,GLenum pname,GLfloat param)2553 void GL2Encoder::s_glTexParameterf(void* self,
2554         GLenum target, GLenum pname, GLfloat param)
2555 {
2556     GL2Encoder* ctx = (GL2Encoder*)self;
2557 
2558     SET_ERROR_IF((target == GL_TEXTURE_EXTERNAL_OES &&
2559             !isValidTextureExternalParam(pname, (GLenum)param)),
2560             GL_INVALID_ENUM);
2561     SET_ERROR_IF(!GLESv2Validation::textureTarget(ctx, target), GL_INVALID_ENUM);
2562     SET_ERROR_IF(!GLESv2Validation::textureParams(ctx, pname), GL_INVALID_ENUM);
2563     SET_ERROR_IF(!GLESv2Validation::textureParamValue(ctx, pname, (GLint)param, param, (GLenum)param), GL_INVALID_ENUM);
2564 
2565     if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
2566         ctx->override2DTextureTarget(target);
2567         ctx->m_glTexParameterf_enc(ctx, GL_TEXTURE_2D, pname, param);
2568         ctx->restore2DTextureTarget(target);
2569     } else {
2570         ctx->m_glTexParameterf_enc(ctx, target, pname, param);
2571     }
2572 }
2573 
s_glTexParameterfv(void * self,GLenum target,GLenum pname,const GLfloat * params)2574 void GL2Encoder::s_glTexParameterfv(void* self,
2575         GLenum target, GLenum pname, const GLfloat* params)
2576 {
2577     GL2Encoder* ctx = (GL2Encoder*)self;
2578 
2579     SET_ERROR_IF((target == GL_TEXTURE_EXTERNAL_OES &&
2580             !isValidTextureExternalParam(pname, (GLenum)params[0])),
2581             GL_INVALID_ENUM);
2582     SET_ERROR_IF(!GLESv2Validation::textureTarget(ctx, target), GL_INVALID_ENUM);
2583     SET_ERROR_IF(!GLESv2Validation::textureParams(ctx, pname), GL_INVALID_ENUM);
2584     SET_ERROR_IF(!params, GL_INVALID_VALUE);
2585     GLfloat param = *params;
2586     SET_ERROR_IF(!GLESv2Validation::textureParamValue(ctx, pname, (GLint)param, param, (GLenum)param), GL_INVALID_ENUM);
2587 
2588     if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
2589         ctx->override2DTextureTarget(target);
2590         ctx->m_glTexParameterfv_enc(ctx, GL_TEXTURE_2D, pname, params);
2591         ctx->restore2DTextureTarget(target);
2592     } else {
2593         ctx->m_glTexParameterfv_enc(ctx, target, pname, params);
2594     }
2595 }
2596 
s_glTexParameteri(void * self,GLenum target,GLenum pname,GLint param)2597 void GL2Encoder::s_glTexParameteri(void* self,
2598         GLenum target, GLenum pname, GLint param)
2599 {
2600     GL2Encoder* ctx = (GL2Encoder*)self;
2601 
2602     SET_ERROR_IF((target == GL_TEXTURE_EXTERNAL_OES &&
2603             !isValidTextureExternalParam(pname, (GLenum)param)),
2604             GL_INVALID_ENUM);
2605     SET_ERROR_IF(!GLESv2Validation::textureTarget(ctx, target), GL_INVALID_ENUM);
2606     SET_ERROR_IF(!GLESv2Validation::textureParams(ctx, pname), GL_INVALID_ENUM);
2607     SET_ERROR_IF(!GLESv2Validation::textureParamValue(ctx, pname, param, (GLfloat)param, (GLenum)param), GL_INVALID_ENUM);
2608 
2609     if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
2610         ctx->override2DTextureTarget(target);
2611         ctx->m_glTexParameteri_enc(ctx, GL_TEXTURE_2D, pname, param);
2612         ctx->restore2DTextureTarget(target);
2613     } else {
2614         ctx->m_glTexParameteri_enc(ctx, target, pname, param);
2615     }
2616 }
2617 
validateTexBuffer(void * self,GLenum target,GLenum internalFormat,GLuint buffer)2618 bool GL2Encoder::validateTexBuffer(void* self, GLenum target, GLenum internalFormat, GLuint buffer) {
2619     GL2Encoder* ctx = (GL2Encoder*)self;
2620     RET_AND_SET_ERROR_IF((target != GL_TEXTURE_BUFFER_OES), GL_INVALID_ENUM, false);
2621     RET_AND_SET_ERROR_IF(!GLESv2Validation::textureBufferFormat(ctx, internalFormat), GL_INVALID_ENUM, false);
2622     RET_AND_SET_ERROR_IF(buffer != 0 && !ctx->getBufferDataById(buffer), GL_INVALID_OPERATION, false);
2623     return true;
2624 }
2625 
validateTexBufferRange(void * self,GLenum target,GLenum internalFormat,GLuint buffer,GLintptr offset,GLsizeiptr size)2626 bool GL2Encoder::validateTexBufferRange(void* self, GLenum target, GLenum internalFormat, GLuint buffer, GLintptr offset, GLsizeiptr size)
2627 {
2628     GL2Encoder* ctx = (GL2Encoder*)self;
2629     RET_AND_SET_ERROR_IF((target != GL_TEXTURE_BUFFER_OES), GL_INVALID_ENUM, false);
2630     RET_AND_SET_ERROR_IF(!GLESv2Validation::textureBufferFormat(ctx, internalFormat), GL_INVALID_ENUM, false);
2631     if (buffer != 0) {
2632         BufferData* buf = ctx->getBufferDataById(buffer);
2633         RET_AND_SET_ERROR_IF(((!buf) || (buf->m_size < offset+size) || (offset < 0) || (size<0)), GL_INVALID_VALUE, false);
2634     }
2635     GLint tex_buffer_offset_align = 1;
2636     ctx->s_glGetIntegerv(ctx, GL_TEXTURE_BUFFER_OFFSET_ALIGNMENT_OES, &tex_buffer_offset_align);
2637     RET_AND_SET_ERROR_IF((offset % tex_buffer_offset_align) != 0, GL_INVALID_VALUE, false);
2638     return true;
2639 }
2640 
s_glTexBufferOES(void * self,GLenum target,GLenum internalFormat,GLuint buffer)2641 void GL2Encoder::s_glTexBufferOES(void* self,
2642           GLenum target, GLenum internalFormat, GLuint buffer)
2643 {
2644     GL2Encoder* ctx = (GL2Encoder*)self;
2645     SET_ERROR_IF(!ctx->getExtensions().textureBufferOES, GL_INVALID_OPERATION);
2646     if(!validateTexBuffer(ctx, target, internalFormat, buffer)) return;
2647     GLClientState* state = ctx->m_state;
2648     state->setBoundTextureInternalFormat(target, internalFormat);
2649     ctx->m_glTexBufferOES_enc(ctx, target, internalFormat, buffer);
2650 }
2651 
2652 
s_glTexBufferRangeOES(void * self,GLenum target,GLenum internalFormat,GLuint buffer,GLintptr offset,GLsizeiptr size)2653 void GL2Encoder::s_glTexBufferRangeOES(void* self,
2654           GLenum target, GLenum internalFormat, GLuint buffer, GLintptr offset, GLsizeiptr size) {
2655     GL2Encoder* ctx = (GL2Encoder*)self;
2656     SET_ERROR_IF(!ctx->getExtensions().textureBufferOES, GL_INVALID_OPERATION);
2657     if(!validateTexBufferRange(ctx, target, internalFormat, buffer, offset, size)) return;
2658     GLClientState* state = ctx->m_state;
2659     state->setBoundTextureInternalFormat(target, internalFormat);
2660     ctx->m_glTexBufferRangeOES_enc(ctx, target, internalFormat, buffer, offset, size);
2661 }
2662 
s_glTexBufferEXT(void * self,GLenum target,GLenum internalFormat,GLuint buffer)2663 void GL2Encoder::s_glTexBufferEXT(void* self,
2664           GLenum target, GLenum internalFormat, GLuint buffer)
2665 {
2666     GL2Encoder* ctx = (GL2Encoder*)self;
2667     SET_ERROR_IF(!ctx->getExtensions().textureBufferEXT, GL_INVALID_OPERATION);
2668     if(!validateTexBuffer(ctx, target, internalFormat, buffer)) return;
2669     GLClientState* state = ctx->m_state;
2670     state->setBoundTextureInternalFormat(target, internalFormat);
2671     ctx->m_glTexBufferEXT_enc(ctx, target, internalFormat, buffer);
2672 }
2673 
2674 
s_glTexBufferRangeEXT(void * self,GLenum target,GLenum internalFormat,GLuint buffer,GLintptr offset,GLsizeiptr size)2675 void GL2Encoder::s_glTexBufferRangeEXT(void* self,
2676           GLenum target, GLenum internalFormat, GLuint buffer, GLintptr offset, GLsizeiptr size) {
2677      GL2Encoder* ctx = (GL2Encoder*)self;
2678      SET_ERROR_IF(!ctx->getExtensions().textureBufferEXT, GL_INVALID_OPERATION);
2679      if(!validateTexBufferRange(ctx, target, internalFormat, buffer, offset, size)) return;
2680      GLClientState* state = ctx->m_state;
2681      state->setBoundTextureInternalFormat(target, internalFormat);
2682      ctx->m_glTexBufferRangeEXT_enc(ctx, target, internalFormat, buffer, offset, size);
2683 }
2684 
validateAllowedEnablei(void * self,GLenum cap,GLuint index)2685 bool GL2Encoder::validateAllowedEnablei(void* self, GLenum cap, GLuint index) {
2686      GL2Encoder* ctx = (GL2Encoder*)self;
2687      switch(cap)
2688      {
2689      case GL_BLEND:
2690        RET_AND_SET_ERROR_IF(index >= ctx->m_state->getMaxDrawBuffers(), GL_INVALID_VALUE, false);
2691        break;
2692      default:
2693        RET_AND_SET_ERROR_IF(false, GL_INVALID_ENUM, false);
2694      }
2695      return true;
2696 }
2697 
s_glEnableiEXT(void * self,GLenum cap,GLuint index)2698 void GL2Encoder::s_glEnableiEXT(void * self, GLenum cap, GLuint index)
2699 {
2700      GL2Encoder* ctx = (GL2Encoder*)self;
2701      SET_ERROR_IF(!ctx->getExtensions().drawBuffersIndexedEXT, GL_INVALID_OPERATION);
2702      if(!validateAllowedEnablei(ctx, cap, index)) return;
2703      ctx->m_glEnableiEXT_enc(ctx, cap, index);
2704 }
2705 
s_glDisableiEXT(void * self,GLenum cap,GLuint index)2706 void GL2Encoder::s_glDisableiEXT(void* self, GLenum cap, GLuint index)
2707 {
2708      GL2Encoder* ctx = (GL2Encoder*)self;
2709      SET_ERROR_IF(!ctx->getExtensions().drawBuffersIndexedEXT, GL_INVALID_OPERATION);
2710      if(!validateAllowedEnablei(ctx, cap, index)) return;
2711      ctx->m_glDisableiEXT_enc(ctx, cap, index);
2712 }
2713 
s_glBlendEquationiEXT(void * self,GLuint buf,GLenum mode)2714 void GL2Encoder::s_glBlendEquationiEXT(void* self, GLuint buf, GLenum mode)
2715 {
2716      GL2Encoder* ctx = (GL2Encoder*)self;
2717      SET_ERROR_IF(!ctx->getExtensions().drawBuffersIndexedEXT, GL_INVALID_OPERATION);
2718      SET_ERROR_IF(buf >= ctx->m_state->getMaxDrawBuffers(), GL_INVALID_VALUE);
2719      SET_ERROR_IF(
2720         !GLESv2Validation::allowedBlendEquation(mode),
2721         GL_INVALID_ENUM);
2722      ctx->m_glBlendEquationiEXT_enc(ctx, buf, mode);
2723 }
2724 
s_glBlendEquationSeparateiEXT(void * self,GLuint buf,GLenum modeRGB,GLenum modeAlpha)2725 void GL2Encoder::s_glBlendEquationSeparateiEXT(void* self, GLuint buf, GLenum modeRGB, GLenum modeAlpha)
2726 {
2727      GL2Encoder* ctx = (GL2Encoder*)self;
2728      SET_ERROR_IF(!ctx->getExtensions().drawBuffersIndexedEXT, GL_INVALID_OPERATION);
2729      SET_ERROR_IF(buf >= ctx->m_state->getMaxDrawBuffers(), GL_INVALID_VALUE);
2730      SET_ERROR_IF(
2731         !GLESv2Validation::allowedBlendEquation(modeRGB) ||
2732         !GLESv2Validation::allowedBlendEquation(modeAlpha),
2733         GL_INVALID_ENUM);
2734      ctx->m_glBlendEquationSeparateiEXT_enc(ctx, buf, modeRGB, modeAlpha);
2735 }
2736 
s_glBlendFunciEXT(void * self,GLuint buf,GLenum sfactor,GLenum dfactor)2737 void GL2Encoder::s_glBlendFunciEXT(void* self, GLuint buf, GLenum sfactor, GLenum dfactor)
2738 {
2739      GL2Encoder* ctx = (GL2Encoder*)self;
2740      SET_ERROR_IF(!ctx->getExtensions().drawBuffersIndexedEXT, GL_INVALID_OPERATION);
2741      SET_ERROR_IF(buf >= ctx->m_state->getMaxDrawBuffers(), GL_INVALID_VALUE);
2742      SET_ERROR_IF(
2743         !GLESv2Validation::allowedBlendFunc(sfactor) ||
2744         !GLESv2Validation::allowedBlendFunc(dfactor),
2745         GL_INVALID_ENUM);
2746      ctx->m_glBlendFunciEXT_enc(ctx, buf, sfactor, dfactor);
2747 }
2748 
s_glBlendFuncSeparateiEXT(void * self,GLuint buf,GLenum srcRGB,GLenum dstRGB,GLenum srcAlpha,GLenum dstAlpha)2749 void GL2Encoder::s_glBlendFuncSeparateiEXT(void* self, GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
2750 {
2751      GL2Encoder* ctx = (GL2Encoder*)self;
2752      SET_ERROR_IF(!ctx->getExtensions().drawBuffersIndexedEXT, GL_INVALID_OPERATION);
2753      SET_ERROR_IF(buf >= ctx->m_state->getMaxDrawBuffers(), GL_INVALID_VALUE);
2754      SET_ERROR_IF(
2755         !GLESv2Validation::allowedBlendFunc(srcRGB) ||
2756         !GLESv2Validation::allowedBlendFunc(dstRGB) ||
2757         !GLESv2Validation::allowedBlendFunc(srcAlpha) ||
2758         !GLESv2Validation::allowedBlendFunc(dstAlpha),
2759         GL_INVALID_ENUM);
2760      ctx->m_glBlendFuncSeparateiEXT_enc(ctx, buf, srcRGB, dstRGB, srcAlpha, dstAlpha);
2761 }
2762 
s_glColorMaskiEXT(void * self,GLuint buf,GLboolean red,GLboolean green,GLboolean blue,GLboolean alpha)2763 void GL2Encoder::s_glColorMaskiEXT(void* self, GLuint buf, GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
2764 {
2765      GL2Encoder* ctx = (GL2Encoder*)self;
2766      SET_ERROR_IF(!ctx->getExtensions().drawBuffersIndexedEXT, GL_INVALID_OPERATION);
2767      SET_ERROR_IF(buf >= ctx->m_state->getMaxDrawBuffers(), GL_INVALID_VALUE);
2768      ctx->m_glColorMaskiEXT_enc(ctx, buf, red, green, blue, alpha);
2769 }
2770 
s_glIsEnablediEXT(void * self,GLenum cap,GLuint index)2771 GLboolean GL2Encoder::s_glIsEnablediEXT(void* self, GLenum cap, GLuint index)
2772 {
2773      GL2Encoder* ctx = (GL2Encoder*)self;
2774      RET_AND_SET_ERROR_IF(!ctx->getExtensions().drawBuffersIndexedEXT, GL_INVALID_OPERATION, GL_FALSE);
2775      if(!validateAllowedEnablei(ctx, cap, index)) return GL_FALSE;
2776      return ctx->m_glIsEnablediEXT_enc(ctx, cap, index);
2777 }
2778 
ilog2(uint32_t x)2779 static int ilog2(uint32_t x) {
2780     int p = 0;
2781     while ((1 << p) < x)
2782         p++;
2783     return p;
2784 }
2785 
s_glTexImage2D(void * self,GLenum target,GLint level,GLint internalformat,GLsizei width,GLsizei height,GLint border,GLenum format,GLenum type,const GLvoid * pixels)2786 void GL2Encoder::s_glTexImage2D(void* self, GLenum target, GLint level,
2787         GLint internalformat, GLsizei width, GLsizei height, GLint border,
2788         GLenum format, GLenum type, const GLvoid* pixels)
2789 {
2790     GL2Encoder* ctx = (GL2Encoder*)self;
2791     GLClientState* state = ctx->m_state;
2792 
2793     SET_ERROR_IF(!GLESv2Validation::textureTarget(ctx, target), GL_INVALID_ENUM);
2794     SET_ERROR_IF(!GLESv2Validation::pixelType(ctx, type), GL_INVALID_ENUM);
2795     SET_ERROR_IF(!GLESv2Validation::pixelFormat(ctx, format), GL_INVALID_ENUM);
2796     SET_ERROR_IF(!GLESv2Validation::pixelFormat(ctx, internalformat) && !GLESv2Validation::pixelInternalFormat(internalformat), GL_INVALID_VALUE);
2797     SET_ERROR_IF(!(GLESv2Validation::pixelOp(format,type)),GL_INVALID_OPERATION);
2798     SET_ERROR_IF(!GLESv2Validation::pixelSizedFormat(ctx, internalformat, format, type), GL_INVALID_OPERATION);
2799     // If unpack buffer is nonzero, verify unmapped state.
2800     SET_ERROR_IF(ctx->isBufferTargetMapped(GL_PIXEL_UNPACK_BUFFER), GL_INVALID_OPERATION);
2801 
2802     GLint max_texture_size;
2803     GLint max_cube_map_texture_size;
2804     ctx->glGetIntegerv(ctx, GL_MAX_TEXTURE_SIZE, &max_texture_size);
2805     ctx->glGetIntegerv(ctx, GL_MAX_CUBE_MAP_TEXTURE_SIZE, &max_cube_map_texture_size);
2806     SET_ERROR_IF(level < 0, GL_INVALID_VALUE);
2807     SET_ERROR_IF(level > ilog2(max_texture_size), GL_INVALID_VALUE);
2808     SET_ERROR_IF((target == GL_TEXTURE_CUBE_MAP) &&
2809                  (level > ilog2(max_cube_map_texture_size)), GL_INVALID_VALUE);
2810     SET_ERROR_IF(width < 0 || height < 0, GL_INVALID_VALUE);
2811     SET_ERROR_IF(width > max_texture_size, GL_INVALID_VALUE);
2812     SET_ERROR_IF(height > max_texture_size, GL_INVALID_VALUE);
2813     SET_ERROR_IF(GLESv2Validation::isCubeMapTarget(target) && width > max_cube_map_texture_size, GL_INVALID_VALUE);
2814     SET_ERROR_IF(GLESv2Validation::isCubeMapTarget(target) && height > max_cube_map_texture_size, GL_INVALID_VALUE);
2815     SET_ERROR_IF(GLESv2Validation::isCubeMapTarget(target) && (width != height), GL_INVALID_VALUE);
2816     SET_ERROR_IF(border != 0, GL_INVALID_VALUE);
2817     // If unpack buffer is nonzero, verify buffer data fits and is evenly divisible by the type.
2818     SET_ERROR_IF(ctx->boundBuffer(GL_PIXEL_UNPACK_BUFFER) &&
2819                  ctx->getBufferData(GL_PIXEL_UNPACK_BUFFER) &&
2820                  (ctx->m_state->pboNeededDataSize(width, height, 1, format, type, 0) >
2821                   ctx->getBufferData(GL_PIXEL_UNPACK_BUFFER)->m_size),
2822                  GL_INVALID_OPERATION);
2823     SET_ERROR_IF(ctx->boundBuffer(GL_PIXEL_UNPACK_BUFFER) &&
2824                  ctx->getBufferData(GL_PIXEL_UNPACK_BUFFER) &&
2825                  (ctx->getBufferData(GL_PIXEL_UNPACK_BUFFER)->m_size %
2826                   glSizeof(type)),
2827                  GL_INVALID_OPERATION);
2828     SET_ERROR_IF(ctx->boundBuffer(GL_PIXEL_UNPACK_BUFFER) &&
2829                  ctx->getBufferData(GL_PIXEL_UNPACK_BUFFER) &&
2830                  ((uintptr_t)pixels % glSizeof(type)),
2831                  GL_INVALID_OPERATION);
2832     SET_ERROR_IF(state->isBoundTextureImmutableFormat(target), GL_INVALID_OPERATION);
2833 
2834     GLenum stateTarget = target;
2835     if (target == GL_TEXTURE_CUBE_MAP_POSITIVE_X ||
2836         target == GL_TEXTURE_CUBE_MAP_POSITIVE_Y ||
2837         target == GL_TEXTURE_CUBE_MAP_POSITIVE_Z ||
2838         target == GL_TEXTURE_CUBE_MAP_NEGATIVE_X ||
2839         target == GL_TEXTURE_CUBE_MAP_NEGATIVE_Y ||
2840         target == GL_TEXTURE_CUBE_MAP_NEGATIVE_Z)
2841         stateTarget = GL_TEXTURE_CUBE_MAP;
2842 
2843     state->setBoundTextureInternalFormat(stateTarget, internalformat);
2844     state->setBoundTextureFormat(stateTarget, format);
2845     state->setBoundTextureType(stateTarget, type);
2846     state->setBoundTextureDims(stateTarget, target, level, width, height, 1);
2847     state->addTextureCubeMapImage(stateTarget, target);
2848 
2849     if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
2850         ctx->override2DTextureTarget(target);
2851     }
2852 
2853     if (ctx->boundBuffer(GL_PIXEL_UNPACK_BUFFER)) {
2854         ctx->glTexImage2DOffsetAEMU(
2855                 ctx, target, level, internalformat,
2856                 width, height, border,
2857                 format, type, (uintptr_t)pixels);
2858     } else {
2859         ctx->m_glTexImage2D_enc(
2860                 ctx, target, level, internalformat,
2861                 width, height, border,
2862                 format, type, pixels);
2863     }
2864 
2865     if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
2866         ctx->restore2DTextureTarget(target);
2867     }
2868 }
2869 
s_glTexSubImage2D(void * self,GLenum target,GLint level,GLint xoffset,GLint yoffset,GLsizei width,GLsizei height,GLenum format,GLenum type,const GLvoid * pixels)2870 void GL2Encoder::s_glTexSubImage2D(void* self, GLenum target, GLint level,
2871         GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format,
2872         GLenum type, const GLvoid* pixels)
2873 {
2874     GL2Encoder* ctx = (GL2Encoder*)self;
2875     GLClientState* state = ctx->m_state;
2876 
2877     SET_ERROR_IF(!GLESv2Validation::textureTarget(ctx, target), GL_INVALID_ENUM);
2878     SET_ERROR_IF(!GLESv2Validation::pixelType(ctx, type), GL_INVALID_ENUM);
2879     SET_ERROR_IF(!GLESv2Validation::pixelFormat(ctx, format), GL_INVALID_ENUM);
2880     // If unpack buffer is nonzero, verify unmapped state.
2881     SET_ERROR_IF(ctx->isBufferTargetMapped(GL_PIXEL_UNPACK_BUFFER), GL_INVALID_OPERATION);
2882 
2883     GLint max_texture_size;
2884     GLint max_cube_map_texture_size;
2885     ctx->glGetIntegerv(ctx, GL_MAX_TEXTURE_SIZE, &max_texture_size);
2886     ctx->glGetIntegerv(ctx, GL_MAX_CUBE_MAP_TEXTURE_SIZE, &max_cube_map_texture_size);
2887     SET_ERROR_IF(level < 0, GL_INVALID_VALUE);
2888     SET_ERROR_IF(level > ilog2(max_texture_size), GL_INVALID_VALUE);
2889     SET_ERROR_IF(GLESv2Validation::isCubeMapTarget(target) &&
2890                  level > ilog2(max_cube_map_texture_size), GL_INVALID_VALUE);
2891     SET_ERROR_IF(width < 0 || height < 0, GL_INVALID_VALUE);
2892     SET_ERROR_IF(xoffset < 0 || yoffset < 0, GL_INVALID_VALUE);
2893 
2894     GLuint tex = state->getBoundTexture(target);
2895     GLsizei neededWidth = xoffset + width;
2896     GLsizei neededHeight = yoffset + height;
2897     GLsizei neededDepth = 1;
2898 
2899     if (tex && !state->queryTexEGLImageBacked(tex)) {
2900         SET_ERROR_IF(
2901                 (neededWidth > state->queryTexWidth(level, tex) ||
2902                  neededHeight > state->queryTexHeight(level, tex) ||
2903                  neededDepth > state->queryTexDepth(level, tex)),
2904                 GL_INVALID_VALUE);
2905     }
2906 
2907     // If unpack buffer is nonzero, verify buffer data fits and is evenly divisible by the type.
2908     SET_ERROR_IF(ctx->boundBuffer(GL_PIXEL_UNPACK_BUFFER) &&
2909                  ctx->getBufferData(GL_PIXEL_UNPACK_BUFFER) &&
2910                  (state->pboNeededDataSize(width, height, 1, format, type, 0, 1) + (uintptr_t)pixels >
2911                   ctx->getBufferData(GL_PIXEL_UNPACK_BUFFER)->m_size),
2912                  GL_INVALID_OPERATION);
2913     SET_ERROR_IF(ctx->boundBuffer(GL_PIXEL_UNPACK_BUFFER) &&
2914                  ctx->getBufferData(GL_PIXEL_UNPACK_BUFFER) &&
2915                  ((uintptr_t)pixels %
2916                   glSizeof(type)),
2917                  GL_INVALID_OPERATION);
2918     SET_ERROR_IF(!ctx->boundBuffer(GL_PIXEL_UNPACK_BUFFER) && !pixels, GL_INVALID_OPERATION);
2919 
2920     if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
2921         ctx->override2DTextureTarget(target);
2922     }
2923 
2924     if (ctx->boundBuffer(GL_PIXEL_UNPACK_BUFFER)) {
2925         ctx->glTexSubImage2DOffsetAEMU(
2926                 ctx, target, level,
2927                 xoffset, yoffset, width, height,
2928                 format, type, (uintptr_t)pixels);
2929     } else {
2930         ctx->m_glTexSubImage2D_enc(ctx, target, level, xoffset, yoffset, width,
2931                 height, format, type, pixels);
2932     }
2933 
2934     if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
2935         ctx->restore2DTextureTarget(target);
2936     }
2937 }
2938 
s_glCopyTexImage2D(void * self,GLenum target,GLint level,GLenum internalformat,GLint x,GLint y,GLsizei width,GLsizei height,GLint border)2939 void GL2Encoder::s_glCopyTexImage2D(void* self, GLenum target, GLint level,
2940         GLenum internalformat, GLint x, GLint y,
2941         GLsizei width, GLsizei height, GLint border)
2942 {
2943     GL2Encoder* ctx = (GL2Encoder*)self;
2944     GLClientState* state = ctx->m_state;
2945 
2946     SET_ERROR_IF(!GLESv2Validation::textureTarget(ctx, target), GL_INVALID_ENUM);
2947     SET_ERROR_IF(!GLESv2Validation::pixelFormat(ctx, internalformat) && !GLESv2Validation::pixelInternalFormat(internalformat), GL_INVALID_VALUE);
2948     GLint max_texture_size;
2949     GLint max_cube_map_texture_size;
2950     ctx->glGetIntegerv(ctx, GL_MAX_TEXTURE_SIZE, &max_texture_size);
2951     ctx->glGetIntegerv(ctx, GL_MAX_CUBE_MAP_TEXTURE_SIZE, &max_cube_map_texture_size);
2952     SET_ERROR_IF(level < 0, GL_INVALID_VALUE);
2953     SET_ERROR_IF(level > ilog2(max_texture_size), GL_INVALID_VALUE);
2954     SET_ERROR_IF((target == GL_TEXTURE_CUBE_MAP) &&
2955                  (level > ilog2(max_cube_map_texture_size)), GL_INVALID_VALUE);
2956     SET_ERROR_IF(width < 0 || height < 0, GL_INVALID_VALUE);
2957     SET_ERROR_IF(width > max_texture_size, GL_INVALID_VALUE);
2958     SET_ERROR_IF(height > max_texture_size, GL_INVALID_VALUE);
2959     SET_ERROR_IF(GLESv2Validation::isCubeMapTarget(target) && width > max_cube_map_texture_size, GL_INVALID_VALUE);
2960     SET_ERROR_IF(GLESv2Validation::isCubeMapTarget(target) && height > max_cube_map_texture_size, GL_INVALID_VALUE);
2961     SET_ERROR_IF(GLESv2Validation::isCubeMapTarget(target) && (width != height), GL_INVALID_VALUE);
2962     SET_ERROR_IF(border != 0, GL_INVALID_VALUE);
2963 
2964     GLenum stateTarget = target;
2965     if (target == GL_TEXTURE_CUBE_MAP_POSITIVE_X ||
2966         target == GL_TEXTURE_CUBE_MAP_POSITIVE_Y ||
2967         target == GL_TEXTURE_CUBE_MAP_POSITIVE_Z ||
2968         target == GL_TEXTURE_CUBE_MAP_NEGATIVE_X ||
2969         target == GL_TEXTURE_CUBE_MAP_NEGATIVE_Y ||
2970         target == GL_TEXTURE_CUBE_MAP_NEGATIVE_Z)
2971         stateTarget = GL_TEXTURE_CUBE_MAP;
2972 
2973     SET_ERROR_IF(state->isBoundTextureImmutableFormat(target), GL_INVALID_OPERATION);
2974 
2975     SET_ERROR_IF(ctx->glCheckFramebufferStatus(ctx, GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE,
2976                  GL_INVALID_FRAMEBUFFER_OPERATION);
2977     // This is needed to work around underlying OpenGL drivers
2978     // (such as those feeding some some AMD GPUs) that expect
2979     // positive components of cube maps to be defined _before_
2980     // the negative components (otherwise a segfault occurs).
2981     GLenum extraTarget =
2982         state->copyTexImageLuminanceCubeMapAMDWorkaround
2983             (target, level, internalformat);
2984 
2985     state->setBoundTextureInternalFormat(stateTarget, internalformat);
2986     state->setBoundTextureDims(stateTarget, target, level, width, height, 1);
2987     state->addTextureCubeMapImage(stateTarget, target);
2988 
2989     if (extraTarget) {
2990         ctx->m_glCopyTexImage2D_enc(ctx, extraTarget, level, internalformat,
2991                                     x, y, width, height, border);
2992     }
2993 
2994     ctx->m_glCopyTexImage2D_enc(ctx, target, level, internalformat,
2995                                 x, y, width, height, border);
2996 }
2997 
s_glTexParameteriv(void * self,GLenum target,GLenum pname,const GLint * params)2998 void GL2Encoder::s_glTexParameteriv(void* self,
2999         GLenum target, GLenum pname, const GLint* params)
3000 {
3001     GL2Encoder* ctx = (GL2Encoder*)self;
3002 
3003     SET_ERROR_IF((target == GL_TEXTURE_EXTERNAL_OES &&
3004             !isValidTextureExternalParam(pname, (GLenum)params[0])),
3005             GL_INVALID_ENUM);
3006     SET_ERROR_IF(!GLESv2Validation::textureTarget(ctx, target), GL_INVALID_ENUM);
3007     SET_ERROR_IF(!GLESv2Validation::textureParams(ctx, pname), GL_INVALID_ENUM);
3008     SET_ERROR_IF(!params, GL_INVALID_VALUE);
3009     GLint param = *params;
3010     SET_ERROR_IF(!GLESv2Validation::textureParamValue(ctx, pname, param, (GLfloat)param, (GLenum)param), GL_INVALID_ENUM);
3011 
3012     if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
3013         ctx->override2DTextureTarget(target);
3014         ctx->m_glTexParameteriv_enc(ctx, GL_TEXTURE_2D, pname, params);
3015         ctx->restore2DTextureTarget(target);
3016     } else {
3017         ctx->m_glTexParameteriv_enc(ctx, target, pname, params);
3018     }
3019 }
3020 
texture2DNeedsOverride(GLenum target) const3021 bool GL2Encoder::texture2DNeedsOverride(GLenum target) const {
3022     return (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) &&
3023            target != m_state->getPriorityEnabledTarget(GL_TEXTURE_2D);
3024 }
3025 
override2DTextureTarget(GLenum target)3026 void GL2Encoder::override2DTextureTarget(GLenum target)
3027 {
3028     if (texture2DNeedsOverride(target)) {
3029         m_glBindTexture_enc(this, GL_TEXTURE_2D,
3030                 m_state->getBoundTexture(target));
3031     }
3032 }
3033 
restore2DTextureTarget(GLenum target)3034 void GL2Encoder::restore2DTextureTarget(GLenum target)
3035 {
3036     if (texture2DNeedsOverride(target)) {
3037         GLuint priorityEnabledBoundTexture =
3038                 m_state->getBoundTexture(
3039                     m_state->getPriorityEnabledTarget(GL_TEXTURE_2D));
3040         GLuint texture2DBoundTexture =
3041                 m_state->getBoundTexture(GL_TEXTURE_2D);
3042         if (!priorityEnabledBoundTexture) {
3043             m_glBindTexture_enc(this, GL_TEXTURE_2D, texture2DBoundTexture);
3044         } else {
3045             m_glBindTexture_enc(this, GL_TEXTURE_2D, priorityEnabledBoundTexture);
3046         }
3047     }
3048 }
3049 
associateEGLImage(GLenum target,GLeglImageOES eglImage,int width,int height)3050 void GL2Encoder::associateEGLImage(GLenum target, GLeglImageOES eglImage, int width, int height) {
3051     m_state->setBoundEGLImage(target, eglImage, width, height);
3052 }
3053 
3054 
boundBuffer(GLenum target) const3055 GLuint GL2Encoder::boundBuffer(GLenum target) const {
3056     return m_state->getBuffer(target);
3057 }
3058 
getBufferData(GLenum target) const3059 BufferData* GL2Encoder::getBufferData(GLenum target) const {
3060     GLuint bufferId = m_state->getBuffer(target);
3061     if (!bufferId) return NULL;
3062     return m_shared->getBufferData(bufferId);
3063 }
3064 
getBufferDataById(GLuint bufferId) const3065 BufferData* GL2Encoder::getBufferDataById(GLuint bufferId) const {
3066     if (!bufferId) return NULL;
3067     return m_shared->getBufferData(bufferId);
3068 }
3069 
isBufferMapped(GLuint buffer) const3070 bool GL2Encoder::isBufferMapped(GLuint buffer) const {
3071     return m_shared->getBufferData(buffer)->m_mapped;
3072 }
3073 
isBufferTargetMapped(GLenum target) const3074 bool GL2Encoder::isBufferTargetMapped(GLenum target) const {
3075     BufferData* buf = getBufferData(target);
3076     if (!buf) return false;
3077     return buf->m_mapped;
3078 }
3079 
s_glGenRenderbuffers(void * self,GLsizei n,GLuint * renderbuffers)3080 void GL2Encoder::s_glGenRenderbuffers(void* self,
3081         GLsizei n, GLuint* renderbuffers) {
3082     GL2Encoder* ctx = (GL2Encoder*)self;
3083     GLClientState* state = ctx->m_state;
3084 
3085     SET_ERROR_IF(n < 0, GL_INVALID_VALUE);
3086 
3087     ctx->m_glGenFramebuffers_enc(self, n, renderbuffers);
3088     state->addRenderbuffers(n, renderbuffers);
3089 }
3090 
s_glDeleteRenderbuffers(void * self,GLsizei n,const GLuint * renderbuffers)3091 void GL2Encoder::s_glDeleteRenderbuffers(void* self,
3092         GLsizei n, const GLuint* renderbuffers) {
3093     GL2Encoder* ctx = (GL2Encoder*)self;
3094     GLClientState* state = ctx->m_state;
3095 
3096     SET_ERROR_IF(n < 0, GL_INVALID_VALUE);
3097 
3098     ctx->m_glDeleteRenderbuffers_enc(self, n, renderbuffers);
3099 
3100     // Nope, lets just leak those for now.
3101     // The spec has an *amazingly* convoluted set of conditions for when
3102     // render buffers are actually deleted:
3103     // 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.
3104     //
3105     // 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***
3106     //
3107     // So, just detach this one from the bound FBO, and ignore the rest.
3108     for (int i = 0; i < n; i++) {
3109         state->detachRbo(renderbuffers[i]);
3110     }
3111     state->removeRenderbuffers(n, renderbuffers);
3112 }
3113 
s_glBindRenderbuffer(void * self,GLenum target,GLuint renderbuffer)3114 void GL2Encoder::s_glBindRenderbuffer(void* self,
3115         GLenum target, GLuint renderbuffer) {
3116     GL2Encoder* ctx = (GL2Encoder*)self;
3117     GLClientState* state = ctx->m_state;
3118 
3119     SET_ERROR_IF((target != GL_RENDERBUFFER),
3120                  GL_INVALID_ENUM);
3121 
3122     ctx->m_glBindRenderbuffer_enc(self, target, renderbuffer);
3123     state->bindRenderbuffer(target, renderbuffer);
3124 }
3125 
s_glRenderbufferStorage(void * self,GLenum target,GLenum internalformat,GLsizei width,GLsizei height)3126 void GL2Encoder::s_glRenderbufferStorage(void* self,
3127         GLenum target, GLenum internalformat,
3128         GLsizei width, GLsizei height) {
3129     GL2Encoder* ctx = (GL2Encoder*) self;
3130     GLClientState* state = ctx->m_state;
3131 
3132     SET_ERROR_IF(target != GL_RENDERBUFFER, GL_INVALID_ENUM);
3133     SET_ERROR_IF(0 == ctx->m_state->boundRenderbuffer(), GL_INVALID_OPERATION);
3134     SET_ERROR_IF(
3135         !GLESv2Validation::rboFormat(ctx, internalformat),
3136         GL_INVALID_ENUM);
3137 
3138     SET_ERROR_IF(width < 0 || height < 0, GL_INVALID_VALUE);
3139     GLint max_rb_size;
3140     ctx->glGetIntegerv(ctx, GL_MAX_RENDERBUFFER_SIZE, &max_rb_size);
3141     SET_ERROR_IF(width > max_rb_size || height > max_rb_size, GL_INVALID_VALUE);
3142 
3143     state->setBoundRenderbufferFormat(internalformat);
3144     state->setBoundRenderbufferSamples(0);
3145     state->setBoundRenderbufferDimensions(width, height);
3146 
3147     ctx->m_glRenderbufferStorage_enc(self, target, internalformat,
3148                                      width, height);
3149 }
3150 
s_glFramebufferRenderbuffer(void * self,GLenum target,GLenum attachment,GLenum renderbuffertarget,GLuint renderbuffer)3151 void GL2Encoder::s_glFramebufferRenderbuffer(void* self,
3152         GLenum target, GLenum attachment,
3153         GLenum renderbuffertarget, GLuint renderbuffer) {
3154     GL2Encoder* ctx = (GL2Encoder*)self;
3155     GLClientState* state = ctx->m_state;
3156 
3157     SET_ERROR_IF(!GLESv2Validation::framebufferTarget(ctx, target), GL_INVALID_ENUM);
3158     SET_ERROR_IF(!GLESv2Validation::framebufferAttachment(ctx, attachment), GL_INVALID_ENUM);
3159     SET_ERROR_IF(GL_RENDERBUFFER != renderbuffertarget, GL_INVALID_ENUM);
3160     SET_ERROR_IF(!state->getBoundFramebuffer(target), GL_INVALID_OPERATION);
3161     SET_ERROR_IF(!state->isRenderbufferThatWasBound(renderbuffer), GL_INVALID_OPERATION);
3162 
3163     state->attachRbo(target, attachment, renderbuffer);
3164 
3165     ctx->m_glFramebufferRenderbuffer_enc(self, target, attachment, renderbuffertarget, renderbuffer);
3166 }
3167 
s_glGenFramebuffers(void * self,GLsizei n,GLuint * framebuffers)3168 void GL2Encoder::s_glGenFramebuffers(void* self,
3169         GLsizei n, GLuint* framebuffers) {
3170     GL2Encoder* ctx = (GL2Encoder*)self;
3171     GLClientState* state = ctx->m_state;
3172 
3173     SET_ERROR_IF(n < 0, GL_INVALID_VALUE);
3174 
3175     ctx->m_glGenFramebuffers_enc(self, n, framebuffers);
3176     state->addFramebuffers(n, framebuffers);
3177 }
3178 
s_glDeleteFramebuffers(void * self,GLsizei n,const GLuint * framebuffers)3179 void GL2Encoder::s_glDeleteFramebuffers(void* self,
3180         GLsizei n, const GLuint* framebuffers) {
3181     GL2Encoder* ctx = (GL2Encoder*)self;
3182     GLClientState* state = ctx->m_state;
3183 
3184     SET_ERROR_IF(n < 0, GL_INVALID_VALUE);
3185 
3186     ctx->m_glDeleteFramebuffers_enc(self, n, framebuffers);
3187     state->removeFramebuffers(n, framebuffers);
3188 }
3189 
s_glBindFramebuffer(void * self,GLenum target,GLuint framebuffer)3190 void GL2Encoder::s_glBindFramebuffer(void* self,
3191         GLenum target, GLuint framebuffer) {
3192     GL2Encoder* ctx = (GL2Encoder*)self;
3193     GLClientState* state = ctx->m_state;
3194 
3195     SET_ERROR_IF(!GLESv2Validation::framebufferTarget(ctx, target), GL_INVALID_ENUM);
3196 
3197     state->bindFramebuffer(target, framebuffer);
3198 
3199     ctx->m_glBindFramebuffer_enc(self, target, framebuffer);
3200 }
3201 
s_glFramebufferParameteri(void * self,GLenum target,GLenum pname,GLint param)3202 void GL2Encoder::s_glFramebufferParameteri(void *self,
3203         GLenum target, GLenum pname, GLint param) {
3204     GL2Encoder* ctx = (GL2Encoder*)self;
3205     GLClientState* state = ctx->m_state;
3206     state->setFramebufferParameter(target, pname, param);
3207     ctx->m_glFramebufferParameteri_enc(self, target, pname, param);
3208 }
3209 
s_glFramebufferTexture2D(void * self,GLenum target,GLenum attachment,GLenum textarget,GLuint texture,GLint level)3210 void GL2Encoder::s_glFramebufferTexture2D(void* self,
3211         GLenum target, GLenum attachment,
3212         GLenum textarget, GLuint texture, GLint level) {
3213     GL2Encoder* ctx = (GL2Encoder*)self;
3214     GLClientState* state = ctx->m_state;
3215 
3216     SET_ERROR_IF(!GLESv2Validation::framebufferTarget(ctx, target), GL_INVALID_ENUM);
3217     SET_ERROR_IF(!GLESv2Validation::textureTarget(ctx, textarget), GL_INVALID_ENUM);
3218     SET_ERROR_IF(!GLESv2Validation::framebufferAttachment(ctx, attachment), GL_INVALID_ENUM);
3219     SET_ERROR_IF(!state->getBoundFramebuffer(target), GL_INVALID_OPERATION);
3220     SET_ERROR_IF(texture && !state->isTexture(texture), GL_INVALID_OPERATION);
3221     SET_ERROR_IF(GLESv2Validation::isCubeMapTarget(textarget) && !state->isTextureCubeMap(texture), GL_INVALID_OPERATION);
3222     SET_ERROR_IF(!GLESv2Validation::isCubeMapTarget(textarget) && state->isTextureCubeMap(texture), GL_INVALID_OPERATION);
3223     SET_ERROR_IF((texture && (level < 0)), GL_INVALID_VALUE);
3224 
3225     if (textarget == GL_TEXTURE_2D) {
3226         SET_ERROR_IF(level > ilog2(ctx->m_state->getMaxTextureSize()), GL_INVALID_VALUE);
3227     } else {
3228         SET_ERROR_IF(level > ilog2(ctx->m_state->getMaxTextureSizeCubeMap()), GL_INVALID_VALUE);
3229     }
3230 
3231     state->attachTextureObject(target, attachment, texture, level, 0);
3232 
3233     ctx->m_glFramebufferTexture2D_enc(self, target, attachment, textarget, texture, level);
3234 }
3235 
s_glFramebufferTexture3DOES(void * self,GLenum target,GLenum attachment,GLenum textarget,GLuint texture,GLint level,GLint zoffset)3236 void GL2Encoder::s_glFramebufferTexture3DOES(void* self,
3237         GLenum target, GLenum attachment,
3238         GLenum textarget, GLuint texture, GLint level, GLint zoffset) {
3239     GL2Encoder* ctx = (GL2Encoder*)self;
3240     GLClientState* state = ctx->m_state;
3241 
3242     state->attachTextureObject(target, attachment, texture, level, zoffset);
3243 
3244     ctx->m_glFramebufferTexture3DOES_enc(self, target, attachment, textarget, texture, level, zoffset);
3245 }
3246 
s_glGetFramebufferAttachmentParameteriv(void * self,GLenum target,GLenum attachment,GLenum pname,GLint * params)3247 void GL2Encoder::s_glGetFramebufferAttachmentParameteriv(void* self,
3248         GLenum target, GLenum attachment, GLenum pname, GLint* params) {
3249     GL2Encoder* ctx = (GL2Encoder*)self;
3250     const GLClientState* state = ctx->m_state;
3251     SET_ERROR_IF(!GLESv2Validation::framebufferTarget(ctx, target), GL_INVALID_ENUM);
3252     SET_ERROR_IF(!state->boundFramebuffer(target) &&
3253                  attachment != GL_BACK &&
3254                  attachment != GL_FRONT &&
3255                  attachment != GL_DEPTH &&
3256                  attachment != GL_STENCIL,
3257                  GL_INVALID_OPERATION);
3258     SET_ERROR_IF(pname != GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME &&
3259                  pname != GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE &&
3260                  !state->attachmentHasObject(target, attachment),
3261                  GL_INVALID_OPERATION);
3262     SET_ERROR_IF((pname == GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL ||
3263                   pname == GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE ||
3264                   pname == GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER) &&
3265                  (!state->attachmentHasObject(target, attachment) ||
3266                   state->getBoundFramebufferAttachmentType(target, attachment) !=
3267                   FBO_ATTACHMENT_TEXTURE),
3268                  !state->attachmentHasObject(target, attachment) ?
3269                  GL_INVALID_OPERATION : GL_INVALID_ENUM);
3270     SET_ERROR_IF(
3271         (attachment == GL_FRONT ||
3272          attachment == GL_BACK) &&
3273         (pname == GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME),
3274         GL_INVALID_ENUM);
3275     SET_ERROR_IF(attachment == GL_DEPTH_STENCIL_ATTACHMENT &&
3276                  pname == GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME &&
3277                  !state->depthStencilHasSameObject(target),
3278                  GL_INVALID_OPERATION);
3279     SET_ERROR_IF(state->boundFramebuffer(target) &&
3280                  (attachment == GL_BACK ||
3281                   attachment == GL_FRONT ||
3282                   attachment == GL_DEPTH ||
3283                   attachment == GL_STENCIL),
3284                  GL_INVALID_OPERATION);
3285     ctx->m_glGetFramebufferAttachmentParameteriv_enc(self, target, attachment, pname, params);
3286 }
3287 
s_glCheckFramebufferStatus(void * self,GLenum target)3288 GLenum GL2Encoder::s_glCheckFramebufferStatus(void* self, GLenum target) {
3289     GL2Encoder* ctx = (GL2Encoder*)self;
3290 
3291     RET_AND_SET_ERROR_IF(
3292         target != GL_DRAW_FRAMEBUFFER && target != GL_FRAMEBUFFER && target != GL_READ_FRAMEBUFFER,
3293         GL_INVALID_ENUM, 0);
3294 
3295     GLClientState* state = ctx->m_state;
3296 
3297     return state->checkFramebufferCompleteness(target);
3298 }
3299 
s_glGenVertexArrays(void * self,GLsizei n,GLuint * arrays)3300 void GL2Encoder::s_glGenVertexArrays(void* self, GLsizei n, GLuint* arrays) {
3301     GL2Encoder* ctx = (GL2Encoder*)self;
3302     GLClientState* state = ctx->m_state;
3303     SET_ERROR_IF(n < 0, GL_INVALID_VALUE);
3304 
3305     ctx->m_glGenVertexArrays_enc(self, n, arrays);
3306     for (int i = 0; i < n; i++) {
3307         ALOGV("%s: gen vao %u", __FUNCTION__, arrays[i]);
3308     }
3309     state->addVertexArrayObjects(n, arrays);
3310 }
3311 
s_glDeleteVertexArrays(void * self,GLsizei n,const GLuint * arrays)3312 void GL2Encoder::s_glDeleteVertexArrays(void* self, GLsizei n, const GLuint* arrays) {
3313     GL2Encoder* ctx = (GL2Encoder*)self;
3314     GLClientState* state = ctx->m_state;
3315     SET_ERROR_IF(n < 0, GL_INVALID_VALUE);
3316 
3317     ctx->m_glDeleteVertexArrays_enc(self, n, arrays);
3318     for (int i = 0; i < n; i++) {
3319         ALOGV("%s: delete vao %u", __FUNCTION__, arrays[i]);
3320     }
3321     state->removeVertexArrayObjects(n, arrays);
3322 }
3323 
s_glBindVertexArray(void * self,GLuint array)3324 void GL2Encoder::s_glBindVertexArray(void* self, GLuint array) {
3325     ALOGV("%s: call. array=%u\n", __FUNCTION__, array);
3326     GL2Encoder* ctx = (GL2Encoder*)self;
3327     GLClientState* state = ctx->m_state;
3328     SET_ERROR_IF(!state->isVertexArrayObject(array), GL_INVALID_OPERATION);
3329     ctx->m_glBindVertexArray_enc(self, array);
3330     state->setVertexArrayObject(array);
3331 }
3332 
s_glMapBufferOES(void * self,GLenum target,GLenum access)3333 void* GL2Encoder::s_glMapBufferOES(void* self, GLenum target, GLenum access) {
3334     GL2Encoder* ctx = (GL2Encoder*)self;
3335 
3336     RET_AND_SET_ERROR_IF(!GLESv2Validation::bufferTarget(ctx, target), GL_INVALID_ENUM, NULL);
3337 
3338     GLuint boundBuffer = ctx->m_state->getBuffer(target);
3339 
3340     RET_AND_SET_ERROR_IF(boundBuffer == 0, GL_INVALID_OPERATION, NULL);
3341 
3342     BufferData* buf = ctx->m_shared->getBufferData(boundBuffer);
3343     RET_AND_SET_ERROR_IF(!buf, GL_INVALID_VALUE, NULL);
3344 
3345     return ctx->glMapBufferRange(ctx, target, 0, buf->m_size, access);
3346 }
3347 
s_glUnmapBufferOES(void * self,GLenum target)3348 GLboolean GL2Encoder::s_glUnmapBufferOES(void* self, GLenum target) {
3349     GL2Encoder* ctx = (GL2Encoder*)self;
3350 
3351     return ctx->glUnmapBuffer(ctx, target);
3352 }
3353 
s_glMapBufferRangeAEMUImpl(GL2Encoder * ctx,GLenum target,GLintptr offset,GLsizeiptr length,GLbitfield access,BufferData * buf)3354 void* GL2Encoder::s_glMapBufferRangeAEMUImpl(GL2Encoder* ctx, GLenum target,
3355                                              GLintptr offset, GLsizeiptr length,
3356                                              GLbitfield access, BufferData* buf) {
3357     char* bits = &buf->m_fixedBuffer[offset];
3358 
3359     if ((access & GL_MAP_READ_BIT) ||
3360         ((access & GL_MAP_WRITE_BIT) &&
3361         (!(access & GL_MAP_INVALIDATE_RANGE_BIT) &&
3362          !(access & GL_MAP_INVALIDATE_BUFFER_BIT)))) {
3363 
3364         if (ctx->m_state->shouldSkipHostMapBuffer(target))
3365             return bits;
3366 
3367         ctx->glMapBufferRangeAEMU(
3368                 ctx, target,
3369                 offset, length,
3370                 access,
3371                 bits);
3372 
3373         ctx->m_state->onHostMappedBuffer(target);
3374     }
3375 
3376     return bits;
3377 }
3378 
s_glMapBufferRange(void * self,GLenum target,GLintptr offset,GLsizeiptr length,GLbitfield access)3379 void* GL2Encoder::s_glMapBufferRange(void* self, GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access) {
3380     GL2Encoder* ctx = (GL2Encoder*)self;
3381 
3382     // begin validation (lots)
3383 
3384     RET_AND_SET_ERROR_IF(!GLESv2Validation::bufferTarget(ctx, target), GL_INVALID_ENUM, NULL);
3385 
3386     GLuint boundBuffer = ctx->m_state->getBuffer(target);
3387 
3388     RET_AND_SET_ERROR_IF(boundBuffer == 0, GL_INVALID_OPERATION, NULL);
3389 
3390     BufferData* buf = ctx->m_shared->getBufferData(boundBuffer);
3391     RET_AND_SET_ERROR_IF(!buf, GL_INVALID_VALUE, NULL);
3392 
3393     GLsizeiptr bufferDataSize = buf->m_size;
3394 
3395     RET_AND_SET_ERROR_IF(offset < 0, GL_INVALID_VALUE, NULL);
3396     RET_AND_SET_ERROR_IF(length < 0, GL_INVALID_VALUE, NULL);
3397     RET_AND_SET_ERROR_IF(offset + length > bufferDataSize, GL_INVALID_VALUE, NULL);
3398     RET_AND_SET_ERROR_IF(access & ~GLESv2Validation::allBufferMapAccessFlags, GL_INVALID_VALUE, NULL);
3399 
3400     RET_AND_SET_ERROR_IF(buf->m_mapped, GL_INVALID_OPERATION, NULL);
3401     RET_AND_SET_ERROR_IF(!(access & (GL_MAP_READ_BIT | GL_MAP_WRITE_BIT)), GL_INVALID_OPERATION, NULL);
3402     RET_AND_SET_ERROR_IF(
3403         (access & GL_MAP_READ_BIT) &&
3404              ((access & GL_MAP_INVALIDATE_RANGE_BIT) ||
3405               (access & GL_MAP_INVALIDATE_BUFFER_BIT) ||
3406               (access & GL_MAP_UNSYNCHRONIZED_BIT) ||
3407               (access & GL_MAP_FLUSH_EXPLICIT_BIT)), GL_INVALID_OPERATION, NULL);
3408 
3409     // end validation; actually do stuff now
3410 
3411     buf->m_mapped = true;
3412     buf->m_mappedAccess = access;
3413     buf->m_mappedOffset = offset;
3414     buf->m_mappedLength = length;
3415 
3416     if (ctx->hasExtension("ANDROID_EMU_dma_v2")) {
3417         if (buf->dma_buffer.get().size < length) {
3418             goldfish_dma_context region;
3419 
3420             const int PAGE_BITS = 12;
3421             GLsizeiptr aligned_length = (length + (1 << PAGE_BITS) - 1) & ~((1 << PAGE_BITS) - 1);
3422 
3423             if (goldfish_dma_create_region(aligned_length, ®ion)) {
3424                 buf->dma_buffer.reset(NULL);
3425                 return s_glMapBufferRangeAEMUImpl(ctx, target, offset, length, access, buf);
3426             }
3427 
3428             if (!goldfish_dma_map(®ion)) {
3429                 buf->dma_buffer.reset(NULL);
3430                 return s_glMapBufferRangeAEMUImpl(ctx, target, offset, length, access, buf);
3431             }
3432 
3433             buf->m_guest_paddr = goldfish_dma_guest_paddr(®ion);
3434             buf->dma_buffer.reset(®ion);
3435         }
3436 
3437         ctx->glMapBufferRangeDMA(
3438                 ctx, target,
3439                 offset, length,
3440                 access,
3441                 buf->m_guest_paddr);
3442 
3443         return reinterpret_cast<void*>(buf->dma_buffer.get().mapped_addr);
3444     } else {
3445         return s_glMapBufferRangeAEMUImpl(ctx, target, offset, length, access, buf);
3446     }
3447 }
3448 
s_glUnmapBuffer(void * self,GLenum target)3449 GLboolean GL2Encoder::s_glUnmapBuffer(void* self, GLenum target) {
3450     GL2Encoder* ctx = (GL2Encoder*)self;
3451 
3452     RET_AND_SET_ERROR_IF(!GLESv2Validation::bufferTarget(ctx, target), GL_INVALID_ENUM, GL_FALSE);
3453 
3454     GLuint boundBuffer = ctx->m_state->getBuffer(target);
3455 
3456     RET_AND_SET_ERROR_IF(boundBuffer == 0, GL_INVALID_OPERATION, GL_FALSE);
3457 
3458     BufferData* buf = ctx->m_shared->getBufferData(boundBuffer);
3459     RET_AND_SET_ERROR_IF(!buf, GL_INVALID_VALUE, GL_FALSE);
3460     RET_AND_SET_ERROR_IF(!buf->m_mapped, GL_INVALID_OPERATION, GL_FALSE);
3461 
3462     if (buf->m_mappedAccess & GL_MAP_WRITE_BIT) {
3463         // invalide index range cache here
3464         if (buf->m_mappedAccess & GL_MAP_INVALIDATE_BUFFER_BIT) {
3465             buf->m_indexRangeCache.invalidateRange(0, buf->m_size);
3466         } else {
3467             buf->m_indexRangeCache.invalidateRange(buf->m_mappedOffset, buf->m_mappedLength);
3468         }
3469     }
3470 
3471     GLboolean host_res = GL_TRUE;
3472 
3473     if (buf->dma_buffer.get().mapped_addr) {
3474         memcpy(&buf->m_fixedBuffer[buf->m_mappedOffset],
3475                reinterpret_cast<void*>(buf->dma_buffer.get().mapped_addr),
3476                buf->m_mappedLength);
3477 
3478         ctx->glUnmapBufferDMA(
3479             ctx, target,
3480             buf->m_mappedOffset,
3481             buf->m_mappedLength,
3482             buf->m_mappedAccess,
3483             goldfish_dma_guest_paddr(&buf->dma_buffer.get()),
3484             &host_res);
3485     } else {
3486         if (ctx->m_hasAsyncUnmapBuffer) {
3487             ctx->glUnmapBufferAsyncAEMU(
3488                     ctx, target,
3489                     buf->m_mappedOffset,
3490                     buf->m_mappedLength,
3491                     buf->m_mappedAccess,
3492                     &buf->m_fixedBuffer[buf->m_mappedOffset],
3493                     &host_res);
3494         } else {
3495             if (buf->m_mappedAccess & GL_MAP_WRITE_BIT) {
3496                 ctx->glUnmapBufferAEMU(
3497                         ctx, target,
3498                         buf->m_mappedOffset,
3499                         buf->m_mappedLength,
3500                         buf->m_mappedAccess,
3501                         &buf->m_fixedBuffer[buf->m_mappedOffset],
3502                         &host_res);
3503             }
3504         }
3505     }
3506 
3507     buf->m_mapped = false;
3508     buf->m_mappedAccess = 0;
3509     buf->m_mappedOffset = 0;
3510     buf->m_mappedLength = 0;
3511 
3512     return host_res;
3513 }
3514 
s_glFlushMappedBufferRange(void * self,GLenum target,GLintptr offset,GLsizeiptr length)3515 void GL2Encoder::s_glFlushMappedBufferRange(void* self, GLenum target, GLintptr offset, GLsizeiptr length) {
3516     GL2Encoder* ctx = (GL2Encoder*)self;
3517 
3518     SET_ERROR_IF(!GLESv2Validation::bufferTarget(ctx, target), GL_INVALID_ENUM);
3519 
3520     GLuint boundBuffer = ctx->m_state->getBuffer(target);
3521     SET_ERROR_IF(!boundBuffer, GL_INVALID_OPERATION);
3522 
3523     BufferData* buf = ctx->m_shared->getBufferData(boundBuffer);
3524     SET_ERROR_IF(!buf, GL_INVALID_VALUE);
3525     SET_ERROR_IF(!buf->m_mapped, GL_INVALID_OPERATION);
3526     SET_ERROR_IF(!(buf->m_mappedAccess & GL_MAP_FLUSH_EXPLICIT_BIT), GL_INVALID_OPERATION);
3527 
3528     SET_ERROR_IF(offset < 0, GL_INVALID_VALUE);
3529     SET_ERROR_IF(length < 0, GL_INVALID_VALUE);
3530     SET_ERROR_IF(offset + length > buf->m_mappedLength, GL_INVALID_VALUE);
3531 
3532     GLintptr totalOffset = buf->m_mappedOffset + offset;
3533 
3534     buf->m_indexRangeCache.invalidateRange(totalOffset, length);
3535 
3536     if (ctx->m_hasAsyncUnmapBuffer) {
3537         ctx->glFlushMappedBufferRangeAEMU2(
3538                 ctx, target,
3539                 totalOffset,
3540                 length,
3541                 buf->m_mappedAccess,
3542                 &buf->m_fixedBuffer[totalOffset]);
3543     } else {
3544         ctx->glFlushMappedBufferRangeAEMU(
3545                 ctx, target,
3546                 totalOffset,
3547                 length,
3548                 buf->m_mappedAccess,
3549                 &buf->m_fixedBuffer[totalOffset]);
3550     }
3551 }
3552 
s_glCompressedTexImage2D(void * self,GLenum target,GLint level,GLenum internalformat,GLsizei width,GLsizei height,GLint border,GLsizei imageSize,const GLvoid * data)3553 void GL2Encoder::s_glCompressedTexImage2D(void* self, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid* data) {
3554     GL2Encoder* ctx = (GL2Encoder*)self;
3555     GLClientState* state = ctx->m_state;
3556 
3557     SET_ERROR_IF(!GLESv2Validation::textureTarget(ctx, target), GL_INVALID_ENUM);
3558     SET_ERROR_IF(target == GL_TEXTURE_CUBE_MAP, GL_INVALID_ENUM);
3559     fprintf(stderr, "%s: format: 0x%x\n", __func__, internalformat);
3560     // Filter compressed formats support.
3561     SET_ERROR_IF(!GLESv2Validation::supportedCompressedFormat(ctx, internalformat), GL_INVALID_ENUM);
3562     // Verify level <= log2(GL_MAX_TEXTURE_SIZE).
3563     GLint max_texture_size;
3564     GLint max_cube_map_texture_size;
3565     ctx->glGetIntegerv(ctx, GL_MAX_TEXTURE_SIZE, &max_texture_size);
3566     ctx->glGetIntegerv(ctx, GL_MAX_CUBE_MAP_TEXTURE_SIZE, &max_cube_map_texture_size);
3567     SET_ERROR_IF(level < 0, GL_INVALID_VALUE);
3568     SET_ERROR_IF(level > ilog2(max_texture_size), GL_INVALID_VALUE);
3569     SET_ERROR_IF(level > ilog2(max_cube_map_texture_size), GL_INVALID_VALUE);
3570     SET_ERROR_IF(width > max_texture_size, GL_INVALID_VALUE);
3571     SET_ERROR_IF(height > max_texture_size, GL_INVALID_VALUE);
3572     SET_ERROR_IF(border, GL_INVALID_VALUE);
3573     // If unpack buffer is nonzero, verify unmapped state.
3574     SET_ERROR_IF(ctx->isBufferTargetMapped(GL_PIXEL_UNPACK_BUFFER), GL_INVALID_OPERATION);
3575     SET_ERROR_IF(width < 0 || height < 0, GL_INVALID_VALUE);
3576 
3577     // If unpack buffer is nonzero, verify buffer data fits.
3578     SET_ERROR_IF(ctx->boundBuffer(GL_PIXEL_UNPACK_BUFFER) &&
3579                  ctx->getBufferData(GL_PIXEL_UNPACK_BUFFER) &&
3580                  (imageSize > ctx->getBufferData(GL_PIXEL_UNPACK_BUFFER)->m_size),
3581                  GL_INVALID_OPERATION);
3582     SET_ERROR_IF(!ctx->m_state->compressedTexImageSizeCompatible(internalformat, width, height, 1, imageSize), GL_INVALID_VALUE);
3583 
3584     GLenum stateTarget = target;
3585     if (target == GL_TEXTURE_CUBE_MAP_POSITIVE_X ||
3586         target == GL_TEXTURE_CUBE_MAP_POSITIVE_Y ||
3587         target == GL_TEXTURE_CUBE_MAP_POSITIVE_Z ||
3588         target == GL_TEXTURE_CUBE_MAP_NEGATIVE_X ||
3589         target == GL_TEXTURE_CUBE_MAP_NEGATIVE_Y ||
3590         target == GL_TEXTURE_CUBE_MAP_NEGATIVE_Z)
3591         stateTarget = GL_TEXTURE_CUBE_MAP;
3592     state->setBoundTextureInternalFormat(stateTarget, (GLint)internalformat);
3593     state->setBoundTextureDims(stateTarget, target, level, width, height, 1);
3594 
3595     if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
3596         ctx->override2DTextureTarget(target);
3597     }
3598 
3599     if (ctx->boundBuffer(GL_PIXEL_UNPACK_BUFFER)) {
3600         ctx->glCompressedTexImage2DOffsetAEMU(
3601                 ctx, target, level, internalformat,
3602                 width, height, border,
3603                 imageSize, (uintptr_t)data);
3604     } else {
3605         ctx->m_glCompressedTexImage2D_enc(
3606                 ctx, target, level, internalformat,
3607                 width, height, border,
3608                 imageSize, data);
3609     }
3610 
3611     if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
3612         ctx->restore2DTextureTarget(target);
3613     }
3614 }
3615 
s_glCompressedTexSubImage2D(void * self,GLenum target,GLint level,GLint xoffset,GLint yoffset,GLsizei width,GLsizei height,GLenum format,GLsizei imageSize,const GLvoid * data)3616 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) {
3617     GL2Encoder* ctx = (GL2Encoder*)self;
3618 
3619     SET_ERROR_IF(!GLESv2Validation::textureTarget(ctx, target), GL_INVALID_ENUM);
3620     SET_ERROR_IF(target == GL_TEXTURE_CUBE_MAP, GL_INVALID_ENUM);
3621     // If unpack buffer is nonzero, verify unmapped state.
3622     SET_ERROR_IF(ctx->isBufferTargetMapped(GL_PIXEL_UNPACK_BUFFER), GL_INVALID_OPERATION);
3623 
3624     GLenum stateTarget = target;
3625     if (target == GL_TEXTURE_CUBE_MAP_POSITIVE_X ||
3626         target == GL_TEXTURE_CUBE_MAP_POSITIVE_Y ||
3627         target == GL_TEXTURE_CUBE_MAP_POSITIVE_Z ||
3628         target == GL_TEXTURE_CUBE_MAP_NEGATIVE_X ||
3629         target == GL_TEXTURE_CUBE_MAP_NEGATIVE_Y ||
3630         target == GL_TEXTURE_CUBE_MAP_NEGATIVE_Z)
3631         stateTarget = GL_TEXTURE_CUBE_MAP;
3632     GLuint tex = ctx->m_state->getBoundTexture(stateTarget);
3633 
3634     GLint internalFormat = ctx->m_state->queryTexInternalFormat(tex);
3635     SET_ERROR_IF(internalFormat != format, GL_INVALID_OPERATION);
3636     SET_ERROR_IF(level < 0, GL_INVALID_VALUE);
3637 
3638     GLint max_texture_size;
3639     GLint max_cube_map_texture_size;
3640     ctx->glGetIntegerv(ctx, GL_MAX_TEXTURE_SIZE, &max_texture_size);
3641     ctx->glGetIntegerv(ctx, GL_MAX_CUBE_MAP_TEXTURE_SIZE, &max_cube_map_texture_size);
3642     SET_ERROR_IF(level > ilog2(max_texture_size), GL_INVALID_VALUE);
3643     SET_ERROR_IF(level > ilog2(max_cube_map_texture_size), GL_INVALID_VALUE);
3644     SET_ERROR_IF(width < 0 || height < 0, GL_INVALID_VALUE);
3645     // If unpack buffer is nonzero, verify buffer data fits.
3646     SET_ERROR_IF(ctx->boundBuffer(GL_PIXEL_UNPACK_BUFFER) &&
3647                  ctx->getBufferData(GL_PIXEL_UNPACK_BUFFER) &&
3648                  (imageSize > ctx->getBufferData(GL_PIXEL_UNPACK_BUFFER)->m_size),
3649                  GL_INVALID_OPERATION);
3650     SET_ERROR_IF(xoffset < 0 || yoffset < 0, GL_INVALID_VALUE);
3651 
3652     GLint totalWidth = ctx->m_state->queryTexWidth(level, tex);
3653     GLint totalHeight = ctx->m_state->queryTexHeight(level, tex);
3654 
3655     if (GLESTextureUtils::isEtc2Format(internalFormat)) {
3656         SET_ERROR_IF((width % 4) && (totalWidth != xoffset + width), GL_INVALID_OPERATION);
3657         SET_ERROR_IF((height % 4) && (totalHeight != yoffset + height), GL_INVALID_OPERATION);
3658         SET_ERROR_IF((xoffset % 4) || (yoffset % 4), GL_INVALID_OPERATION);
3659     }
3660 
3661     SET_ERROR_IF(totalWidth < xoffset + width, GL_INVALID_VALUE);
3662     SET_ERROR_IF(totalHeight < yoffset + height, GL_INVALID_VALUE);
3663 
3664     SET_ERROR_IF(!ctx->m_state->compressedTexImageSizeCompatible(internalFormat, width, height, 1, imageSize), GL_INVALID_VALUE);
3665 
3666     if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
3667         ctx->override2DTextureTarget(target);
3668     }
3669 
3670     if (ctx->boundBuffer(GL_PIXEL_UNPACK_BUFFER)) {
3671         ctx->glCompressedTexSubImage2DOffsetAEMU(
3672                 ctx, target, level,
3673                 xoffset, yoffset,
3674                 width, height, format,
3675                 imageSize, (uintptr_t)data);
3676     } else {
3677         ctx->m_glCompressedTexSubImage2D_enc(
3678                 ctx, target, level,
3679                 xoffset, yoffset,
3680                 width, height, format,
3681                 imageSize, data);
3682     }
3683 
3684     if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
3685         ctx->restore2DTextureTarget(target);
3686     }
3687 }
3688 
s_glBindBufferRange(void * self,GLenum target,GLuint index,GLuint buffer,GLintptr offset,GLsizeiptr size)3689 void GL2Encoder::s_glBindBufferRange(void* self, GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size) {
3690     GL2Encoder* ctx = (GL2Encoder*)self;
3691     GLClientState* state = ctx->m_state;
3692 
3693     SET_ERROR_IF(!GLESv2Validation::bufferTarget(ctx, target), GL_INVALID_ENUM);
3694 
3695     // Only works with certain targets
3696     SET_ERROR_IF(
3697         !(target == GL_ATOMIC_COUNTER_BUFFER ||
3698           target == GL_SHADER_STORAGE_BUFFER ||
3699           target == GL_TRANSFORM_FEEDBACK_BUFFER ||
3700           target == GL_UNIFORM_BUFFER),
3701         GL_INVALID_ENUM);
3702 
3703     // Can't exceed range
3704     SET_ERROR_IF(index < 0 ||
3705                  index >= state->getMaxIndexedBufferBindings(target),
3706                  GL_INVALID_VALUE);
3707     SET_ERROR_IF(buffer && size <= 0, GL_INVALID_VALUE);
3708     SET_ERROR_IF((target == GL_ATOMIC_COUNTER_BUFFER ||
3709                   target == GL_TRANSFORM_FEEDBACK_BUFFER) &&
3710                  (size % 4 || offset % 4),
3711                  GL_INVALID_VALUE);
3712 
3713     GLint ssbo_offset_align, ubo_offset_align;
3714 
3715     if (ctx->majorVersion() >= 3 && ctx->minorVersion() >= 1) {
3716         ctx->s_glGetIntegerv(ctx, GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT, &ssbo_offset_align);
3717         SET_ERROR_IF(target == GL_SHADER_STORAGE_BUFFER &&
3718                      offset % ssbo_offset_align,
3719                      GL_INVALID_VALUE);
3720     }
3721 
3722     ctx->s_glGetIntegerv(ctx, GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT, &ubo_offset_align);
3723     SET_ERROR_IF(target == GL_UNIFORM_BUFFER &&
3724                  offset % ubo_offset_align,
3725                  GL_INVALID_VALUE);
3726 
3727     if (ctx->m_state->isIndexedBindNoOp(target, index, buffer, offset, size, 0, 0)) return;
3728 
3729     state->bindBuffer(target, buffer);
3730     ctx->m_state->addBuffer(buffer);
3731     state->bindIndexedBuffer(target, index, buffer, offset, size, 0, 0);
3732 
3733     ctx->m_glBindBufferRange_enc(ctx, target, index, buffer, offset, size);
3734     ctx->m_state->setLastEncodedBufferBind(target, buffer);
3735 }
3736 
s_glBindBufferBase(void * self,GLenum target,GLuint index,GLuint buffer)3737 void GL2Encoder::s_glBindBufferBase(void* self, GLenum target, GLuint index, GLuint buffer) {
3738     GL2Encoder* ctx = (GL2Encoder*)self;
3739     GLClientState* state = ctx->m_state;
3740 
3741     SET_ERROR_IF(!GLESv2Validation::bufferTarget(ctx, target), GL_INVALID_ENUM);
3742 
3743     // Only works with certain targets
3744     SET_ERROR_IF(
3745         !(target == GL_ATOMIC_COUNTER_BUFFER ||
3746           target == GL_SHADER_STORAGE_BUFFER ||
3747           target == GL_TRANSFORM_FEEDBACK_BUFFER ||
3748           target == GL_UNIFORM_BUFFER),
3749         GL_INVALID_ENUM);
3750     // Can't exceed range
3751     SET_ERROR_IF(index < 0 ||
3752                  index >= state->getMaxIndexedBufferBindings(target),
3753                  GL_INVALID_VALUE);
3754 
3755     BufferData* buf = ctx->getBufferDataById(buffer);
3756     GLsizeiptr size = buf ? buf->m_size : 0;
3757 
3758     if (ctx->m_state->isIndexedBindNoOp(target, index, buffer, 0, size, 0, 0)) return;
3759 
3760     state->bindBuffer(target, buffer);
3761     ctx->m_state->addBuffer(buffer);
3762 
3763     state->bindIndexedBuffer(target, index, buffer, 0, size, 0, 0);
3764 
3765     ctx->m_glBindBufferBase_enc(ctx, target, index, buffer);
3766     ctx->m_state->setLastEncodedBufferBind(target, buffer);
3767 }
3768 
doIndexedBufferBindEncodeCached(IndexedBufferBindOp op,GLenum target,GLuint index,GLuint buffer,GLintptr offset,GLsizeiptr size,GLintptr stride,GLintptr effectiveStride)3769 void GL2Encoder::doIndexedBufferBindEncodeCached(IndexedBufferBindOp op, GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size, GLintptr stride, GLintptr effectiveStride)
3770 {
3771     if (m_state->isIndexedBindNoOp(target, index, buffer, offset, size, stride, effectiveStride)) return;
3772 
3773     switch (op) {
3774         case BindBufferBase:
3775             // can emulate with bindBufferRange
3776         case BindBufferRange:
3777             m_glBindBufferRange_enc(this, target, index, buffer, offset, size);
3778             break;
3779         // TODO: other ops
3780     }
3781 
3782     m_state->setLastEncodedBufferBind(target, buffer);
3783 }
3784 
s_glCopyBufferSubData(void * self,GLenum readtarget,GLenum writetarget,GLintptr readoffset,GLintptr writeoffset,GLsizeiptr size)3785 void GL2Encoder::s_glCopyBufferSubData(void *self , GLenum readtarget, GLenum writetarget, GLintptr readoffset, GLintptr writeoffset, GLsizeiptr size) {
3786     GL2Encoder* ctx = (GL2Encoder*)self;
3787 
3788     SET_ERROR_IF(!GLESv2Validation::bufferTarget(ctx, readtarget), GL_INVALID_ENUM);
3789     SET_ERROR_IF(!GLESv2Validation::bufferTarget(ctx, writetarget), GL_INVALID_ENUM);
3790     SET_ERROR_IF((readtarget == GL_ATOMIC_COUNTER_BUFFER ||
3791                   readtarget == GL_DISPATCH_INDIRECT_BUFFER ||
3792                   readtarget == GL_DRAW_INDIRECT_BUFFER ||
3793                   readtarget == GL_SHADER_STORAGE_BUFFER), GL_INVALID_ENUM);
3794     SET_ERROR_IF((writetarget == GL_ATOMIC_COUNTER_BUFFER ||
3795                   writetarget == GL_DISPATCH_INDIRECT_BUFFER ||
3796                   writetarget == GL_DRAW_INDIRECT_BUFFER ||
3797                   writetarget == GL_SHADER_STORAGE_BUFFER), GL_INVALID_ENUM);
3798 
3799     GLuint readBufferId = ctx->boundBuffer(readtarget);
3800     GLuint writeBufferId = ctx->boundBuffer(writetarget);
3801 
3802     SET_ERROR_IF(!readBufferId || !writeBufferId, GL_INVALID_OPERATION);
3803 
3804     SET_ERROR_IF(ctx->isBufferTargetMapped(readtarget), GL_INVALID_OPERATION);
3805     SET_ERROR_IF(ctx->isBufferTargetMapped(writetarget), GL_INVALID_OPERATION);
3806 
3807     SET_ERROR_IF(readoffset < 0, GL_INVALID_VALUE);
3808     SET_ERROR_IF(writeoffset < 0, GL_INVALID_VALUE);
3809     SET_ERROR_IF(size < 0, GL_INVALID_VALUE);
3810 
3811     BufferData* readBufferData = ctx->getBufferData(readtarget);
3812     BufferData* writeBufferData = ctx->getBufferData(writetarget);
3813 
3814     SET_ERROR_IF(
3815         readBufferData &&
3816         (readoffset + size > readBufferData->m_size),
3817         GL_INVALID_VALUE);
3818 
3819     SET_ERROR_IF(
3820         writeBufferData &&
3821         (writeoffset + size > writeBufferData->m_size),
3822         GL_INVALID_VALUE);
3823 
3824     SET_ERROR_IF(readBufferId == writeBufferId &&
3825                  !((writeoffset >= readoffset + size) ||
3826                    (readoffset >= writeoffset + size)),
3827                  GL_INVALID_VALUE);
3828 
3829     ctx->m_glCopyBufferSubData_enc(self, readtarget, writetarget, readoffset, writeoffset, size);
3830 }
3831 
s_glGetBufferParameteriv(void * self,GLenum target,GLenum pname,GLint * params)3832 void GL2Encoder::s_glGetBufferParameteriv(void* self, GLenum target, GLenum pname, GLint* params) {
3833     GL2Encoder* ctx = (GL2Encoder*)self;
3834 
3835     SET_ERROR_IF(!GLESv2Validation::bufferTarget(ctx, target), GL_INVALID_ENUM);
3836     SET_ERROR_IF(
3837         target != GL_ARRAY_BUFFER &&
3838         target != GL_ELEMENT_ARRAY_BUFFER &&
3839         target != GL_COPY_READ_BUFFER &&
3840         target != GL_COPY_WRITE_BUFFER &&
3841         target != GL_PIXEL_PACK_BUFFER &&
3842         target != GL_PIXEL_UNPACK_BUFFER &&
3843         target != GL_TRANSFORM_FEEDBACK_BUFFER &&
3844         target != GL_UNIFORM_BUFFER,
3845         GL_INVALID_ENUM);
3846     SET_ERROR_IF(!GLESv2Validation::bufferParam(ctx, pname), GL_INVALID_ENUM);
3847     SET_ERROR_IF(!ctx->boundBuffer(target), GL_INVALID_OPERATION);
3848     SET_ERROR_IF(pname != GL_BUFFER_ACCESS_FLAGS &&
3849                  pname != GL_BUFFER_MAPPED &&
3850                  pname != GL_BUFFER_SIZE &&
3851                  pname != GL_BUFFER_USAGE &&
3852                  pname != GL_BUFFER_MAP_LENGTH &&
3853                  pname != GL_BUFFER_MAP_OFFSET,
3854                  GL_INVALID_ENUM);
3855 
3856     if (!params) return;
3857 
3858     BufferData* buf = ctx->getBufferData(target);
3859 
3860     switch (pname) {
3861         case GL_BUFFER_ACCESS_FLAGS:
3862             *params = buf ? buf->m_mappedAccess : 0;
3863             break;
3864         case GL_BUFFER_MAPPED:
3865             *params = buf ? (buf->m_mapped ? GL_TRUE : GL_FALSE) : GL_FALSE;
3866             break;
3867         case GL_BUFFER_SIZE:
3868             *params = buf ? buf->m_size : 0;
3869             break;
3870         case GL_BUFFER_USAGE:
3871             *params = buf ? buf->m_usage : GL_STATIC_DRAW;
3872             break;
3873         case GL_BUFFER_MAP_LENGTH:
3874             *params = buf ? buf->m_mappedLength : 0;
3875             break;
3876         case GL_BUFFER_MAP_OFFSET:
3877             *params = buf ? buf->m_mappedOffset : 0;
3878             break;
3879         default:
3880             break;
3881     }
3882 }
3883 
s_glGetBufferParameteri64v(void * self,GLenum target,GLenum pname,GLint64 * params)3884 void GL2Encoder::s_glGetBufferParameteri64v(void* self, GLenum target, GLenum pname, GLint64* params) {
3885     GL2Encoder* ctx = (GL2Encoder*)self;
3886 
3887     SET_ERROR_IF(!GLESv2Validation::bufferTarget(ctx, target), GL_INVALID_ENUM);
3888     SET_ERROR_IF(
3889         target != GL_ARRAY_BUFFER &&
3890         target != GL_ELEMENT_ARRAY_BUFFER &&
3891         target != GL_COPY_READ_BUFFER &&
3892         target != GL_COPY_WRITE_BUFFER &&
3893         target != GL_PIXEL_PACK_BUFFER &&
3894         target != GL_PIXEL_UNPACK_BUFFER &&
3895         target != GL_TRANSFORM_FEEDBACK_BUFFER &&
3896         target != GL_UNIFORM_BUFFER,
3897         GL_INVALID_ENUM);
3898     SET_ERROR_IF(!GLESv2Validation::bufferParam(ctx, pname), GL_INVALID_ENUM);
3899     SET_ERROR_IF(!ctx->boundBuffer(target), GL_INVALID_OPERATION);
3900     SET_ERROR_IF(pname != GL_BUFFER_ACCESS_FLAGS &&
3901                  pname != GL_BUFFER_MAPPED &&
3902                  pname != GL_BUFFER_SIZE &&
3903                  pname != GL_BUFFER_USAGE &&
3904                  pname != GL_BUFFER_MAP_LENGTH &&
3905                  pname != GL_BUFFER_MAP_OFFSET,
3906                  GL_INVALID_ENUM);
3907 
3908     if (!params) return;
3909 
3910     BufferData* buf = ctx->getBufferData(target);
3911 
3912     switch (pname) {
3913         case GL_BUFFER_ACCESS_FLAGS:
3914             *params = buf ? buf->m_mappedAccess : 0;
3915             break;
3916         case GL_BUFFER_MAPPED:
3917             *params = buf ? (buf->m_mapped ? GL_TRUE : GL_FALSE) : GL_FALSE;
3918             break;
3919         case GL_BUFFER_SIZE:
3920             *params = buf ? buf->m_size : 0;
3921             break;
3922         case GL_BUFFER_USAGE:
3923             *params = buf ? buf->m_usage : GL_STATIC_DRAW;
3924             break;
3925         case GL_BUFFER_MAP_LENGTH:
3926             *params = buf ? buf->m_mappedLength : 0;
3927             break;
3928         case GL_BUFFER_MAP_OFFSET:
3929             *params = buf ? buf->m_mappedOffset : 0;
3930             break;
3931         default:
3932             break;
3933     }
3934 }
3935 
s_glGetBufferPointerv(void * self,GLenum target,GLenum pname,GLvoid ** params)3936 void GL2Encoder::s_glGetBufferPointerv(void* self, GLenum target, GLenum pname, GLvoid** params) {
3937     GL2Encoder* ctx = (GL2Encoder*)self;
3938     SET_ERROR_IF(!GLESv2Validation::bufferTarget(ctx, target), GL_INVALID_ENUM);
3939     SET_ERROR_IF(
3940         target == GL_ATOMIC_COUNTER_BUFFER ||
3941         target == GL_DISPATCH_INDIRECT_BUFFER ||
3942         target == GL_DRAW_INDIRECT_BUFFER ||
3943         target == GL_SHADER_STORAGE_BUFFER,
3944         GL_INVALID_ENUM);
3945     SET_ERROR_IF(pname != GL_BUFFER_MAP_POINTER, GL_INVALID_ENUM);
3946     SET_ERROR_IF(!ctx->boundBuffer(target), GL_INVALID_OPERATION);
3947     if (!params) return;
3948 
3949     BufferData* buf = ctx->getBufferData(target);
3950 
3951     if (!buf || !buf->m_mapped) { *params = NULL; return; }
3952 
3953     *params = &buf->m_fixedBuffer[buf->m_mappedOffset];
3954 }
3955 
3956 static const char* const kNameDelimiter = ";";
3957 
packVarNames(GLsizei count,const char ** names,GLint * err_out)3958 static std::string packVarNames(GLsizei count, const char** names, GLint* err_out) {
3959 
3960 #define VALIDATE(cond, err) if (cond) { *err_out = err; return packed; } \
3961 
3962     std::string packed;
3963     // validate the array of char[]'s
3964     const char* currName;
3965     for (GLsizei i = 0; i < count; i++) {
3966         currName = names[i];
3967         VALIDATE(!currName, GL_INVALID_OPERATION);
3968         // check if has reasonable size
3969         size_t len = strlen(currName);
3970         VALIDATE(!len, GL_INVALID_OPERATION);
3971         // check for our delimiter, which if present
3972         // in the name, means an invalid name anyway.
3973         VALIDATE(strstr(currName, kNameDelimiter),
3974                  GL_INVALID_OPERATION);
3975         packed += currName;
3976         packed += ";";
3977     }
3978 
3979     *err_out = GL_NO_ERROR;
3980     return packed;
3981 }
3982 
s_glGetUniformIndices(void * self,GLuint program,GLsizei uniformCount,const GLchar ** uniformNames,GLuint * uniformIndices)3983 void GL2Encoder::s_glGetUniformIndices(void* self, GLuint program, GLsizei uniformCount, const GLchar ** uniformNames, GLuint* uniformIndices) {
3984     GL2Encoder* ctx = (GL2Encoder*)self;
3985 
3986     VALIDATE_PROGRAM_NAME(program);
3987 
3988     if (!uniformCount) return;
3989 
3990     GLint err = GL_NO_ERROR;
3991     std::string packed = packVarNames(uniformCount, (const char**)uniformNames, &err);
3992     SET_ERROR_IF(err != GL_NO_ERROR, GL_INVALID_OPERATION);
3993 
3994     std::vector<int> arrIndices;
3995     for (size_t i = 0; i < uniformCount; i++) {
3996         int err;
3997         arrIndices.push_back(sArrIndexOfUniformExpr(uniformNames[i], &err));
3998         if (err) {
3999             ALOGE("%s: invalid uniform name %s!", __FUNCTION__, uniformNames[i]);
4000             return;
4001         }
4002     }
4003 
4004     ctx->glGetUniformIndicesAEMU(ctx, program, uniformCount, (const GLchar*)&packed[0], packed.size() + 1, uniformIndices);
4005 }
4006 
s_glUniform1ui(void * self,GLint location,GLuint v0)4007 void GL2Encoder::s_glUniform1ui(void* self, GLint location, GLuint v0) {
4008     GL2Encoder *ctx = (GL2Encoder*)self;
4009     GLClientState* state = ctx->m_state;
4010     GLSharedGroupPtr shared = ctx->m_shared;
4011 
4012     ctx->m_state->validateUniform(false /* is float? */, true /* is unsigned? */, 1 /* columns */, 1 /* rows */, location, 1 /* count */, ctx->getErrorPtr());
4013     ctx->m_glUniform1ui_enc(self, location, v0);
4014 
4015     GLenum target;
4016     if (shared->setSamplerUniform(state->currentShaderProgram(), location, v0, &target)) {
4017         GLenum origActiveTexture = state->getActiveTextureUnit();
4018         if (ctx->updateHostTexture2DBinding(GL_TEXTURE0 + v0, target)) {
4019             ctx->m_glActiveTexture_enc(self, origActiveTexture);
4020         }
4021         state->setActiveTextureUnit(origActiveTexture);
4022     }
4023 }
4024 
s_glUniform2ui(void * self,GLint location,GLuint v0,GLuint v1)4025 void GL2Encoder::s_glUniform2ui(void* self, GLint location, GLuint v0, GLuint v1) {
4026     GL2Encoder *ctx = (GL2Encoder*)self;
4027     ctx->m_state->validateUniform(false /* is float? */, true /* is unsigned? */, 2 /* columns */, 1 /* rows */, location, 1 /* count */, ctx->getErrorPtr());
4028     ctx->m_glUniform2ui_enc(self, location, v0, v1);
4029 }
4030 
s_glUniform3ui(void * self,GLint location,GLuint v0,GLuint v1,GLuint v2)4031 void GL2Encoder::s_glUniform3ui(void* self, GLint location, GLuint v0, GLuint v1, GLuint v2) {
4032     GL2Encoder *ctx = (GL2Encoder*)self;
4033     ctx->m_state->validateUniform(false /* is float? */, true /* is unsigned? */, 3 /* columns */, 1 /* rows */, location, 1 /* count */, ctx->getErrorPtr());
4034     ctx->m_glUniform3ui_enc(self, location, v0, v1, v2);
4035 }
4036 
s_glUniform4ui(void * self,GLint location,GLint v0,GLuint v1,GLuint v2,GLuint v3)4037 void GL2Encoder::s_glUniform4ui(void* self, GLint location, GLint v0, GLuint v1, GLuint v2, GLuint v3) {
4038     GL2Encoder *ctx = (GL2Encoder*)self;
4039     ctx->m_state->validateUniform(false /* is float? */, true /* is unsigned? */, 4 /* columns */, 1 /* rows */, location, 1 /* count */, ctx->getErrorPtr());
4040     ctx->m_glUniform4ui_enc(self, location, v0, v1, v2, v3);
4041 }
4042 
s_glUniform1uiv(void * self,GLint location,GLsizei count,const GLuint * value)4043 void GL2Encoder::s_glUniform1uiv(void* self, GLint location, GLsizei count, const GLuint *value) {
4044     GL2Encoder *ctx = (GL2Encoder*)self;
4045     ctx->m_state->validateUniform(false /* is float? */, true /* is unsigned? */, 1 /* columns */, 1 /* rows */, location, count /* count */, ctx->getErrorPtr());
4046     ctx->m_glUniform1uiv_enc(self, location, count, value);
4047 }
4048 
s_glUniform2uiv(void * self,GLint location,GLsizei count,const GLuint * value)4049 void GL2Encoder::s_glUniform2uiv(void* self, GLint location, GLsizei count, const GLuint *value) {
4050     GL2Encoder *ctx = (GL2Encoder*)self;
4051     ctx->m_state->validateUniform(false /* is float? */, true /* is unsigned? */, 2 /* columns */, 1 /* rows */, location, count /* count */, ctx->getErrorPtr());
4052     ctx->m_glUniform2uiv_enc(self, location, count, value);
4053 }
4054 
s_glUniform3uiv(void * self,GLint location,GLsizei count,const GLuint * value)4055 void GL2Encoder::s_glUniform3uiv(void* self, GLint location, GLsizei count, const GLuint *value) {
4056     GL2Encoder *ctx = (GL2Encoder*)self;
4057     ctx->m_state->validateUniform(false /* is float? */, true /* is unsigned? */, 3 /* columns */, 1 /* rows */, location, count /* count */, ctx->getErrorPtr());
4058     ctx->m_glUniform3uiv_enc(self, location, count, value);
4059 }
4060 
s_glUniform4uiv(void * self,GLint location,GLsizei count,const GLuint * value)4061 void GL2Encoder::s_glUniform4uiv(void* self, GLint location, GLsizei count, const GLuint *value) {
4062     GL2Encoder *ctx = (GL2Encoder*)self;
4063     ctx->m_state->validateUniform(false /* is float? */, true /* is unsigned? */, 4 /* columns */, 1 /* rows */, location, count /* count */, ctx->getErrorPtr());
4064     ctx->m_glUniform4uiv_enc(self, location, count, value);
4065 }
4066 
s_glUniformMatrix2x3fv(void * self,GLint location,GLsizei count,GLboolean transpose,const GLfloat * value)4067 void GL2Encoder::s_glUniformMatrix2x3fv(void* self, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) {
4068     GL2Encoder *ctx = (GL2Encoder*)self;
4069     ctx->m_state->validateUniform(true /* is float? */, false /* is unsigned? */, 2 /* columns */, 3 /* rows */, location, count /* count */, ctx->getErrorPtr());
4070     ctx->m_glUniformMatrix2x3fv_enc(self, location, count, transpose, value);
4071 }
4072 
s_glUniformMatrix3x2fv(void * self,GLint location,GLsizei count,GLboolean transpose,const GLfloat * value)4073 void GL2Encoder::s_glUniformMatrix3x2fv(void* self, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) {
4074     GL2Encoder *ctx = (GL2Encoder*)self;
4075     ctx->m_state->validateUniform(true /* is float? */, false /* is unsigned? */, 3 /* columns */, 2 /* rows */, location, count /* count */, ctx->getErrorPtr());
4076     ctx->m_glUniformMatrix3x2fv_enc(self, location, count, transpose, value);
4077 }
4078 
s_glUniformMatrix2x4fv(void * self,GLint location,GLsizei count,GLboolean transpose,const GLfloat * value)4079 void GL2Encoder::s_glUniformMatrix2x4fv(void* self, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) {
4080     GL2Encoder *ctx = (GL2Encoder*)self;
4081     ctx->m_state->validateUniform(true /* is float? */, false /* is unsigned? */, 2 /* columns */, 4 /* rows */, location, count /* count */, ctx->getErrorPtr());
4082     ctx->m_glUniformMatrix2x4fv_enc(self, location, count, transpose, value);
4083 }
4084 
s_glUniformMatrix4x2fv(void * self,GLint location,GLsizei count,GLboolean transpose,const GLfloat * value)4085 void GL2Encoder::s_glUniformMatrix4x2fv(void* self, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) {
4086     GL2Encoder *ctx = (GL2Encoder*)self;
4087     ctx->m_state->validateUniform(true /* is float? */, false /* is unsigned? */, 4 /* columns */, 2 /* rows */, location, count /* count */, ctx->getErrorPtr());
4088     ctx->m_glUniformMatrix4x2fv_enc(self, location, count, transpose, value);
4089 }
4090 
s_glUniformMatrix3x4fv(void * self,GLint location,GLsizei count,GLboolean transpose,const GLfloat * value)4091 void GL2Encoder::s_glUniformMatrix3x4fv(void* self, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) {
4092     GL2Encoder *ctx = (GL2Encoder*)self;
4093     ctx->m_state->validateUniform(true /* is float? */, false /* is unsigned? */, 3 /* columns */, 4 /* rows */, location, count /* count */, ctx->getErrorPtr());
4094     ctx->m_glUniformMatrix3x4fv_enc(self, location, count, transpose, value);
4095 }
4096 
s_glUniformMatrix4x3fv(void * self,GLint location,GLsizei count,GLboolean transpose,const GLfloat * value)4097 void GL2Encoder::s_glUniformMatrix4x3fv(void* self, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) {
4098     GL2Encoder *ctx = (GL2Encoder*)self;
4099     ctx->m_state->validateUniform(true /* is float? */, false /* is unsigned? */, 4 /* columns */, 3 /* rows */, location, count /* count */, ctx->getErrorPtr());
4100     ctx->m_glUniformMatrix4x3fv_enc(self, location, count, transpose, value);
4101 }
4102 
s_glGetUniformuiv(void * self,GLuint program,GLint location,GLuint * params)4103 void GL2Encoder::s_glGetUniformuiv(void* self, GLuint program, GLint location, GLuint* params) {
4104     GL2Encoder *ctx = (GL2Encoder*)self;
4105     SET_ERROR_IF(!ctx->m_shared->isShaderOrProgramObject(program), GL_INVALID_VALUE);
4106     SET_ERROR_IF(!ctx->m_shared->isProgram(program), GL_INVALID_OPERATION);
4107     SET_ERROR_IF(!ctx->m_shared->isProgramInitialized(program), GL_INVALID_OPERATION);
4108     SET_ERROR_IF(ctx->m_shared->getProgramUniformType(program,location)==0, GL_INVALID_OPERATION);
4109     SET_ERROR_IF(!ctx->m_shared->isProgramUniformLocationValid(program,location), GL_INVALID_OPERATION);
4110     ctx->m_glGetUniformuiv_enc(self, program, location, params);
4111 }
4112 
s_glGetActiveUniformBlockiv(void * self,GLuint program,GLuint uniformBlockIndex,GLenum pname,GLint * params)4113 void GL2Encoder::s_glGetActiveUniformBlockiv(void* self, GLuint program, GLuint uniformBlockIndex, GLenum pname, GLint* params) {
4114     GL2Encoder* ctx = (GL2Encoder*)self;
4115 
4116     VALIDATE_PROGRAM_NAME(program);
4117     SET_ERROR_IF(!GLESv2Validation::allowedGetActiveUniformBlock(pname), GL_INVALID_ENUM);
4118     SET_ERROR_IF(uniformBlockIndex >= ctx->m_shared->getActiveUniformBlockCount(program), GL_INVALID_VALUE);
4119 
4120     // refresh client state's # active uniforms in this block
4121     if (pname == GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES) {
4122         // TODO if worth it: cache uniform count and other params,
4123         // invalidate on program relinking.
4124         GLint numActiveUniforms;
4125         ctx->m_glGetActiveUniformBlockiv_enc(ctx,
4126                 program, uniformBlockIndex,
4127                 GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS,
4128                 &numActiveUniforms);
4129         ctx->m_state->setNumActiveUniformsInUniformBlock(
4130                 program, uniformBlockIndex, numActiveUniforms);
4131     }
4132 
4133     ctx->m_glGetActiveUniformBlockiv_enc(ctx,
4134             program, uniformBlockIndex,
4135             pname, params);
4136 }
4137 
s_glGetVertexAttribIiv(void * self,GLuint index,GLenum pname,GLint * params)4138 void GL2Encoder::s_glGetVertexAttribIiv(void* self, GLuint index, GLenum pname, GLint* params) {
4139     GL2Encoder *ctx = (GL2Encoder *)self;
4140     VALIDATE_VERTEX_ATTRIB_INDEX(index);
4141     SET_ERROR_IF(!GLESv2Validation::allowedGetVertexAttrib(pname), GL_INVALID_ENUM);
4142 
4143     if (!ctx->m_state->getVertexAttribParameter<GLint>(index, pname, params)) {
4144         ctx->m_glGetVertexAttribIiv_enc(self, index, pname, params);
4145     }
4146 }
4147 
s_glGetVertexAttribIuiv(void * self,GLuint index,GLenum pname,GLuint * params)4148 void GL2Encoder::s_glGetVertexAttribIuiv(void* self, GLuint index, GLenum pname, GLuint* params) {
4149     GL2Encoder *ctx = (GL2Encoder *)self;
4150     VALIDATE_VERTEX_ATTRIB_INDEX(index);
4151     SET_ERROR_IF(!GLESv2Validation::allowedGetVertexAttrib(pname), GL_INVALID_ENUM);
4152 
4153     if (!ctx->m_state->getVertexAttribParameter<GLuint>(index, pname, params)) {
4154         ctx->m_glGetVertexAttribIuiv_enc(self, index, pname, params);
4155     }
4156 }
4157 
s_glVertexAttribIPointer(void * self,GLuint index,GLint size,GLenum type,GLsizei stride,const GLvoid * pointer)4158 void GL2Encoder::s_glVertexAttribIPointer(void* self, GLuint index, GLint size, GLenum type, GLsizei stride, const GLvoid* pointer) {
4159     GL2Encoder *ctx = (GL2Encoder *)self;
4160     assert(ctx->m_state != NULL);
4161     VALIDATE_VERTEX_ATTRIB_INDEX(index);
4162     SET_ERROR_IF((size < 1 || size > 4), GL_INVALID_VALUE);
4163     SET_ERROR_IF(
4164         !(type == GL_BYTE ||
4165           type == GL_UNSIGNED_BYTE ||
4166           type == GL_SHORT ||
4167           type == GL_UNSIGNED_SHORT ||
4168           type == GL_INT ||
4169           type == GL_UNSIGNED_INT),
4170         GL_INVALID_ENUM);
4171     SET_ERROR_IF(stride < 0, GL_INVALID_VALUE);
4172 
4173     ctx->m_state->setVertexAttribBinding(index, index);
4174     ctx->m_state->setVertexAttribFormat(index, size, type, false, 0, true);
4175     GLsizei effectiveStride = stride;
4176     if (stride == 0) {
4177         effectiveStride = glSizeof(type) * size;
4178     }
4179     ctx->m_state->bindIndexedBuffer(0, index, ctx->m_state->currentArrayVbo(), (uintptr_t)pointer, 0, stride, effectiveStride);
4180 
4181     if (ctx->m_state->currentArrayVbo() != 0) {
4182         ctx->glVertexAttribIPointerOffsetAEMU(ctx, index, size, type, stride, (uintptr_t)pointer);
4183     } else {
4184         SET_ERROR_IF(ctx->m_state->currentVertexArrayObject() != 0 && pointer, GL_INVALID_OPERATION);
4185         // wait for client-array handler
4186     }
4187 }
4188 
s_glVertexAttribDivisor(void * self,GLuint index,GLuint divisor)4189 void GL2Encoder::s_glVertexAttribDivisor(void* self, GLuint index, GLuint divisor) {
4190     GL2Encoder *ctx = (GL2Encoder *)self;
4191     assert(ctx->m_state != NULL);
4192     VALIDATE_VERTEX_ATTRIB_INDEX(index);
4193     ctx->m_state->setVertexAttribBinding(index, index);
4194     ctx->m_state->setVertexBindingDivisor(index, divisor);
4195     ctx->m_glVertexAttribDivisor_enc(ctx, index, divisor);
4196 }
4197 
s_glRenderbufferStorageMultisample(void * self,GLenum target,GLsizei samples,GLenum internalformat,GLsizei width,GLsizei height)4198 void GL2Encoder::s_glRenderbufferStorageMultisample(void* self,
4199         GLenum target, GLsizei samples, GLenum internalformat,
4200         GLsizei width, GLsizei height) {
4201     GL2Encoder *ctx = (GL2Encoder *)self;
4202     GLClientState* state = ctx->m_state;
4203 
4204     SET_ERROR_IF(target != GL_RENDERBUFFER, GL_INVALID_ENUM);
4205     SET_ERROR_IF(!GLESv2Validation::rboFormat(ctx, internalformat), GL_INVALID_ENUM);
4206 
4207     SET_ERROR_IF(width < 0 || height < 0, GL_INVALID_VALUE);
4208     GLint max_rb_size;
4209     ctx->glGetIntegerv(ctx, GL_MAX_RENDERBUFFER_SIZE, &max_rb_size);
4210     SET_ERROR_IF(width > max_rb_size || height > max_rb_size, GL_INVALID_VALUE);
4211 
4212     GLint max_samples;
4213     ctx->s_glGetInternalformativ(ctx, target, internalformat, GL_SAMPLES, 1, &max_samples);
4214     SET_ERROR_IF(samples > max_samples, GL_INVALID_OPERATION);
4215 
4216     state->setBoundRenderbufferFormat(internalformat);
4217     state->setBoundRenderbufferSamples(samples);
4218     state->setBoundRenderbufferDimensions(width, height);
4219     ctx->m_glRenderbufferStorageMultisample_enc(
4220             self, target, samples, internalformat, width, height);
4221 }
4222 
s_glDrawBuffers(void * self,GLsizei n,const GLenum * bufs)4223 void GL2Encoder::s_glDrawBuffers(void* self, GLsizei n, const GLenum* bufs) {
4224     GL2Encoder* ctx = (GL2Encoder*)self;
4225     SET_ERROR_IF(!ctx->m_state->boundFramebuffer(GL_DRAW_FRAMEBUFFER) && n > 1, GL_INVALID_OPERATION);
4226     SET_ERROR_IF(n < 0 || n > ctx->m_state->getMaxDrawBuffers(), GL_INVALID_VALUE);
4227     for (int i = 0; i < n; i++) {
4228         SET_ERROR_IF(
4229             bufs[i] != GL_NONE &&
4230             bufs[i] != GL_BACK &&
4231             glUtilsColorAttachmentIndex(bufs[i]) == -1,
4232             GL_INVALID_ENUM);
4233         SET_ERROR_IF(
4234             !ctx->m_state->boundFramebuffer(GL_DRAW_FRAMEBUFFER) &&
4235             glUtilsColorAttachmentIndex(bufs[i]) != -1,
4236             GL_INVALID_OPERATION);
4237         SET_ERROR_IF(
4238             ctx->m_state->boundFramebuffer(GL_DRAW_FRAMEBUFFER) &&
4239             ((glUtilsColorAttachmentIndex(bufs[i]) != -1 &&
4240               glUtilsColorAttachmentIndex(bufs[i]) != i) ||
4241              (glUtilsColorAttachmentIndex(bufs[i]) == -1 &&
4242               bufs[i] != GL_NONE)),
4243             GL_INVALID_OPERATION);
4244     }
4245 
4246     ctx->m_glDrawBuffers_enc(ctx, n, bufs);
4247 }
4248 
s_glReadBuffer(void * self,GLenum src)4249 void GL2Encoder::s_glReadBuffer(void* self, GLenum src) {
4250     GL2Encoder* ctx = (GL2Encoder*)self;
4251 
4252     SET_ERROR_IF(
4253         glUtilsColorAttachmentIndex(src) != -1 &&
4254          (glUtilsColorAttachmentIndex(src) >=
4255          ctx->m_state->getMaxColorAttachments()),
4256         GL_INVALID_OPERATION);
4257     SET_ERROR_IF(
4258         src != GL_NONE &&
4259         src != GL_BACK &&
4260         src > GL_COLOR_ATTACHMENT0 &&
4261         src < GL_DEPTH_ATTACHMENT &&
4262         (src - GL_COLOR_ATTACHMENT0) >
4263         ctx->m_state->getMaxColorAttachments(),
4264         GL_INVALID_OPERATION);
4265     SET_ERROR_IF(
4266         src != GL_NONE &&
4267         src != GL_BACK &&
4268         glUtilsColorAttachmentIndex(src) == -1,
4269         GL_INVALID_ENUM);
4270     SET_ERROR_IF(
4271         !ctx->m_state->boundFramebuffer(GL_READ_FRAMEBUFFER) &&
4272         src != GL_NONE &&
4273         src != GL_BACK,
4274         GL_INVALID_OPERATION);
4275     SET_ERROR_IF(
4276         ctx->m_state->boundFramebuffer(GL_READ_FRAMEBUFFER) &&
4277         src != GL_NONE &&
4278         glUtilsColorAttachmentIndex(src) == -1,
4279         GL_INVALID_OPERATION);
4280 
4281     ctx->m_glReadBuffer_enc(ctx, src);
4282 }
4283 
s_glFramebufferTextureLayer(void * self,GLenum target,GLenum attachment,GLuint texture,GLint level,GLint layer)4284 void GL2Encoder::s_glFramebufferTextureLayer(void* self, GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer) {
4285     GL2Encoder* ctx = (GL2Encoder*)self;
4286     GLClientState* state = ctx->m_state;
4287 
4288     SET_ERROR_IF(!GLESv2Validation::framebufferTarget(ctx, target), GL_INVALID_ENUM);
4289     SET_ERROR_IF(!GLESv2Validation::framebufferAttachment(ctx, attachment), GL_INVALID_ENUM);
4290     SET_ERROR_IF(texture != 0 && layer < 0, GL_INVALID_VALUE);
4291     GLint maxArrayTextureLayers;
4292     ctx->glGetIntegerv(ctx, GL_MAX_ARRAY_TEXTURE_LAYERS, &maxArrayTextureLayers);
4293     SET_ERROR_IF(texture != 0 && layer > maxArrayTextureLayers - 1, GL_INVALID_VALUE);
4294     SET_ERROR_IF(!ctx->m_state->boundFramebuffer(target), GL_INVALID_OPERATION);
4295     GLenum lastBoundTarget = state->queryTexLastBoundTarget(texture);
4296     SET_ERROR_IF(lastBoundTarget != GL_TEXTURE_2D_ARRAY &&
4297                  lastBoundTarget != GL_TEXTURE_3D,
4298                  GL_INVALID_OPERATION);
4299     state->attachTextureObject(target, attachment, texture, level, layer);
4300 
4301     GLint max3DTextureSize;
4302     ctx->glGetIntegerv(ctx, GL_MAX_3D_TEXTURE_SIZE, &max3DTextureSize);
4303     SET_ERROR_IF(
4304             layer >= max3DTextureSize,
4305             GL_INVALID_VALUE);
4306 
4307     ctx->m_glFramebufferTextureLayer_enc(self, target, attachment, texture, level, layer);
4308 }
4309 
s_glTexStorage2D(void * self,GLenum target,GLsizei levels,GLenum internalformat,GLsizei width,GLsizei height)4310 void GL2Encoder::s_glTexStorage2D(void* self, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height) {
4311     GL2Encoder* ctx = (GL2Encoder*)self;
4312     GLClientState* state = ctx->m_state;
4313 
4314     SET_ERROR_IF(
4315         target != GL_TEXTURE_2D &&
4316         target != GL_TEXTURE_CUBE_MAP,
4317         GL_INVALID_ENUM);
4318     SET_ERROR_IF(!GLESv2Validation::pixelInternalFormat(internalformat), GL_INVALID_ENUM);
4319     SET_ERROR_IF(!state->getBoundTexture(target), GL_INVALID_OPERATION);
4320     SET_ERROR_IF(levels < 1 || width < 1 || height < 1, GL_INVALID_VALUE);
4321     SET_ERROR_IF(levels > ilog2((uint32_t)std::max(width, height)) + 1,
4322                  GL_INVALID_OPERATION);
4323     SET_ERROR_IF(state->isBoundTextureImmutableFormat(target), GL_INVALID_OPERATION);
4324 
4325     state->setBoundTextureInternalFormat(target, internalformat);
4326     state->setBoundTextureDims(target, -1 /* set all cube dimensions */, -1, width, height, 1);
4327     state->setBoundTextureImmutableFormat(target);
4328 
4329     if (target == GL_TEXTURE_2D) {
4330         ctx->override2DTextureTarget(target);
4331     }
4332 
4333     ctx->m_glTexStorage2D_enc(ctx, target, levels, internalformat, width, height);
4334 
4335     if (target == GL_TEXTURE_2D) {
4336         ctx->restore2DTextureTarget(target);
4337     }
4338 }
4339 
s_glTransformFeedbackVaryings(void * self,GLuint program,GLsizei count,const char ** varyings,GLenum bufferMode)4340 void GL2Encoder::s_glTransformFeedbackVaryings(void* self, GLuint program, GLsizei count, const char** varyings, GLenum bufferMode) {
4341     GL2Encoder* ctx = (GL2Encoder*)self;
4342 
4343     SET_ERROR_IF(!ctx->m_shared->isProgram(program), GL_INVALID_VALUE);
4344 
4345     GLint maxCount = 0;
4346     ctx->glGetIntegerv(ctx, GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS, &maxCount);
4347 
4348     SET_ERROR_IF(
4349         bufferMode == GL_SEPARATE_ATTRIBS &&
4350         maxCount < count,
4351         GL_INVALID_VALUE);
4352     SET_ERROR_IF(
4353         bufferMode != GL_INTERLEAVED_ATTRIBS &&
4354         bufferMode != GL_SEPARATE_ATTRIBS,
4355         GL_INVALID_ENUM);
4356 
4357     // NOTE: This only has an effect on the program that is being linked.
4358     // The dEQP test in dEQP-GLES3.functional.negative_api doesn't know
4359     // about this.
4360     ctx->m_state->setTransformFeedbackVaryingsCountForLinking(count);
4361 
4362     if (!count) return;
4363 
4364     GLint err = GL_NO_ERROR;
4365     std::string packed = packVarNames(count, varyings, &err);
4366     SET_ERROR_IF(err != GL_NO_ERROR, GL_INVALID_OPERATION);
4367 
4368     ctx->glTransformFeedbackVaryingsAEMU(ctx, program, count, (const char*)&packed[0], packed.size() + 1, bufferMode);
4369 }
4370 
s_glBeginTransformFeedback(void * self,GLenum primitiveMode)4371 void GL2Encoder::s_glBeginTransformFeedback(void* self, GLenum primitiveMode) {
4372     GL2Encoder* ctx = (GL2Encoder*)self;
4373     GLClientState* state = ctx->m_state;
4374     SET_ERROR_IF(
4375         primitiveMode != GL_POINTS &&
4376         primitiveMode != GL_LINES &&
4377         primitiveMode != GL_TRIANGLES,
4378         GL_INVALID_ENUM);
4379     SET_ERROR_IF(
4380         ctx->m_state->getTransformFeedbackActive(),
4381         GL_INVALID_OPERATION);
4382     // TODO:
4383     // dEQP-GLES3.functional.lifetime.attach.deleted_output.buffer_transform_feedback
4384     // SET_ERROR_IF(
4385     //     !ctx->boundBuffer(GL_TRANSFORM_FEEDBACK_BUFFER),
4386     //     GL_INVALID_OPERATION);
4387     SET_ERROR_IF(
4388         !ctx->m_state->currentProgram(), GL_INVALID_OPERATION);
4389     ctx->m_glBeginTransformFeedback_enc(ctx, primitiveMode);
4390     state->setTransformFeedbackActive(true);
4391     state->setTransformFeedbackUnpaused(true);
4392 }
4393 
s_glEndTransformFeedback(void * self)4394 void GL2Encoder::s_glEndTransformFeedback(void* self) {
4395     GL2Encoder* ctx = (GL2Encoder*)self;
4396     GLClientState* state = ctx->m_state;
4397     SET_ERROR_IF(!state->getTransformFeedbackActive(), GL_INVALID_OPERATION);
4398     ctx->m_glEndTransformFeedback_enc(ctx);
4399     state->setTransformFeedbackActive(false);
4400     state->setTransformFeedbackUnpaused(false);
4401 }
4402 
s_glPauseTransformFeedback(void * self)4403 void GL2Encoder::s_glPauseTransformFeedback(void* self) {
4404     GL2Encoder* ctx = (GL2Encoder*)self;
4405     GLClientState* state = ctx->m_state;
4406     SET_ERROR_IF(!state->getTransformFeedbackActive(), GL_INVALID_OPERATION);
4407     SET_ERROR_IF(!state->getTransformFeedbackUnpaused(), GL_INVALID_OPERATION);
4408     ctx->m_glPauseTransformFeedback_enc(ctx);
4409     state->setTransformFeedbackUnpaused(false);
4410 }
4411 
s_glResumeTransformFeedback(void * self)4412 void GL2Encoder::s_glResumeTransformFeedback(void* self) {
4413     GL2Encoder* ctx = (GL2Encoder*)self;
4414     GLClientState* state = ctx->m_state;
4415     SET_ERROR_IF(!state->getTransformFeedbackActive(), GL_INVALID_OPERATION);
4416     SET_ERROR_IF(state->getTransformFeedbackUnpaused(), GL_INVALID_OPERATION);
4417     ctx->m_glResumeTransformFeedback_enc(ctx);
4418     state->setTransformFeedbackUnpaused(true);
4419 }
4420 
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)4421 void GL2Encoder::s_glTexImage3D(void* self, GLenum target, GLint level, GLint internalFormat,
4422                                GLsizei width, GLsizei height, GLsizei depth,
4423                                GLint border, GLenum format, GLenum type, const GLvoid* data) {
4424     GL2Encoder* ctx = (GL2Encoder*)self;
4425     GLClientState* state = ctx->m_state;
4426 
4427     SET_ERROR_IF(target != GL_TEXTURE_3D &&
4428                  target != GL_TEXTURE_2D_ARRAY,
4429                  GL_INVALID_ENUM);
4430     SET_ERROR_IF(!GLESv2Validation::pixelType(ctx, type), GL_INVALID_ENUM);
4431     SET_ERROR_IF(!GLESv2Validation::pixelFormat(ctx, format), GL_INVALID_ENUM);
4432     SET_ERROR_IF(!(GLESv2Validation::pixelOp(format,type)),GL_INVALID_OPERATION);
4433     SET_ERROR_IF(!GLESv2Validation::pixelSizedFormat(ctx, internalFormat, format, type), GL_INVALID_OPERATION);
4434     SET_ERROR_IF(target == GL_TEXTURE_3D &&
4435         ((format == GL_DEPTH_COMPONENT) ||
4436          (format == GL_DEPTH_STENCIL)), GL_INVALID_OPERATION);
4437 
4438     // If unpack buffer is nonzero, verify unmapped state.
4439     SET_ERROR_IF(ctx->isBufferTargetMapped(GL_PIXEL_UNPACK_BUFFER), GL_INVALID_OPERATION);
4440 
4441     GLint max_texture_size;
4442     GLint max_3d_texture_size;
4443     ctx->glGetIntegerv(ctx, GL_MAX_TEXTURE_SIZE, &max_texture_size);
4444     ctx->glGetIntegerv(ctx, GL_MAX_3D_TEXTURE_SIZE, &max_3d_texture_size);
4445     SET_ERROR_IF(level < 0, GL_INVALID_VALUE);
4446     SET_ERROR_IF(level > ilog2(max_texture_size), GL_INVALID_VALUE);
4447     SET_ERROR_IF(level > ilog2(max_3d_texture_size), GL_INVALID_VALUE);
4448 
4449     SET_ERROR_IF(width < 0 || height < 0 || depth < 0, GL_INVALID_VALUE);
4450     SET_ERROR_IF(width > max_texture_size, GL_INVALID_VALUE);
4451     SET_ERROR_IF(height > max_texture_size, GL_INVALID_VALUE);
4452     if (target == GL_TEXTURE_3D) {
4453         SET_ERROR_IF(depth > max_texture_size, GL_INVALID_VALUE);
4454     } else {
4455         GLint maxArrayTextureLayers;
4456         ctx->glGetIntegerv(ctx, GL_MAX_ARRAY_TEXTURE_LAYERS, &maxArrayTextureLayers);
4457         SET_ERROR_IF(depth > maxArrayTextureLayers, GL_INVALID_VALUE);
4458     }
4459     SET_ERROR_IF(width > max_3d_texture_size, GL_INVALID_VALUE);
4460     SET_ERROR_IF(height > max_3d_texture_size, GL_INVALID_VALUE);
4461     SET_ERROR_IF(depth > max_3d_texture_size, GL_INVALID_VALUE);
4462     SET_ERROR_IF(border != 0, GL_INVALID_VALUE);
4463     // If unpack buffer is nonzero, verify buffer data fits and is evenly divisible by the type.
4464     SET_ERROR_IF(ctx->boundBuffer(GL_PIXEL_UNPACK_BUFFER) &&
4465                  ctx->getBufferData(GL_PIXEL_UNPACK_BUFFER) &&
4466                  ((uintptr_t)data + ctx->m_state->pboNeededDataSize(width, height, depth, format, type, 0) >
4467                   ctx->getBufferData(GL_PIXEL_UNPACK_BUFFER)->m_size),
4468                  GL_INVALID_OPERATION);
4469     SET_ERROR_IF(ctx->boundBuffer(GL_PIXEL_UNPACK_BUFFER) &&
4470                  ctx->getBufferData(GL_PIXEL_UNPACK_BUFFER) &&
4471                  ((uintptr_t)data %
4472                   glSizeof(type)),
4473                  GL_INVALID_OPERATION);
4474     SET_ERROR_IF(state->isBoundTextureImmutableFormat(target), GL_INVALID_OPERATION);
4475 
4476     state->setBoundTextureInternalFormat(target, internalFormat);
4477     state->setBoundTextureFormat(target, format);
4478     state->setBoundTextureType(target, type);
4479     state->setBoundTextureDims(target, target, level, width, height, depth);
4480 
4481     if (ctx->boundBuffer(GL_PIXEL_UNPACK_BUFFER)) {
4482         ctx->glTexImage3DOffsetAEMU(
4483                 ctx, target, level, internalFormat,
4484                 width, height, depth,
4485                 border, format, type, (uintptr_t)data);
4486     } else {
4487         ctx->m_glTexImage3D_enc(ctx,
4488                 target, level, internalFormat,
4489                 width, height, depth,
4490                 border, format, type, data);
4491     }
4492 }
4493 
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)4494 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) {
4495     GL2Encoder* ctx = (GL2Encoder*)self;
4496     GLClientState* state = ctx->m_state;
4497 
4498     SET_ERROR_IF(target != GL_TEXTURE_3D &&
4499                  target != GL_TEXTURE_2D_ARRAY,
4500                  GL_INVALID_ENUM);
4501     SET_ERROR_IF(!GLESv2Validation::pixelType(ctx, type), GL_INVALID_ENUM);
4502     SET_ERROR_IF(!GLESv2Validation::pixelFormat(ctx, format), GL_INVALID_ENUM);
4503     // If unpack buffer is nonzero, verify unmapped state.
4504     SET_ERROR_IF(ctx->isBufferTargetMapped(GL_PIXEL_UNPACK_BUFFER), GL_INVALID_OPERATION);
4505     GLint max_texture_size;
4506     GLint max_3d_texture_size;
4507     ctx->glGetIntegerv(ctx, GL_MAX_TEXTURE_SIZE, &max_texture_size);
4508     ctx->glGetIntegerv(ctx, GL_MAX_3D_TEXTURE_SIZE, &max_3d_texture_size);
4509     SET_ERROR_IF(level < 0, GL_INVALID_VALUE);
4510     SET_ERROR_IF(level > ilog2(max_texture_size), GL_INVALID_VALUE);
4511     SET_ERROR_IF(level > ilog2(max_3d_texture_size), GL_INVALID_VALUE);
4512     SET_ERROR_IF(width < 0 || height < 0 || depth < 0, GL_INVALID_VALUE);
4513     SET_ERROR_IF(xoffset < 0 || yoffset < 0 || zoffset < 0, GL_INVALID_VALUE);
4514     GLuint tex = state->getBoundTexture(target);
4515     GLsizei neededWidth = xoffset + width;
4516     GLsizei neededHeight = yoffset + height;
4517     GLsizei neededDepth = zoffset + depth;
4518 
4519     SET_ERROR_IF(tex &&
4520                  (neededWidth > state->queryTexWidth(level, tex) ||
4521                   neededHeight > state->queryTexHeight(level, tex) ||
4522                   neededDepth > state->queryTexDepth(level, tex)),
4523                  GL_INVALID_VALUE);
4524     // If unpack buffer is nonzero, verify buffer data fits and is evenly divisible by the type.
4525     SET_ERROR_IF(ctx->boundBuffer(GL_PIXEL_UNPACK_BUFFER) &&
4526                  ctx->getBufferData(GL_PIXEL_UNPACK_BUFFER) &&
4527                  ((uintptr_t)data + ctx->m_state->pboNeededDataSize(width, height, depth, format, type, 0) >
4528                   ctx->getBufferData(GL_PIXEL_UNPACK_BUFFER)->m_size),
4529                  GL_INVALID_OPERATION);
4530     SET_ERROR_IF(ctx->boundBuffer(GL_PIXEL_UNPACK_BUFFER) &&
4531                  ctx->getBufferData(GL_PIXEL_UNPACK_BUFFER) &&
4532                  ((uintptr_t)data % glSizeof(type)),
4533                  GL_INVALID_OPERATION);
4534     SET_ERROR_IF(!ctx->boundBuffer(GL_PIXEL_UNPACK_BUFFER) && !data, GL_INVALID_OPERATION);
4535     SET_ERROR_IF(xoffset < 0 || yoffset < 0 || zoffset < 0, GL_INVALID_VALUE);
4536 
4537     if (ctx->boundBuffer(GL_PIXEL_UNPACK_BUFFER)) {
4538         ctx->glTexSubImage3DOffsetAEMU(ctx,
4539                 target, level,
4540                 xoffset, yoffset, zoffset,
4541                 width, height, depth,
4542                 format, type, (uintptr_t)data);
4543     } else {
4544         ctx->m_glTexSubImage3D_enc(ctx,
4545                 target, level,
4546                 xoffset, yoffset, zoffset,
4547                 width, height, depth,
4548                 format, type, data);
4549     }
4550 }
4551 
s_glCompressedTexImage3D(void * self,GLenum target,GLint level,GLenum internalformat,GLsizei width,GLsizei height,GLsizei depth,GLint border,GLsizei imageSize,const GLvoid * data)4552 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) {
4553     GL2Encoder* ctx = (GL2Encoder*)self;
4554     GLClientState* state = ctx->m_state;
4555 
4556     SET_ERROR_IF(target != GL_TEXTURE_3D &&
4557                  target != GL_TEXTURE_2D_ARRAY,
4558                  GL_INVALID_ENUM);
4559     // Filter compressed formats support.
4560     SET_ERROR_IF(!GLESv2Validation::supportedCompressedFormat(ctx, internalformat), GL_INVALID_ENUM);
4561     SET_ERROR_IF(target == GL_TEXTURE_CUBE_MAP, GL_INVALID_ENUM);
4562     // If unpack buffer is nonzero, verify unmapped state.
4563     SET_ERROR_IF(ctx->isBufferTargetMapped(GL_PIXEL_UNPACK_BUFFER), GL_INVALID_OPERATION);
4564     SET_ERROR_IF(width < 0 || height < 0 || depth < 0, GL_INVALID_VALUE);
4565     SET_ERROR_IF(border, GL_INVALID_VALUE);
4566 
4567     GLint max_texture_size;
4568     GLint max_3d_texture_size;
4569     ctx->glGetIntegerv(ctx, GL_MAX_TEXTURE_SIZE, &max_texture_size);
4570     ctx->glGetIntegerv(ctx, GL_MAX_3D_TEXTURE_SIZE, &max_3d_texture_size);
4571     SET_ERROR_IF(level < 0, GL_INVALID_VALUE);
4572     SET_ERROR_IF(level > ilog2(max_texture_size), GL_INVALID_VALUE);
4573     SET_ERROR_IF(level > ilog2(max_3d_texture_size), GL_INVALID_VALUE);
4574 
4575     SET_ERROR_IF(width < 0 || height < 0 || depth < 0, GL_INVALID_VALUE);
4576     SET_ERROR_IF(width > max_texture_size, GL_INVALID_VALUE);
4577     SET_ERROR_IF(height > max_texture_size, GL_INVALID_VALUE);
4578     if (target == GL_TEXTURE_3D) {
4579         SET_ERROR_IF(depth > max_texture_size, GL_INVALID_VALUE);
4580     } else {
4581         GLint maxArrayTextureLayers;
4582         ctx->glGetIntegerv(ctx, GL_MAX_ARRAY_TEXTURE_LAYERS, &maxArrayTextureLayers);
4583         SET_ERROR_IF(depth > maxArrayTextureLayers, GL_INVALID_VALUE);
4584     }
4585     SET_ERROR_IF(width > max_3d_texture_size, GL_INVALID_VALUE);
4586     SET_ERROR_IF(height > max_3d_texture_size, GL_INVALID_VALUE);
4587     SET_ERROR_IF(depth > max_3d_texture_size, GL_INVALID_VALUE);
4588     SET_ERROR_IF(GLESTextureUtils::isAstcFormat(internalformat) && GL_TEXTURE_3D == target, GL_INVALID_OPERATION);
4589 
4590     // If unpack buffer is nonzero, verify buffer data fits.
4591     SET_ERROR_IF(ctx->boundBuffer(GL_PIXEL_UNPACK_BUFFER) &&
4592                  ctx->getBufferData(GL_PIXEL_UNPACK_BUFFER) &&
4593                  (imageSize > ctx->getBufferData(GL_PIXEL_UNPACK_BUFFER)->m_size),
4594                  GL_INVALID_OPERATION);
4595     SET_ERROR_IF(!ctx->m_state->compressedTexImageSizeCompatible(internalformat, width, height, depth, imageSize), GL_INVALID_VALUE);
4596     state->setBoundTextureInternalFormat(target, (GLint)internalformat);
4597     state->setBoundTextureDims(target, target, level, width, height, depth);
4598 
4599     if (ctx->boundBuffer(GL_PIXEL_UNPACK_BUFFER)) {
4600         ctx->glCompressedTexImage3DOffsetAEMU(
4601                 ctx, target, level, internalformat,
4602                 width, height, depth, border,
4603                 imageSize, (uintptr_t)data);
4604     } else {
4605         ctx->m_glCompressedTexImage3D_enc(
4606                 ctx, target, level, internalformat,
4607                 width, height, depth, border,
4608                 imageSize, data);
4609     }
4610 }
4611 
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)4612 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) {
4613     GL2Encoder* ctx = (GL2Encoder*)self;
4614 
4615     SET_ERROR_IF(!GLESv2Validation::textureTarget(ctx, target), GL_INVALID_ENUM);
4616     SET_ERROR_IF(target == GL_TEXTURE_CUBE_MAP, GL_INVALID_ENUM);
4617     // If unpack buffer is nonzero, verify unmapped state.
4618     SET_ERROR_IF(ctx->isBufferTargetMapped(GL_PIXEL_UNPACK_BUFFER), GL_INVALID_OPERATION);
4619     SET_ERROR_IF(width < 0 || height < 0 || depth < 0, GL_INVALID_VALUE);
4620     // If unpack buffer is nonzero, verify buffer data fits.
4621     SET_ERROR_IF(ctx->boundBuffer(GL_PIXEL_UNPACK_BUFFER) &&
4622                  ctx->getBufferData(GL_PIXEL_UNPACK_BUFFER) &&
4623                  (imageSize > ctx->getBufferData(GL_PIXEL_UNPACK_BUFFER)->m_size),
4624                  GL_INVALID_OPERATION);
4625     SET_ERROR_IF(xoffset < 0 || yoffset < 0 || zoffset < 0, GL_INVALID_VALUE);
4626 
4627     GLint max_texture_size;
4628     GLint max_3d_texture_size;
4629     ctx->glGetIntegerv(ctx, GL_MAX_TEXTURE_SIZE, &max_texture_size);
4630     ctx->glGetIntegerv(ctx, GL_MAX_3D_TEXTURE_SIZE, &max_3d_texture_size);
4631     SET_ERROR_IF(level < 0, GL_INVALID_VALUE);
4632     SET_ERROR_IF(level > ilog2(max_texture_size), GL_INVALID_VALUE);
4633     SET_ERROR_IF(level > ilog2(max_3d_texture_size), GL_INVALID_VALUE);
4634     SET_ERROR_IF(width < 0 || height < 0 || depth < 0, GL_INVALID_VALUE);
4635     SET_ERROR_IF(xoffset < 0 || yoffset < 0 || zoffset < 0, GL_INVALID_VALUE);
4636     GLenum stateTarget = target;
4637     if (target == GL_TEXTURE_CUBE_MAP_POSITIVE_X ||
4638         target == GL_TEXTURE_CUBE_MAP_POSITIVE_Y ||
4639         target == GL_TEXTURE_CUBE_MAP_POSITIVE_Z ||
4640         target == GL_TEXTURE_CUBE_MAP_NEGATIVE_X ||
4641         target == GL_TEXTURE_CUBE_MAP_NEGATIVE_Y ||
4642         target == GL_TEXTURE_CUBE_MAP_NEGATIVE_Z)
4643         stateTarget = GL_TEXTURE_CUBE_MAP;
4644 
4645     GLuint tex = ctx->m_state->getBoundTexture(stateTarget);
4646     GLsizei neededWidth = xoffset + width;
4647     GLsizei neededHeight = yoffset + height;
4648     GLsizei neededDepth = zoffset + depth;
4649 
4650     SET_ERROR_IF(tex &&
4651                  (neededWidth > ctx->m_state->queryTexWidth(level, tex) ||
4652                   neededHeight > ctx->m_state->queryTexHeight(level, tex) ||
4653                   neededDepth > ctx->m_state->queryTexDepth(level, tex)),
4654                  GL_INVALID_VALUE);
4655 
4656     GLint internalFormat = ctx->m_state->queryTexInternalFormat(tex);
4657     SET_ERROR_IF(internalFormat != format, GL_INVALID_OPERATION);
4658 
4659     GLint totalWidth = ctx->m_state->queryTexWidth(level, tex);
4660     GLint totalHeight = ctx->m_state->queryTexHeight(level, tex);
4661 
4662     if (GLESTextureUtils::isEtc2Format(internalFormat)) {
4663         SET_ERROR_IF((width % 4) && (totalWidth != xoffset + width), GL_INVALID_OPERATION);
4664         SET_ERROR_IF((height % 4) && (totalHeight != yoffset + height), GL_INVALID_OPERATION);
4665         SET_ERROR_IF((xoffset % 4) || (yoffset % 4), GL_INVALID_OPERATION);
4666     }
4667 
4668     SET_ERROR_IF(totalWidth < xoffset + width, GL_INVALID_VALUE);
4669     SET_ERROR_IF(totalHeight < yoffset + height, GL_INVALID_VALUE);
4670 
4671     SET_ERROR_IF(!ctx->m_state->compressedTexImageSizeCompatible(internalFormat, width, height, depth, imageSize), GL_INVALID_VALUE);
4672 
4673     if (ctx->boundBuffer(GL_PIXEL_UNPACK_BUFFER)) {
4674         ctx->glCompressedTexSubImage3DOffsetAEMU(
4675                 ctx, target, level,
4676                 xoffset, yoffset, zoffset,
4677                 width, height, depth,
4678                 format, imageSize, (uintptr_t)data);
4679     } else {
4680         ctx->m_glCompressedTexSubImage3D_enc(
4681                 ctx, target, level,
4682                 xoffset, yoffset, zoffset,
4683                 width, height, depth,
4684                 format, imageSize, data);
4685 
4686     }
4687 }
4688 
s_glTexStorage3D(void * self,GLenum target,GLsizei levels,GLenum internalformat,GLsizei width,GLsizei height,GLsizei depth)4689 void GL2Encoder::s_glTexStorage3D(void* self, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth) {
4690     GL2Encoder* ctx = (GL2Encoder*)self;
4691     GLClientState* state = ctx->m_state;
4692     SET_ERROR_IF(target != GL_TEXTURE_3D &&
4693                  target != GL_TEXTURE_2D_ARRAY,
4694                  GL_INVALID_ENUM);
4695     SET_ERROR_IF(!GLESv2Validation::pixelInternalFormat(internalformat), GL_INVALID_ENUM);
4696     SET_ERROR_IF(!state->getBoundTexture(target), GL_INVALID_OPERATION);
4697     SET_ERROR_IF(levels < 1 || width < 1 || height < 1 || depth < 1, GL_INVALID_VALUE);
4698     GLint max_texture_size;
4699     GLint max_3d_texture_size;
4700     ctx->glGetIntegerv(ctx, GL_MAX_TEXTURE_SIZE, &max_texture_size);
4701     ctx->glGetIntegerv(ctx, GL_MAX_3D_TEXTURE_SIZE, &max_3d_texture_size);
4702     SET_ERROR_IF(width > max_texture_size, GL_INVALID_VALUE);
4703     SET_ERROR_IF(height > max_texture_size, GL_INVALID_VALUE);
4704     if (target == GL_TEXTURE_3D) {
4705         SET_ERROR_IF(depth > max_texture_size, GL_INVALID_VALUE);
4706     } else {
4707         GLint maxArrayTextureLayers;
4708         ctx->glGetIntegerv(ctx, GL_MAX_ARRAY_TEXTURE_LAYERS, &maxArrayTextureLayers);
4709         SET_ERROR_IF(depth > maxArrayTextureLayers, GL_INVALID_VALUE);
4710     }
4711 
4712     SET_ERROR_IF(width > max_3d_texture_size, GL_INVALID_VALUE);
4713     SET_ERROR_IF(height > max_3d_texture_size, GL_INVALID_VALUE);
4714     SET_ERROR_IF(depth > max_3d_texture_size, GL_INVALID_VALUE);
4715 
4716     SET_ERROR_IF(GLESTextureUtils::isAstcFormat(internalformat) && GL_TEXTURE_3D == target, GL_INVALID_OPERATION);
4717 
4718     SET_ERROR_IF(target == GL_TEXTURE_3D && (levels > ilog2((uint32_t)std::max(width, std::max(height, depth))) + 1),
4719                  GL_INVALID_OPERATION);
4720     SET_ERROR_IF(target == GL_TEXTURE_2D_ARRAY && (levels > ilog2((uint32_t)std::max(width, height)) + 1),
4721                  GL_INVALID_OPERATION);
4722     SET_ERROR_IF(state->isBoundTextureImmutableFormat(target), GL_INVALID_OPERATION);
4723 
4724     state->setBoundTextureInternalFormat(target, internalformat);
4725     state->setBoundTextureDims(target, target, -1, width, height, depth);
4726     state->setBoundTextureImmutableFormat(target);
4727     ctx->m_glTexStorage3D_enc(ctx, target, levels, internalformat, width, height, depth);
4728     state->setBoundTextureImmutableFormat(target);
4729 }
4730 
s_glDrawArraysInstanced(void * self,GLenum mode,GLint first,GLsizei count,GLsizei primcount)4731 void GL2Encoder::s_glDrawArraysInstanced(void* self, GLenum mode, GLint first, GLsizei count, GLsizei primcount) {
4732     GL2Encoder *ctx = (GL2Encoder *)self;
4733     assert(ctx->m_state != NULL);
4734     SET_ERROR_IF(!isValidDrawMode(mode), GL_INVALID_ENUM);
4735     SET_ERROR_IF(count < 0, GL_INVALID_VALUE);
4736     SET_ERROR_IF(primcount < 0, GL_INVALID_VALUE);
4737     SET_ERROR_IF(ctx->m_state->checkFramebufferCompleteness(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE, GL_INVALID_FRAMEBUFFER_OPERATION);
4738 
4739     bool has_client_vertex_arrays = false;
4740     bool has_indirect_arrays = false;
4741     ctx->getVBOUsage(&has_client_vertex_arrays,
4742                      &has_indirect_arrays);
4743 
4744     if (has_client_vertex_arrays ||
4745         (!has_client_vertex_arrays &&
4746          !has_indirect_arrays)) {
4747         ctx->sendVertexAttributes(first, count, true, primcount);
4748         ctx->m_glDrawArraysInstanced_enc(ctx, mode, 0, count, primcount);
4749     } else {
4750         ctx->sendVertexAttributes(0, count, false, primcount);
4751         ctx->m_glDrawArraysInstanced_enc(ctx, mode, first, count, primcount);
4752     }
4753     ctx->m_stream->flush();
4754     ctx->m_state->postDraw();
4755 }
4756 
s_glDrawElementsInstanced(void * self,GLenum mode,GLsizei count,GLenum type,const void * indices,GLsizei primcount)4757 void GL2Encoder::s_glDrawElementsInstanced(void* self, GLenum mode, GLsizei count, GLenum type, const void* indices, GLsizei primcount)
4758 {
4759 
4760     GL2Encoder *ctx = (GL2Encoder *)self;
4761     assert(ctx->m_state != NULL);
4762     SET_ERROR_IF(!isValidDrawMode(mode), GL_INVALID_ENUM);
4763     SET_ERROR_IF(count < 0, GL_INVALID_VALUE);
4764     SET_ERROR_IF(primcount < 0, GL_INVALID_VALUE);
4765     SET_ERROR_IF(!(type == GL_UNSIGNED_BYTE || type == GL_UNSIGNED_SHORT || type == GL_UNSIGNED_INT), GL_INVALID_ENUM);
4766     SET_ERROR_IF(ctx->m_state->getTransformFeedbackActiveUnpaused(), GL_INVALID_OPERATION);
4767     SET_ERROR_IF(ctx->m_state->checkFramebufferCompleteness(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE, GL_INVALID_FRAMEBUFFER_OPERATION);
4768 
4769     bool has_client_vertex_arrays = false;
4770     bool has_indirect_arrays = false;
4771     GLintptr offset = 0;
4772 
4773     ctx->getVBOUsage(&has_client_vertex_arrays, &has_indirect_arrays);
4774 
4775     if (!has_client_vertex_arrays && !has_indirect_arrays) {
4776         // ALOGW("glDrawElements: no vertex arrays / buffers bound to the command\n");
4777         GLenum status = ctx->glCheckFramebufferStatus(self, GL_FRAMEBUFFER);
4778         SET_ERROR_IF(status != GL_FRAMEBUFFER_COMPLETE, GL_INVALID_FRAMEBUFFER_OPERATION);
4779     }
4780 
4781     BufferData* buf = NULL;
4782     int minIndex = 0, maxIndex = 0;
4783 
4784     // For validation/immediate index array purposes,
4785     // we need the min/max vertex index of the index array.
4786     // If the VBO != 0, this may not be the first time we have
4787     // used this particular index buffer. getBufferIndexRange
4788     // can more quickly get min/max vertex index by
4789     // caching previous results.
4790     if (ctx->m_state->currentIndexVbo() != 0) {
4791         buf = ctx->m_shared->getBufferData(ctx->m_state->currentIndexVbo());
4792         offset = (GLintptr)indices;
4793         indices = &buf->m_fixedBuffer[offset];
4794         ctx->getBufferIndexRange(buf,
4795                                  indices,
4796                                  type,
4797                                  (size_t)count,
4798                                  (size_t)offset,
4799                                  &minIndex, &maxIndex);
4800     } else {
4801         // In this case, the |indices| field holds a real
4802         // array, so calculate the indices now. They will
4803         // also be needed to know how much data to
4804         // transfer to host.
4805         ctx->calcIndexRange(indices,
4806                             type,
4807                             count,
4808                             &minIndex,
4809                             &maxIndex);
4810     }
4811 
4812     if (count == 0) return;
4813 
4814     bool adjustIndices = true;
4815     if (ctx->m_state->currentIndexVbo() != 0) {
4816         if (!has_client_vertex_arrays) {
4817             ctx->sendVertexAttributes(0, maxIndex + 1, false, primcount);
4818             ctx->doBindBufferEncodeCached(GL_ELEMENT_ARRAY_BUFFER, ctx->m_state->currentIndexVbo());
4819             ctx->glDrawElementsInstancedOffsetAEMU(ctx, mode, count, type, offset, primcount);
4820             ctx->flushDrawCall();
4821             adjustIndices = false;
4822         } else {
4823             ctx->doBindBufferEncodeCached(GL_ELEMENT_ARRAY_BUFFER, 0);
4824         }
4825     }
4826     if (adjustIndices) {
4827         void *adjustedIndices =
4828             ctx->recenterIndices(indices,
4829                                  type,
4830                                  count,
4831                                  minIndex);
4832 
4833         if (has_indirect_arrays || 1) {
4834             ctx->sendVertexAttributes(minIndex, maxIndex - minIndex + 1, true, primcount);
4835             ctx->glDrawElementsInstancedDataAEMU(ctx, mode, count, type, adjustedIndices, primcount, count * glSizeof(type));
4836             ctx->m_stream->flush();
4837             // XXX - OPTIMIZATION (see the other else branch) should be implemented
4838             if(!has_indirect_arrays) {
4839                 //ALOGD("unoptimized drawelements !!!\n");
4840             }
4841         } else {
4842             // we are all direct arrays and immidate mode index array -
4843             // rebuild the arrays and the index array;
4844             ALOGE("glDrawElements: direct index & direct buffer data - will be implemented in later versions;\n");
4845         }
4846     }
4847     ctx->m_state->postDraw();
4848 }
4849 
s_glDrawRangeElements(void * self,GLenum mode,GLuint start,GLuint end,GLsizei count,GLenum type,const void * indices)4850 void GL2Encoder::s_glDrawRangeElements(void* self, GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void* indices)
4851 {
4852 
4853     GL2Encoder *ctx = (GL2Encoder *)self;
4854     assert(ctx->m_state != NULL);
4855     SET_ERROR_IF(!isValidDrawMode(mode), GL_INVALID_ENUM);
4856     SET_ERROR_IF(end < start, GL_INVALID_VALUE);
4857     SET_ERROR_IF(count < 0, GL_INVALID_VALUE);
4858     SET_ERROR_IF(!(type == GL_UNSIGNED_BYTE || type == GL_UNSIGNED_SHORT || type == GL_UNSIGNED_INT), GL_INVALID_ENUM);
4859     SET_ERROR_IF(ctx->m_state->getTransformFeedbackActiveUnpaused(), GL_INVALID_OPERATION);
4860     SET_ERROR_IF(ctx->m_state->checkFramebufferCompleteness(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE, GL_INVALID_FRAMEBUFFER_OPERATION);
4861 
4862     bool has_client_vertex_arrays = false;
4863     bool has_indirect_arrays = false;
4864     GLintptr offset = 0;
4865 
4866     ctx->getVBOUsage(&has_client_vertex_arrays, &has_indirect_arrays);
4867 
4868     if (!has_client_vertex_arrays && !has_indirect_arrays) {
4869         // ALOGW("glDrawElements: no vertex arrays / buffers bound to the command\n");
4870         GLenum status = ctx->glCheckFramebufferStatus(self, GL_FRAMEBUFFER);
4871         SET_ERROR_IF(status != GL_FRAMEBUFFER_COMPLETE, GL_INVALID_FRAMEBUFFER_OPERATION);
4872     }
4873 
4874     BufferData* buf = NULL;
4875     int minIndex = 0, maxIndex = 0;
4876 
4877     // For validation/immediate index array purposes,
4878     // we need the min/max vertex index of the index array.
4879     // If the VBO != 0, this may not be the first time we have
4880     // used this particular index buffer. getBufferIndexRange
4881     // can more quickly get min/max vertex index by
4882     // caching previous results.
4883     if (ctx->m_state->currentIndexVbo() != 0) {
4884         buf = ctx->m_shared->getBufferData(ctx->m_state->currentIndexVbo());
4885         ALOGV("%s: current index vbo: %p len %zu count %zu\n", __func__, buf, buf->m_fixedBuffer.size(), (size_t)count);
4886         offset = (GLintptr)indices;
4887         void* oldIndices = (void*)indices;
4888         indices = &buf->m_fixedBuffer[offset];
4889         ALOGV("%s: indices arg: %p buffer start: %p indices: %p\n", __func__,
4890                 (void*)(uintptr_t)(oldIndices),
4891                 buf->m_fixedBuffer.data(),
4892                 indices);
4893         ctx->getBufferIndexRange(buf,
4894                                  indices,
4895                                  type,
4896                                  (size_t)count,
4897                                  (size_t)offset,
4898                                  &minIndex, &maxIndex);
4899     } else {
4900         // In this case, the |indices| field holds a real
4901         // array, so calculate the indices now. They will
4902         // also be needed to know how much data to
4903         // transfer to host.
4904         ctx->calcIndexRange(indices,
4905                             type,
4906                             count,
4907                             &minIndex,
4908                             &maxIndex);
4909     }
4910 
4911     if (count == 0) return;
4912 
4913     bool adjustIndices = true;
4914     if (ctx->m_state->currentIndexVbo() != 0) {
4915         if (!has_client_vertex_arrays) {
4916             ctx->sendVertexAttributes(0, maxIndex + 1, false);
4917             ctx->doBindBufferEncodeCached(GL_ELEMENT_ARRAY_BUFFER, ctx->m_state->currentIndexVbo());
4918             ctx->glDrawElementsOffset(ctx, mode, count, type, offset);
4919             ctx->flushDrawCall();
4920             adjustIndices = false;
4921         } else {
4922             ctx->doBindBufferEncodeCached(GL_ELEMENT_ARRAY_BUFFER, 0);
4923         }
4924     }
4925     if (adjustIndices) {
4926         void *adjustedIndices =
4927             ctx->recenterIndices(indices,
4928                                  type,
4929                                  count,
4930                                  minIndex);
4931 
4932         if (has_indirect_arrays || 1) {
4933             ctx->sendVertexAttributes(minIndex, maxIndex - minIndex + 1, true);
4934             ctx->glDrawElementsData(ctx, mode, count, type, adjustedIndices, count * glSizeof(type));
4935             ctx->m_stream->flush();
4936             // XXX - OPTIMIZATION (see the other else branch) should be implemented
4937             if(!has_indirect_arrays) {
4938                 //ALOGD("unoptimized drawelements !!!\n");
4939             }
4940         } else {
4941             // we are all direct arrays and immidate mode index array -
4942             // rebuild the arrays and the index array;
4943             ALOGE("glDrawElements: direct index & direct buffer data - will be implemented in later versions;\n");
4944         }
4945     }
4946     ctx->m_state->postDraw();
4947 }
4948 
s_glGetStringi(void * self,GLenum name,GLuint index)4949 const GLubyte* GL2Encoder::s_glGetStringi(void* self, GLenum name, GLuint index) {
4950     GL2Encoder *ctx = (GL2Encoder *)self;
4951     const GLubyte *retval =  (GLubyte *) "";
4952 
4953     RET_AND_SET_ERROR_IF(
4954         name != GL_VENDOR &&
4955         name != GL_RENDERER &&
4956         name != GL_VERSION &&
4957         name != GL_EXTENSIONS,
4958         GL_INVALID_ENUM,
4959         retval);
4960 
4961     RET_AND_SET_ERROR_IF(
4962         (name == GL_VENDOR ||
4963          name == GL_RENDERER ||
4964          name == GL_VERSION) &&
4965         index != 0,
4966         GL_INVALID_VALUE,
4967         retval);
4968 
4969     RET_AND_SET_ERROR_IF(
4970         name == GL_EXTENSIONS &&
4971         index >= ctx->m_currExtensionsArray.size(),
4972         GL_INVALID_VALUE,
4973         retval);
4974 
4975     switch (name) {
4976     case GL_VENDOR:
4977         retval = gVendorString;
4978         break;
4979     case GL_RENDERER:
4980         retval = gRendererString;
4981         break;
4982     case GL_VERSION:
4983         retval = gVersionString;
4984         break;
4985     case GL_EXTENSIONS:
4986         retval = (const GLubyte*)(ctx->m_currExtensionsArray[index].c_str());
4987         break;
4988     }
4989 
4990     return retval;
4991 }
4992 
s_glGetProgramBinary(void * self,GLuint program,GLsizei bufSize,GLsizei * length,GLenum * binaryFormat,void * binary)4993 void GL2Encoder::s_glGetProgramBinary(void* self, GLuint program, GLsizei bufSize, GLsizei* length, GLenum* binaryFormat, void* binary) {
4994     GL2Encoder *ctx = (GL2Encoder *)self;
4995 
4996     VALIDATE_PROGRAM_NAME(program);
4997 
4998     GLint linkStatus = 0;
4999     ctx->m_glGetProgramiv_enc(self, program, GL_LINK_STATUS, &linkStatus);
5000     GLint properLength = 0;
5001     ctx->m_glGetProgramiv_enc(self, program, GL_PROGRAM_BINARY_LENGTH, &properLength);
5002 
5003     SET_ERROR_IF(!linkStatus, GL_INVALID_OPERATION);
5004     SET_ERROR_IF(bufSize < properLength, GL_INVALID_OPERATION);
5005 
5006     ctx->m_glGetProgramBinary_enc(ctx, program, bufSize, length, binaryFormat, binary);
5007 }
5008 
s_glReadPixels(void * self,GLint x,GLint y,GLsizei width,GLsizei height,GLenum format,GLenum type,GLvoid * pixels)5009 void GL2Encoder::s_glReadPixels(void* self, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels) {
5010     GL2Encoder *ctx = (GL2Encoder *)self;
5011 
5012     SET_ERROR_IF(!GLESv2Validation::readPixelsFormat(format), GL_INVALID_ENUM);
5013     SET_ERROR_IF(!GLESv2Validation::readPixelsType(type), GL_INVALID_ENUM);
5014     SET_ERROR_IF(!(GLESv2Validation::pixelOp(format,type)),GL_INVALID_OPERATION);
5015     SET_ERROR_IF(width < 0 || height < 0, GL_INVALID_VALUE);
5016     SET_ERROR_IF(ctx->isBufferTargetMapped(GL_PIXEL_PACK_BUFFER), GL_INVALID_OPERATION);
5017     SET_ERROR_IF(ctx->boundBuffer(GL_PIXEL_PACK_BUFFER) &&
5018                  ctx->getBufferData(GL_PIXEL_PACK_BUFFER) &&
5019                  (ctx->m_state->pboNeededDataSize(width, height, 1, format, type, 1) >
5020                   ctx->getBufferData(GL_PIXEL_PACK_BUFFER)->m_size),
5021                  GL_INVALID_OPERATION);
5022     SET_ERROR_IF(ctx->s_glCheckFramebufferStatus(ctx, GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE, GL_INVALID_FRAMEBUFFER_OPERATION);
5023 
5024     // now is complete
5025     // GL_INVALID_OPERATION is generated if GL_READ_FRAMEBUFFER_BINDING is nonzero, the read fbo is complete, and the value of
5026     // GL_SAMPLE_BUFFERS for the read framebuffer is greater than zero
5027     if (ctx->m_state->boundFramebuffer(GL_READ_FRAMEBUFFER) &&
5028         ctx->s_glCheckFramebufferStatus(ctx, GL_READ_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE) {
5029         FboFormatInfo resInfo;
5030         ctx->m_state->getBoundFramebufferFormat(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, &resInfo);
5031         if (resInfo.type == FBO_ATTACHMENT_RENDERBUFFER) {
5032             SET_ERROR_IF(resInfo.rb_multisamples > 0, GL_INVALID_OPERATION);
5033         }
5034         if (resInfo.type == FBO_ATTACHMENT_TEXTURE) {
5035             SET_ERROR_IF(resInfo.tex_multisamples > 0, GL_INVALID_OPERATION);
5036         }
5037     }
5038 
5039 
5040     /*
5041 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.
5042 
5043 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.
5044 
5045 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.
5046 
5047 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.
5048 */
5049 
5050     FboFormatInfo fbo_format_info;
5051     ctx->m_state->getBoundFramebufferFormat(
5052             GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, &fbo_format_info);
5053     SET_ERROR_IF(
5054         fbo_format_info.type == FBO_ATTACHMENT_TEXTURE &&
5055         !GLESv2Validation::readPixelsFboFormatMatch(
5056             format, type, fbo_format_info.tex_type),
5057         GL_INVALID_OPERATION);
5058 
5059     if (ctx->boundBuffer(GL_PIXEL_PACK_BUFFER)) {
5060         ctx->glReadPixelsOffsetAEMU(
5061                 ctx, x, y, width, height,
5062                 format, type, (uintptr_t)pixels);
5063     } else {
5064         ctx->m_glReadPixels_enc(
5065                 ctx, x, y, width, height,
5066                 format, type, pixels);
5067     }
5068     ctx->m_state->postReadPixels();
5069 }
5070 
5071 // Track enabled state for some things like:
5072 // - Primitive restart
s_glEnable(void * self,GLenum what)5073 void GL2Encoder::s_glEnable(void* self, GLenum what) {
5074     GL2Encoder *ctx = (GL2Encoder *)self;
5075 
5076 	SET_ERROR_IF(!GLESv2Validation::allowedEnable(ctx->majorVersion(), ctx->minorVersion(), what), GL_INVALID_ENUM);
5077     if (!ctx->m_state) return;
5078 
5079     switch (what) {
5080     case GL_PRIMITIVE_RESTART_FIXED_INDEX:
5081         ctx->m_primitiveRestartEnabled = true;
5082         break;
5083     case GL_STENCIL_TEST:
5084         ctx->m_state->state_GL_STENCIL_TEST = true;
5085         break;
5086     }
5087 
5088     ctx->m_glEnable_enc(ctx, what);
5089 }
5090 
s_glDisable(void * self,GLenum what)5091 void GL2Encoder::s_glDisable(void* self, GLenum what) {
5092     GL2Encoder *ctx = (GL2Encoder *)self;
5093 
5094 	SET_ERROR_IF(!GLESv2Validation::allowedEnable(ctx->majorVersion(), ctx->minorVersion(), what), GL_INVALID_ENUM);
5095     if (!ctx->m_state) return;
5096 
5097     switch (what) {
5098     case GL_PRIMITIVE_RESTART_FIXED_INDEX:
5099         ctx->m_primitiveRestartEnabled = false;
5100         break;
5101     case GL_STENCIL_TEST:
5102         ctx->m_state->state_GL_STENCIL_TEST = false;
5103         break;
5104     }
5105 
5106     ctx->m_glDisable_enc(ctx, what);
5107 }
5108 
s_glClearBufferiv(void * self,GLenum buffer,GLint drawBuffer,const GLint * value)5109 void GL2Encoder::s_glClearBufferiv(void* self, GLenum buffer, GLint drawBuffer, const GLint * value) {
5110     GL2Encoder *ctx = (GL2Encoder *)self;
5111 
5112     SET_ERROR_IF(buffer != GL_COLOR && buffer != GL_STENCIL, GL_INVALID_ENUM);
5113 
5114     GLint maxDrawBuffers;
5115     ctx->glGetIntegerv(ctx, GL_MAX_DRAW_BUFFERS, &maxDrawBuffers);
5116 
5117     SET_ERROR_IF(!value, GL_INVALID_VALUE);
5118 
5119     if (buffer == GL_COLOR) {
5120         SET_ERROR_IF(drawBuffer < 0 || drawBuffer>= maxDrawBuffers, GL_INVALID_VALUE);
5121     } else {
5122         SET_ERROR_IF(drawBuffer != 0, GL_INVALID_VALUE);
5123     }
5124 
5125     ctx->m_glClearBufferiv_enc(ctx, buffer, drawBuffer, value);
5126 }
5127 
s_glClearBufferuiv(void * self,GLenum buffer,GLint drawBuffer,const GLuint * value)5128 void GL2Encoder::s_glClearBufferuiv(void* self, GLenum buffer, GLint drawBuffer, const GLuint * value) {
5129     GL2Encoder *ctx = (GL2Encoder *)self;
5130 
5131     SET_ERROR_IF(buffer != GL_COLOR, GL_INVALID_ENUM);
5132     SET_ERROR_IF(!value, GL_INVALID_VALUE);
5133 
5134     GLint maxDrawBuffers;
5135     ctx->glGetIntegerv(ctx, GL_MAX_DRAW_BUFFERS, &maxDrawBuffers);
5136     SET_ERROR_IF(drawBuffer < 0 || drawBuffer>= maxDrawBuffers, GL_INVALID_VALUE);
5137 
5138     ctx->m_glClearBufferuiv_enc(ctx, buffer, drawBuffer, value);
5139 }
5140 
s_glClearBufferfv(void * self,GLenum buffer,GLint drawBuffer,const GLfloat * value)5141 void GL2Encoder::s_glClearBufferfv(void* self, GLenum buffer, GLint drawBuffer, const GLfloat * value) {
5142     GL2Encoder *ctx = (GL2Encoder *)self;
5143 
5144     SET_ERROR_IF(buffer != GL_COLOR && buffer != GL_DEPTH, GL_INVALID_ENUM);
5145 
5146     SET_ERROR_IF(!value, GL_INVALID_VALUE);
5147 
5148     GLint maxDrawBuffers;
5149     ctx->glGetIntegerv(ctx, GL_MAX_DRAW_BUFFERS, &maxDrawBuffers);
5150 
5151     if (buffer == GL_COLOR) {
5152         SET_ERROR_IF(drawBuffer < 0 || drawBuffer>= maxDrawBuffers, GL_INVALID_VALUE);
5153     } else {
5154         SET_ERROR_IF(drawBuffer != 0, GL_INVALID_VALUE);
5155     }
5156 
5157     ctx->m_glClearBufferfv_enc(ctx, buffer, drawBuffer, value);
5158 }
5159 
s_glClearBufferfi(void * self,GLenum buffer,GLint drawBuffer,float depth,int stencil)5160 void GL2Encoder::s_glClearBufferfi(void* self, GLenum buffer, GLint drawBuffer, float depth, int stencil) {
5161     GL2Encoder *ctx = (GL2Encoder *)self;
5162 
5163     SET_ERROR_IF(buffer != GL_DEPTH_STENCIL, GL_INVALID_ENUM);
5164     SET_ERROR_IF(drawBuffer != 0, GL_INVALID_VALUE);
5165 
5166     ctx->m_glClearBufferfi_enc(ctx, buffer, drawBuffer, depth, stencil);
5167 }
5168 
s_glBlitFramebuffer(void * self,GLint srcX0,GLint srcY0,GLint srcX1,GLint srcY1,GLint dstX0,GLint dstY0,GLint dstX1,GLint dstY1,GLbitfield mask,GLenum filter)5169 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) {
5170     GL2Encoder *ctx = (GL2Encoder *)self;
5171     GLClientState* state = ctx->m_state;
5172 
5173     bool validateColor = mask & GL_COLOR_BUFFER_BIT;
5174     bool validateDepth = mask & GL_DEPTH_BUFFER_BIT;
5175     bool validateStencil = mask & GL_STENCIL_BUFFER_BIT;
5176     bool validateDepthOrStencil = validateDepth || validateStencil;
5177 
5178     FboFormatInfo read_fbo_format_info;
5179     FboFormatInfo draw_fbo_format_info;
5180     if (validateColor) {
5181         state->getBoundFramebufferFormat(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, &read_fbo_format_info);
5182         state->getBoundFramebufferFormat(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, &draw_fbo_format_info);
5183 
5184         if (read_fbo_format_info.type == FBO_ATTACHMENT_TEXTURE) {
5185             SET_ERROR_IF(
5186                 GL_LINEAR == filter &&
5187                 GLESv2Validation::isIntegerFormat(read_fbo_format_info.tex_format),
5188                     GL_INVALID_OPERATION);
5189         }
5190 
5191         if (read_fbo_format_info.type == FBO_ATTACHMENT_TEXTURE &&
5192             draw_fbo_format_info.type == FBO_ATTACHMENT_TEXTURE) {
5193             SET_ERROR_IF(
5194                     state->boundFramebuffer(GL_READ_FRAMEBUFFER) &&
5195                     state->boundFramebuffer(GL_DRAW_FRAMEBUFFER) &&
5196                     !GLESv2Validation::blitFramebufferFormat(
5197                         read_fbo_format_info.tex_type,
5198                         draw_fbo_format_info.tex_type),
5199                     GL_INVALID_OPERATION);
5200         }
5201     }
5202 
5203     if (validateDepth) {
5204         state->getBoundFramebufferFormat(GL_READ_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, &read_fbo_format_info);
5205         state->getBoundFramebufferFormat(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, &draw_fbo_format_info);
5206 
5207         if (read_fbo_format_info.type == FBO_ATTACHMENT_RENDERBUFFER &&
5208             draw_fbo_format_info.type == FBO_ATTACHMENT_RENDERBUFFER) {
5209             SET_ERROR_IF(
5210                     state->boundFramebuffer(GL_READ_FRAMEBUFFER) &&
5211                     state->boundFramebuffer(GL_DRAW_FRAMEBUFFER) &&
5212                     !GLESv2Validation::blitFramebufferFormat(
5213                         read_fbo_format_info.rb_format,
5214                         draw_fbo_format_info.rb_format),
5215                     GL_INVALID_OPERATION);
5216         }
5217     }
5218 
5219     if (validateStencil) {
5220         state->getBoundFramebufferFormat(GL_READ_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, &read_fbo_format_info);
5221         state->getBoundFramebufferFormat(GL_DRAW_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, &draw_fbo_format_info);
5222 
5223         if (read_fbo_format_info.type == FBO_ATTACHMENT_RENDERBUFFER &&
5224             draw_fbo_format_info.type == FBO_ATTACHMENT_RENDERBUFFER) {
5225             SET_ERROR_IF(
5226                     state->boundFramebuffer(GL_READ_FRAMEBUFFER) &&
5227                     state->boundFramebuffer(GL_DRAW_FRAMEBUFFER) &&
5228                     !GLESv2Validation::blitFramebufferFormat(
5229                         read_fbo_format_info.rb_format,
5230                         draw_fbo_format_info.rb_format),
5231                     GL_INVALID_OPERATION);
5232         }
5233     }
5234 
5235     if (validateDepthOrStencil) {
5236         SET_ERROR_IF(filter != GL_NEAREST, GL_INVALID_OPERATION);
5237     }
5238 
5239     state->getBoundFramebufferFormat(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, &draw_fbo_format_info);
5240     SET_ERROR_IF(
5241             draw_fbo_format_info.type == FBO_ATTACHMENT_RENDERBUFFER &&
5242             draw_fbo_format_info.rb_multisamples > 0,
5243             GL_INVALID_OPERATION);
5244     SET_ERROR_IF(
5245             draw_fbo_format_info.type == FBO_ATTACHMENT_TEXTURE &&
5246             draw_fbo_format_info.tex_multisamples > 0,
5247             GL_INVALID_OPERATION);
5248 
5249     state->getBoundFramebufferFormat(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, &read_fbo_format_info);
5250     SET_ERROR_IF(
5251             read_fbo_format_info.type == FBO_ATTACHMENT_RENDERBUFFER &&
5252             read_fbo_format_info.rb_multisamples > 0 &&
5253             draw_fbo_format_info.type == FBO_ATTACHMENT_RENDERBUFFER &&
5254             state->boundFramebuffer(GL_READ_FRAMEBUFFER) &&
5255             state->boundFramebuffer(GL_DRAW_FRAMEBUFFER) &&
5256             (read_fbo_format_info.rb_format !=
5257              draw_fbo_format_info.rb_format),
5258             GL_INVALID_OPERATION);
5259     SET_ERROR_IF(
5260             read_fbo_format_info.type == FBO_ATTACHMENT_RENDERBUFFER &&
5261             read_fbo_format_info.rb_multisamples > 0 &&
5262             draw_fbo_format_info.type == FBO_ATTACHMENT_RENDERBUFFER &&
5263             (srcX0 != dstX0 || srcY0 != dstY0 ||
5264              srcX1 != dstX1 || srcY1 != dstY1),
5265             GL_INVALID_OPERATION);
5266 
5267 	ctx->m_glBlitFramebuffer_enc(ctx,
5268             srcX0, srcY0, srcX1, srcY1,
5269             dstX0, dstY0, dstX1, dstY1,
5270             mask, filter);
5271 }
5272 
s_glGetInternalformativ(void * self,GLenum target,GLenum internalformat,GLenum pname,GLsizei bufSize,GLint * params)5273 void GL2Encoder::s_glGetInternalformativ(void* self, GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint *params) {
5274     GL2Encoder *ctx = (GL2Encoder *)self;
5275 
5276     SET_ERROR_IF(pname != GL_NUM_SAMPLE_COUNTS &&
5277                  pname != GL_SAMPLES,
5278                  GL_INVALID_ENUM);
5279     SET_ERROR_IF(!GLESv2Validation::internalFormatTarget(ctx, target), GL_INVALID_ENUM);
5280     SET_ERROR_IF(!GLESv2Validation::unsizedFormat(internalformat) &&
5281                  !GLESv2Validation::colorRenderableFormat(ctx, internalformat) &&
5282                  !GLESv2Validation::depthRenderableFormat(ctx, internalformat) &&
5283                  !GLESv2Validation::stencilRenderableFormat(ctx, internalformat),
5284                  GL_INVALID_ENUM);
5285     SET_ERROR_IF(bufSize < 0, GL_INVALID_VALUE);
5286 
5287     if (bufSize < 1) return;
5288 
5289     // Desktop OpenGL can allow a mindboggling # samples per pixel (such as 64).
5290     // Limit to 4 (spec minimum) to keep dEQP tests from timing out.
5291     switch (pname) {
5292         case GL_NUM_SAMPLE_COUNTS:
5293             *params = 3;
5294             break;
5295         case GL_SAMPLES:
5296             params[0] = 4;
5297             if (bufSize > 1) params[1] = 2;
5298             if (bufSize > 2) params[2] = 1;
5299             break;
5300         default:
5301             break;
5302     }
5303 }
5304 
s_glGenerateMipmap(void * self,GLenum target)5305 void GL2Encoder::s_glGenerateMipmap(void* self, GLenum target) {
5306     GL2Encoder *ctx = (GL2Encoder *)self;
5307     GLClientState* state = ctx->m_state;
5308 
5309     SET_ERROR_IF(target != GL_TEXTURE_2D &&
5310                  target != GL_TEXTURE_3D &&
5311                  target != GL_TEXTURE_CUBE_MAP &&
5312                  target != GL_TEXTURE_2D_ARRAY,
5313                  GL_INVALID_ENUM);
5314 
5315     GLuint tex = state->getBoundTexture(target);
5316     GLenum internalformat = state->queryTexInternalFormat(tex);
5317 
5318     SET_ERROR_IF(tex && GLESv2Validation::isCompressedFormat(internalformat),
5319                  GL_INVALID_OPERATION);
5320     SET_ERROR_IF(tex &&
5321                  !GLESv2Validation::unsizedFormat(internalformat) &&
5322                  !(GLESv2Validation::colorRenderableFormat(ctx, internalformat) &&
5323                    GLESv2Validation::filterableTexFormat(ctx, internalformat)),
5324                  GL_INVALID_OPERATION);
5325 
5326     GLenum stateTarget = target;
5327     if (target == GL_TEXTURE_CUBE_MAP_POSITIVE_X ||
5328         target == GL_TEXTURE_CUBE_MAP_POSITIVE_Y ||
5329         target == GL_TEXTURE_CUBE_MAP_POSITIVE_Z ||
5330         target == GL_TEXTURE_CUBE_MAP_NEGATIVE_X ||
5331         target == GL_TEXTURE_CUBE_MAP_NEGATIVE_Y ||
5332         target == GL_TEXTURE_CUBE_MAP_NEGATIVE_Z)
5333         stateTarget = GL_TEXTURE_CUBE_MAP;
5334 
5335     SET_ERROR_IF(!ctx->m_state->isBoundTextureComplete(stateTarget), GL_INVALID_OPERATION);
5336 
5337     if (target == GL_TEXTURE_2D) {
5338         ctx->override2DTextureTarget(target);
5339     }
5340 
5341     ctx->m_glGenerateMipmap_enc(ctx, target);
5342 
5343     if (target == GL_TEXTURE_2D) {
5344         ctx->restore2DTextureTarget(target);
5345     }
5346 }
5347 
s_glBindSampler(void * self,GLuint unit,GLuint sampler)5348 void GL2Encoder::s_glBindSampler(void* self, GLuint unit, GLuint sampler) {
5349     GL2Encoder *ctx = (GL2Encoder *)self;
5350     GLint maxCombinedUnits;
5351     ctx->glGetIntegerv(ctx, GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &maxCombinedUnits);
5352     SET_ERROR_IF(unit >= maxCombinedUnits, GL_INVALID_VALUE);
5353     SET_ERROR_IF(!ctx->m_state->samplerExists(sampler), GL_INVALID_OPERATION);
5354     if (ctx->m_state->isSamplerBindNoOp(unit, sampler)) return;
5355     ctx->m_glBindSampler_enc(ctx, unit, sampler);
5356     ctx->m_state->bindSampler(unit, sampler);
5357 }
5358 
s_glDeleteSamplers(void * self,GLsizei n,const GLuint * samplers)5359 void GL2Encoder::s_glDeleteSamplers(void* self, GLsizei n, const GLuint* samplers) {
5360     GL2Encoder *ctx = (GL2Encoder *)self;
5361     ctx->m_state->onDeleteSamplers(n, samplers);
5362     ctx->m_state->setExistence(GLClientState::ObjectType::Sampler, false, n, samplers);
5363     ctx->m_glDeleteSamplers_enc(ctx, n, samplers);
5364 }
5365 
s_glFenceSync(void * self,GLenum condition,GLbitfield flags)5366 GLsync GL2Encoder::s_glFenceSync(void* self, GLenum condition, GLbitfield flags) {
5367     GL2Encoder *ctx = (GL2Encoder *)self;
5368     RET_AND_SET_ERROR_IF(condition != GL_SYNC_GPU_COMMANDS_COMPLETE, GL_INVALID_ENUM, 0);
5369     RET_AND_SET_ERROR_IF(flags != 0, GL_INVALID_VALUE, 0);
5370     uint64_t syncHandle = ctx->glFenceSyncAEMU(ctx, condition, flags);
5371 
5372     GLsync res = (GLsync)(uintptr_t)syncHandle;
5373     GLClientState::onFenceCreated(res);
5374     return res;
5375 }
5376 
s_glClientWaitSync(void * self,GLsync wait_on,GLbitfield flags,GLuint64 timeout)5377 GLenum GL2Encoder::s_glClientWaitSync(void* self, GLsync wait_on, GLbitfield flags, GLuint64 timeout) {
5378     GL2Encoder *ctx = (GL2Encoder *)self;
5379     RET_AND_SET_ERROR_IF(!GLClientState::fenceExists(wait_on), GL_INVALID_VALUE, GL_WAIT_FAILED);
5380     RET_AND_SET_ERROR_IF(flags && !(flags & GL_SYNC_FLUSH_COMMANDS_BIT), GL_INVALID_VALUE, GL_WAIT_FAILED);
5381     return ctx->glClientWaitSyncAEMU(ctx, (uint64_t)(uintptr_t)wait_on, flags, timeout);
5382 }
5383 
s_glWaitSync(void * self,GLsync wait_on,GLbitfield flags,GLuint64 timeout)5384 void GL2Encoder::s_glWaitSync(void* self, GLsync wait_on, GLbitfield flags, GLuint64 timeout) {
5385     GL2Encoder *ctx = (GL2Encoder *)self;
5386     SET_ERROR_IF(flags != 0, GL_INVALID_VALUE);
5387     SET_ERROR_IF(timeout != GL_TIMEOUT_IGNORED, GL_INVALID_VALUE);
5388     SET_ERROR_IF(!GLClientState::fenceExists(wait_on), GL_INVALID_VALUE);
5389     ctx->glWaitSyncAEMU(ctx, (uint64_t)(uintptr_t)wait_on, flags, timeout);
5390 }
5391 
s_glDeleteSync(void * self,GLsync sync)5392 void GL2Encoder::s_glDeleteSync(void* self, GLsync sync) {
5393     GL2Encoder *ctx = (GL2Encoder *)self;
5394 
5395     if (!sync) return;
5396 
5397     SET_ERROR_IF(!GLClientState::fenceExists(sync), GL_INVALID_VALUE);
5398     GLClientState::onFenceDestroyed(sync);
5399     ctx->glDeleteSyncAEMU(ctx, (uint64_t)(uintptr_t)sync);
5400 }
5401 
s_glIsSync(void * self,GLsync sync)5402 GLboolean GL2Encoder::s_glIsSync(void* self, GLsync sync) {
5403     GL2Encoder *ctx = (GL2Encoder *)self;
5404     return ctx->glIsSyncAEMU(ctx, (uint64_t)(uintptr_t)sync);
5405 }
5406 
s_glGetSynciv(void * self,GLsync sync,GLenum pname,GLsizei bufSize,GLsizei * length,GLint * values)5407 void GL2Encoder::s_glGetSynciv(void* self, GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values) {
5408     GL2Encoder *ctx = (GL2Encoder *)self;
5409 
5410     SET_ERROR_IF(!GLESv2Validation::allowedGetSyncParam(pname), GL_INVALID_ENUM);
5411     SET_ERROR_IF(bufSize < 0, GL_INVALID_VALUE);
5412     SET_ERROR_IF(!GLClientState::fenceExists(sync), GL_INVALID_VALUE);
5413 
5414     return ctx->glGetSyncivAEMU(ctx, (uint64_t)(uintptr_t)sync, pname, bufSize, length, values);
5415 }
5416 
5417 #define LIMIT_CASE(target, lim) \
5418     case target: \
5419         ctx->glGetIntegerv(ctx, lim, &limit); \
5420         SET_ERROR_IF(index < 0 || index >= limit, GL_INVALID_VALUE); \
5421         break; \
5422 
s_glGetIntegeri_v(void * self,GLenum target,GLuint index,GLint * params)5423 void GL2Encoder::s_glGetIntegeri_v(void* self, GLenum target, GLuint index, GLint* params) {
5424     GL2Encoder *ctx = (GL2Encoder *)self;
5425     GLClientState* state = ctx->m_state;
5426 
5427     GLint limit;
5428 
5429     switch (target) {
5430     LIMIT_CASE(GL_TRANSFORM_FEEDBACK_BUFFER_BINDING, GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS)
5431     LIMIT_CASE(GL_UNIFORM_BUFFER_BINDING, GL_MAX_UNIFORM_BUFFER_BINDINGS)
5432     LIMIT_CASE(GL_ATOMIC_COUNTER_BUFFER_BINDING, GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS)
5433     LIMIT_CASE(GL_SHADER_STORAGE_BUFFER_BINDING, GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS)
5434     default:
5435         break;
5436     }
5437 
5438     const GLClientState::VertexAttribBindingVector& currBindings =
5439         state->currentVertexBufferBindings();
5440 
5441     switch (target) {
5442     case GL_VERTEX_BINDING_DIVISOR:
5443     case GL_VERTEX_BINDING_OFFSET:
5444     case GL_VERTEX_BINDING_STRIDE:
5445     case GL_VERTEX_BINDING_BUFFER:
5446         SET_ERROR_IF(index < 0 || index > currBindings.size(), GL_INVALID_VALUE);
5447         break;
5448     default:
5449         break;
5450     }
5451 
5452     switch (target) {
5453     case GL_VERTEX_BINDING_DIVISOR:
5454         *params = currBindings[index].divisor;
5455         return;
5456     case GL_VERTEX_BINDING_OFFSET:
5457         *params = currBindings[index].offset;
5458         return;
5459     case GL_VERTEX_BINDING_STRIDE:
5460         *params = currBindings[index].effectiveStride;
5461         return;
5462     case GL_VERTEX_BINDING_BUFFER:
5463         *params = currBindings[index].buffer;
5464         return;
5465     default:
5466         break;
5467     }
5468 
5469     ctx->safe_glGetIntegeri_v(target, index, params);
5470 }
5471 
s_glGetInteger64i_v(void * self,GLenum target,GLuint index,GLint64 * params)5472 void GL2Encoder::s_glGetInteger64i_v(void* self, GLenum target, GLuint index, GLint64* params) {
5473     GL2Encoder *ctx = (GL2Encoder *)self;
5474     GLClientState* state = ctx->m_state;
5475 
5476     GLint limit;
5477 
5478     switch (target) {
5479     LIMIT_CASE(GL_TRANSFORM_FEEDBACK_BUFFER_BINDING, GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS)
5480     LIMIT_CASE(GL_UNIFORM_BUFFER_BINDING, GL_MAX_UNIFORM_BUFFER_BINDINGS)
5481     LIMIT_CASE(GL_ATOMIC_COUNTER_BUFFER_BINDING, GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS)
5482     LIMIT_CASE(GL_SHADER_STORAGE_BUFFER_BINDING, GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS)
5483     default:
5484         break;
5485     }
5486 
5487     const GLClientState::VertexAttribBindingVector& currBindings =
5488         state->currentVertexBufferBindings();
5489 
5490     switch (target) {
5491     case GL_VERTEX_BINDING_DIVISOR:
5492     case GL_VERTEX_BINDING_OFFSET:
5493     case GL_VERTEX_BINDING_STRIDE:
5494     case GL_VERTEX_BINDING_BUFFER:
5495         SET_ERROR_IF(index < 0 || index > currBindings.size(), GL_INVALID_VALUE);
5496         break;
5497     default:
5498         break;
5499     }
5500 
5501     switch (target) {
5502     case GL_VERTEX_BINDING_DIVISOR:
5503         *params = currBindings[index].divisor;
5504         return;
5505     case GL_VERTEX_BINDING_OFFSET:
5506         *params = currBindings[index].offset;
5507         return;
5508     case GL_VERTEX_BINDING_STRIDE:
5509         *params = currBindings[index].effectiveStride;
5510         return;
5511     case GL_VERTEX_BINDING_BUFFER:
5512         *params = currBindings[index].buffer;
5513         return;
5514     default:
5515         break;
5516     }
5517 
5518     ctx->safe_glGetInteger64i_v(target, index, params);
5519 }
5520 
s_glGetInteger64v(void * self,GLenum param,GLint64 * val)5521 void GL2Encoder::s_glGetInteger64v(void* self, GLenum param, GLint64* val) {
5522     GL2Encoder *ctx = (GL2Encoder *)self;
5523     ctx->safe_glGetInteger64v(param, val);
5524 }
5525 
s_glGetBooleani_v(void * self,GLenum param,GLuint index,GLboolean * val)5526 void GL2Encoder::s_glGetBooleani_v(void* self, GLenum param, GLuint index, GLboolean* val) {
5527     GL2Encoder *ctx = (GL2Encoder *)self;
5528     ctx->safe_glGetBooleani_v(param, index, val);
5529 }
5530 
s_glGetShaderiv(void * self,GLuint shader,GLenum pname,GLint * params)5531 void GL2Encoder::s_glGetShaderiv(void* self, GLuint shader, GLenum pname, GLint* params) {
5532     GL2Encoder *ctx = (GL2Encoder *)self;
5533     ctx->m_glGetShaderiv_enc(self, shader, pname, params);
5534 
5535     SET_ERROR_IF(!GLESv2Validation::allowedGetShader(pname), GL_INVALID_ENUM);
5536     VALIDATE_SHADER_NAME(shader);
5537 
5538     if (pname == GL_SHADER_SOURCE_LENGTH) {
5539         ShaderData* shaderData = ctx->m_shared->getShaderData(shader);
5540         if (shaderData) {
5541             int totalLen = 0;
5542             for (int i = 0; i < shaderData->sources.size(); i++) {
5543                 totalLen += shaderData->sources[i].size();
5544             }
5545             if (totalLen != 0) {
5546                 *params = totalLen + 1; // account for null terminator
5547             }
5548         }
5549     }
5550 }
5551 
s_glActiveShaderProgram(void * self,GLuint pipeline,GLuint program)5552 void GL2Encoder::s_glActiveShaderProgram(void* self, GLuint pipeline, GLuint program) {
5553     GL2Encoder *ctx = (GL2Encoder*)self;
5554     GLClientState* state = ctx->m_state;
5555     GLSharedGroupPtr shared = ctx->m_shared;
5556 
5557     SET_ERROR_IF(!pipeline, GL_INVALID_OPERATION);
5558     SET_ERROR_IF(program && !shared->isShaderOrProgramObject(program), GL_INVALID_VALUE);
5559     SET_ERROR_IF(program && !shared->isProgram(program), GL_INVALID_OPERATION);
5560 
5561     ctx->m_glActiveShaderProgram_enc(ctx, pipeline, program);
5562     if (!state->currentProgram()) {
5563         state->setCurrentShaderProgram(program);
5564     }
5565 }
5566 
s_glCreateShaderProgramv(void * self,GLenum shaderType,GLsizei count,const char ** strings)5567 GLuint GL2Encoder::s_glCreateShaderProgramv(void* self, GLenum shaderType, GLsizei count, const char** strings) {
5568 
5569     GLint* length = NULL;
5570     GL2Encoder* ctx = (GL2Encoder*)self;
5571 
5572     int len = glUtilsCalcShaderSourceLen((char**)strings, length, count);
5573     char *str = new char[len + 1];
5574     glUtilsPackStrings(str, (char**)strings, (GLint*)length, count);
5575 
5576     // Do GLSharedGroup and location WorkARound-specific initialization
5577     // Phase 1: create a ShaderData and initialize with replaceSamplerExternalWith2D()
5578     uint32_t spDataId = ctx->m_shared->addNewShaderProgramData();
5579     ShaderProgramData* spData = ctx->m_shared->getShaderProgramDataById(spDataId);
5580 
5581     if (!replaceSamplerExternalWith2D(str, &spData->shaderData)) {
5582         delete [] str;
5583         ctx->setError(GL_OUT_OF_MEMORY);
5584         ctx->m_shared->deleteShaderProgramDataById(spDataId);
5585         return -1;
5586     }
5587 
5588     GLuint res = ctx->glCreateShaderProgramvAEMU(ctx, shaderType, count, str, len + 1);
5589     delete [] str;
5590 
5591     // Phase 2: do glLinkProgram-related initialization for locationWorkARound
5592     GLint linkStatus = 0;
5593     ctx->m_glGetProgramiv_enc(self, res, GL_LINK_STATUS ,&linkStatus);
5594     ctx->m_shared->setProgramLinkStatus(res, linkStatus);
5595     if (!linkStatus) {
5596         ctx->m_shared->deleteShaderProgramDataById(spDataId);
5597         return -1;
5598     }
5599 
5600     ctx->m_shared->associateGLShaderProgram(res, spDataId);
5601 
5602     GLint numUniforms = 0;
5603     GLint numAttributes = 0;
5604     ctx->m_glGetProgramiv_enc(self, res, GL_ACTIVE_UNIFORMS, &numUniforms);
5605     ctx->m_glGetProgramiv_enc(self, res, GL_ACTIVE_ATTRIBUTES, &numAttributes);
5606     ctx->m_shared->initShaderProgramData(res, numUniforms, numAttributes);
5607 
5608     GLint maxLength=0;
5609     GLint maxAttribLength=0;
5610     ctx->m_glGetProgramiv_enc(self, res, GL_ACTIVE_UNIFORM_MAX_LENGTH, &maxLength);
5611     ctx->m_glGetProgramiv_enc(self, res, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &maxAttribLength);
5612 
5613     size_t bufLen = maxLength > maxAttribLength ? maxLength : maxAttribLength;
5614     GLint size; GLenum type; GLchar *name = new GLchar[bufLen + 1];
5615 
5616     for (GLint i = 0; i < numUniforms; ++i) {
5617         ctx->m_glGetActiveUniform_enc(self, res, i, maxLength, NULL, &size, &type, name);
5618         GLint location = ctx->m_glGetUniformLocation_enc(self, res, name);
5619         ctx->m_shared->setShaderProgramIndexInfo(res, i, location, size, type, name);
5620     }
5621 
5622     for (GLint i = 0; i < numAttributes; ++i) {
5623         ctx->m_glGetActiveAttrib_enc(self, res, i, maxAttribLength,  NULL, &size, &type, name);
5624         GLint location = ctx->m_glGetAttribLocation_enc(self, res, name);
5625         ctx->m_shared->setProgramAttribInfo(res, i, location, size, type, name);
5626     }
5627 
5628     GLint numBlocks;
5629     ctx->m_glGetProgramiv_enc(ctx, res, GL_ACTIVE_UNIFORM_BLOCKS, &numBlocks);
5630     ctx->m_shared->setActiveUniformBlockCountForProgram(res, numBlocks);
5631 
5632     GLint tfVaryingsCount;
5633     ctx->m_glGetProgramiv_enc(ctx, res, GL_TRANSFORM_FEEDBACK_VARYINGS, &tfVaryingsCount);
5634     ctx->m_shared->setTransformFeedbackVaryingsCountForProgram(res, tfVaryingsCount);
5635 
5636     delete [] name;
5637 
5638     return res;
5639 }
5640 
s_glProgramUniform1f(void * self,GLuint program,GLint location,GLfloat v0)5641 void GL2Encoder::s_glProgramUniform1f(void* self, GLuint program, GLint location, GLfloat v0)
5642 {
5643     GL2Encoder *ctx = (GL2Encoder*)self;
5644     ctx->m_glProgramUniform1f_enc(self, program, location, v0);
5645 }
5646 
s_glProgramUniform1fv(void * self,GLuint program,GLint location,GLsizei count,const GLfloat * value)5647 void GL2Encoder::s_glProgramUniform1fv(void* self, GLuint program, GLint location, GLsizei count, const GLfloat *value)
5648 {
5649     GL2Encoder *ctx = (GL2Encoder*)self;
5650     ctx->m_glProgramUniform1fv_enc(self, program, location, count, value);
5651 }
5652 
s_glProgramUniform1i(void * self,GLuint program,GLint location,GLint v0)5653 void GL2Encoder::s_glProgramUniform1i(void* self, GLuint program, GLint location, GLint v0)
5654 {
5655     GL2Encoder *ctx = (GL2Encoder*)self;
5656     ctx->m_glProgramUniform1i_enc(self, program, location, v0);
5657 
5658     GLClientState* state = ctx->m_state;
5659     GLSharedGroupPtr shared = ctx->m_shared;
5660     GLenum target;
5661 
5662     if (shared->setSamplerUniform(program, location, v0, &target)) {
5663         GLenum origActiveTexture = state->getActiveTextureUnit();
5664         if (ctx->updateHostTexture2DBinding(GL_TEXTURE0 + v0, target)) {
5665             ctx->m_glActiveTexture_enc(self, origActiveTexture);
5666         }
5667         state->setActiveTextureUnit(origActiveTexture);
5668     }
5669 }
5670 
s_glProgramUniform1iv(void * self,GLuint program,GLint location,GLsizei count,const GLint * value)5671 void GL2Encoder::s_glProgramUniform1iv(void* self, GLuint program, GLint location, GLsizei count, const GLint *value)
5672 {
5673     GL2Encoder *ctx = (GL2Encoder*)self;
5674     ctx->m_glProgramUniform1iv_enc(self, program, location, count, value);
5675 }
5676 
s_glProgramUniform1ui(void * self,GLuint program,GLint location,GLuint v0)5677 void GL2Encoder::s_glProgramUniform1ui(void* self, GLuint program, GLint location, GLuint v0)
5678 {
5679     GL2Encoder *ctx = (GL2Encoder*)self;
5680     ctx->m_glProgramUniform1ui_enc(self, program, location, v0);
5681 
5682     GLClientState* state = ctx->m_state;
5683     GLSharedGroupPtr shared = ctx->m_shared;
5684     GLenum target;
5685 
5686     if (shared->setSamplerUniform(program, location, v0, &target)) {
5687         GLenum origActiveTexture = state->getActiveTextureUnit();
5688         if (ctx->updateHostTexture2DBinding(GL_TEXTURE0 + v0, target)) {
5689             ctx->m_glActiveTexture_enc(self, origActiveTexture);
5690         }
5691         state->setActiveTextureUnit(origActiveTexture);
5692     }
5693 }
5694 
s_glProgramUniform1uiv(void * self,GLuint program,GLint location,GLsizei count,const GLuint * value)5695 void GL2Encoder::s_glProgramUniform1uiv(void* self, GLuint program, GLint location, GLsizei count, const GLuint *value)
5696 {
5697     GL2Encoder *ctx = (GL2Encoder*)self;
5698     ctx->m_glProgramUniform1uiv_enc(self, program, location, count, value);
5699 }
5700 
s_glProgramUniform2f(void * self,GLuint program,GLint location,GLfloat v0,GLfloat v1)5701 void GL2Encoder::s_glProgramUniform2f(void* self, GLuint program, GLint location, GLfloat v0, GLfloat v1)
5702 {
5703     GL2Encoder *ctx = (GL2Encoder*)self;
5704     ctx->m_glProgramUniform2f_enc(self, program, location, v0, v1);
5705 }
5706 
s_glProgramUniform2fv(void * self,GLuint program,GLint location,GLsizei count,const GLfloat * value)5707 void GL2Encoder::s_glProgramUniform2fv(void* self, GLuint program, GLint location, GLsizei count, const GLfloat *value)
5708 {
5709     GL2Encoder *ctx = (GL2Encoder*)self;
5710     ctx->m_glProgramUniform2fv_enc(self, program, location, count, value);
5711 }
5712 
s_glProgramUniform2i(void * self,GLuint program,GLint location,GLint v0,GLint v1)5713 void GL2Encoder::s_glProgramUniform2i(void* self, GLuint program, GLint location, GLint v0, GLint v1)
5714 {
5715     GL2Encoder *ctx = (GL2Encoder*)self;
5716     ctx->m_glProgramUniform2i_enc(self, program, location, v0, v1);
5717 }
5718 
s_glProgramUniform2iv(void * self,GLuint program,GLint location,GLsizei count,const GLint * value)5719 void GL2Encoder::s_glProgramUniform2iv(void* self, GLuint program, GLint location, GLsizei count, const GLint *value)
5720 {
5721     GL2Encoder *ctx = (GL2Encoder*)self;
5722     ctx->m_glProgramUniform2iv_enc(self, program, location, count, value);
5723 }
5724 
s_glProgramUniform2ui(void * self,GLuint program,GLint location,GLint v0,GLuint v1)5725 void GL2Encoder::s_glProgramUniform2ui(void* self, GLuint program, GLint location, GLint v0, GLuint v1)
5726 {
5727     GL2Encoder *ctx = (GL2Encoder*)self;
5728     ctx->m_glProgramUniform2ui_enc(self, program, location, v0, v1);
5729 }
5730 
s_glProgramUniform2uiv(void * self,GLuint program,GLint location,GLsizei count,const GLuint * value)5731 void GL2Encoder::s_glProgramUniform2uiv(void* self, GLuint program, GLint location, GLsizei count, const GLuint *value)
5732 {
5733     GL2Encoder *ctx = (GL2Encoder*)self;
5734     ctx->m_glProgramUniform2uiv_enc(self, program, location, count, value);
5735 }
5736 
s_glProgramUniform3f(void * self,GLuint program,GLint location,GLfloat v0,GLfloat v1,GLfloat v2)5737 void GL2Encoder::s_glProgramUniform3f(void* self, GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2)
5738 {
5739     GL2Encoder *ctx = (GL2Encoder*)self;
5740     ctx->m_glProgramUniform3f_enc(self, program, location, v0, v1, v2);
5741 }
5742 
s_glProgramUniform3fv(void * self,GLuint program,GLint location,GLsizei count,const GLfloat * value)5743 void GL2Encoder::s_glProgramUniform3fv(void* self, GLuint program, GLint location, GLsizei count, const GLfloat *value)
5744 {
5745     GL2Encoder *ctx = (GL2Encoder*)self;
5746     ctx->m_glProgramUniform3fv_enc(self, program, location, count, value);
5747 }
5748 
s_glProgramUniform3i(void * self,GLuint program,GLint location,GLint v0,GLint v1,GLint v2)5749 void GL2Encoder::s_glProgramUniform3i(void* self, GLuint program, GLint location, GLint v0, GLint v1, GLint v2)
5750 {
5751     GL2Encoder *ctx = (GL2Encoder*)self;
5752     ctx->m_glProgramUniform3i_enc(self, program, location, v0, v1, v2);
5753 }
5754 
s_glProgramUniform3iv(void * self,GLuint program,GLint location,GLsizei count,const GLint * value)5755 void GL2Encoder::s_glProgramUniform3iv(void* self, GLuint program, GLint location, GLsizei count, const GLint *value)
5756 {
5757     GL2Encoder *ctx = (GL2Encoder*)self;
5758     ctx->m_glProgramUniform3iv_enc(self, program, location, count, value);
5759 }
5760 
s_glProgramUniform3ui(void * self,GLuint program,GLint location,GLint v0,GLint v1,GLuint v2)5761 void GL2Encoder::s_glProgramUniform3ui(void* self, GLuint program, GLint location, GLint v0, GLint v1, GLuint v2)
5762 {
5763     GL2Encoder *ctx = (GL2Encoder*)self;
5764     ctx->m_glProgramUniform3ui_enc(self, program, location, v0, v1, v2);
5765 }
5766 
s_glProgramUniform3uiv(void * self,GLuint program,GLint location,GLsizei count,const GLuint * value)5767 void GL2Encoder::s_glProgramUniform3uiv(void* self, GLuint program, GLint location, GLsizei count, const GLuint *value)
5768 {
5769     GL2Encoder *ctx = (GL2Encoder*)self;
5770     ctx->m_glProgramUniform3uiv_enc(self, program, location, count, value);
5771 }
5772 
s_glProgramUniform4f(void * self,GLuint program,GLint location,GLfloat v0,GLfloat v1,GLfloat v2,GLfloat v3)5773 void GL2Encoder::s_glProgramUniform4f(void* self, GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3)
5774 {
5775     GL2Encoder *ctx = (GL2Encoder*)self;
5776     ctx->m_glProgramUniform4f_enc(self, program, location, v0, v1, v2, v3);
5777 }
5778 
s_glProgramUniform4fv(void * self,GLuint program,GLint location,GLsizei count,const GLfloat * value)5779 void GL2Encoder::s_glProgramUniform4fv(void* self, GLuint program, GLint location, GLsizei count, const GLfloat *value)
5780 {
5781     GL2Encoder *ctx = (GL2Encoder*)self;
5782     ctx->m_glProgramUniform4fv_enc(self, program, location, count, value);
5783 }
5784 
s_glProgramUniform4i(void * self,GLuint program,GLint location,GLint v0,GLint v1,GLint v2,GLint v3)5785 void GL2Encoder::s_glProgramUniform4i(void* self, GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLint v3)
5786 {
5787     GL2Encoder *ctx = (GL2Encoder*)self;
5788     ctx->m_glProgramUniform4i_enc(self, program, location, v0, v1, v2, v3);
5789 }
5790 
s_glProgramUniform4iv(void * self,GLuint program,GLint location,GLsizei count,const GLint * value)5791 void GL2Encoder::s_glProgramUniform4iv(void* self, GLuint program, GLint location, GLsizei count, const GLint *value)
5792 {
5793     GL2Encoder *ctx = (GL2Encoder*)self;
5794     ctx->m_glProgramUniform4iv_enc(self, program, location, count, value);
5795 }
5796 
s_glProgramUniform4ui(void * self,GLuint program,GLint location,GLint v0,GLint v1,GLint v2,GLuint v3)5797 void GL2Encoder::s_glProgramUniform4ui(void* self, GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLuint v3)
5798 {
5799     GL2Encoder *ctx = (GL2Encoder*)self;
5800     ctx->m_glProgramUniform4ui_enc(self, program, location, v0, v1, v2, v3);
5801 }
5802 
s_glProgramUniform4uiv(void * self,GLuint program,GLint location,GLsizei count,const GLuint * value)5803 void GL2Encoder::s_glProgramUniform4uiv(void* self, GLuint program, GLint location, GLsizei count, const GLuint *value)
5804 {
5805     GL2Encoder *ctx = (GL2Encoder*)self;
5806     ctx->m_glProgramUniform4uiv_enc(self, program, location, count, value);
5807 }
5808 
s_glProgramUniformMatrix2fv(void * self,GLuint program,GLint location,GLsizei count,GLboolean transpose,const GLfloat * value)5809 void GL2Encoder::s_glProgramUniformMatrix2fv(void* self, GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
5810 {
5811     GL2Encoder *ctx = (GL2Encoder*)self;
5812     ctx->m_glProgramUniformMatrix2fv_enc(self, program, location, count, transpose, value);
5813 }
5814 
s_glProgramUniformMatrix2x3fv(void * self,GLuint program,GLint location,GLsizei count,GLboolean transpose,const GLfloat * value)5815 void GL2Encoder::s_glProgramUniformMatrix2x3fv(void* self, GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
5816 {
5817     GL2Encoder *ctx = (GL2Encoder*)self;
5818     ctx->m_glProgramUniformMatrix2x3fv_enc(self, program, location, count, transpose, value);
5819 }
5820 
s_glProgramUniformMatrix2x4fv(void * self,GLuint program,GLint location,GLsizei count,GLboolean transpose,const GLfloat * value)5821 void GL2Encoder::s_glProgramUniformMatrix2x4fv(void* self, GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
5822 {
5823     GL2Encoder *ctx = (GL2Encoder*)self;
5824     ctx->m_glProgramUniformMatrix2x4fv_enc(self, program, location, count, transpose, value);
5825 }
5826 
s_glProgramUniformMatrix3fv(void * self,GLuint program,GLint location,GLsizei count,GLboolean transpose,const GLfloat * value)5827 void GL2Encoder::s_glProgramUniformMatrix3fv(void* self, GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
5828 {
5829     GL2Encoder *ctx = (GL2Encoder*)self;
5830     ctx->m_glProgramUniformMatrix3fv_enc(self, program, location, count, transpose, value);
5831 }
5832 
s_glProgramUniformMatrix3x2fv(void * self,GLuint program,GLint location,GLsizei count,GLboolean transpose,const GLfloat * value)5833 void GL2Encoder::s_glProgramUniformMatrix3x2fv(void* self, GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
5834 {
5835     GL2Encoder *ctx = (GL2Encoder*)self;
5836     ctx->m_glProgramUniformMatrix3x2fv_enc(self, program, location, count, transpose, value);
5837 }
5838 
s_glProgramUniformMatrix3x4fv(void * self,GLuint program,GLint location,GLsizei count,GLboolean transpose,const GLfloat * value)5839 void GL2Encoder::s_glProgramUniformMatrix3x4fv(void* self, GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
5840 {
5841     GL2Encoder *ctx = (GL2Encoder*)self;
5842     ctx->m_glProgramUniformMatrix3x4fv_enc(self, program, location, count, transpose, value);
5843 }
5844 
s_glProgramUniformMatrix4fv(void * self,GLuint program,GLint location,GLsizei count,GLboolean transpose,const GLfloat * value)5845 void GL2Encoder::s_glProgramUniformMatrix4fv(void* self, GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
5846 {
5847     GL2Encoder *ctx = (GL2Encoder*)self;
5848     ctx->m_glProgramUniformMatrix4fv_enc(self, program, location, count, transpose, value);
5849 }
5850 
s_glProgramUniformMatrix4x2fv(void * self,GLuint program,GLint location,GLsizei count,GLboolean transpose,const GLfloat * value)5851 void GL2Encoder::s_glProgramUniformMatrix4x2fv(void* self, GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
5852 {
5853     GL2Encoder *ctx = (GL2Encoder*)self;
5854     ctx->m_glProgramUniformMatrix4x2fv_enc(self, program, location, count, transpose, value);
5855 }
5856 
s_glProgramUniformMatrix4x3fv(void * self,GLuint program,GLint location,GLsizei count,GLboolean transpose,const GLfloat * value)5857 void GL2Encoder::s_glProgramUniformMatrix4x3fv(void* self, GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
5858 {
5859     GL2Encoder *ctx = (GL2Encoder*)self;
5860     ctx->m_glProgramUniformMatrix4x3fv_enc(self, program, location, count, transpose, value);
5861 }
5862 
s_glProgramParameteri(void * self,GLuint program,GLenum pname,GLint value)5863 void GL2Encoder::s_glProgramParameteri(void* self, GLuint program, GLenum pname, GLint value) {
5864     GL2Encoder* ctx = (GL2Encoder*)self;
5865     VALIDATE_PROGRAM_NAME(program);
5866     SET_ERROR_IF(pname != GL_PROGRAM_BINARY_RETRIEVABLE_HINT && pname != GL_PROGRAM_SEPARABLE, GL_INVALID_ENUM);
5867     SET_ERROR_IF(value != GL_FALSE && value != GL_TRUE, GL_INVALID_VALUE);
5868     ctx->m_glProgramParameteri_enc(self, program, pname, value);
5869 }
5870 
s_glUseProgramStages(void * self,GLuint pipeline,GLbitfield stages,GLuint program)5871 void GL2Encoder::s_glUseProgramStages(void *self, GLuint pipeline, GLbitfield stages, GLuint program)
5872 {
5873     GL2Encoder *ctx = (GL2Encoder*)self;
5874     GLClientState* state = ctx->m_state;
5875     GLSharedGroupPtr shared = ctx->m_shared;
5876 
5877     SET_ERROR_IF(!pipeline, GL_INVALID_OPERATION);
5878     SET_ERROR_IF(program && !shared->isShaderOrProgramObject(program), GL_INVALID_VALUE);
5879     SET_ERROR_IF(program && !shared->isProgram(program), GL_INVALID_OPERATION);
5880 
5881     ctx->m_glUseProgramStages_enc(self, pipeline, stages, program);
5882     state->associateProgramWithPipeline(program, pipeline);
5883 
5884     // There is an active non-separable shader program in effect; no need to update external/2D bindings.
5885     if (state->currentProgram()) {
5886         return;
5887     }
5888 
5889     // Otherwise, update host texture 2D bindings.
5890     ctx->updateHostTexture2DBindingsFromProgramData(program);
5891 
5892     if (program) {
5893         ctx->m_state->currentUniformValidationInfo = ctx->m_shared->getUniformValidationInfo(program);
5894         ctx->m_state->currentAttribValidationInfo = ctx->m_shared->getAttribValidationInfo(program);
5895     }
5896 }
5897 
s_glBindProgramPipeline(void * self,GLuint pipeline)5898 void GL2Encoder::s_glBindProgramPipeline(void* self, GLuint pipeline)
5899 {
5900     GL2Encoder *ctx = (GL2Encoder*)self;
5901     GLClientState* state = ctx->m_state;
5902 
5903     ctx->m_glBindProgramPipeline_enc(self, pipeline);
5904 
5905     // There is an active non-separable shader program in effect; no need to update external/2D bindings.
5906     if (!pipeline || state->currentProgram()) {
5907         return;
5908     }
5909 
5910     GLClientState::ProgramPipelineIterator it = state->programPipelineBegin();
5911     for (; it != state->programPipelineEnd(); ++it) {
5912         if (it->second == pipeline) {
5913             ctx->updateHostTexture2DBindingsFromProgramData(it->first);
5914         }
5915     }
5916 }
5917 
s_glGetProgramResourceiv(void * self,GLuint program,GLenum programInterface,GLuint index,GLsizei propCount,const GLenum * props,GLsizei bufSize,GLsizei * length,GLint * params)5918 void GL2Encoder::s_glGetProgramResourceiv(void* self, GLuint program, GLenum programInterface, GLuint index, GLsizei propCount, const GLenum * props, GLsizei bufSize, GLsizei * length, GLint * params) {
5919     GL2Encoder *ctx = (GL2Encoder*)self;
5920     SET_ERROR_IF(bufSize < 0, GL_INVALID_VALUE);
5921     if (bufSize == 0) {
5922         if (length) *length = 0;
5923         return;
5924     }
5925 
5926     // Avoid modifying |name| if |*length| < bufSize.
5927     GLint* intermediate = new GLint[bufSize];
5928     GLsizei* myLength = length ? length : new GLsizei;
5929     bool needFreeLength = length == NULL;
5930 
5931     ctx->m_glGetProgramResourceiv_enc(self, program, programInterface, index, propCount, props, bufSize, myLength, intermediate);
5932     GLsizei writtenInts = *myLength;
5933     memcpy(params, intermediate, writtenInts * sizeof(GLint));
5934 
5935     delete [] intermediate;
5936     if (needFreeLength)
5937         delete myLength;
5938 }
5939 
s_glGetProgramResourceIndex(void * self,GLuint program,GLenum programInterface,const char * name)5940 GLuint GL2Encoder::s_glGetProgramResourceIndex(void* self, GLuint program, GLenum programInterface, const char* name) {
5941     GL2Encoder *ctx = (GL2Encoder*)self;
5942     return ctx->m_glGetProgramResourceIndex_enc(self, program, programInterface, name);
5943 }
5944 
s_glGetProgramResourceLocation(void * self,GLuint program,GLenum programInterface,const char * name)5945 GLint GL2Encoder::s_glGetProgramResourceLocation(void* self, GLuint program, GLenum programInterface, const char* name) {
5946     GL2Encoder *ctx = (GL2Encoder*)self;
5947     return ctx->m_glGetProgramResourceLocation_enc(self, program, programInterface, name);
5948 }
5949 
s_glGetProgramResourceName(void * self,GLuint program,GLenum programInterface,GLuint index,GLsizei bufSize,GLsizei * length,char * name)5950 void GL2Encoder::s_glGetProgramResourceName(void* self, GLuint program, GLenum programInterface, GLuint index, GLsizei bufSize, GLsizei* length, char* name) {
5951     GL2Encoder *ctx = (GL2Encoder*)self;
5952     SET_ERROR_IF(bufSize < 0, GL_INVALID_VALUE);
5953     if (bufSize == 0) {
5954         if (length) *length = 0;
5955         return;
5956     }
5957 
5958     // Avoid modifying |name| if |*length| < bufSize.
5959     char* intermediate = new char[bufSize];
5960     GLsizei* myLength = length ? length : new GLsizei;
5961     bool needFreeLength = length == NULL;
5962 
5963     ctx->m_glGetProgramResourceName_enc(self, program, programInterface, index, bufSize, myLength, intermediate);
5964     GLsizei writtenStrLen = *myLength;
5965     memcpy(name, intermediate, writtenStrLen + 1);
5966 
5967     delete [] intermediate;
5968     if (needFreeLength)
5969         delete myLength;
5970 }
5971 
s_glGetProgramPipelineInfoLog(void * self,GLuint pipeline,GLsizei bufSize,GLsizei * length,GLchar * infoLog)5972 void GL2Encoder::s_glGetProgramPipelineInfoLog(void* self, GLuint pipeline, GLsizei bufSize, GLsizei* length, GLchar* infoLog) {
5973     GL2Encoder *ctx = (GL2Encoder*)self;
5974     SET_ERROR_IF(bufSize < 0, GL_INVALID_VALUE);
5975     if (bufSize == 0) {
5976         if (length) *length = 0;
5977         return;
5978     }
5979 
5980     // Avoid modifying |infoLog| if |*length| < bufSize.
5981     GLchar* intermediate = new GLchar[bufSize];
5982     GLsizei* myLength = length ? length : new GLsizei;
5983     bool needFreeLength = length == NULL;
5984 
5985     ctx->m_glGetProgramPipelineInfoLog_enc(self, pipeline, bufSize, myLength, intermediate);
5986     GLsizei writtenStrLen = *myLength;
5987     memcpy(infoLog, intermediate, writtenStrLen + 1);
5988 
5989     delete [] intermediate;
5990     if (needFreeLength)
5991         delete myLength;
5992 }
5993 
s_glVertexAttribFormat(void * self,GLuint attribindex,GLint size,GLenum type,GLboolean normalized,GLuint relativeoffset)5994 void GL2Encoder::s_glVertexAttribFormat(void* self, GLuint attribindex, GLint size, GLenum type, GLboolean normalized, GLuint relativeoffset) {
5995     GL2Encoder *ctx = (GL2Encoder*)self;
5996     GLClientState* state = ctx->m_state;
5997 
5998     VALIDATE_VERTEX_ATTRIB_INDEX(attribindex);
5999     SET_ERROR_IF(!state->currentVertexArrayObject(), GL_INVALID_OPERATION);
6000 
6001     state->setVertexAttribFormat(attribindex, size, type, normalized, relativeoffset, false);
6002     ctx->m_glVertexAttribFormat_enc(ctx, attribindex, size, type, normalized, relativeoffset);
6003 }
6004 
s_glVertexAttribIFormat(void * self,GLuint attribindex,GLint size,GLenum type,GLuint relativeoffset)6005 void GL2Encoder::s_glVertexAttribIFormat(void* self, GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset) {
6006     GL2Encoder *ctx = (GL2Encoder*)self;
6007     GLClientState* state = ctx->m_state;
6008 
6009     VALIDATE_VERTEX_ATTRIB_INDEX(attribindex);
6010     SET_ERROR_IF(!state->currentVertexArrayObject(), GL_INVALID_OPERATION);
6011 
6012     state->setVertexAttribFormat(attribindex, size, type, GL_FALSE, relativeoffset, true);
6013     ctx->m_glVertexAttribIFormat_enc(ctx, attribindex, size, type, relativeoffset);
6014 }
6015 
s_glVertexBindingDivisor(void * self,GLuint bindingindex,GLuint divisor)6016 void GL2Encoder::s_glVertexBindingDivisor(void* self, GLuint bindingindex, GLuint divisor) {
6017     GL2Encoder *ctx = (GL2Encoder*)self;
6018     GLClientState* state = ctx->m_state;
6019 
6020     SET_ERROR_IF(!state->currentVertexArrayObject(), GL_INVALID_OPERATION);
6021 
6022     state->setVertexBindingDivisor(bindingindex, divisor);
6023     ctx->m_glVertexBindingDivisor_enc(ctx, bindingindex, divisor);
6024 }
6025 
s_glVertexAttribBinding(void * self,GLuint attribindex,GLuint bindingindex)6026 void GL2Encoder::s_glVertexAttribBinding(void* self, GLuint attribindex, GLuint bindingindex) {
6027     GL2Encoder *ctx = (GL2Encoder*)self;
6028     GLClientState* state = ctx->m_state;
6029     VALIDATE_VERTEX_ATTRIB_INDEX(attribindex);
6030     SET_ERROR_IF(!state->currentVertexArrayObject(), GL_INVALID_OPERATION);
6031 
6032     state->setVertexAttribBinding(attribindex, bindingindex);
6033     ctx->m_glVertexAttribBinding_enc(ctx, attribindex, bindingindex);
6034 }
6035 
s_glBindVertexBuffer(void * self,GLuint bindingindex,GLuint buffer,GLintptr offset,GLintptr stride)6036 void GL2Encoder::s_glBindVertexBuffer(void* self, GLuint bindingindex, GLuint buffer, GLintptr offset, GLintptr stride) {
6037     GL2Encoder *ctx = (GL2Encoder*)self;
6038     GLClientState* state = ctx->m_state;
6039 
6040     SET_ERROR_IF(offset < 0, GL_INVALID_VALUE);
6041 
6042     GLint maxStride;
6043     ctx->glGetIntegerv(ctx, GL_MAX_VERTEX_ATTRIB_STRIDE, &maxStride);
6044     SET_ERROR_IF(stride < 0 || stride > maxStride, GL_INVALID_VALUE);
6045 
6046     SET_ERROR_IF(!state->currentVertexArrayObject(), GL_INVALID_OPERATION);
6047 
6048     state->bindIndexedBuffer(0, bindingindex, buffer, offset, 0, stride, stride);
6049     ctx->m_glBindVertexBuffer_enc(ctx, bindingindex, buffer, offset, stride);
6050 }
6051 
s_glDrawArraysIndirect(void * self,GLenum mode,const void * indirect)6052 void GL2Encoder::s_glDrawArraysIndirect(void* self, GLenum mode, const void* indirect) {
6053     GL2Encoder *ctx = (GL2Encoder*)self;
6054     GLClientState* state = ctx->m_state;
6055 
6056     bool hasClientArrays = false;
6057     bool hasVBOs = false;
6058     ctx->getVBOUsage(&hasClientArrays, &hasVBOs);
6059 
6060     SET_ERROR_IF(hasClientArrays, GL_INVALID_OPERATION);
6061     SET_ERROR_IF(!state->currentVertexArrayObject(), GL_INVALID_OPERATION);
6062     SET_ERROR_IF(!ctx->boundBuffer(GL_DRAW_INDIRECT_BUFFER), GL_INVALID_OPERATION);
6063     SET_ERROR_IF(ctx->m_state->checkFramebufferCompleteness(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE, GL_INVALID_FRAMEBUFFER_OPERATION);
6064 
6065     GLuint indirectStructSize = glUtilsIndirectStructSize(INDIRECT_COMMAND_DRAWARRAYS);
6066     if (ctx->boundBuffer(GL_DRAW_INDIRECT_BUFFER)) {
6067         // BufferData* buf = ctx->getBufferData(target);
6068         // if (buf) {
6069         //     SET_ERROR_IF((GLuint)(uintptr_t)indirect + indirectStructSize > buf->m_size, GL_INVALID_VALUE);
6070         // }
6071         ctx->glDrawArraysIndirectOffsetAEMU(ctx, mode, (uintptr_t)indirect);
6072     } else {
6073         // Client command structs are technically allowed in desktop OpenGL, but not in ES.
6074         // This is purely for debug/dev purposes.
6075         ctx->glDrawArraysIndirectDataAEMU(ctx, mode, indirect, indirectStructSize);
6076     }
6077     ctx->m_state->postDraw();
6078 }
6079 
s_glDrawElementsIndirect(void * self,GLenum mode,GLenum type,const void * indirect)6080 void GL2Encoder::s_glDrawElementsIndirect(void* self, GLenum mode, GLenum type, const void* indirect) {
6081     GL2Encoder *ctx = (GL2Encoder*)self;
6082 
6083     GLClientState* state = ctx->m_state;
6084 
6085     bool hasClientArrays = false;
6086     bool hasVBOs = false;
6087     ctx->getVBOUsage(&hasClientArrays, &hasVBOs);
6088 
6089     SET_ERROR_IF(hasClientArrays, GL_INVALID_OPERATION);
6090     SET_ERROR_IF(!state->currentVertexArrayObject(), GL_INVALID_OPERATION);
6091     SET_ERROR_IF(!ctx->boundBuffer(GL_DRAW_INDIRECT_BUFFER), GL_INVALID_OPERATION);
6092 
6093     SET_ERROR_IF(ctx->m_state->getTransformFeedbackActiveUnpaused(), GL_INVALID_OPERATION);
6094     SET_ERROR_IF(ctx->m_state->checkFramebufferCompleteness(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE, GL_INVALID_FRAMEBUFFER_OPERATION);
6095 
6096     GLuint indirectStructSize = glUtilsIndirectStructSize(INDIRECT_COMMAND_DRAWELEMENTS);
6097     if (ctx->boundBuffer(GL_DRAW_INDIRECT_BUFFER)) {
6098         // BufferData* buf = ctx->getBufferData(target);
6099         // if (buf) {
6100         //     SET_ERROR_IF((GLuint)(uintptr_t)indirect + indirectStructSize > buf->m_size, GL_INVALID_VALUE);
6101         // }
6102         ctx->glDrawElementsIndirectOffsetAEMU(ctx, mode, type, (uintptr_t)indirect);
6103     } else {
6104         // Client command structs are technically allowed in desktop OpenGL, but not in ES.
6105         // This is purely for debug/dev purposes.
6106         ctx->glDrawElementsIndirectDataAEMU(ctx, mode, type, indirect, indirectStructSize);
6107     }
6108     ctx->m_state->postDraw();
6109 }
6110 
s_glTexStorage2DMultisample(void * self,GLenum target,GLsizei samples,GLenum internalformat,GLsizei width,GLsizei height,GLboolean fixedsamplelocations)6111 void GL2Encoder::s_glTexStorage2DMultisample(void* self, GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations) {
6112     GL2Encoder *ctx = (GL2Encoder*)self;
6113     GLClientState* state = ctx->m_state;
6114 
6115     SET_ERROR_IF(target != GL_TEXTURE_2D_MULTISAMPLE, GL_INVALID_ENUM);
6116     SET_ERROR_IF(!GLESv2Validation::pixelInternalFormat(internalformat), GL_INVALID_ENUM);
6117     SET_ERROR_IF(!state->getBoundTexture(target), GL_INVALID_OPERATION);
6118     SET_ERROR_IF(width < 1 || height < 1, GL_INVALID_VALUE);
6119     SET_ERROR_IF(state->isBoundTextureImmutableFormat(target), GL_INVALID_OPERATION);
6120     GLint max_samples;
6121     ctx->s_glGetInternalformativ(ctx, target, internalformat, GL_SAMPLES, 1, &max_samples);
6122     SET_ERROR_IF(samples > max_samples, GL_INVALID_OPERATION);
6123 
6124     state->setBoundTextureInternalFormat(target, internalformat);
6125     state->setBoundTextureDims(target, target, 0, width, height, 1);
6126     state->setBoundTextureImmutableFormat(target);
6127     state->setBoundTextureSamples(target, samples);
6128 
6129     ctx->m_glTexStorage2DMultisample_enc(ctx, target, samples, internalformat, width, height, fixedsamplelocations);
6130 }
6131 
s_glGetGraphicsResetStatusEXT(void * self)6132 GLenum GL2Encoder::s_glGetGraphicsResetStatusEXT(void* self) {
6133     (void)self;
6134     return GL_NO_ERROR;
6135 }
6136 
s_glReadnPixelsEXT(void * self,GLint x,GLint y,GLsizei width,GLsizei height,GLenum format,GLenum type,GLsizei bufSize,GLvoid * pixels)6137 void GL2Encoder::s_glReadnPixelsEXT(void* self, GLint x, GLint y, GLsizei width,
6138         GLsizei height, GLenum format, GLenum type, GLsizei bufSize,
6139         GLvoid* pixels) {
6140     GL2Encoder *ctx = (GL2Encoder*)self;
6141     SET_ERROR_IF(bufSize < glesv2_enc::pixelDataSize(self, width, height, format,
6142         type, 1), GL_INVALID_OPERATION);
6143     s_glReadPixels(self, x, y, width, height, format, type, pixels);
6144     ctx->m_state->postReadPixels();
6145 }
6146 
s_glGetnUniformfvEXT(void * self,GLuint program,GLint location,GLsizei bufSize,GLfloat * params)6147 void GL2Encoder::s_glGetnUniformfvEXT(void *self, GLuint program, GLint location,
6148         GLsizei bufSize, GLfloat* params) {
6149     GL2Encoder *ctx = (GL2Encoder*)self;
6150     SET_ERROR_IF(bufSize < glSizeof(glesv2_enc::uniformType(self, program,
6151         location)), GL_INVALID_OPERATION);
6152     s_glGetUniformfv(self, program, location, params);
6153 }
6154 
s_glGetnUniformivEXT(void * self,GLuint program,GLint location,GLsizei bufSize,GLint * params)6155 void GL2Encoder::s_glGetnUniformivEXT(void *self, GLuint program, GLint location,
6156         GLsizei bufSize, GLint* params) {
6157     GL2Encoder *ctx = (GL2Encoder*)self;
6158     SET_ERROR_IF(bufSize < glSizeof(glesv2_enc::uniformType(self, program,
6159         location)), GL_INVALID_OPERATION);
6160     s_glGetUniformiv(self, program, location, params);
6161 }
6162 
s_glInvalidateFramebuffer(void * self,GLenum target,GLsizei numAttachments,const GLenum * attachments)6163 void GL2Encoder::s_glInvalidateFramebuffer(void* self, GLenum target, GLsizei numAttachments, const GLenum *attachments) {
6164     GL2Encoder *ctx = (GL2Encoder*)self;
6165     SET_ERROR_IF((target != GL_FRAMEBUFFER) &&
6166                  (target != GL_READ_FRAMEBUFFER) &&
6167                  (target != GL_DRAW_FRAMEBUFFER), GL_INVALID_ENUM);
6168     SET_ERROR_IF(numAttachments < 0, GL_INVALID_VALUE);
6169 
6170     GLint maxColorAttachments;
6171     ctx->glGetIntegerv(ctx, GL_MAX_COLOR_ATTACHMENTS, &maxColorAttachments);
6172     for (GLsizei i = 0; i < numAttachments; ++i) {
6173         if (attachments[i] != GL_DEPTH_ATTACHMENT && attachments[i] != GL_STENCIL_ATTACHMENT && attachments[i] != GL_DEPTH_STENCIL_ATTACHMENT) {
6174             SET_ERROR_IF(attachments[i] >= GL_COLOR_ATTACHMENT0 + maxColorAttachments, GL_INVALID_OPERATION);
6175         }
6176     }
6177 
6178     ctx->m_glInvalidateFramebuffer_enc(ctx, target, numAttachments, attachments);
6179 }
6180 
s_glInvalidateSubFramebuffer(void * self,GLenum target,GLsizei numAttachments,const GLenum * attachments,GLint x,GLint y,GLsizei width,GLsizei height)6181 void GL2Encoder::s_glInvalidateSubFramebuffer(void* self, GLenum target, GLsizei numAttachments, const GLenum *attachments, GLint x, GLint y, GLsizei width, GLsizei height) {
6182     GL2Encoder *ctx = (GL2Encoder*)self;
6183     SET_ERROR_IF(target != GL_FRAMEBUFFER && target != GL_READ_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER, GL_INVALID_ENUM);
6184     SET_ERROR_IF(numAttachments < 0, GL_INVALID_VALUE);
6185     SET_ERROR_IF(width < 0, GL_INVALID_VALUE);
6186     SET_ERROR_IF(height < 0, GL_INVALID_VALUE);
6187     GLint maxColorAttachments;
6188     ctx->glGetIntegerv(ctx, GL_MAX_COLOR_ATTACHMENTS, &maxColorAttachments);
6189     for (GLsizei i = 0; i < numAttachments; ++i) {
6190         if (attachments[i] != GL_DEPTH_ATTACHMENT && attachments[i] != GL_STENCIL_ATTACHMENT && attachments[i] != GL_DEPTH_STENCIL_ATTACHMENT) {
6191             SET_ERROR_IF(attachments[i] >= GL_COLOR_ATTACHMENT0 + maxColorAttachments, GL_INVALID_OPERATION);
6192         }
6193     }
6194     ctx->m_glInvalidateSubFramebuffer_enc(ctx, target, numAttachments, attachments, x, y, width, height);
6195 }
6196 
s_glDispatchCompute(void * self,GLuint num_groups_x,GLuint num_groups_y,GLuint num_groups_z)6197 void GL2Encoder::s_glDispatchCompute(void* self, GLuint num_groups_x, GLuint num_groups_y, GLuint num_groups_z) {
6198     GL2Encoder *ctx = (GL2Encoder*)self;
6199     ctx->m_glDispatchCompute_enc(ctx, num_groups_x, num_groups_y, num_groups_z);
6200     ctx->m_state->postDispatchCompute();
6201 }
6202 
s_glDispatchComputeIndirect(void * self,GLintptr indirect)6203 void GL2Encoder::s_glDispatchComputeIndirect(void* self, GLintptr indirect) {
6204     GL2Encoder *ctx = (GL2Encoder*)self;
6205     ctx->m_glDispatchComputeIndirect_enc(ctx, indirect);
6206     ctx->m_state->postDispatchCompute();
6207 }
6208 
s_glGenTransformFeedbacks(void * self,GLsizei n,GLuint * ids)6209 void GL2Encoder::s_glGenTransformFeedbacks(void* self, GLsizei n, GLuint* ids) {
6210     GL2Encoder *ctx = (GL2Encoder*)self;
6211     ctx->m_glGenTransformFeedbacks_enc(ctx, n, ids);
6212     ctx->m_state->setExistence(GLClientState::ObjectType::TransformFeedback, true, n, ids);
6213 }
6214 
s_glDeleteTransformFeedbacks(void * self,GLsizei n,const GLuint * ids)6215 void GL2Encoder::s_glDeleteTransformFeedbacks(void* self, GLsizei n, const GLuint* ids) {
6216     GL2Encoder *ctx = (GL2Encoder*)self;
6217     SET_ERROR_IF(ctx->m_state->getTransformFeedbackActive(), GL_INVALID_OPERATION);
6218 
6219     ctx->m_state->setExistence(GLClientState::ObjectType::TransformFeedback, false, n, ids);
6220     ctx->m_glDeleteTransformFeedbacks_enc(ctx, n, ids);
6221 }
6222 
s_glGenSamplers(void * self,GLsizei n,GLuint * ids)6223 void GL2Encoder::s_glGenSamplers(void* self, GLsizei n, GLuint* ids) {
6224     GL2Encoder *ctx = (GL2Encoder*)self;
6225     ctx->m_glGenSamplers_enc(ctx, n, ids);
6226     ctx->m_state->setExistence(GLClientState::ObjectType::Sampler, true, n, ids);
6227 }
6228 
s_glGenQueries(void * self,GLsizei n,GLuint * ids)6229 void GL2Encoder::s_glGenQueries(void* self, GLsizei n, GLuint* ids) {
6230     GL2Encoder *ctx = (GL2Encoder*)self;
6231     ctx->m_glGenQueries_enc(ctx, n, ids);
6232     ctx->m_state->setExistence(GLClientState::ObjectType::Query, true, n, ids);
6233 }
6234 
s_glDeleteQueries(void * self,GLsizei n,const GLuint * ids)6235 void GL2Encoder::s_glDeleteQueries(void* self, GLsizei n, const GLuint* ids) {
6236     GL2Encoder *ctx = (GL2Encoder*)self;
6237     ctx->m_state->setExistence(GLClientState::ObjectType::Query, false, n, ids);
6238     ctx->m_glDeleteQueries_enc(ctx, n, ids);
6239 }
6240 
s_glBindTransformFeedback(void * self,GLenum target,GLuint id)6241 void GL2Encoder::s_glBindTransformFeedback(void* self, GLenum target, GLuint id) {
6242     GL2Encoder *ctx = (GL2Encoder*)self;
6243     SET_ERROR_IF(GL_TRANSFORM_FEEDBACK != target, GL_INVALID_ENUM);
6244     SET_ERROR_IF(ctx->m_state->getTransformFeedbackActiveUnpaused(), GL_INVALID_OPERATION);
6245     SET_ERROR_IF(!ctx->m_state->tryBind(target, id), GL_INVALID_OPERATION);
6246     ctx->m_glBindTransformFeedback_enc(ctx, target, id);
6247 }
6248 
s_glBeginQuery(void * self,GLenum target,GLuint query)6249 void GL2Encoder::s_glBeginQuery(void* self, GLenum target, GLuint query) {
6250     GL2Encoder *ctx = (GL2Encoder*)self;
6251     SET_ERROR_IF(!GLESv2Validation::allowedQueryTarget(target), GL_INVALID_ENUM);
6252 
6253     if (target != GL_ANY_SAMPLES_PASSED_CONSERVATIVE &&
6254         target != GL_ANY_SAMPLES_PASSED) {
6255         SET_ERROR_IF(ctx->m_state->isQueryBound(target), GL_INVALID_OPERATION);
6256     } else {
6257         SET_ERROR_IF(ctx->m_state->isQueryBound(GL_ANY_SAMPLES_PASSED_CONSERVATIVE), GL_INVALID_OPERATION);
6258         SET_ERROR_IF(ctx->m_state->isQueryBound(GL_ANY_SAMPLES_PASSED), GL_INVALID_OPERATION);
6259     }
6260 
6261     GLenum lastTarget = ctx->m_state->getLastQueryTarget(query);
6262 
6263     if (lastTarget) {
6264         SET_ERROR_IF(target != lastTarget, GL_INVALID_OPERATION);
6265     }
6266 
6267     SET_ERROR_IF(!query, GL_INVALID_OPERATION);
6268     SET_ERROR_IF(!ctx->m_state->tryBind(target, query), GL_INVALID_OPERATION);
6269     ctx->m_state->setLastQueryTarget(target, query);
6270     ctx->m_glBeginQuery_enc(ctx, target, query);
6271 }
6272 
s_glEndQuery(void * self,GLenum target)6273 void GL2Encoder::s_glEndQuery(void* self, GLenum target) {
6274     GL2Encoder *ctx = (GL2Encoder*)self;
6275     SET_ERROR_IF(!GLESv2Validation::allowedQueryTarget(target), GL_INVALID_ENUM);
6276     SET_ERROR_IF(!ctx->m_state->isBoundTargetValid(target), GL_INVALID_OPERATION);
6277     SET_ERROR_IF(!ctx->m_state->tryBind(target, 0), GL_INVALID_OPERATION);
6278     ctx->m_glEndQuery_enc(ctx, target);
6279 }
6280 
s_glClear(void * self,GLbitfield mask)6281 void GL2Encoder::s_glClear(void* self, GLbitfield mask) {
6282     GL2Encoder *ctx = (GL2Encoder*)self;
6283 
6284     GLbitfield allowed_bits = GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT;
6285     GLbitfield has_disallowed_bits = (mask & ~allowed_bits);
6286     SET_ERROR_IF(has_disallowed_bits, GL_INVALID_VALUE);
6287 
6288     ctx->m_glClear_enc(ctx, mask);
6289 }
6290 
s_glCopyTexSubImage2D(void * self,GLenum target,GLint level,GLint xoffset,GLint yoffset,GLint x,GLint y,GLsizei width,GLsizei height)6291 void GL2Encoder::s_glCopyTexSubImage2D(void *self , GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height) {
6292     GL2Encoder *ctx = (GL2Encoder*)self;
6293     SET_ERROR_IF(!GLESv2Validation::textureTarget(ctx, target), GL_INVALID_ENUM);
6294     SET_ERROR_IF(level < 0, GL_INVALID_VALUE);
6295     GLint max_texture_size;
6296     GLint max_cube_map_texture_size;
6297     ctx->glGetIntegerv(ctx, GL_MAX_TEXTURE_SIZE, &max_texture_size);
6298     ctx->glGetIntegerv(ctx, GL_MAX_CUBE_MAP_TEXTURE_SIZE, &max_cube_map_texture_size);
6299     SET_ERROR_IF(level > ilog2(max_texture_size), GL_INVALID_VALUE);
6300     SET_ERROR_IF((target == GL_TEXTURE_CUBE_MAP) &&
6301                  (level > ilog2(max_cube_map_texture_size)), GL_INVALID_VALUE);
6302     SET_ERROR_IF(xoffset < 0 || yoffset < 0, GL_INVALID_VALUE);
6303     SET_ERROR_IF(width < 0 || height < 0, GL_INVALID_VALUE);
6304     SET_ERROR_IF(width > max_texture_size, GL_INVALID_VALUE);
6305     SET_ERROR_IF(height > max_texture_size, GL_INVALID_VALUE);
6306     SET_ERROR_IF(GLESv2Validation::isCubeMapTarget(target) && width > max_cube_map_texture_size, GL_INVALID_VALUE);
6307     SET_ERROR_IF(GLESv2Validation::isCubeMapTarget(target) && height > max_cube_map_texture_size, GL_INVALID_VALUE);
6308     GLuint tex = ctx->m_state->getBoundTexture(target);
6309     GLsizei neededWidth = xoffset + width;
6310     GLsizei neededHeight = yoffset + height;
6311     ALOGV("%s: tex %u needed width height %d %d xoff %d width %d yoff %d height %d (texture width %d height %d) level %d\n", __func__,
6312             tex,
6313             neededWidth,
6314             neededHeight,
6315             xoffset,
6316             width,
6317             yoffset,
6318             height,
6319             ctx->m_state->queryTexWidth(level, tex),
6320             ctx->m_state->queryTexWidth(level, tex),
6321             level);
6322 
6323     SET_ERROR_IF(tex &&
6324                  (neededWidth > ctx->m_state->queryTexWidth(level, tex) ||
6325                   neededHeight > ctx->m_state->queryTexHeight(level, tex)),
6326                  GL_INVALID_VALUE);
6327     SET_ERROR_IF(ctx->glCheckFramebufferStatus(ctx, GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE,
6328                  GL_INVALID_FRAMEBUFFER_OPERATION);
6329 
6330     ctx->m_glCopyTexSubImage2D_enc(ctx, target, level, xoffset, yoffset, x, y, width, height);
6331 }
6332 
s_glCopyTexSubImage3D(void * self,GLenum target,GLint level,GLint xoffset,GLint yoffset,GLint zoffset,GLint x,GLint y,GLsizei width,GLsizei height)6333 void GL2Encoder::s_glCopyTexSubImage3D(void *self , GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height) {
6334     GL2Encoder *ctx = (GL2Encoder*)self;
6335     SET_ERROR_IF(target != GL_TEXTURE_3D &&
6336                  target != GL_TEXTURE_2D_ARRAY,
6337                  GL_INVALID_ENUM);
6338     GLint max_texture_size;
6339     GLint max_3d_texture_size;
6340     ctx->glGetIntegerv(ctx, GL_MAX_TEXTURE_SIZE, &max_texture_size);
6341     ctx->glGetIntegerv(ctx, GL_MAX_3D_TEXTURE_SIZE, &max_3d_texture_size);
6342     SET_ERROR_IF(level < 0, GL_INVALID_VALUE);
6343     SET_ERROR_IF(level > ilog2(max_texture_size), GL_INVALID_VALUE);
6344     SET_ERROR_IF(level > ilog2(max_3d_texture_size), GL_INVALID_VALUE);
6345     SET_ERROR_IF(width < 0 || height < 0, GL_INVALID_VALUE);
6346     SET_ERROR_IF(xoffset < 0 || yoffset < 0 || zoffset < 0, GL_INVALID_VALUE);
6347     GLuint tex = ctx->m_state->getBoundTexture(target);
6348     GLsizei neededWidth = xoffset + width;
6349     GLsizei neededHeight = yoffset + height;
6350     GLsizei neededDepth = zoffset + 1;
6351     SET_ERROR_IF(tex &&
6352                  (neededWidth > ctx->m_state->queryTexWidth(level, tex) ||
6353                   neededHeight > ctx->m_state->queryTexHeight(level, tex) ||
6354                   neededDepth > ctx->m_state->queryTexDepth(level, tex)),
6355                  GL_INVALID_VALUE);
6356     SET_ERROR_IF(ctx->glCheckFramebufferStatus(ctx, GL_READ_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE,
6357                  GL_INVALID_FRAMEBUFFER_OPERATION);
6358 
6359     ctx->m_glCopyTexSubImage3D_enc(ctx, target, level, xoffset, yoffset, zoffset, x, y, width, height);
6360 }
6361 
s_glCompileShader(void * self,GLuint shader)6362 void GL2Encoder::s_glCompileShader(void* self, GLuint shader) {
6363     GL2Encoder *ctx = (GL2Encoder*)self;
6364     bool isShaderOrProgramObject =
6365         ctx->m_shared->isShaderOrProgramObject(shader);
6366     bool isShader =
6367         ctx->m_shared->isShader(shader);
6368 
6369     SET_ERROR_IF(isShaderOrProgramObject && !isShader, GL_INVALID_OPERATION);
6370     SET_ERROR_IF(!isShaderOrProgramObject && !isShader, GL_INVALID_VALUE);
6371 
6372     ctx->m_glCompileShader_enc(ctx, shader);
6373 }
6374 
s_glValidateProgram(void * self,GLuint program)6375 void GL2Encoder::s_glValidateProgram(void* self, GLuint program ) {
6376     GL2Encoder *ctx = (GL2Encoder*)self;
6377 
6378     VALIDATE_PROGRAM_NAME(program);
6379 
6380     ctx->m_glValidateProgram_enc(self, program);
6381 }
6382 
s_glProgramBinary(void * self,GLuint program,GLenum binaryFormat,const void * binary,GLsizei length)6383 void GL2Encoder::s_glProgramBinary(void *self , GLuint program, GLenum binaryFormat, const void* binary, GLsizei length) {
6384     GL2Encoder *ctx = (GL2Encoder*)self;
6385 
6386     VALIDATE_PROGRAM_NAME(program);
6387 
6388     SET_ERROR_IF(~0 == binaryFormat, GL_INVALID_ENUM);
6389 
6390     ctx->m_glProgramBinary_enc(self, program, binaryFormat, binary, length);
6391 }
6392 
s_glGetSamplerParameterfv(void * self,GLuint sampler,GLenum pname,GLfloat * params)6393 void GL2Encoder::s_glGetSamplerParameterfv(void *self, GLuint sampler, GLenum pname, GLfloat* params) {
6394     GL2Encoder *ctx = (GL2Encoder*)self;
6395 
6396     SET_ERROR_IF(!ctx->m_state->samplerExists(sampler), GL_INVALID_OPERATION);
6397     SET_ERROR_IF(!GLESv2Validation::samplerParams(ctx, pname), GL_INVALID_ENUM);
6398 
6399     if (!params) return;
6400 
6401     ctx->m_glGetSamplerParameterfv_enc(ctx, sampler, pname, params);
6402 }
6403 
s_glGetSamplerParameteriv(void * self,GLuint sampler,GLenum pname,GLint * params)6404 void GL2Encoder::s_glGetSamplerParameteriv(void *self, GLuint sampler, GLenum pname, GLint* params) {
6405     GL2Encoder *ctx = (GL2Encoder*)self;
6406     SET_ERROR_IF(!ctx->m_state->samplerExists(sampler), GL_INVALID_OPERATION);
6407     SET_ERROR_IF(!GLESv2Validation::samplerParams(ctx, pname), GL_INVALID_ENUM);
6408 
6409     if (!params) return;
6410 
6411     ctx->m_glGetSamplerParameteriv_enc(ctx, sampler, pname, params);
6412 }
6413 
s_glSamplerParameterf(void * self,GLuint sampler,GLenum pname,GLfloat param)6414 void GL2Encoder::s_glSamplerParameterf(void *self , GLuint sampler, GLenum pname, GLfloat param) {
6415     GL2Encoder *ctx = (GL2Encoder*)self;
6416     SET_ERROR_IF(!ctx->m_state->samplerExists(sampler), GL_INVALID_OPERATION);
6417     SET_ERROR_IF(!GLESv2Validation::samplerParams(ctx, pname), GL_INVALID_ENUM);
6418     SET_ERROR_IF(!GLESv2Validation::textureParamValue(ctx, pname, (GLint)param, param, (GLenum)param), GL_INVALID_ENUM);
6419 
6420     ctx->m_glSamplerParameterf_enc(ctx, sampler, pname, param);
6421 }
6422 
s_glSamplerParameteri(void * self,GLuint sampler,GLenum pname,GLint param)6423 void GL2Encoder::s_glSamplerParameteri(void *self , GLuint sampler, GLenum pname, GLint param) {
6424     GL2Encoder *ctx = (GL2Encoder*)self;
6425     SET_ERROR_IF(!ctx->m_state->samplerExists(sampler), GL_INVALID_OPERATION);
6426     SET_ERROR_IF(!GLESv2Validation::samplerParams(ctx, pname), GL_INVALID_ENUM);
6427     SET_ERROR_IF(!GLESv2Validation::textureParamValue(ctx, pname, param, (GLfloat)param, (GLenum)param), GL_INVALID_ENUM);
6428 
6429     ctx->m_glSamplerParameteri_enc(ctx, sampler, pname, param);
6430 }
6431 
s_glSamplerParameterfv(void * self,GLuint sampler,GLenum pname,const GLfloat * params)6432 void GL2Encoder::s_glSamplerParameterfv(void *self , GLuint sampler, GLenum pname, const GLfloat* params) {
6433     GL2Encoder *ctx = (GL2Encoder*)self;
6434     SET_ERROR_IF(!ctx->m_state->samplerExists(sampler), GL_INVALID_OPERATION);
6435     SET_ERROR_IF(!GLESv2Validation::samplerParams(ctx, pname), GL_INVALID_ENUM);
6436     SET_ERROR_IF(!params, GL_INVALID_VALUE);
6437     GLfloat param = *params;
6438     SET_ERROR_IF(!GLESv2Validation::textureParamValue(ctx, pname, (GLint)param, param, (GLenum)param), GL_INVALID_ENUM);
6439 
6440     ctx->m_glSamplerParameterfv_enc(ctx, sampler, pname, params);
6441 }
6442 
s_glSamplerParameteriv(void * self,GLuint sampler,GLenum pname,const GLint * params)6443 void GL2Encoder::s_glSamplerParameteriv(void *self , GLuint sampler, GLenum pname, const GLint* params) {
6444     GL2Encoder *ctx = (GL2Encoder*)self;
6445     SET_ERROR_IF(!ctx->m_state->samplerExists(sampler), GL_INVALID_OPERATION);
6446     SET_ERROR_IF(!GLESv2Validation::samplerParams(ctx, pname), GL_INVALID_ENUM);
6447     SET_ERROR_IF(!params, GL_INVALID_VALUE);
6448     GLint param = *params;
6449     SET_ERROR_IF(!GLESv2Validation::textureParamValue(ctx, pname, (GLint)param, param, (GLenum)param), GL_INVALID_ENUM);
6450 
6451     ctx->m_glSamplerParameteriv_enc(ctx, sampler, pname, params);
6452 }
6453 
s_glGetAttribLocation(void * self,GLuint program,const GLchar * name)6454 int GL2Encoder::s_glGetAttribLocation(void *self , GLuint program, const GLchar* name) {
6455     GL2Encoder *ctx = (GL2Encoder*)self;
6456 
6457     bool isShaderOrProgramObject =
6458         ctx->m_shared->isShaderOrProgramObject(program);
6459     bool isProgram =
6460         ctx->m_shared->isProgram(program);
6461 
6462     RET_AND_SET_ERROR_IF(!isShaderOrProgramObject, GL_INVALID_VALUE, -1);
6463     RET_AND_SET_ERROR_IF(!isProgram, GL_INVALID_OPERATION, -1);
6464     RET_AND_SET_ERROR_IF(!ctx->m_shared->getProgramLinkStatus(program), GL_INVALID_OPERATION, -1);
6465 
6466     return ctx->m_glGetAttribLocation_enc(ctx, program, name);
6467 }
6468 
s_glBindAttribLocation(void * self,GLuint program,GLuint index,const GLchar * name)6469 void GL2Encoder::s_glBindAttribLocation(void *self , GLuint program, GLuint index, const GLchar* name) {
6470     GL2Encoder* ctx = (GL2Encoder*)self;
6471 
6472     VALIDATE_PROGRAM_NAME(program);
6473 
6474     GLint maxVertexAttribs;
6475     ctx->glGetIntegerv(self, GL_MAX_VERTEX_ATTRIBS, &maxVertexAttribs);
6476     SET_ERROR_IF(!(index < maxVertexAttribs), GL_INVALID_VALUE);
6477     SET_ERROR_IF(index > maxVertexAttribs, GL_INVALID_VALUE);
6478     SET_ERROR_IF(name && !strncmp("gl_", name, 3), GL_INVALID_OPERATION);
6479 
6480     fprintf(stderr, "%s: bind attrib %u name %s\n", __func__, index, name);
6481     ctx->m_glBindAttribLocation_enc(ctx, program, index, name);
6482 }
6483 
6484 // TODO-SLOW
s_glUniformBlockBinding(void * self,GLuint program,GLuint uniformBlockIndex,GLuint uniformBlockBinding)6485 void GL2Encoder::s_glUniformBlockBinding(void *self , GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding) {
6486     GL2Encoder* ctx = (GL2Encoder*)self;
6487 
6488     VALIDATE_PROGRAM_NAME(program);
6489     SET_ERROR_IF(uniformBlockIndex >= ctx->m_shared->getActiveUniformBlockCount(program), GL_INVALID_VALUE);
6490 
6491     GLint maxUniformBufferBindings;
6492     ctx->glGetIntegerv(ctx, GL_MAX_UNIFORM_BUFFER_BINDINGS, &maxUniformBufferBindings);
6493     SET_ERROR_IF(uniformBlockBinding >= maxUniformBufferBindings, GL_INVALID_VALUE);
6494 
6495     ctx->m_glUniformBlockBinding_enc(ctx, program, uniformBlockIndex, uniformBlockBinding);
6496 }
6497 
s_glGetTransformFeedbackVarying(void * self,GLuint program,GLuint index,GLsizei bufSize,GLsizei * length,GLsizei * size,GLenum * type,char * name)6498 void GL2Encoder::s_glGetTransformFeedbackVarying(void *self , GLuint program, GLuint index, GLsizei bufSize, GLsizei* length, GLsizei* size, GLenum* type, char* name) {
6499     GL2Encoder* ctx = (GL2Encoder*)self;
6500 
6501     VALIDATE_PROGRAM_NAME(program);
6502     SET_ERROR_IF(!ctx->m_shared->getProgramLinkStatus(program), GL_INVALID_OPERATION);
6503     SET_ERROR_IF(index >= ctx->m_shared->getTransformFeedbackVaryingsCountForProgram(program), GL_INVALID_VALUE);
6504 
6505     ctx->m_glGetTransformFeedbackVarying_enc(ctx, program, index, bufSize, length, size, type, name);
6506 }
6507 
s_glScissor(void * self,GLint x,GLint y,GLsizei width,GLsizei height)6508 void GL2Encoder::s_glScissor(void *self , GLint x, GLint y, GLsizei width, GLsizei height) {
6509     GL2Encoder* ctx = (GL2Encoder*)self;
6510     SET_ERROR_IF(width < 0 || height < 0, GL_INVALID_VALUE);
6511     ctx->m_glScissor_enc(ctx, x, y, width, height);
6512 }
6513 
s_glDepthFunc(void * self,GLenum func)6514 void GL2Encoder::s_glDepthFunc(void *self , GLenum func) {
6515     GL2Encoder* ctx = (GL2Encoder*)self;
6516     SET_ERROR_IF(
6517         (func != GL_NEVER) &&
6518         (func != GL_ALWAYS) &&
6519         (func != GL_LESS) &&
6520         (func != GL_LEQUAL) &&
6521         (func != GL_EQUAL) &&
6522         (func != GL_GREATER) &&
6523         (func != GL_GEQUAL) &&
6524         (func != GL_NOTEQUAL),
6525         GL_INVALID_ENUM);
6526     ctx->m_glDepthFunc_enc(ctx, func);
6527 }
6528 
s_glViewport(void * self,GLint x,GLint y,GLsizei width,GLsizei height)6529 void GL2Encoder::s_glViewport(void *self , GLint x, GLint y, GLsizei width, GLsizei height) {
6530     GL2Encoder* ctx = (GL2Encoder*)self;
6531     SET_ERROR_IF(width < 0 || height < 0, GL_INVALID_VALUE);
6532     ctx->m_glViewport_enc(ctx, x, y, width, height);
6533 }
6534 
s_glStencilFunc(void * self,GLenum func,GLint ref,GLuint mask)6535 void GL2Encoder::s_glStencilFunc(void *self , GLenum func, GLint ref, GLuint mask) {
6536     GL2Encoder* ctx = (GL2Encoder*)self;
6537     SET_ERROR_IF(!GLESv2Validation::allowedFunc(func), GL_INVALID_ENUM);
6538     if (!ctx->m_state) return;
6539     ctx->m_state->stencilFuncSeparate(GL_FRONT_AND_BACK, func, ref, mask);
6540     ctx->m_glStencilFunc_enc(ctx, func, ref, mask);
6541 }
6542 
s_glStencilFuncSeparate(void * self,GLenum face,GLenum func,GLint ref,GLuint mask)6543 void GL2Encoder::s_glStencilFuncSeparate(void *self , GLenum face, GLenum func, GLint ref, GLuint mask) {
6544     GL2Encoder* ctx = (GL2Encoder*)self;
6545     SET_ERROR_IF(!GLESv2Validation::allowedFace(face) || !GLESv2Validation::allowedFunc(func), GL_INVALID_ENUM);
6546     if (!ctx->m_state) return;
6547     ctx->m_state->stencilFuncSeparate(face, func, ref, mask);
6548     ctx->m_glStencilFuncSeparate_enc(ctx, face, func, ref, mask);
6549 }
6550 
s_glStencilOp(void * self,GLenum fail,GLenum zfail,GLenum zpass)6551 void GL2Encoder::s_glStencilOp(void *self , GLenum fail, GLenum zfail, GLenum zpass) {
6552     GL2Encoder* ctx = (GL2Encoder*)self;
6553     SET_ERROR_IF(
6554         !GLESv2Validation::allowedStencilOp(fail) ||
6555         !GLESv2Validation::allowedStencilOp(zfail) ||
6556         !GLESv2Validation::allowedStencilOp(zpass),
6557         GL_INVALID_ENUM);
6558     if (!ctx->m_state) return;
6559     ctx->m_state->stencilOpSeparate(GL_FRONT_AND_BACK, fail, zfail, zpass);
6560     ctx->m_glStencilOp_enc(ctx, fail, zfail, zpass);
6561 }
6562 
s_glStencilOpSeparate(void * self,GLenum face,GLenum fail,GLenum zfail,GLenum zpass)6563 void GL2Encoder::s_glStencilOpSeparate(void *self , GLenum face, GLenum fail, GLenum zfail, GLenum zpass) {
6564     GL2Encoder* ctx = (GL2Encoder*)self;
6565     SET_ERROR_IF(
6566         !GLESv2Validation::allowedFace(face) ||
6567         !GLESv2Validation::allowedStencilOp(fail) ||
6568         !GLESv2Validation::allowedStencilOp(zfail) ||
6569         !GLESv2Validation::allowedStencilOp(zpass),
6570         GL_INVALID_ENUM);
6571     if (!ctx->m_state) return;
6572     ctx->m_state->stencilOpSeparate(face, fail, zfail, zpass);
6573     ctx->m_glStencilOpSeparate_enc(ctx, face, fail, zfail, zpass);
6574 }
6575 
s_glStencilMaskSeparate(void * self,GLenum face,GLuint mask)6576 void GL2Encoder::s_glStencilMaskSeparate(void *self , GLenum face, GLuint mask) {
6577     GL2Encoder* ctx = (GL2Encoder*)self;
6578     SET_ERROR_IF(
6579         !GLESv2Validation::allowedFace(face),
6580         GL_INVALID_ENUM);
6581     if (!ctx->m_state) return;
6582     ctx->m_state->stencilMaskSeparate(face, mask);
6583     ctx->m_glStencilMaskSeparate_enc(ctx, face, mask);
6584 }
6585 
s_glBlendEquation(void * self,GLenum mode)6586 void GL2Encoder::s_glBlendEquation(void *self , GLenum mode) {
6587     GL2Encoder* ctx = (GL2Encoder*)self;
6588     SET_ERROR_IF(
6589         !GLESv2Validation::allowedBlendEquation(mode),
6590         GL_INVALID_ENUM);
6591     ctx->m_glBlendEquation_enc(ctx, mode);
6592 }
6593 
s_glBlendEquationSeparate(void * self,GLenum modeRGB,GLenum modeAlpha)6594 void GL2Encoder::s_glBlendEquationSeparate(void *self , GLenum modeRGB, GLenum modeAlpha) {
6595     GL2Encoder* ctx = (GL2Encoder*)self;
6596     SET_ERROR_IF(
6597         !GLESv2Validation::allowedBlendEquation(modeRGB) ||
6598         !GLESv2Validation::allowedBlendEquation(modeAlpha),
6599         GL_INVALID_ENUM);
6600     ctx->m_glBlendEquationSeparate_enc(ctx, modeRGB, modeAlpha);
6601 }
6602 
s_glBlendFunc(void * self,GLenum sfactor,GLenum dfactor)6603 void GL2Encoder::s_glBlendFunc(void *self , GLenum sfactor, GLenum dfactor) {
6604     GL2Encoder* ctx = (GL2Encoder*)self;
6605     SET_ERROR_IF(
6606         !GLESv2Validation::allowedBlendFunc(sfactor) ||
6607         !GLESv2Validation::allowedBlendFunc(dfactor),
6608         GL_INVALID_ENUM);
6609     ctx->m_glBlendFunc_enc(ctx, sfactor, dfactor);
6610 }
6611 
s_glBlendFuncSeparate(void * self,GLenum srcRGB,GLenum dstRGB,GLenum srcAlpha,GLenum dstAlpha)6612 void GL2Encoder::s_glBlendFuncSeparate(void *self , GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha) {
6613     GL2Encoder* ctx = (GL2Encoder*)self;
6614     SET_ERROR_IF(
6615         !GLESv2Validation::allowedBlendFunc(srcRGB) ||
6616         !GLESv2Validation::allowedBlendFunc(dstRGB) ||
6617         !GLESv2Validation::allowedBlendFunc(srcAlpha) ||
6618         !GLESv2Validation::allowedBlendFunc(dstAlpha),
6619         GL_INVALID_ENUM);
6620     ctx->m_glBlendFuncSeparate_enc(ctx, srcRGB, dstRGB, srcAlpha, dstAlpha);
6621 }
6622 
s_glCullFace(void * self,GLenum mode)6623 void GL2Encoder::s_glCullFace(void *self , GLenum mode) {
6624     GL2Encoder* ctx = (GL2Encoder*)self;
6625     SET_ERROR_IF(
6626         !GLESv2Validation::allowedCullFace(mode),
6627         GL_INVALID_ENUM);
6628     ctx->m_glCullFace_enc(ctx, mode);
6629 }
6630 
s_glFrontFace(void * self,GLenum mode)6631 void GL2Encoder::s_glFrontFace(void *self , GLenum mode) {
6632     GL2Encoder* ctx = (GL2Encoder*)self;
6633     SET_ERROR_IF(
6634         !GLESv2Validation::allowedFrontFace(mode),
6635         GL_INVALID_ENUM);
6636     ctx->m_glFrontFace_enc(ctx, mode);
6637 }
6638 
s_glLineWidth(void * self,GLfloat width)6639 void GL2Encoder::s_glLineWidth(void *self , GLfloat width) {
6640     GL2Encoder* ctx = (GL2Encoder*)self;
6641     SET_ERROR_IF(width <= 0.0f, GL_INVALID_VALUE);
6642     ctx->m_glLineWidth_enc(ctx, width);
6643 }
6644 
s_glVertexAttrib1f(void * self,GLuint indx,GLfloat x)6645 void GL2Encoder::s_glVertexAttrib1f(void *self , GLuint indx, GLfloat x) {
6646     GL2Encoder* ctx = (GL2Encoder*)self;
6647     VALIDATE_VERTEX_ATTRIB_INDEX(indx);
6648     ctx->m_glVertexAttrib1f_enc(ctx, indx, x);
6649 }
6650 
s_glVertexAttrib2f(void * self,GLuint indx,GLfloat x,GLfloat y)6651 void GL2Encoder::s_glVertexAttrib2f(void *self , GLuint indx, GLfloat x, GLfloat y) {
6652     GL2Encoder* ctx = (GL2Encoder*)self;
6653     VALIDATE_VERTEX_ATTRIB_INDEX(indx);
6654     ctx->m_glVertexAttrib2f_enc(ctx, indx, x, y);
6655 }
6656 
s_glVertexAttrib3f(void * self,GLuint indx,GLfloat x,GLfloat y,GLfloat z)6657 void GL2Encoder::s_glVertexAttrib3f(void *self , GLuint indx, GLfloat x, GLfloat y, GLfloat z) {
6658     GL2Encoder* ctx = (GL2Encoder*)self;
6659     VALIDATE_VERTEX_ATTRIB_INDEX(indx);
6660     ctx->m_glVertexAttrib3f_enc(ctx, indx, x, y, z);
6661 }
6662 
s_glVertexAttrib4f(void * self,GLuint indx,GLfloat x,GLfloat y,GLfloat z,GLfloat w)6663 void GL2Encoder::s_glVertexAttrib4f(void *self , GLuint indx, GLfloat x, GLfloat y, GLfloat z, GLfloat w) {
6664     GL2Encoder* ctx = (GL2Encoder*)self;
6665     VALIDATE_VERTEX_ATTRIB_INDEX(indx);
6666     ctx->m_glVertexAttrib4f_enc(ctx, indx, x, y, z, w);
6667 }
6668 
s_glVertexAttrib1fv(void * self,GLuint indx,const GLfloat * values)6669 void GL2Encoder::s_glVertexAttrib1fv(void *self , GLuint indx, const GLfloat* values) {
6670     GL2Encoder* ctx = (GL2Encoder*)self;
6671     VALIDATE_VERTEX_ATTRIB_INDEX(indx);
6672     ctx->m_glVertexAttrib1fv_enc(ctx, indx, values);
6673 }
6674 
s_glVertexAttrib2fv(void * self,GLuint indx,const GLfloat * values)6675 void GL2Encoder::s_glVertexAttrib2fv(void *self , GLuint indx, const GLfloat* values) {
6676     GL2Encoder* ctx = (GL2Encoder*)self;
6677     VALIDATE_VERTEX_ATTRIB_INDEX(indx);
6678     ctx->m_glVertexAttrib2fv_enc(ctx, indx, values);
6679 }
6680 
s_glVertexAttrib3fv(void * self,GLuint indx,const GLfloat * values)6681 void GL2Encoder::s_glVertexAttrib3fv(void *self , GLuint indx, const GLfloat* values) {
6682     GL2Encoder* ctx = (GL2Encoder*)self;
6683     VALIDATE_VERTEX_ATTRIB_INDEX(indx);
6684     ctx->m_glVertexAttrib3fv_enc(ctx, indx, values);
6685 }
6686 
s_glVertexAttrib4fv(void * self,GLuint indx,const GLfloat * values)6687 void GL2Encoder::s_glVertexAttrib4fv(void *self , GLuint indx, const GLfloat* values) {
6688     GL2Encoder* ctx = (GL2Encoder*)self;
6689     VALIDATE_VERTEX_ATTRIB_INDEX(indx);
6690     ctx->m_glVertexAttrib4fv_enc(ctx, indx, values);
6691 }
6692 
s_glVertexAttribI4i(void * self,GLuint index,GLint v0,GLint v1,GLint v2,GLint v3)6693 void GL2Encoder::s_glVertexAttribI4i(void *self , GLuint index, GLint v0, GLint v1, GLint v2, GLint v3) {
6694     GL2Encoder* ctx = (GL2Encoder*)self;
6695     VALIDATE_VERTEX_ATTRIB_INDEX(index);
6696     ctx->m_glVertexAttribI4i_enc(ctx, index, v0, v1, v2, v3);
6697 }
6698 
s_glVertexAttribI4ui(void * self,GLuint index,GLuint v0,GLuint v1,GLuint v2,GLuint v3)6699 void GL2Encoder::s_glVertexAttribI4ui(void *self , GLuint index, GLuint v0, GLuint v1, GLuint v2, GLuint v3) {
6700     GL2Encoder* ctx = (GL2Encoder*)self;
6701     VALIDATE_VERTEX_ATTRIB_INDEX(index);
6702     ctx->m_glVertexAttribI4ui_enc(ctx, index, v0, v1, v2, v3);
6703 }
6704 
s_glVertexAttribI4iv(void * self,GLuint index,const GLint * v)6705 void GL2Encoder::s_glVertexAttribI4iv(void *self , GLuint index, const GLint* v) {
6706     GL2Encoder* ctx = (GL2Encoder*)self;
6707     VALIDATE_VERTEX_ATTRIB_INDEX(index);
6708     ctx->m_glVertexAttribI4iv_enc(ctx, index, v);
6709 }
6710 
s_glVertexAttribI4uiv(void * self,GLuint index,const GLuint * v)6711 void GL2Encoder::s_glVertexAttribI4uiv(void *self , GLuint index, const GLuint* v) {
6712     GL2Encoder* ctx = (GL2Encoder*)self;
6713     VALIDATE_VERTEX_ATTRIB_INDEX(index);
6714     ctx->m_glVertexAttribI4uiv_enc(ctx, index, v);
6715 }
6716 
s_glGetShaderPrecisionFormat(void * self,GLenum shadertype,GLenum precisiontype,GLint * range,GLint * precision)6717 void GL2Encoder::s_glGetShaderPrecisionFormat(void *self , GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision) {
6718     GL2Encoder* ctx = (GL2Encoder*)self;
6719     SET_ERROR_IF(!GLESv2Validation::allowedShaderType(shadertype), GL_INVALID_ENUM);
6720     SET_ERROR_IF(!GLESv2Validation::allowedPrecisionType(precisiontype), GL_INVALID_ENUM);
6721     ctx->m_glGetShaderPrecisionFormat_enc(ctx, shadertype, precisiontype, range, precision);
6722 }
6723 
s_glGetProgramiv(void * self,GLuint program,GLenum pname,GLint * params)6724 void GL2Encoder::s_glGetProgramiv(void *self , GLuint program, GLenum pname, GLint* params) {
6725     GL2Encoder* ctx = (GL2Encoder*)self;
6726     SET_ERROR_IF(!GLESv2Validation::allowedGetProgram(ctx->majorVersion(), ctx->minorVersion(), pname), GL_INVALID_ENUM);
6727     VALIDATE_PROGRAM_NAME(program);
6728     ctx->m_glGetProgramiv_enc(ctx, program, pname, params);
6729 }
6730 
s_glGetActiveUniform(void * self,GLuint program,GLuint index,GLsizei bufsize,GLsizei * length,GLint * size,GLenum * type,GLchar * name)6731 void GL2Encoder::s_glGetActiveUniform(void *self , GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name) {
6732     GL2Encoder* ctx = (GL2Encoder*)self;
6733     VALIDATE_PROGRAM_NAME(program);
6734     SET_ERROR_IF(index >= ctx->m_shared->getActiveUniformsCountForProgram(program), GL_INVALID_VALUE);
6735     ctx->m_glGetActiveUniform_enc(ctx, program, index, bufsize, length, size, type, name);
6736 }
6737 
s_glGetActiveUniformsiv(void * self,GLuint program,GLsizei uniformCount,const GLuint * uniformIndices,GLenum pname,GLint * params)6738 void GL2Encoder::s_glGetActiveUniformsiv(void *self , GLuint program, GLsizei uniformCount, const GLuint* uniformIndices, GLenum pname, GLint* params) {
6739     GL2Encoder* ctx = (GL2Encoder*)self;
6740     VALIDATE_PROGRAM_NAME(program);
6741     SET_ERROR_IF(uniformCount < 0, GL_INVALID_VALUE);
6742     SET_ERROR_IF(!GLESv2Validation::allowedGetActiveUniforms(pname), GL_INVALID_ENUM);
6743     int activeUniformsCount = ctx->m_shared->getActiveUniformsCountForProgram(program);
6744     for (GLsizei i = 0; i < uniformCount; ++i) {
6745         SET_ERROR_IF(uniformIndices[i] >= activeUniformsCount, GL_INVALID_VALUE);
6746     }
6747     ctx->m_glGetActiveUniformsiv_enc(ctx, program, uniformCount, uniformIndices, pname, params);
6748 }
6749 
s_glGetActiveUniformBlockName(void * self,GLuint program,GLuint uniformBlockIndex,GLsizei bufSize,GLsizei * length,GLchar * uniformBlockName)6750 void GL2Encoder::s_glGetActiveUniformBlockName(void *self , GLuint program, GLuint uniformBlockIndex, GLsizei bufSize, GLsizei* length, GLchar* uniformBlockName) {
6751     GL2Encoder* ctx = (GL2Encoder*)self;
6752     VALIDATE_PROGRAM_NAME(program);
6753     SET_ERROR_IF(bufSize < 0, GL_INVALID_VALUE);
6754     SET_ERROR_IF(uniformBlockIndex >= ctx->m_shared->getActiveUniformBlockCount(program), GL_INVALID_VALUE);
6755     ctx->m_glGetActiveUniformBlockName_enc(ctx, program, uniformBlockIndex, bufSize, length, uniformBlockName);
6756 }
6757 
s_glGetActiveAttrib(void * self,GLuint program,GLuint index,GLsizei bufsize,GLsizei * length,GLint * size,GLenum * type,GLchar * name)6758 void GL2Encoder::s_glGetActiveAttrib(void *self , GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name) {
6759     GL2Encoder* ctx = (GL2Encoder*)self;
6760     VALIDATE_PROGRAM_NAME(program);
6761     VALIDATE_VERTEX_ATTRIB_INDEX(index);
6762     SET_ERROR_IF(bufsize < 0, GL_INVALID_VALUE);
6763     SET_ERROR_IF(index >= ctx->m_shared->getActiveAttributesCountForProgram(program), GL_INVALID_VALUE);
6764     ctx->m_glGetActiveAttrib_enc(ctx, program, index, bufsize, length, size, type, name);
6765 }
6766 
s_glGetRenderbufferParameteriv(void * self,GLenum target,GLenum pname,GLint * params)6767 void GL2Encoder::s_glGetRenderbufferParameteriv(void *self , GLenum target, GLenum pname, GLint* params) {
6768     GL2Encoder* ctx = (GL2Encoder*)self;
6769     SET_ERROR_IF(target != GL_RENDERBUFFER, GL_INVALID_ENUM);
6770     SET_ERROR_IF(!GLESv2Validation::allowedGetRenderbufferParameter(pname), GL_INVALID_ENUM);
6771     SET_ERROR_IF(0 == ctx->m_state->boundRenderbuffer(), GL_INVALID_OPERATION);
6772     ctx->m_glGetRenderbufferParameteriv_enc(ctx, target, pname, params);
6773 }
6774 
s_glGetQueryiv(void * self,GLenum target,GLenum pname,GLint * params)6775 void GL2Encoder::s_glGetQueryiv(void *self , GLenum target, GLenum pname, GLint* params) {
6776     GL2Encoder* ctx = (GL2Encoder*)self;
6777     SET_ERROR_IF(!GLESv2Validation::allowedQueryTarget(target), GL_INVALID_ENUM);
6778     SET_ERROR_IF(!GLESv2Validation::allowedQueryParam(pname), GL_INVALID_ENUM);
6779     ctx->m_glGetQueryiv_enc(ctx, target, pname, params);
6780 }
6781 
s_glGetQueryObjectuiv(void * self,GLuint query,GLenum pname,GLuint * params)6782 void GL2Encoder::s_glGetQueryObjectuiv(void *self , GLuint query, GLenum pname, GLuint* params) {
6783     GL2Encoder* ctx = (GL2Encoder*)self;
6784     GLClientState* state = ctx->m_state;
6785     SET_ERROR_IF(!GLESv2Validation::allowedQueryObjectParam(pname), GL_INVALID_ENUM);
6786     SET_ERROR_IF(!state->queryExistence(GLClientState::ObjectType::Query, query), GL_INVALID_OPERATION);
6787     SET_ERROR_IF(!state->getLastQueryTarget(query), GL_INVALID_OPERATION);
6788     SET_ERROR_IF(ctx->m_state->isQueryObjectActive(query), GL_INVALID_OPERATION);
6789 
6790     ctx->m_glGetQueryObjectuiv_enc(ctx, query, pname, params);
6791 }
6792 
s_glIsEnabled(void * self,GLenum cap)6793 GLboolean GL2Encoder::s_glIsEnabled(void *self , GLenum cap) {
6794     GL2Encoder* ctx = (GL2Encoder*)self;
6795     RET_AND_SET_ERROR_IF(!GLESv2Validation::allowedEnable(ctx->majorVersion(), ctx->minorVersion(), cap), GL_INVALID_ENUM, 0);
6796     return ctx->m_glIsEnabled_enc(ctx, cap);
6797 }
6798 
s_glHint(void * self,GLenum target,GLenum mode)6799 void GL2Encoder::s_glHint(void *self , GLenum target, GLenum mode) {
6800     GL2Encoder* ctx = (GL2Encoder*)self;
6801     SET_ERROR_IF(!GLESv2Validation::allowedHintTarget(target), GL_INVALID_ENUM);
6802     SET_ERROR_IF(!GLESv2Validation::allowedHintMode(mode), GL_INVALID_ENUM);
6803     ctx->m_glHint_enc(ctx, target, mode);
6804 }
6805 
s_glGetFragDataLocation(void * self,GLuint program,const char * name)6806 GLint GL2Encoder::s_glGetFragDataLocation (void *self , GLuint program, const char* name) {
6807     GL2Encoder* ctx = (GL2Encoder*)self;
6808     VALIDATE_PROGRAM_NAME_RET(program, -1);
6809     RET_AND_SET_ERROR_IF(!ctx->m_shared->getProgramLinkStatus(program), GL_INVALID_OPERATION, -1);
6810     return ctx->m_glGetFragDataLocation_enc(ctx, program, name);
6811 }
6812 
s_glStencilMask(void * self,GLuint mask)6813 void GL2Encoder::s_glStencilMask(void* self, GLuint mask) {
6814     GL2Encoder* ctx = (GL2Encoder*)self;
6815     if (!ctx->m_state) return;
6816     ctx->m_state->stencilMaskSeparate(GL_FRONT_AND_BACK, mask);
6817     ctx->m_glStencilMask_enc(ctx, mask);
6818 }
6819 
s_glClearStencil(void * self,int v)6820 void GL2Encoder::s_glClearStencil(void* self, int v) {
6821     GL2Encoder* ctx = (GL2Encoder*)self;
6822     if (!ctx->m_state) return;
6823     ctx->m_state->state_GL_STENCIL_CLEAR_VALUE = v;
6824     ctx->m_glClearStencil_enc(ctx, v);
6825 }
6826