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