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