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