• 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     SET_ERROR_IF(ctx->boundBuffer(GL_PIXEL_UNPACK_BUFFER) &&
2725                  ctx->getBufferData(GL_PIXEL_UNPACK_BUFFER) &&
2726                  (state->pboNeededDataSize(width, height, 1, format, type, 0, 1) + (uintptr_t)pixels >
2727                   ctx->getBufferData(GL_PIXEL_UNPACK_BUFFER)->m_size),
2728                  GL_INVALID_OPERATION);
2729     SET_ERROR_IF(ctx->boundBuffer(GL_PIXEL_UNPACK_BUFFER) &&
2730                  ctx->getBufferData(GL_PIXEL_UNPACK_BUFFER) &&
2731                  ((uintptr_t)pixels %
2732                   glSizeof(type)),
2733                  GL_INVALID_OPERATION);
2734     SET_ERROR_IF(!ctx->boundBuffer(GL_PIXEL_UNPACK_BUFFER) && !pixels, GL_INVALID_OPERATION);
2735 
2736     if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
2737         ctx->override2DTextureTarget(target);
2738     }
2739 
2740     if (ctx->boundBuffer(GL_PIXEL_UNPACK_BUFFER)) {
2741         ctx->glTexSubImage2DOffsetAEMU(
2742                 ctx, target, level,
2743                 xoffset, yoffset, width, height,
2744                 format, type, (uintptr_t)pixels);
2745     } else {
2746         ctx->m_glTexSubImage2D_enc(ctx, target, level, xoffset, yoffset, width,
2747                 height, format, type, pixels);
2748     }
2749 
2750     if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
2751         ctx->restore2DTextureTarget(target);
2752     }
2753 }
2754 
s_glCopyTexImage2D(void * self,GLenum target,GLint level,GLenum internalformat,GLint x,GLint y,GLsizei width,GLsizei height,GLint border)2755 void GL2Encoder::s_glCopyTexImage2D(void* self, GLenum target, GLint level,
2756         GLenum internalformat, GLint x, GLint y,
2757         GLsizei width, GLsizei height, GLint border)
2758 {
2759     GL2Encoder* ctx = (GL2Encoder*)self;
2760     GLClientState* state = ctx->m_state;
2761 
2762     SET_ERROR_IF(!GLESv2Validation::textureTarget(ctx, target), GL_INVALID_ENUM);
2763     SET_ERROR_IF(!GLESv2Validation::pixelFormat(ctx, internalformat) && !GLESv2Validation::pixelInternalFormat(internalformat), GL_INVALID_VALUE);
2764     GLint max_texture_size;
2765     GLint max_cube_map_texture_size;
2766     ctx->glGetIntegerv(ctx, GL_MAX_TEXTURE_SIZE, &max_texture_size);
2767     ctx->glGetIntegerv(ctx, GL_MAX_CUBE_MAP_TEXTURE_SIZE, &max_cube_map_texture_size);
2768     SET_ERROR_IF(level < 0, GL_INVALID_VALUE);
2769     SET_ERROR_IF(level > ilog2(max_texture_size), GL_INVALID_VALUE);
2770     SET_ERROR_IF((target == GL_TEXTURE_CUBE_MAP) &&
2771                  (level > ilog2(max_cube_map_texture_size)), GL_INVALID_VALUE);
2772     SET_ERROR_IF(width < 0 || height < 0, GL_INVALID_VALUE);
2773     SET_ERROR_IF(width > max_texture_size, GL_INVALID_VALUE);
2774     SET_ERROR_IF(height > max_texture_size, GL_INVALID_VALUE);
2775     SET_ERROR_IF(GLESv2Validation::isCubeMapTarget(target) && width > max_cube_map_texture_size, GL_INVALID_VALUE);
2776     SET_ERROR_IF(GLESv2Validation::isCubeMapTarget(target) && height > max_cube_map_texture_size, GL_INVALID_VALUE);
2777     SET_ERROR_IF(GLESv2Validation::isCubeMapTarget(target) && (width != height), GL_INVALID_VALUE);
2778     SET_ERROR_IF(border != 0, GL_INVALID_VALUE);
2779 
2780     GLenum stateTarget = target;
2781     if (target == GL_TEXTURE_CUBE_MAP_POSITIVE_X ||
2782         target == GL_TEXTURE_CUBE_MAP_POSITIVE_Y ||
2783         target == GL_TEXTURE_CUBE_MAP_POSITIVE_Z ||
2784         target == GL_TEXTURE_CUBE_MAP_NEGATIVE_X ||
2785         target == GL_TEXTURE_CUBE_MAP_NEGATIVE_Y ||
2786         target == GL_TEXTURE_CUBE_MAP_NEGATIVE_Z)
2787         stateTarget = GL_TEXTURE_CUBE_MAP;
2788 
2789     SET_ERROR_IF(state->isBoundTextureImmutableFormat(target), GL_INVALID_OPERATION);
2790 
2791     SET_ERROR_IF(ctx->glCheckFramebufferStatus(ctx, GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE,
2792                  GL_INVALID_FRAMEBUFFER_OPERATION);
2793     // This is needed to work around underlying OpenGL drivers
2794     // (such as those feeding some some AMD GPUs) that expect
2795     // positive components of cube maps to be defined _before_
2796     // the negative components (otherwise a segfault occurs).
2797     GLenum extraTarget =
2798         state->copyTexImageLuminanceCubeMapAMDWorkaround
2799             (target, level, internalformat);
2800 
2801     state->setBoundTextureInternalFormat(stateTarget, internalformat);
2802     state->setBoundTextureDims(stateTarget, target, level, width, height, 1);
2803     state->addTextureCubeMapImage(stateTarget, target);
2804 
2805     if (extraTarget) {
2806         ctx->m_glCopyTexImage2D_enc(ctx, extraTarget, level, internalformat,
2807                                     x, y, width, height, border);
2808     }
2809 
2810     ctx->m_glCopyTexImage2D_enc(ctx, target, level, internalformat,
2811                                 x, y, width, height, border);
2812 }
2813 
s_glTexParameteriv(void * self,GLenum target,GLenum pname,const GLint * params)2814 void GL2Encoder::s_glTexParameteriv(void* self,
2815         GLenum target, GLenum pname, const GLint* params)
2816 {
2817     GL2Encoder* ctx = (GL2Encoder*)self;
2818 
2819     SET_ERROR_IF((target == GL_TEXTURE_EXTERNAL_OES &&
2820             !isValidTextureExternalParam(pname, (GLenum)params[0])),
2821             GL_INVALID_ENUM);
2822     SET_ERROR_IF(!GLESv2Validation::textureTarget(ctx, target), GL_INVALID_ENUM);
2823     SET_ERROR_IF(!GLESv2Validation::textureParams(ctx, pname), GL_INVALID_ENUM);
2824     SET_ERROR_IF(!params, GL_INVALID_VALUE);
2825     GLint param = *params;
2826     SET_ERROR_IF(!GLESv2Validation::textureParamValue(ctx, pname, param, (GLfloat)param, (GLenum)param), GL_INVALID_ENUM);
2827 
2828     if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
2829         ctx->override2DTextureTarget(target);
2830         ctx->m_glTexParameteriv_enc(ctx, GL_TEXTURE_2D, pname, params);
2831         ctx->restore2DTextureTarget(target);
2832     } else {
2833         ctx->m_glTexParameteriv_enc(ctx, target, pname, params);
2834     }
2835 }
2836 
texture2DNeedsOverride(GLenum target) const2837 bool GL2Encoder::texture2DNeedsOverride(GLenum target) const {
2838     return (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) &&
2839            target != m_state->getPriorityEnabledTarget(GL_TEXTURE_2D);
2840 }
2841 
override2DTextureTarget(GLenum target)2842 void GL2Encoder::override2DTextureTarget(GLenum target)
2843 {
2844     if (texture2DNeedsOverride(target)) {
2845         m_glBindTexture_enc(this, GL_TEXTURE_2D,
2846                 m_state->getBoundTexture(target));
2847     }
2848 }
2849 
restore2DTextureTarget(GLenum target)2850 void GL2Encoder::restore2DTextureTarget(GLenum target)
2851 {
2852     if (texture2DNeedsOverride(target)) {
2853         GLuint priorityEnabledBoundTexture =
2854                 m_state->getBoundTexture(
2855                     m_state->getPriorityEnabledTarget(GL_TEXTURE_2D));
2856         GLuint texture2DBoundTexture =
2857                 m_state->getBoundTexture(GL_TEXTURE_2D);
2858         if (!priorityEnabledBoundTexture) {
2859             m_glBindTexture_enc(this, GL_TEXTURE_2D, texture2DBoundTexture);
2860         } else {
2861             m_glBindTexture_enc(this, GL_TEXTURE_2D, priorityEnabledBoundTexture);
2862         }
2863     }
2864 }
2865 
associateEGLImage(GLenum target,GLeglImageOES eglImage,int width,int height)2866 void GL2Encoder::associateEGLImage(GLenum target, GLeglImageOES eglImage, int width, int height) {
2867     m_state->setBoundEGLImage(target, eglImage, width, height);
2868 }
2869 
2870 
boundBuffer(GLenum target) const2871 GLuint GL2Encoder::boundBuffer(GLenum target) const {
2872     return m_state->getBuffer(target);
2873 }
2874 
getBufferData(GLenum target) const2875 BufferData* GL2Encoder::getBufferData(GLenum target) const {
2876     GLuint bufferId = m_state->getBuffer(target);
2877     if (!bufferId) return NULL;
2878     return m_shared->getBufferData(bufferId);
2879 }
2880 
getBufferDataById(GLuint bufferId) const2881 BufferData* GL2Encoder::getBufferDataById(GLuint bufferId) const {
2882     if (!bufferId) return NULL;
2883     return m_shared->getBufferData(bufferId);
2884 }
2885 
isBufferMapped(GLuint buffer) const2886 bool GL2Encoder::isBufferMapped(GLuint buffer) const {
2887     return m_shared->getBufferData(buffer)->m_mapped;
2888 }
2889 
isBufferTargetMapped(GLenum target) const2890 bool GL2Encoder::isBufferTargetMapped(GLenum target) const {
2891     BufferData* buf = getBufferData(target);
2892     if (!buf) return false;
2893     return buf->m_mapped;
2894 }
2895 
s_glGenRenderbuffers(void * self,GLsizei n,GLuint * renderbuffers)2896 void GL2Encoder::s_glGenRenderbuffers(void* self,
2897         GLsizei n, GLuint* renderbuffers) {
2898     GL2Encoder* ctx = (GL2Encoder*)self;
2899     GLClientState* state = ctx->m_state;
2900 
2901     SET_ERROR_IF(n < 0, GL_INVALID_VALUE);
2902 
2903     ctx->m_glGenFramebuffers_enc(self, n, renderbuffers);
2904     state->addRenderbuffers(n, renderbuffers);
2905 }
2906 
s_glDeleteRenderbuffers(void * self,GLsizei n,const GLuint * renderbuffers)2907 void GL2Encoder::s_glDeleteRenderbuffers(void* self,
2908         GLsizei n, const GLuint* renderbuffers) {
2909     GL2Encoder* ctx = (GL2Encoder*)self;
2910     GLClientState* state = ctx->m_state;
2911 
2912     SET_ERROR_IF(n < 0, GL_INVALID_VALUE);
2913 
2914     ctx->m_glDeleteRenderbuffers_enc(self, n, renderbuffers);
2915 
2916     // Nope, lets just leak those for now.
2917     // The spec has an *amazingly* convoluted set of conditions for when
2918     // render buffers are actually deleted:
2919     // 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.
2920     //
2921     // 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***
2922     //
2923     // So, just detach this one from the bound FBO, and ignore the rest.
2924     for (int i = 0; i < n; i++) {
2925         state->detachRbo(renderbuffers[i]);
2926     }
2927     state->removeRenderbuffers(n, renderbuffers);
2928 }
2929 
s_glBindRenderbuffer(void * self,GLenum target,GLuint renderbuffer)2930 void GL2Encoder::s_glBindRenderbuffer(void* self,
2931         GLenum target, GLuint renderbuffer) {
2932     GL2Encoder* ctx = (GL2Encoder*)self;
2933     GLClientState* state = ctx->m_state;
2934 
2935     SET_ERROR_IF((target != GL_RENDERBUFFER),
2936                  GL_INVALID_ENUM);
2937 
2938     ctx->m_glBindRenderbuffer_enc(self, target, renderbuffer);
2939     state->bindRenderbuffer(target, renderbuffer);
2940 }
2941 
s_glRenderbufferStorage(void * self,GLenum target,GLenum internalformat,GLsizei width,GLsizei height)2942 void GL2Encoder::s_glRenderbufferStorage(void* self,
2943         GLenum target, GLenum internalformat,
2944         GLsizei width, GLsizei height) {
2945     GL2Encoder* ctx = (GL2Encoder*) self;
2946     GLClientState* state = ctx->m_state;
2947 
2948     SET_ERROR_IF(target != GL_RENDERBUFFER, GL_INVALID_ENUM);
2949     SET_ERROR_IF(0 == ctx->m_state->boundRenderbuffer(), GL_INVALID_OPERATION);
2950     SET_ERROR_IF(
2951         !GLESv2Validation::rboFormat(ctx, internalformat),
2952         GL_INVALID_ENUM);
2953 
2954     SET_ERROR_IF(width < 0 || height < 0, GL_INVALID_VALUE);
2955     GLint max_rb_size;
2956     ctx->glGetIntegerv(ctx, GL_MAX_RENDERBUFFER_SIZE, &max_rb_size);
2957     SET_ERROR_IF(width > max_rb_size || height > max_rb_size, GL_INVALID_VALUE);
2958 
2959     state->setBoundRenderbufferFormat(internalformat);
2960     state->setBoundRenderbufferSamples(0);
2961     state->setBoundRenderbufferDimensions(width, height);
2962 
2963     ctx->m_glRenderbufferStorage_enc(self, target, internalformat,
2964                                      width, height);
2965 }
2966 
s_glFramebufferRenderbuffer(void * self,GLenum target,GLenum attachment,GLenum renderbuffertarget,GLuint renderbuffer)2967 void GL2Encoder::s_glFramebufferRenderbuffer(void* self,
2968         GLenum target, GLenum attachment,
2969         GLenum renderbuffertarget, GLuint renderbuffer) {
2970     GL2Encoder* ctx = (GL2Encoder*)self;
2971     GLClientState* state = ctx->m_state;
2972 
2973     SET_ERROR_IF(!GLESv2Validation::framebufferTarget(ctx, target), GL_INVALID_ENUM);
2974     SET_ERROR_IF(!GLESv2Validation::framebufferAttachment(ctx, attachment), GL_INVALID_ENUM);
2975     SET_ERROR_IF(GL_RENDERBUFFER != renderbuffertarget, GL_INVALID_ENUM);
2976     SET_ERROR_IF(!state->getBoundFramebuffer(target), GL_INVALID_OPERATION);
2977     SET_ERROR_IF(!state->isRenderbufferThatWasBound(renderbuffer), GL_INVALID_OPERATION);
2978 
2979     state->attachRbo(target, attachment, renderbuffer);
2980 
2981     ctx->m_glFramebufferRenderbuffer_enc(self, target, attachment, renderbuffertarget, renderbuffer);
2982 }
2983 
s_glGenFramebuffers(void * self,GLsizei n,GLuint * framebuffers)2984 void GL2Encoder::s_glGenFramebuffers(void* self,
2985         GLsizei n, GLuint* framebuffers) {
2986     GL2Encoder* ctx = (GL2Encoder*)self;
2987     GLClientState* state = ctx->m_state;
2988 
2989     SET_ERROR_IF(n < 0, GL_INVALID_VALUE);
2990 
2991     ctx->m_glGenFramebuffers_enc(self, n, framebuffers);
2992     state->addFramebuffers(n, framebuffers);
2993 }
2994 
s_glDeleteFramebuffers(void * self,GLsizei n,const GLuint * framebuffers)2995 void GL2Encoder::s_glDeleteFramebuffers(void* self,
2996         GLsizei n, const GLuint* framebuffers) {
2997     GL2Encoder* ctx = (GL2Encoder*)self;
2998     GLClientState* state = ctx->m_state;
2999 
3000     SET_ERROR_IF(n < 0, GL_INVALID_VALUE);
3001 
3002     ctx->m_glDeleteFramebuffers_enc(self, n, framebuffers);
3003     state->removeFramebuffers(n, framebuffers);
3004 }
3005 
s_glBindFramebuffer(void * self,GLenum target,GLuint framebuffer)3006 void GL2Encoder::s_glBindFramebuffer(void* self,
3007         GLenum target, GLuint framebuffer) {
3008     GL2Encoder* ctx = (GL2Encoder*)self;
3009     GLClientState* state = ctx->m_state;
3010 
3011     SET_ERROR_IF(!GLESv2Validation::framebufferTarget(ctx, target), GL_INVALID_ENUM);
3012 
3013     state->bindFramebuffer(target, framebuffer);
3014 
3015     ctx->m_glBindFramebuffer_enc(self, target, framebuffer);
3016 }
3017 
s_glFramebufferParameteri(void * self,GLenum target,GLenum pname,GLint param)3018 void GL2Encoder::s_glFramebufferParameteri(void *self,
3019         GLenum target, GLenum pname, GLint param) {
3020     GL2Encoder* ctx = (GL2Encoder*)self;
3021     GLClientState* state = ctx->m_state;
3022     state->setFramebufferParameter(target, pname, param);
3023     ctx->m_glFramebufferParameteri_enc(self, target, pname, param);
3024 }
3025 
s_glFramebufferTexture2D(void * self,GLenum target,GLenum attachment,GLenum textarget,GLuint texture,GLint level)3026 void GL2Encoder::s_glFramebufferTexture2D(void* self,
3027         GLenum target, GLenum attachment,
3028         GLenum textarget, GLuint texture, GLint level) {
3029     GL2Encoder* ctx = (GL2Encoder*)self;
3030     GLClientState* state = ctx->m_state;
3031 
3032     SET_ERROR_IF(!GLESv2Validation::framebufferTarget(ctx, target), GL_INVALID_ENUM);
3033     SET_ERROR_IF(!GLESv2Validation::textureTarget(ctx, textarget), GL_INVALID_ENUM);
3034     SET_ERROR_IF(!GLESv2Validation::framebufferAttachment(ctx, attachment), GL_INVALID_ENUM);
3035     SET_ERROR_IF(!state->getBoundFramebuffer(target), GL_INVALID_OPERATION);
3036     SET_ERROR_IF(texture && !state->isTexture(texture), GL_INVALID_OPERATION);
3037     SET_ERROR_IF(GLESv2Validation::isCubeMapTarget(textarget) && !state->isTextureCubeMap(texture), GL_INVALID_OPERATION);
3038     SET_ERROR_IF(!GLESv2Validation::isCubeMapTarget(textarget) && state->isTextureCubeMap(texture), GL_INVALID_OPERATION);
3039     SET_ERROR_IF((texture && (level < 0)), GL_INVALID_VALUE);
3040 
3041     if (textarget == GL_TEXTURE_2D) {
3042         SET_ERROR_IF(level > ilog2(ctx->m_state->getMaxTextureSize()), GL_INVALID_VALUE);
3043     } else {
3044         SET_ERROR_IF(level > ilog2(ctx->m_state->getMaxTextureSizeCubeMap()), GL_INVALID_VALUE);
3045     }
3046 
3047     state->attachTextureObject(target, attachment, texture, level, 0);
3048 
3049     ctx->m_glFramebufferTexture2D_enc(self, target, attachment, textarget, texture, level);
3050 }
3051 
s_glFramebufferTexture3DOES(void * self,GLenum target,GLenum attachment,GLenum textarget,GLuint texture,GLint level,GLint zoffset)3052 void GL2Encoder::s_glFramebufferTexture3DOES(void* self,
3053         GLenum target, GLenum attachment,
3054         GLenum textarget, GLuint texture, GLint level, GLint zoffset) {
3055     GL2Encoder* ctx = (GL2Encoder*)self;
3056     GLClientState* state = ctx->m_state;
3057 
3058     state->attachTextureObject(target, attachment, texture, level, zoffset);
3059 
3060     ctx->m_glFramebufferTexture3DOES_enc(self, target, attachment, textarget, texture, level, zoffset);
3061 }
3062 
s_glGetFramebufferAttachmentParameteriv(void * self,GLenum target,GLenum attachment,GLenum pname,GLint * params)3063 void GL2Encoder::s_glGetFramebufferAttachmentParameteriv(void* self,
3064         GLenum target, GLenum attachment, GLenum pname, GLint* params) {
3065     GL2Encoder* ctx = (GL2Encoder*)self;
3066     const GLClientState* state = ctx->m_state;
3067     SET_ERROR_IF(!GLESv2Validation::framebufferTarget(ctx, target), GL_INVALID_ENUM);
3068     SET_ERROR_IF(!state->boundFramebuffer(target) &&
3069                  attachment != GL_BACK &&
3070                  attachment != GL_FRONT &&
3071                  attachment != GL_DEPTH &&
3072                  attachment != GL_STENCIL,
3073                  GL_INVALID_OPERATION);
3074     SET_ERROR_IF(pname != GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME &&
3075                  pname != GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE &&
3076                  !state->attachmentHasObject(target, attachment),
3077                  GL_INVALID_OPERATION);
3078     SET_ERROR_IF((pname == GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL ||
3079                   pname == GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE ||
3080                   pname == GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER) &&
3081                  (!state->attachmentHasObject(target, attachment) ||
3082                   state->getBoundFramebufferAttachmentType(target, attachment) !=
3083                   FBO_ATTACHMENT_TEXTURE),
3084                  !state->attachmentHasObject(target, attachment) ?
3085                  GL_INVALID_OPERATION : GL_INVALID_ENUM);
3086     SET_ERROR_IF(
3087         (attachment == GL_FRONT ||
3088          attachment == GL_BACK) &&
3089         (pname == GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME),
3090         GL_INVALID_ENUM);
3091     SET_ERROR_IF(attachment == GL_DEPTH_STENCIL_ATTACHMENT &&
3092                  pname == GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME &&
3093                  !state->depthStencilHasSameObject(target),
3094                  GL_INVALID_OPERATION);
3095     SET_ERROR_IF(state->boundFramebuffer(target) &&
3096                  (attachment == GL_BACK ||
3097                   attachment == GL_FRONT ||
3098                   attachment == GL_DEPTH ||
3099                   attachment == GL_STENCIL),
3100                  GL_INVALID_OPERATION);
3101     ctx->m_glGetFramebufferAttachmentParameteriv_enc(self, target, attachment, pname, params);
3102 }
3103 
s_glCheckFramebufferStatus(void * self,GLenum target)3104 GLenum GL2Encoder::s_glCheckFramebufferStatus(void* self, GLenum target) {
3105     GL2Encoder* ctx = (GL2Encoder*)self;
3106 
3107     RET_AND_SET_ERROR_IF(
3108         target != GL_DRAW_FRAMEBUFFER && target != GL_FRAMEBUFFER && target != GL_READ_FRAMEBUFFER,
3109         GL_INVALID_ENUM, 0);
3110 
3111     GLClientState* state = ctx->m_state;
3112 
3113     return state->checkFramebufferCompleteness(target);
3114 }
3115 
s_glGenVertexArrays(void * self,GLsizei n,GLuint * arrays)3116 void GL2Encoder::s_glGenVertexArrays(void* self, GLsizei n, GLuint* arrays) {
3117     GL2Encoder* ctx = (GL2Encoder*)self;
3118     GLClientState* state = ctx->m_state;
3119     SET_ERROR_IF(n < 0, GL_INVALID_VALUE);
3120 
3121     ctx->m_glGenVertexArrays_enc(self, n, arrays);
3122     for (int i = 0; i < n; i++) {
3123         ALOGV("%s: gen vao %u", __FUNCTION__, arrays[i]);
3124     }
3125     state->addVertexArrayObjects(n, arrays);
3126 }
3127 
s_glDeleteVertexArrays(void * self,GLsizei n,const GLuint * arrays)3128 void GL2Encoder::s_glDeleteVertexArrays(void* self, GLsizei n, const GLuint* arrays) {
3129     GL2Encoder* ctx = (GL2Encoder*)self;
3130     GLClientState* state = ctx->m_state;
3131     SET_ERROR_IF(n < 0, GL_INVALID_VALUE);
3132 
3133     ctx->m_glDeleteVertexArrays_enc(self, n, arrays);
3134     for (int i = 0; i < n; i++) {
3135         ALOGV("%s: delete vao %u", __FUNCTION__, arrays[i]);
3136     }
3137     state->removeVertexArrayObjects(n, arrays);
3138 }
3139 
s_glBindVertexArray(void * self,GLuint array)3140 void GL2Encoder::s_glBindVertexArray(void* self, GLuint array) {
3141     ALOGV("%s: call. array=%u\n", __FUNCTION__, array);
3142     GL2Encoder* ctx = (GL2Encoder*)self;
3143     GLClientState* state = ctx->m_state;
3144     SET_ERROR_IF(!state->isVertexArrayObject(array), GL_INVALID_OPERATION);
3145     ctx->m_glBindVertexArray_enc(self, array);
3146     state->setVertexArrayObject(array);
3147 }
3148 
s_glMapBufferOES(void * self,GLenum target,GLenum access)3149 void* GL2Encoder::s_glMapBufferOES(void* self, GLenum target, GLenum access) {
3150     GL2Encoder* ctx = (GL2Encoder*)self;
3151 
3152     RET_AND_SET_ERROR_IF(!GLESv2Validation::bufferTarget(ctx, target), GL_INVALID_ENUM, NULL);
3153 
3154     GLuint boundBuffer = ctx->m_state->getBuffer(target);
3155 
3156     RET_AND_SET_ERROR_IF(boundBuffer == 0, GL_INVALID_OPERATION, NULL);
3157 
3158     BufferData* buf = ctx->m_shared->getBufferData(boundBuffer);
3159     RET_AND_SET_ERROR_IF(!buf, GL_INVALID_VALUE, NULL);
3160 
3161     return ctx->glMapBufferRange(ctx, target, 0, buf->m_size, access);
3162 }
3163 
s_glUnmapBufferOES(void * self,GLenum target)3164 GLboolean GL2Encoder::s_glUnmapBufferOES(void* self, GLenum target) {
3165     GL2Encoder* ctx = (GL2Encoder*)self;
3166 
3167     return ctx->glUnmapBuffer(ctx, target);
3168 }
3169 
s_glMapBufferRangeAEMUImpl(GL2Encoder * ctx,GLenum target,GLintptr offset,GLsizeiptr length,GLbitfield access,BufferData * buf)3170 void* GL2Encoder::s_glMapBufferRangeAEMUImpl(GL2Encoder* ctx, GLenum target,
3171                                              GLintptr offset, GLsizeiptr length,
3172                                              GLbitfield access, BufferData* buf) {
3173     char* bits = &buf->m_fixedBuffer[offset];
3174 
3175     if ((access & GL_MAP_READ_BIT) ||
3176         ((access & GL_MAP_WRITE_BIT) &&
3177         (!(access & GL_MAP_INVALIDATE_RANGE_BIT) &&
3178          !(access & GL_MAP_INVALIDATE_BUFFER_BIT)))) {
3179 
3180         if (ctx->m_state->shouldSkipHostMapBuffer(target))
3181             return bits;
3182 
3183         ctx->glMapBufferRangeAEMU(
3184                 ctx, target,
3185                 offset, length,
3186                 access,
3187                 bits);
3188 
3189         ctx->m_state->onHostMappedBuffer(target);
3190     }
3191 
3192     return bits;
3193 }
3194 
s_glMapBufferRange(void * self,GLenum target,GLintptr offset,GLsizeiptr length,GLbitfield access)3195 void* GL2Encoder::s_glMapBufferRange(void* self, GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access) {
3196     GL2Encoder* ctx = (GL2Encoder*)self;
3197 
3198     // begin validation (lots)
3199 
3200     RET_AND_SET_ERROR_IF(!GLESv2Validation::bufferTarget(ctx, target), GL_INVALID_ENUM, NULL);
3201 
3202     GLuint boundBuffer = ctx->m_state->getBuffer(target);
3203 
3204     RET_AND_SET_ERROR_IF(boundBuffer == 0, GL_INVALID_OPERATION, NULL);
3205 
3206     BufferData* buf = ctx->m_shared->getBufferData(boundBuffer);
3207     RET_AND_SET_ERROR_IF(!buf, GL_INVALID_VALUE, NULL);
3208 
3209     GLsizeiptr bufferDataSize = buf->m_size;
3210 
3211     RET_AND_SET_ERROR_IF(offset < 0, GL_INVALID_VALUE, NULL);
3212     RET_AND_SET_ERROR_IF(length < 0, GL_INVALID_VALUE, NULL);
3213     RET_AND_SET_ERROR_IF(offset + length > bufferDataSize, GL_INVALID_VALUE, NULL);
3214     RET_AND_SET_ERROR_IF(access & ~GLESv2Validation::allBufferMapAccessFlags, GL_INVALID_VALUE, NULL);
3215 
3216     RET_AND_SET_ERROR_IF(buf->m_mapped, GL_INVALID_OPERATION, NULL);
3217     RET_AND_SET_ERROR_IF(!(access & (GL_MAP_READ_BIT | GL_MAP_WRITE_BIT)), GL_INVALID_OPERATION, NULL);
3218     RET_AND_SET_ERROR_IF(
3219         (access & GL_MAP_READ_BIT) &&
3220              ((access & GL_MAP_INVALIDATE_RANGE_BIT) ||
3221               (access & GL_MAP_INVALIDATE_BUFFER_BIT) ||
3222               (access & GL_MAP_UNSYNCHRONIZED_BIT) ||
3223               (access & GL_MAP_FLUSH_EXPLICIT_BIT)), GL_INVALID_OPERATION, NULL);
3224 
3225     // end validation; actually do stuff now
3226 
3227     buf->m_mapped = true;
3228     buf->m_mappedAccess = access;
3229     buf->m_mappedOffset = offset;
3230     buf->m_mappedLength = length;
3231 
3232     if (ctx->hasExtension("ANDROID_EMU_dma_v2")) {
3233         if (buf->dma_buffer.get().size < length) {
3234             goldfish_dma_context region;
3235 
3236             const int PAGE_BITS = 12;
3237             GLsizeiptr aligned_length = (length + (1 << PAGE_BITS) - 1) & ~((1 << PAGE_BITS) - 1);
3238 
3239             if (goldfish_dma_create_region(aligned_length, &region)) {
3240                 buf->dma_buffer.reset(NULL);
3241                 return s_glMapBufferRangeAEMUImpl(ctx, target, offset, length, access, buf);
3242             }
3243 
3244             if (!goldfish_dma_map(&region)) {
3245                 buf->dma_buffer.reset(NULL);
3246                 return s_glMapBufferRangeAEMUImpl(ctx, target, offset, length, access, buf);
3247             }
3248 
3249             buf->m_guest_paddr = goldfish_dma_guest_paddr(&region);
3250             buf->dma_buffer.reset(&region);
3251         }
3252 
3253         ctx->glMapBufferRangeDMA(
3254                 ctx, target,
3255                 offset, length,
3256                 access,
3257                 buf->m_guest_paddr);
3258 
3259         return reinterpret_cast<void*>(buf->dma_buffer.get().mapped_addr);
3260     } else {
3261         return s_glMapBufferRangeAEMUImpl(ctx, target, offset, length, access, buf);
3262     }
3263 }
3264 
s_glUnmapBuffer(void * self,GLenum target)3265 GLboolean GL2Encoder::s_glUnmapBuffer(void* self, GLenum target) {
3266     GL2Encoder* ctx = (GL2Encoder*)self;
3267 
3268     RET_AND_SET_ERROR_IF(!GLESv2Validation::bufferTarget(ctx, target), GL_INVALID_ENUM, GL_FALSE);
3269 
3270     GLuint boundBuffer = ctx->m_state->getBuffer(target);
3271 
3272     RET_AND_SET_ERROR_IF(boundBuffer == 0, GL_INVALID_OPERATION, GL_FALSE);
3273 
3274     BufferData* buf = ctx->m_shared->getBufferData(boundBuffer);
3275     RET_AND_SET_ERROR_IF(!buf, GL_INVALID_VALUE, GL_FALSE);
3276     RET_AND_SET_ERROR_IF(!buf->m_mapped, GL_INVALID_OPERATION, GL_FALSE);
3277 
3278     if (buf->m_mappedAccess & GL_MAP_WRITE_BIT) {
3279         // invalide index range cache here
3280         if (buf->m_mappedAccess & GL_MAP_INVALIDATE_BUFFER_BIT) {
3281             buf->m_indexRangeCache.invalidateRange(0, buf->m_size);
3282         } else {
3283             buf->m_indexRangeCache.invalidateRange(buf->m_mappedOffset, buf->m_mappedLength);
3284         }
3285     }
3286 
3287     GLboolean host_res = GL_TRUE;
3288 
3289     if (buf->dma_buffer.get().mapped_addr) {
3290         memcpy(&buf->m_fixedBuffer[buf->m_mappedOffset],
3291                reinterpret_cast<void*>(buf->dma_buffer.get().mapped_addr),
3292                buf->m_mappedLength);
3293 
3294         ctx->glUnmapBufferDMA(
3295             ctx, target,
3296             buf->m_mappedOffset,
3297             buf->m_mappedLength,
3298             buf->m_mappedAccess,
3299             goldfish_dma_guest_paddr(&buf->dma_buffer.get()),
3300             &host_res);
3301     } else {
3302         if (ctx->m_hasAsyncUnmapBuffer) {
3303             ctx->glUnmapBufferAsyncAEMU(
3304                     ctx, target,
3305                     buf->m_mappedOffset,
3306                     buf->m_mappedLength,
3307                     buf->m_mappedAccess,
3308                     &buf->m_fixedBuffer[buf->m_mappedOffset],
3309                     &host_res);
3310         } else {
3311             if (buf->m_mappedAccess & GL_MAP_WRITE_BIT) {
3312                 ctx->glUnmapBufferAEMU(
3313                         ctx, target,
3314                         buf->m_mappedOffset,
3315                         buf->m_mappedLength,
3316                         buf->m_mappedAccess,
3317                         &buf->m_fixedBuffer[buf->m_mappedOffset],
3318                         &host_res);
3319             }
3320         }
3321     }
3322 
3323     buf->m_mapped = false;
3324     buf->m_mappedAccess = 0;
3325     buf->m_mappedOffset = 0;
3326     buf->m_mappedLength = 0;
3327 
3328     return host_res;
3329 }
3330 
s_glFlushMappedBufferRange(void * self,GLenum target,GLintptr offset,GLsizeiptr length)3331 void GL2Encoder::s_glFlushMappedBufferRange(void* self, GLenum target, GLintptr offset, GLsizeiptr length) {
3332     GL2Encoder* ctx = (GL2Encoder*)self;
3333 
3334     SET_ERROR_IF(!GLESv2Validation::bufferTarget(ctx, target), GL_INVALID_ENUM);
3335 
3336     GLuint boundBuffer = ctx->m_state->getBuffer(target);
3337     SET_ERROR_IF(!boundBuffer, GL_INVALID_OPERATION);
3338 
3339     BufferData* buf = ctx->m_shared->getBufferData(boundBuffer);
3340     SET_ERROR_IF(!buf, GL_INVALID_VALUE);
3341     SET_ERROR_IF(!buf->m_mapped, GL_INVALID_OPERATION);
3342     SET_ERROR_IF(!(buf->m_mappedAccess & GL_MAP_FLUSH_EXPLICIT_BIT), GL_INVALID_OPERATION);
3343 
3344     SET_ERROR_IF(offset < 0, GL_INVALID_VALUE);
3345     SET_ERROR_IF(length < 0, GL_INVALID_VALUE);
3346     SET_ERROR_IF(offset + length > buf->m_mappedLength, GL_INVALID_VALUE);
3347 
3348     GLintptr totalOffset = buf->m_mappedOffset + offset;
3349 
3350     buf->m_indexRangeCache.invalidateRange(totalOffset, length);
3351 
3352     if (ctx->m_hasAsyncUnmapBuffer) {
3353         ctx->glFlushMappedBufferRangeAEMU2(
3354                 ctx, target,
3355                 totalOffset,
3356                 length,
3357                 buf->m_mappedAccess,
3358                 &buf->m_fixedBuffer[totalOffset]);
3359     } else {
3360         ctx->glFlushMappedBufferRangeAEMU(
3361                 ctx, target,
3362                 totalOffset,
3363                 length,
3364                 buf->m_mappedAccess,
3365                 &buf->m_fixedBuffer[totalOffset]);
3366     }
3367 }
3368 
s_glCompressedTexImage2D(void * self,GLenum target,GLint level,GLenum internalformat,GLsizei width,GLsizei height,GLint border,GLsizei imageSize,const GLvoid * data)3369 void GL2Encoder::s_glCompressedTexImage2D(void* self, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid* data) {
3370     GL2Encoder* ctx = (GL2Encoder*)self;
3371     GLClientState* state = ctx->m_state;
3372 
3373     SET_ERROR_IF(!GLESv2Validation::textureTarget(ctx, target), GL_INVALID_ENUM);
3374     SET_ERROR_IF(target == GL_TEXTURE_CUBE_MAP, GL_INVALID_ENUM);
3375     fprintf(stderr, "%s: format: 0x%x\n", __func__, internalformat);
3376     // Filter compressed formats support.
3377     SET_ERROR_IF(!GLESv2Validation::supportedCompressedFormat(ctx, internalformat), GL_INVALID_ENUM);
3378     // Verify level <= log2(GL_MAX_TEXTURE_SIZE).
3379     GLint max_texture_size;
3380     GLint max_cube_map_texture_size;
3381     ctx->glGetIntegerv(ctx, GL_MAX_TEXTURE_SIZE, &max_texture_size);
3382     ctx->glGetIntegerv(ctx, GL_MAX_CUBE_MAP_TEXTURE_SIZE, &max_cube_map_texture_size);
3383     SET_ERROR_IF(level < 0, GL_INVALID_VALUE);
3384     SET_ERROR_IF(level > ilog2(max_texture_size), GL_INVALID_VALUE);
3385     SET_ERROR_IF(level > ilog2(max_cube_map_texture_size), GL_INVALID_VALUE);
3386     SET_ERROR_IF(width > max_texture_size, GL_INVALID_VALUE);
3387     SET_ERROR_IF(height > max_texture_size, GL_INVALID_VALUE);
3388     SET_ERROR_IF(border, GL_INVALID_VALUE);
3389     // If unpack buffer is nonzero, verify unmapped state.
3390     SET_ERROR_IF(ctx->isBufferTargetMapped(GL_PIXEL_UNPACK_BUFFER), GL_INVALID_OPERATION);
3391     SET_ERROR_IF(width < 0 || height < 0, GL_INVALID_VALUE);
3392 
3393     // If unpack buffer is nonzero, verify buffer data fits.
3394     SET_ERROR_IF(ctx->boundBuffer(GL_PIXEL_UNPACK_BUFFER) &&
3395                  ctx->getBufferData(GL_PIXEL_UNPACK_BUFFER) &&
3396                  (imageSize > ctx->getBufferData(GL_PIXEL_UNPACK_BUFFER)->m_size),
3397                  GL_INVALID_OPERATION);
3398     SET_ERROR_IF(!ctx->m_state->compressedTexImageSizeCompatible(internalformat, width, height, 1, imageSize), GL_INVALID_VALUE);
3399 
3400     GLenum stateTarget = target;
3401     if (target == GL_TEXTURE_CUBE_MAP_POSITIVE_X ||
3402         target == GL_TEXTURE_CUBE_MAP_POSITIVE_Y ||
3403         target == GL_TEXTURE_CUBE_MAP_POSITIVE_Z ||
3404         target == GL_TEXTURE_CUBE_MAP_NEGATIVE_X ||
3405         target == GL_TEXTURE_CUBE_MAP_NEGATIVE_Y ||
3406         target == GL_TEXTURE_CUBE_MAP_NEGATIVE_Z)
3407         stateTarget = GL_TEXTURE_CUBE_MAP;
3408     state->setBoundTextureInternalFormat(stateTarget, (GLint)internalformat);
3409     state->setBoundTextureDims(stateTarget, target, level, width, height, 1);
3410 
3411     if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
3412         ctx->override2DTextureTarget(target);
3413     }
3414 
3415     if (ctx->boundBuffer(GL_PIXEL_UNPACK_BUFFER)) {
3416         ctx->glCompressedTexImage2DOffsetAEMU(
3417                 ctx, target, level, internalformat,
3418                 width, height, border,
3419                 imageSize, (uintptr_t)data);
3420     } else {
3421         ctx->m_glCompressedTexImage2D_enc(
3422                 ctx, target, level, internalformat,
3423                 width, height, border,
3424                 imageSize, data);
3425     }
3426 
3427     if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
3428         ctx->restore2DTextureTarget(target);
3429     }
3430 }
3431 
s_glCompressedTexSubImage2D(void * self,GLenum target,GLint level,GLint xoffset,GLint yoffset,GLsizei width,GLsizei height,GLenum format,GLsizei imageSize,const GLvoid * data)3432 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) {
3433     GL2Encoder* ctx = (GL2Encoder*)self;
3434 
3435     SET_ERROR_IF(!GLESv2Validation::textureTarget(ctx, target), GL_INVALID_ENUM);
3436     SET_ERROR_IF(target == GL_TEXTURE_CUBE_MAP, GL_INVALID_ENUM);
3437     // If unpack buffer is nonzero, verify unmapped state.
3438     SET_ERROR_IF(ctx->isBufferTargetMapped(GL_PIXEL_UNPACK_BUFFER), GL_INVALID_OPERATION);
3439 
3440     GLenum stateTarget = target;
3441     if (target == GL_TEXTURE_CUBE_MAP_POSITIVE_X ||
3442         target == GL_TEXTURE_CUBE_MAP_POSITIVE_Y ||
3443         target == GL_TEXTURE_CUBE_MAP_POSITIVE_Z ||
3444         target == GL_TEXTURE_CUBE_MAP_NEGATIVE_X ||
3445         target == GL_TEXTURE_CUBE_MAP_NEGATIVE_Y ||
3446         target == GL_TEXTURE_CUBE_MAP_NEGATIVE_Z)
3447         stateTarget = GL_TEXTURE_CUBE_MAP;
3448     GLuint tex = ctx->m_state->getBoundTexture(stateTarget);
3449 
3450     GLint internalFormat = ctx->m_state->queryTexInternalFormat(tex);
3451     SET_ERROR_IF(internalFormat != format, GL_INVALID_OPERATION);
3452     SET_ERROR_IF(level < 0, GL_INVALID_VALUE);
3453 
3454     GLint max_texture_size;
3455     GLint max_cube_map_texture_size;
3456     ctx->glGetIntegerv(ctx, GL_MAX_TEXTURE_SIZE, &max_texture_size);
3457     ctx->glGetIntegerv(ctx, GL_MAX_CUBE_MAP_TEXTURE_SIZE, &max_cube_map_texture_size);
3458     SET_ERROR_IF(level > ilog2(max_texture_size), GL_INVALID_VALUE);
3459     SET_ERROR_IF(level > ilog2(max_cube_map_texture_size), GL_INVALID_VALUE);
3460     SET_ERROR_IF(width < 0 || height < 0, GL_INVALID_VALUE);
3461     // If unpack buffer is nonzero, verify buffer data fits.
3462     SET_ERROR_IF(ctx->boundBuffer(GL_PIXEL_UNPACK_BUFFER) &&
3463                  ctx->getBufferData(GL_PIXEL_UNPACK_BUFFER) &&
3464                  (imageSize > ctx->getBufferData(GL_PIXEL_UNPACK_BUFFER)->m_size),
3465                  GL_INVALID_OPERATION);
3466     SET_ERROR_IF(xoffset < 0 || yoffset < 0, GL_INVALID_VALUE);
3467 
3468     GLint totalWidth = ctx->m_state->queryTexWidth(level, tex);
3469     GLint totalHeight = ctx->m_state->queryTexHeight(level, tex);
3470 
3471     if (GLESTextureUtils::isEtc2Format(internalFormat)) {
3472         SET_ERROR_IF((width % 4) && (totalWidth != xoffset + width), GL_INVALID_OPERATION);
3473         SET_ERROR_IF((height % 4) && (totalHeight != yoffset + height), GL_INVALID_OPERATION);
3474         SET_ERROR_IF((xoffset % 4) || (yoffset % 4), GL_INVALID_OPERATION);
3475     }
3476 
3477     SET_ERROR_IF(totalWidth < xoffset + width, GL_INVALID_VALUE);
3478     SET_ERROR_IF(totalHeight < yoffset + height, GL_INVALID_VALUE);
3479 
3480     SET_ERROR_IF(!ctx->m_state->compressedTexImageSizeCompatible(internalFormat, width, height, 1, imageSize), GL_INVALID_VALUE);
3481 
3482     if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
3483         ctx->override2DTextureTarget(target);
3484     }
3485 
3486     if (ctx->boundBuffer(GL_PIXEL_UNPACK_BUFFER)) {
3487         ctx->glCompressedTexSubImage2DOffsetAEMU(
3488                 ctx, target, level,
3489                 xoffset, yoffset,
3490                 width, height, format,
3491                 imageSize, (uintptr_t)data);
3492     } else {
3493         ctx->m_glCompressedTexSubImage2D_enc(
3494                 ctx, target, level,
3495                 xoffset, yoffset,
3496                 width, height, format,
3497                 imageSize, data);
3498     }
3499 
3500     if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
3501         ctx->restore2DTextureTarget(target);
3502     }
3503 }
3504 
s_glBindBufferRange(void * self,GLenum target,GLuint index,GLuint buffer,GLintptr offset,GLsizeiptr size)3505 void GL2Encoder::s_glBindBufferRange(void* self, GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size) {
3506     GL2Encoder* ctx = (GL2Encoder*)self;
3507     GLClientState* state = ctx->m_state;
3508 
3509     SET_ERROR_IF(!GLESv2Validation::bufferTarget(ctx, target), GL_INVALID_ENUM);
3510 
3511     // Only works with certain targets
3512     SET_ERROR_IF(
3513         !(target == GL_ATOMIC_COUNTER_BUFFER ||
3514           target == GL_SHADER_STORAGE_BUFFER ||
3515           target == GL_TRANSFORM_FEEDBACK_BUFFER ||
3516           target == GL_UNIFORM_BUFFER),
3517         GL_INVALID_ENUM);
3518 
3519     // Can't exceed range
3520     SET_ERROR_IF(index < 0 ||
3521                  index >= state->getMaxIndexedBufferBindings(target),
3522                  GL_INVALID_VALUE);
3523     SET_ERROR_IF(buffer && size <= 0, GL_INVALID_VALUE);
3524     SET_ERROR_IF((target == GL_ATOMIC_COUNTER_BUFFER ||
3525                   target == GL_TRANSFORM_FEEDBACK_BUFFER) &&
3526                  (size % 4 || offset % 4),
3527                  GL_INVALID_VALUE);
3528 
3529     GLint ssbo_offset_align, ubo_offset_align;
3530 
3531     if (ctx->majorVersion() >= 3 && ctx->minorVersion() >= 1) {
3532         ctx->s_glGetIntegerv(ctx, GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT, &ssbo_offset_align);
3533         SET_ERROR_IF(target == GL_SHADER_STORAGE_BUFFER &&
3534                      offset % ssbo_offset_align,
3535                      GL_INVALID_VALUE);
3536     }
3537 
3538     ctx->s_glGetIntegerv(ctx, GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT, &ubo_offset_align);
3539     SET_ERROR_IF(target == GL_UNIFORM_BUFFER &&
3540                  offset % ubo_offset_align,
3541                  GL_INVALID_VALUE);
3542 
3543     if (ctx->m_state->isIndexedBindNoOp(target, index, buffer, offset, size, 0, 0)) return;
3544 
3545     state->bindBuffer(target, buffer);
3546     ctx->m_state->addBuffer(buffer);
3547     state->bindIndexedBuffer(target, index, buffer, offset, size, 0, 0);
3548 
3549     ctx->m_glBindBufferRange_enc(ctx, target, index, buffer, offset, size);
3550     ctx->m_state->setLastEncodedBufferBind(target, buffer);
3551 }
3552 
s_glBindBufferBase(void * self,GLenum target,GLuint index,GLuint buffer)3553 void GL2Encoder::s_glBindBufferBase(void* self, GLenum target, GLuint index, GLuint buffer) {
3554     GL2Encoder* ctx = (GL2Encoder*)self;
3555     GLClientState* state = ctx->m_state;
3556 
3557     SET_ERROR_IF(!GLESv2Validation::bufferTarget(ctx, target), GL_INVALID_ENUM);
3558 
3559     // Only works with certain targets
3560     SET_ERROR_IF(
3561         !(target == GL_ATOMIC_COUNTER_BUFFER ||
3562           target == GL_SHADER_STORAGE_BUFFER ||
3563           target == GL_TRANSFORM_FEEDBACK_BUFFER ||
3564           target == GL_UNIFORM_BUFFER),
3565         GL_INVALID_ENUM);
3566     // Can't exceed range
3567     SET_ERROR_IF(index < 0 ||
3568                  index >= state->getMaxIndexedBufferBindings(target),
3569                  GL_INVALID_VALUE);
3570 
3571     BufferData* buf = ctx->getBufferDataById(buffer);
3572     GLsizeiptr size = buf ? buf->m_size : 0;
3573 
3574     if (ctx->m_state->isIndexedBindNoOp(target, index, buffer, 0, size, 0, 0)) return;
3575 
3576     state->bindBuffer(target, buffer);
3577     ctx->m_state->addBuffer(buffer);
3578 
3579     state->bindIndexedBuffer(target, index, buffer, 0, size, 0, 0);
3580 
3581     ctx->m_glBindBufferBase_enc(ctx, target, index, buffer);
3582     ctx->m_state->setLastEncodedBufferBind(target, buffer);
3583 }
3584 
doIndexedBufferBindEncodeCached(IndexedBufferBindOp op,GLenum target,GLuint index,GLuint buffer,GLintptr offset,GLsizeiptr size,GLintptr stride,GLintptr effectiveStride)3585 void GL2Encoder::doIndexedBufferBindEncodeCached(IndexedBufferBindOp op, GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size, GLintptr stride, GLintptr effectiveStride)
3586 {
3587     if (m_state->isIndexedBindNoOp(target, index, buffer, offset, size, stride, effectiveStride)) return;
3588 
3589     switch (op) {
3590         case BindBufferBase:
3591             // can emulate with bindBufferRange
3592         case BindBufferRange:
3593             m_glBindBufferRange_enc(this, target, index, buffer, offset, size);
3594             break;
3595         // TODO: other ops
3596     }
3597 
3598     m_state->setLastEncodedBufferBind(target, buffer);
3599 }
3600 
s_glCopyBufferSubData(void * self,GLenum readtarget,GLenum writetarget,GLintptr readoffset,GLintptr writeoffset,GLsizeiptr size)3601 void GL2Encoder::s_glCopyBufferSubData(void *self , GLenum readtarget, GLenum writetarget, GLintptr readoffset, GLintptr writeoffset, GLsizeiptr size) {
3602     GL2Encoder* ctx = (GL2Encoder*)self;
3603 
3604     SET_ERROR_IF(!GLESv2Validation::bufferTarget(ctx, readtarget), GL_INVALID_ENUM);
3605     SET_ERROR_IF(!GLESv2Validation::bufferTarget(ctx, writetarget), GL_INVALID_ENUM);
3606     SET_ERROR_IF((readtarget == GL_ATOMIC_COUNTER_BUFFER ||
3607                   readtarget == GL_DISPATCH_INDIRECT_BUFFER ||
3608                   readtarget == GL_DRAW_INDIRECT_BUFFER ||
3609                   readtarget == GL_SHADER_STORAGE_BUFFER), GL_INVALID_ENUM);
3610     SET_ERROR_IF((writetarget == GL_ATOMIC_COUNTER_BUFFER ||
3611                   writetarget == GL_DISPATCH_INDIRECT_BUFFER ||
3612                   writetarget == GL_DRAW_INDIRECT_BUFFER ||
3613                   writetarget == GL_SHADER_STORAGE_BUFFER), GL_INVALID_ENUM);
3614 
3615     GLuint readBufferId = ctx->boundBuffer(readtarget);
3616     GLuint writeBufferId = ctx->boundBuffer(writetarget);
3617 
3618     SET_ERROR_IF(!readBufferId || !writeBufferId, GL_INVALID_OPERATION);
3619 
3620     SET_ERROR_IF(ctx->isBufferTargetMapped(readtarget), GL_INVALID_OPERATION);
3621     SET_ERROR_IF(ctx->isBufferTargetMapped(writetarget), GL_INVALID_OPERATION);
3622 
3623     SET_ERROR_IF(readoffset < 0, GL_INVALID_VALUE);
3624     SET_ERROR_IF(writeoffset < 0, GL_INVALID_VALUE);
3625     SET_ERROR_IF(size < 0, GL_INVALID_VALUE);
3626 
3627     BufferData* readBufferData = ctx->getBufferData(readtarget);
3628     BufferData* writeBufferData = ctx->getBufferData(writetarget);
3629 
3630     SET_ERROR_IF(
3631         readBufferData &&
3632         (readoffset + size > readBufferData->m_size),
3633         GL_INVALID_VALUE);
3634 
3635     SET_ERROR_IF(
3636         writeBufferData &&
3637         (writeoffset + size > writeBufferData->m_size),
3638         GL_INVALID_VALUE);
3639 
3640     SET_ERROR_IF(readBufferId == writeBufferId &&
3641                  !((writeoffset >= readoffset + size) ||
3642                    (readoffset >= writeoffset + size)),
3643                  GL_INVALID_VALUE);
3644 
3645     ctx->m_glCopyBufferSubData_enc(self, readtarget, writetarget, readoffset, writeoffset, size);
3646 }
3647 
s_glGetBufferParameteriv(void * self,GLenum target,GLenum pname,GLint * params)3648 void GL2Encoder::s_glGetBufferParameteriv(void* self, GLenum target, GLenum pname, GLint* params) {
3649     GL2Encoder* ctx = (GL2Encoder*)self;
3650 
3651     SET_ERROR_IF(!GLESv2Validation::bufferTarget(ctx, target), GL_INVALID_ENUM);
3652     SET_ERROR_IF(
3653         target != GL_ARRAY_BUFFER &&
3654         target != GL_ELEMENT_ARRAY_BUFFER &&
3655         target != GL_COPY_READ_BUFFER &&
3656         target != GL_COPY_WRITE_BUFFER &&
3657         target != GL_PIXEL_PACK_BUFFER &&
3658         target != GL_PIXEL_UNPACK_BUFFER &&
3659         target != GL_TRANSFORM_FEEDBACK_BUFFER &&
3660         target != GL_UNIFORM_BUFFER,
3661         GL_INVALID_ENUM);
3662     SET_ERROR_IF(!GLESv2Validation::bufferParam(ctx, pname), GL_INVALID_ENUM);
3663     SET_ERROR_IF(!ctx->boundBuffer(target), GL_INVALID_OPERATION);
3664     SET_ERROR_IF(pname != GL_BUFFER_ACCESS_FLAGS &&
3665                  pname != GL_BUFFER_MAPPED &&
3666                  pname != GL_BUFFER_SIZE &&
3667                  pname != GL_BUFFER_USAGE &&
3668                  pname != GL_BUFFER_MAP_LENGTH &&
3669                  pname != GL_BUFFER_MAP_OFFSET,
3670                  GL_INVALID_ENUM);
3671 
3672     if (!params) return;
3673 
3674     BufferData* buf = ctx->getBufferData(target);
3675 
3676     switch (pname) {
3677         case GL_BUFFER_ACCESS_FLAGS:
3678             *params = buf ? buf->m_mappedAccess : 0;
3679             break;
3680         case GL_BUFFER_MAPPED:
3681             *params = buf ? (buf->m_mapped ? GL_TRUE : GL_FALSE) : GL_FALSE;
3682             break;
3683         case GL_BUFFER_SIZE:
3684             *params = buf ? buf->m_size : 0;
3685             break;
3686         case GL_BUFFER_USAGE:
3687             *params = buf ? buf->m_usage : GL_STATIC_DRAW;
3688             break;
3689         case GL_BUFFER_MAP_LENGTH:
3690             *params = buf ? buf->m_mappedLength : 0;
3691             break;
3692         case GL_BUFFER_MAP_OFFSET:
3693             *params = buf ? buf->m_mappedOffset : 0;
3694             break;
3695         default:
3696             break;
3697     }
3698 }
3699 
s_glGetBufferParameteri64v(void * self,GLenum target,GLenum pname,GLint64 * params)3700 void GL2Encoder::s_glGetBufferParameteri64v(void* self, GLenum target, GLenum pname, GLint64* params) {
3701     GL2Encoder* ctx = (GL2Encoder*)self;
3702 
3703     SET_ERROR_IF(!GLESv2Validation::bufferTarget(ctx, target), GL_INVALID_ENUM);
3704     SET_ERROR_IF(
3705         target != GL_ARRAY_BUFFER &&
3706         target != GL_ELEMENT_ARRAY_BUFFER &&
3707         target != GL_COPY_READ_BUFFER &&
3708         target != GL_COPY_WRITE_BUFFER &&
3709         target != GL_PIXEL_PACK_BUFFER &&
3710         target != GL_PIXEL_UNPACK_BUFFER &&
3711         target != GL_TRANSFORM_FEEDBACK_BUFFER &&
3712         target != GL_UNIFORM_BUFFER,
3713         GL_INVALID_ENUM);
3714     SET_ERROR_IF(!GLESv2Validation::bufferParam(ctx, pname), GL_INVALID_ENUM);
3715     SET_ERROR_IF(!ctx->boundBuffer(target), GL_INVALID_OPERATION);
3716     SET_ERROR_IF(pname != GL_BUFFER_ACCESS_FLAGS &&
3717                  pname != GL_BUFFER_MAPPED &&
3718                  pname != GL_BUFFER_SIZE &&
3719                  pname != GL_BUFFER_USAGE &&
3720                  pname != GL_BUFFER_MAP_LENGTH &&
3721                  pname != GL_BUFFER_MAP_OFFSET,
3722                  GL_INVALID_ENUM);
3723 
3724     if (!params) return;
3725 
3726     BufferData* buf = ctx->getBufferData(target);
3727 
3728     switch (pname) {
3729         case GL_BUFFER_ACCESS_FLAGS:
3730             *params = buf ? buf->m_mappedAccess : 0;
3731             break;
3732         case GL_BUFFER_MAPPED:
3733             *params = buf ? (buf->m_mapped ? GL_TRUE : GL_FALSE) : GL_FALSE;
3734             break;
3735         case GL_BUFFER_SIZE:
3736             *params = buf ? buf->m_size : 0;
3737             break;
3738         case GL_BUFFER_USAGE:
3739             *params = buf ? buf->m_usage : GL_STATIC_DRAW;
3740             break;
3741         case GL_BUFFER_MAP_LENGTH:
3742             *params = buf ? buf->m_mappedLength : 0;
3743             break;
3744         case GL_BUFFER_MAP_OFFSET:
3745             *params = buf ? buf->m_mappedOffset : 0;
3746             break;
3747         default:
3748             break;
3749     }
3750 }
3751 
s_glGetBufferPointerv(void * self,GLenum target,GLenum pname,GLvoid ** params)3752 void GL2Encoder::s_glGetBufferPointerv(void* self, GLenum target, GLenum pname, GLvoid** params) {
3753     GL2Encoder* ctx = (GL2Encoder*)self;
3754     SET_ERROR_IF(!GLESv2Validation::bufferTarget(ctx, target), GL_INVALID_ENUM);
3755     SET_ERROR_IF(
3756         target == GL_ATOMIC_COUNTER_BUFFER ||
3757         target == GL_DISPATCH_INDIRECT_BUFFER ||
3758         target == GL_DRAW_INDIRECT_BUFFER ||
3759         target == GL_SHADER_STORAGE_BUFFER,
3760         GL_INVALID_ENUM);
3761     SET_ERROR_IF(pname != GL_BUFFER_MAP_POINTER, GL_INVALID_ENUM);
3762     SET_ERROR_IF(!ctx->boundBuffer(target), GL_INVALID_OPERATION);
3763     if (!params) return;
3764 
3765     BufferData* buf = ctx->getBufferData(target);
3766 
3767     if (!buf || !buf->m_mapped) { *params = NULL; return; }
3768 
3769     *params = &buf->m_fixedBuffer[buf->m_mappedOffset];
3770 }
3771 
3772 static const char* const kNameDelimiter = ";";
3773 
packVarNames(GLsizei count,const char ** names,GLint * err_out)3774 static std::string packVarNames(GLsizei count, const char** names, GLint* err_out) {
3775 
3776 #define VALIDATE(cond, err) if (cond) { *err_out = err; return packed; } \
3777 
3778     std::string packed;
3779     // validate the array of char[]'s
3780     const char* currName;
3781     for (GLsizei i = 0; i < count; i++) {
3782         currName = names[i];
3783         VALIDATE(!currName, GL_INVALID_OPERATION);
3784         // check if has reasonable size
3785         size_t len = strlen(currName);
3786         VALIDATE(!len, GL_INVALID_OPERATION);
3787         // check for our delimiter, which if present
3788         // in the name, means an invalid name anyway.
3789         VALIDATE(strstr(currName, kNameDelimiter),
3790                  GL_INVALID_OPERATION);
3791         packed += currName;
3792         packed += ";";
3793     }
3794 
3795     *err_out = GL_NO_ERROR;
3796     return packed;
3797 }
3798 
s_glGetUniformIndices(void * self,GLuint program,GLsizei uniformCount,const GLchar ** uniformNames,GLuint * uniformIndices)3799 void GL2Encoder::s_glGetUniformIndices(void* self, GLuint program, GLsizei uniformCount, const GLchar ** uniformNames, GLuint* uniformIndices) {
3800     GL2Encoder* ctx = (GL2Encoder*)self;
3801 
3802     VALIDATE_PROGRAM_NAME(program);
3803 
3804     if (!uniformCount) return;
3805 
3806     GLint err = GL_NO_ERROR;
3807     std::string packed = packVarNames(uniformCount, (const char**)uniformNames, &err);
3808     SET_ERROR_IF(err != GL_NO_ERROR, GL_INVALID_OPERATION);
3809 
3810     std::vector<int> arrIndices;
3811     for (size_t i = 0; i < uniformCount; i++) {
3812         int err;
3813         arrIndices.push_back(sArrIndexOfUniformExpr(uniformNames[i], &err));
3814         if (err) {
3815             ALOGE("%s: invalid uniform name %s!", __FUNCTION__, uniformNames[i]);
3816             return;
3817         }
3818     }
3819 
3820     ctx->glGetUniformIndicesAEMU(ctx, program, uniformCount, (const GLchar*)&packed[0], packed.size() + 1, uniformIndices);
3821 }
3822 
s_glUniform1ui(void * self,GLint location,GLuint v0)3823 void GL2Encoder::s_glUniform1ui(void* self, GLint location, GLuint v0) {
3824     GL2Encoder *ctx = (GL2Encoder*)self;
3825     GLClientState* state = ctx->m_state;
3826     GLSharedGroupPtr shared = ctx->m_shared;
3827 
3828     ctx->m_state->validateUniform(false /* is float? */, true /* is unsigned? */, 1 /* columns */, 1 /* rows */, location, 1 /* count */, ctx->getErrorPtr());
3829     ctx->m_glUniform1ui_enc(self, location, v0);
3830 
3831     GLenum target;
3832     if (shared->setSamplerUniform(state->currentShaderProgram(), location, v0, &target)) {
3833         GLenum origActiveTexture = state->getActiveTextureUnit();
3834         if (ctx->updateHostTexture2DBinding(GL_TEXTURE0 + v0, target)) {
3835             ctx->m_glActiveTexture_enc(self, origActiveTexture);
3836         }
3837         state->setActiveTextureUnit(origActiveTexture);
3838     }
3839 }
3840 
s_glUniform2ui(void * self,GLint location,GLuint v0,GLuint v1)3841 void GL2Encoder::s_glUniform2ui(void* self, GLint location, GLuint v0, GLuint v1) {
3842     GL2Encoder *ctx = (GL2Encoder*)self;
3843     ctx->m_state->validateUniform(false /* is float? */, true /* is unsigned? */, 2 /* columns */, 1 /* rows */, location, 1 /* count */, ctx->getErrorPtr());
3844     ctx->m_glUniform2ui_enc(self, location, v0, v1);
3845 }
3846 
s_glUniform3ui(void * self,GLint location,GLuint v0,GLuint v1,GLuint v2)3847 void GL2Encoder::s_glUniform3ui(void* self, GLint location, GLuint v0, GLuint v1, GLuint v2) {
3848     GL2Encoder *ctx = (GL2Encoder*)self;
3849     ctx->m_state->validateUniform(false /* is float? */, true /* is unsigned? */, 3 /* columns */, 1 /* rows */, location, 1 /* count */, ctx->getErrorPtr());
3850     ctx->m_glUniform3ui_enc(self, location, v0, v1, v2);
3851 }
3852 
s_glUniform4ui(void * self,GLint location,GLint v0,GLuint v1,GLuint v2,GLuint v3)3853 void GL2Encoder::s_glUniform4ui(void* self, GLint location, GLint v0, GLuint v1, GLuint v2, GLuint v3) {
3854     GL2Encoder *ctx = (GL2Encoder*)self;
3855     ctx->m_state->validateUniform(false /* is float? */, true /* is unsigned? */, 4 /* columns */, 1 /* rows */, location, 1 /* count */, ctx->getErrorPtr());
3856     ctx->m_glUniform4ui_enc(self, location, v0, v1, v2, v3);
3857 }
3858 
s_glUniform1uiv(void * self,GLint location,GLsizei count,const GLuint * value)3859 void GL2Encoder::s_glUniform1uiv(void* self, GLint location, GLsizei count, const GLuint *value) {
3860     GL2Encoder *ctx = (GL2Encoder*)self;
3861     ctx->m_state->validateUniform(false /* is float? */, true /* is unsigned? */, 1 /* columns */, 1 /* rows */, location, count /* count */, ctx->getErrorPtr());
3862     ctx->m_glUniform1uiv_enc(self, location, count, value);
3863 }
3864 
s_glUniform2uiv(void * self,GLint location,GLsizei count,const GLuint * value)3865 void GL2Encoder::s_glUniform2uiv(void* self, GLint location, GLsizei count, const GLuint *value) {
3866     GL2Encoder *ctx = (GL2Encoder*)self;
3867     ctx->m_state->validateUniform(false /* is float? */, true /* is unsigned? */, 2 /* columns */, 1 /* rows */, location, count /* count */, ctx->getErrorPtr());
3868     ctx->m_glUniform2uiv_enc(self, location, count, value);
3869 }
3870 
s_glUniform3uiv(void * self,GLint location,GLsizei count,const GLuint * value)3871 void GL2Encoder::s_glUniform3uiv(void* self, GLint location, GLsizei count, const GLuint *value) {
3872     GL2Encoder *ctx = (GL2Encoder*)self;
3873     ctx->m_state->validateUniform(false /* is float? */, true /* is unsigned? */, 3 /* columns */, 1 /* rows */, location, count /* count */, ctx->getErrorPtr());
3874     ctx->m_glUniform3uiv_enc(self, location, count, value);
3875 }
3876 
s_glUniform4uiv(void * self,GLint location,GLsizei count,const GLuint * value)3877 void GL2Encoder::s_glUniform4uiv(void* self, GLint location, GLsizei count, const GLuint *value) {
3878     GL2Encoder *ctx = (GL2Encoder*)self;
3879     ctx->m_state->validateUniform(false /* is float? */, true /* is unsigned? */, 4 /* columns */, 1 /* rows */, location, count /* count */, ctx->getErrorPtr());
3880     ctx->m_glUniform4uiv_enc(self, location, count, value);
3881 }
3882 
s_glUniformMatrix2x3fv(void * self,GLint location,GLsizei count,GLboolean transpose,const GLfloat * value)3883 void GL2Encoder::s_glUniformMatrix2x3fv(void* self, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) {
3884     GL2Encoder *ctx = (GL2Encoder*)self;
3885     ctx->m_state->validateUniform(true /* is float? */, false /* is unsigned? */, 2 /* columns */, 3 /* rows */, location, count /* count */, ctx->getErrorPtr());
3886     ctx->m_glUniformMatrix2x3fv_enc(self, location, count, transpose, value);
3887 }
3888 
s_glUniformMatrix3x2fv(void * self,GLint location,GLsizei count,GLboolean transpose,const GLfloat * value)3889 void GL2Encoder::s_glUniformMatrix3x2fv(void* self, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) {
3890     GL2Encoder *ctx = (GL2Encoder*)self;
3891     ctx->m_state->validateUniform(true /* is float? */, false /* is unsigned? */, 3 /* columns */, 2 /* rows */, location, count /* count */, ctx->getErrorPtr());
3892     ctx->m_glUniformMatrix3x2fv_enc(self, location, count, transpose, value);
3893 }
3894 
s_glUniformMatrix2x4fv(void * self,GLint location,GLsizei count,GLboolean transpose,const GLfloat * value)3895 void GL2Encoder::s_glUniformMatrix2x4fv(void* self, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) {
3896     GL2Encoder *ctx = (GL2Encoder*)self;
3897     ctx->m_state->validateUniform(true /* is float? */, false /* is unsigned? */, 2 /* columns */, 4 /* rows */, location, count /* count */, ctx->getErrorPtr());
3898     ctx->m_glUniformMatrix2x4fv_enc(self, location, count, transpose, value);
3899 }
3900 
s_glUniformMatrix4x2fv(void * self,GLint location,GLsizei count,GLboolean transpose,const GLfloat * value)3901 void GL2Encoder::s_glUniformMatrix4x2fv(void* self, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) {
3902     GL2Encoder *ctx = (GL2Encoder*)self;
3903     ctx->m_state->validateUniform(true /* is float? */, false /* is unsigned? */, 4 /* columns */, 2 /* rows */, location, count /* count */, ctx->getErrorPtr());
3904     ctx->m_glUniformMatrix4x2fv_enc(self, location, count, transpose, value);
3905 }
3906 
s_glUniformMatrix3x4fv(void * self,GLint location,GLsizei count,GLboolean transpose,const GLfloat * value)3907 void GL2Encoder::s_glUniformMatrix3x4fv(void* self, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) {
3908     GL2Encoder *ctx = (GL2Encoder*)self;
3909     ctx->m_state->validateUniform(true /* is float? */, false /* is unsigned? */, 3 /* columns */, 4 /* rows */, location, count /* count */, ctx->getErrorPtr());
3910     ctx->m_glUniformMatrix3x4fv_enc(self, location, count, transpose, value);
3911 }
3912 
s_glUniformMatrix4x3fv(void * self,GLint location,GLsizei count,GLboolean transpose,const GLfloat * value)3913 void GL2Encoder::s_glUniformMatrix4x3fv(void* self, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) {
3914     GL2Encoder *ctx = (GL2Encoder*)self;
3915     ctx->m_state->validateUniform(true /* is float? */, false /* is unsigned? */, 4 /* columns */, 3 /* rows */, location, count /* count */, ctx->getErrorPtr());
3916     ctx->m_glUniformMatrix4x3fv_enc(self, location, count, transpose, value);
3917 }
3918 
s_glGetUniformuiv(void * self,GLuint program,GLint location,GLuint * params)3919 void GL2Encoder::s_glGetUniformuiv(void* self, GLuint program, GLint location, GLuint* params) {
3920     GL2Encoder *ctx = (GL2Encoder*)self;
3921     SET_ERROR_IF(!ctx->m_shared->isShaderOrProgramObject(program), GL_INVALID_VALUE);
3922     SET_ERROR_IF(!ctx->m_shared->isProgram(program), GL_INVALID_OPERATION);
3923     SET_ERROR_IF(!ctx->m_shared->isProgramInitialized(program), GL_INVALID_OPERATION);
3924     SET_ERROR_IF(ctx->m_shared->getProgramUniformType(program,location)==0, GL_INVALID_OPERATION);
3925     SET_ERROR_IF(!ctx->m_shared->isProgramUniformLocationValid(program,location), GL_INVALID_OPERATION);
3926     ctx->m_glGetUniformuiv_enc(self, program, location, params);
3927 }
3928 
s_glGetActiveUniformBlockiv(void * self,GLuint program,GLuint uniformBlockIndex,GLenum pname,GLint * params)3929 void GL2Encoder::s_glGetActiveUniformBlockiv(void* self, GLuint program, GLuint uniformBlockIndex, GLenum pname, GLint* params) {
3930     GL2Encoder* ctx = (GL2Encoder*)self;
3931 
3932     VALIDATE_PROGRAM_NAME(program);
3933     SET_ERROR_IF(!GLESv2Validation::allowedGetActiveUniformBlock(pname), GL_INVALID_ENUM);
3934     SET_ERROR_IF(uniformBlockIndex >= ctx->m_shared->getActiveUniformBlockCount(program), GL_INVALID_VALUE);
3935 
3936     // refresh client state's # active uniforms in this block
3937     if (pname == GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES) {
3938         // TODO if worth it: cache uniform count and other params,
3939         // invalidate on program relinking.
3940         GLint numActiveUniforms;
3941         ctx->m_glGetActiveUniformBlockiv_enc(ctx,
3942                 program, uniformBlockIndex,
3943                 GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS,
3944                 &numActiveUniforms);
3945         ctx->m_state->setNumActiveUniformsInUniformBlock(
3946                 program, uniformBlockIndex, numActiveUniforms);
3947     }
3948 
3949     ctx->m_glGetActiveUniformBlockiv_enc(ctx,
3950             program, uniformBlockIndex,
3951             pname, params);
3952 }
3953 
s_glGetVertexAttribIiv(void * self,GLuint index,GLenum pname,GLint * params)3954 void GL2Encoder::s_glGetVertexAttribIiv(void* self, GLuint index, GLenum pname, GLint* params) {
3955     GL2Encoder *ctx = (GL2Encoder *)self;
3956     VALIDATE_VERTEX_ATTRIB_INDEX(index);
3957     SET_ERROR_IF(!GLESv2Validation::allowedGetVertexAttrib(pname), GL_INVALID_ENUM);
3958 
3959     if (!ctx->m_state->getVertexAttribParameter<GLint>(index, pname, params)) {
3960         ctx->m_glGetVertexAttribIiv_enc(self, index, pname, params);
3961     }
3962 }
3963 
s_glGetVertexAttribIuiv(void * self,GLuint index,GLenum pname,GLuint * params)3964 void GL2Encoder::s_glGetVertexAttribIuiv(void* self, GLuint index, GLenum pname, GLuint* params) {
3965     GL2Encoder *ctx = (GL2Encoder *)self;
3966     VALIDATE_VERTEX_ATTRIB_INDEX(index);
3967     SET_ERROR_IF(!GLESv2Validation::allowedGetVertexAttrib(pname), GL_INVALID_ENUM);
3968 
3969     if (!ctx->m_state->getVertexAttribParameter<GLuint>(index, pname, params)) {
3970         ctx->m_glGetVertexAttribIuiv_enc(self, index, pname, params);
3971     }
3972 }
3973 
s_glVertexAttribIPointer(void * self,GLuint index,GLint size,GLenum type,GLsizei stride,const GLvoid * pointer)3974 void GL2Encoder::s_glVertexAttribIPointer(void* self, GLuint index, GLint size, GLenum type, GLsizei stride, const GLvoid* pointer) {
3975     GL2Encoder *ctx = (GL2Encoder *)self;
3976     assert(ctx->m_state != NULL);
3977     VALIDATE_VERTEX_ATTRIB_INDEX(index);
3978     SET_ERROR_IF((size < 1 || size > 4), GL_INVALID_VALUE);
3979     SET_ERROR_IF(
3980         !(type == GL_BYTE ||
3981           type == GL_UNSIGNED_BYTE ||
3982           type == GL_SHORT ||
3983           type == GL_UNSIGNED_SHORT ||
3984           type == GL_INT ||
3985           type == GL_UNSIGNED_INT),
3986         GL_INVALID_ENUM);
3987     SET_ERROR_IF(stride < 0, GL_INVALID_VALUE);
3988 
3989     ctx->m_state->setVertexAttribBinding(index, index);
3990     ctx->m_state->setVertexAttribFormat(index, size, type, false, 0, true);
3991     GLsizei effectiveStride = stride;
3992     if (stride == 0) {
3993         effectiveStride = glSizeof(type) * size;
3994     }
3995     ctx->m_state->bindIndexedBuffer(0, index, ctx->m_state->currentArrayVbo(), (uintptr_t)pointer, 0, stride, effectiveStride);
3996 
3997     if (ctx->m_state->currentArrayVbo() != 0) {
3998         ctx->glVertexAttribIPointerOffsetAEMU(ctx, index, size, type, stride, (uintptr_t)pointer);
3999     } else {
4000         SET_ERROR_IF(ctx->m_state->currentVertexArrayObject() != 0 && pointer, GL_INVALID_OPERATION);
4001         // wait for client-array handler
4002     }
4003 }
4004 
s_glVertexAttribDivisor(void * self,GLuint index,GLuint divisor)4005 void GL2Encoder::s_glVertexAttribDivisor(void* self, GLuint index, GLuint divisor) {
4006     GL2Encoder *ctx = (GL2Encoder *)self;
4007     assert(ctx->m_state != NULL);
4008     VALIDATE_VERTEX_ATTRIB_INDEX(index);
4009     ctx->m_state->setVertexAttribBinding(index, index);
4010     ctx->m_state->setVertexBindingDivisor(index, divisor);
4011     ctx->m_glVertexAttribDivisor_enc(ctx, index, divisor);
4012 }
4013 
s_glRenderbufferStorageMultisample(void * self,GLenum target,GLsizei samples,GLenum internalformat,GLsizei width,GLsizei height)4014 void GL2Encoder::s_glRenderbufferStorageMultisample(void* self,
4015         GLenum target, GLsizei samples, GLenum internalformat,
4016         GLsizei width, GLsizei height) {
4017     GL2Encoder *ctx = (GL2Encoder *)self;
4018     GLClientState* state = ctx->m_state;
4019 
4020     SET_ERROR_IF(target != GL_RENDERBUFFER, GL_INVALID_ENUM);
4021     SET_ERROR_IF(!GLESv2Validation::rboFormat(ctx, internalformat), GL_INVALID_ENUM);
4022 
4023     SET_ERROR_IF(width < 0 || height < 0, GL_INVALID_VALUE);
4024     GLint max_rb_size;
4025     ctx->glGetIntegerv(ctx, GL_MAX_RENDERBUFFER_SIZE, &max_rb_size);
4026     SET_ERROR_IF(width > max_rb_size || height > max_rb_size, GL_INVALID_VALUE);
4027 
4028     GLint max_samples;
4029     ctx->s_glGetInternalformativ(ctx, target, internalformat, GL_SAMPLES, 1, &max_samples);
4030     SET_ERROR_IF(samples > max_samples, GL_INVALID_OPERATION);
4031 
4032     state->setBoundRenderbufferFormat(internalformat);
4033     state->setBoundRenderbufferSamples(samples);
4034     state->setBoundRenderbufferDimensions(width, height);
4035     ctx->m_glRenderbufferStorageMultisample_enc(
4036             self, target, samples, internalformat, width, height);
4037 }
4038 
s_glDrawBuffers(void * self,GLsizei n,const GLenum * bufs)4039 void GL2Encoder::s_glDrawBuffers(void* self, GLsizei n, const GLenum* bufs) {
4040     GL2Encoder* ctx = (GL2Encoder*)self;
4041     SET_ERROR_IF(!ctx->m_state->boundFramebuffer(GL_DRAW_FRAMEBUFFER) && n > 1, GL_INVALID_OPERATION);
4042     SET_ERROR_IF(n < 0 || n > ctx->m_state->getMaxDrawBuffers(), GL_INVALID_VALUE);
4043     for (int i = 0; i < n; i++) {
4044         SET_ERROR_IF(
4045             bufs[i] != GL_NONE &&
4046             bufs[i] != GL_BACK &&
4047             glUtilsColorAttachmentIndex(bufs[i]) == -1,
4048             GL_INVALID_ENUM);
4049         SET_ERROR_IF(
4050             !ctx->m_state->boundFramebuffer(GL_DRAW_FRAMEBUFFER) &&
4051             glUtilsColorAttachmentIndex(bufs[i]) != -1,
4052             GL_INVALID_OPERATION);
4053         SET_ERROR_IF(
4054             ctx->m_state->boundFramebuffer(GL_DRAW_FRAMEBUFFER) &&
4055             ((glUtilsColorAttachmentIndex(bufs[i]) != -1 &&
4056               glUtilsColorAttachmentIndex(bufs[i]) != i) ||
4057              (glUtilsColorAttachmentIndex(bufs[i]) == -1 &&
4058               bufs[i] != GL_NONE)),
4059             GL_INVALID_OPERATION);
4060     }
4061 
4062     ctx->m_glDrawBuffers_enc(ctx, n, bufs);
4063 }
4064 
s_glReadBuffer(void * self,GLenum src)4065 void GL2Encoder::s_glReadBuffer(void* self, GLenum src) {
4066     GL2Encoder* ctx = (GL2Encoder*)self;
4067 
4068     SET_ERROR_IF(
4069         glUtilsColorAttachmentIndex(src) != -1 &&
4070          (glUtilsColorAttachmentIndex(src) >=
4071          ctx->m_state->getMaxColorAttachments()),
4072         GL_INVALID_OPERATION);
4073     SET_ERROR_IF(
4074         src != GL_NONE &&
4075         src != GL_BACK &&
4076         src > GL_COLOR_ATTACHMENT0 &&
4077         src < GL_DEPTH_ATTACHMENT &&
4078         (src - GL_COLOR_ATTACHMENT0) >
4079         ctx->m_state->getMaxColorAttachments(),
4080         GL_INVALID_OPERATION);
4081     SET_ERROR_IF(
4082         src != GL_NONE &&
4083         src != GL_BACK &&
4084         glUtilsColorAttachmentIndex(src) == -1,
4085         GL_INVALID_ENUM);
4086     SET_ERROR_IF(
4087         !ctx->m_state->boundFramebuffer(GL_READ_FRAMEBUFFER) &&
4088         src != GL_NONE &&
4089         src != GL_BACK,
4090         GL_INVALID_OPERATION);
4091     SET_ERROR_IF(
4092         ctx->m_state->boundFramebuffer(GL_READ_FRAMEBUFFER) &&
4093         src != GL_NONE &&
4094         glUtilsColorAttachmentIndex(src) == -1,
4095         GL_INVALID_OPERATION);
4096 
4097     ctx->m_glReadBuffer_enc(ctx, src);
4098 }
4099 
s_glFramebufferTextureLayer(void * self,GLenum target,GLenum attachment,GLuint texture,GLint level,GLint layer)4100 void GL2Encoder::s_glFramebufferTextureLayer(void* self, GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer) {
4101     GL2Encoder* ctx = (GL2Encoder*)self;
4102     GLClientState* state = ctx->m_state;
4103 
4104     SET_ERROR_IF(!GLESv2Validation::framebufferTarget(ctx, target), GL_INVALID_ENUM);
4105     SET_ERROR_IF(!GLESv2Validation::framebufferAttachment(ctx, attachment), GL_INVALID_ENUM);
4106     SET_ERROR_IF(texture != 0 && layer < 0, GL_INVALID_VALUE);
4107     GLint maxArrayTextureLayers;
4108     ctx->glGetIntegerv(ctx, GL_MAX_ARRAY_TEXTURE_LAYERS, &maxArrayTextureLayers);
4109     SET_ERROR_IF(texture != 0 && layer > maxArrayTextureLayers - 1, GL_INVALID_VALUE);
4110     SET_ERROR_IF(!ctx->m_state->boundFramebuffer(target), GL_INVALID_OPERATION);
4111     GLenum lastBoundTarget = state->queryTexLastBoundTarget(texture);
4112     SET_ERROR_IF(lastBoundTarget != GL_TEXTURE_2D_ARRAY &&
4113                  lastBoundTarget != GL_TEXTURE_3D,
4114                  GL_INVALID_OPERATION);
4115     state->attachTextureObject(target, attachment, texture, level, layer);
4116 
4117     GLint max3DTextureSize;
4118     ctx->glGetIntegerv(ctx, GL_MAX_3D_TEXTURE_SIZE, &max3DTextureSize);
4119     SET_ERROR_IF(
4120             layer >= max3DTextureSize,
4121             GL_INVALID_VALUE);
4122 
4123     ctx->m_glFramebufferTextureLayer_enc(self, target, attachment, texture, level, layer);
4124 }
4125 
s_glTexStorage2D(void * self,GLenum target,GLsizei levels,GLenum internalformat,GLsizei width,GLsizei height)4126 void GL2Encoder::s_glTexStorage2D(void* self, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height) {
4127     GL2Encoder* ctx = (GL2Encoder*)self;
4128     GLClientState* state = ctx->m_state;
4129 
4130     SET_ERROR_IF(
4131         target != GL_TEXTURE_2D &&
4132         target != GL_TEXTURE_CUBE_MAP,
4133         GL_INVALID_ENUM);
4134     SET_ERROR_IF(!GLESv2Validation::pixelInternalFormat(internalformat), GL_INVALID_ENUM);
4135     SET_ERROR_IF(!state->getBoundTexture(target), GL_INVALID_OPERATION);
4136     SET_ERROR_IF(levels < 1 || width < 1 || height < 1, GL_INVALID_VALUE);
4137     SET_ERROR_IF(levels > ilog2((uint32_t)std::max(width, height)) + 1,
4138                  GL_INVALID_OPERATION);
4139     SET_ERROR_IF(state->isBoundTextureImmutableFormat(target), GL_INVALID_OPERATION);
4140 
4141     state->setBoundTextureInternalFormat(target, internalformat);
4142     state->setBoundTextureDims(target, -1 /* set all cube dimensions */, -1, width, height, 1);
4143     state->setBoundTextureImmutableFormat(target);
4144 
4145     if (target == GL_TEXTURE_2D) {
4146         ctx->override2DTextureTarget(target);
4147     }
4148 
4149     ctx->m_glTexStorage2D_enc(ctx, target, levels, internalformat, width, height);
4150 
4151     if (target == GL_TEXTURE_2D) {
4152         ctx->restore2DTextureTarget(target);
4153     }
4154 }
4155 
s_glTransformFeedbackVaryings(void * self,GLuint program,GLsizei count,const char ** varyings,GLenum bufferMode)4156 void GL2Encoder::s_glTransformFeedbackVaryings(void* self, GLuint program, GLsizei count, const char** varyings, GLenum bufferMode) {
4157     GL2Encoder* ctx = (GL2Encoder*)self;
4158 
4159     SET_ERROR_IF(!ctx->m_shared->isProgram(program), GL_INVALID_VALUE);
4160 
4161     GLint maxCount = 0;
4162     ctx->glGetIntegerv(ctx, GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS, &maxCount);
4163 
4164     SET_ERROR_IF(
4165         bufferMode == GL_SEPARATE_ATTRIBS &&
4166         maxCount < count,
4167         GL_INVALID_VALUE);
4168     SET_ERROR_IF(
4169         bufferMode != GL_INTERLEAVED_ATTRIBS &&
4170         bufferMode != GL_SEPARATE_ATTRIBS,
4171         GL_INVALID_ENUM);
4172 
4173     // NOTE: This only has an effect on the program that is being linked.
4174     // The dEQP test in dEQP-GLES3.functional.negative_api doesn't know
4175     // about this.
4176     ctx->m_state->setTransformFeedbackVaryingsCountForLinking(count);
4177 
4178     if (!count) return;
4179 
4180     GLint err = GL_NO_ERROR;
4181     std::string packed = packVarNames(count, varyings, &err);
4182     SET_ERROR_IF(err != GL_NO_ERROR, GL_INVALID_OPERATION);
4183 
4184     ctx->glTransformFeedbackVaryingsAEMU(ctx, program, count, (const char*)&packed[0], packed.size() + 1, bufferMode);
4185 }
4186 
s_glBeginTransformFeedback(void * self,GLenum primitiveMode)4187 void GL2Encoder::s_glBeginTransformFeedback(void* self, GLenum primitiveMode) {
4188     GL2Encoder* ctx = (GL2Encoder*)self;
4189     GLClientState* state = ctx->m_state;
4190     SET_ERROR_IF(
4191         primitiveMode != GL_POINTS &&
4192         primitiveMode != GL_LINES &&
4193         primitiveMode != GL_TRIANGLES,
4194         GL_INVALID_ENUM);
4195     SET_ERROR_IF(
4196         ctx->m_state->getTransformFeedbackActive(),
4197         GL_INVALID_OPERATION);
4198     // TODO:
4199     // dEQP-GLES3.functional.lifetime.attach.deleted_output.buffer_transform_feedback
4200     // SET_ERROR_IF(
4201     //     !ctx->boundBuffer(GL_TRANSFORM_FEEDBACK_BUFFER),
4202     //     GL_INVALID_OPERATION);
4203     SET_ERROR_IF(
4204         !ctx->m_state->currentProgram(), GL_INVALID_OPERATION);
4205     ctx->m_glBeginTransformFeedback_enc(ctx, primitiveMode);
4206     state->setTransformFeedbackActive(true);
4207     state->setTransformFeedbackUnpaused(true);
4208 }
4209 
s_glEndTransformFeedback(void * self)4210 void GL2Encoder::s_glEndTransformFeedback(void* self) {
4211     GL2Encoder* ctx = (GL2Encoder*)self;
4212     GLClientState* state = ctx->m_state;
4213     SET_ERROR_IF(!state->getTransformFeedbackActive(), GL_INVALID_OPERATION);
4214     ctx->m_glEndTransformFeedback_enc(ctx);
4215     state->setTransformFeedbackActive(false);
4216     state->setTransformFeedbackUnpaused(false);
4217 }
4218 
s_glPauseTransformFeedback(void * self)4219 void GL2Encoder::s_glPauseTransformFeedback(void* self) {
4220     GL2Encoder* ctx = (GL2Encoder*)self;
4221     GLClientState* state = ctx->m_state;
4222     SET_ERROR_IF(!state->getTransformFeedbackActive(), GL_INVALID_OPERATION);
4223     SET_ERROR_IF(!state->getTransformFeedbackUnpaused(), GL_INVALID_OPERATION);
4224     ctx->m_glPauseTransformFeedback_enc(ctx);
4225     state->setTransformFeedbackUnpaused(false);
4226 }
4227 
s_glResumeTransformFeedback(void * self)4228 void GL2Encoder::s_glResumeTransformFeedback(void* self) {
4229     GL2Encoder* ctx = (GL2Encoder*)self;
4230     GLClientState* state = ctx->m_state;
4231     SET_ERROR_IF(!state->getTransformFeedbackActive(), GL_INVALID_OPERATION);
4232     SET_ERROR_IF(state->getTransformFeedbackUnpaused(), GL_INVALID_OPERATION);
4233     ctx->m_glResumeTransformFeedback_enc(ctx);
4234     state->setTransformFeedbackUnpaused(true);
4235 }
4236 
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)4237 void GL2Encoder::s_glTexImage3D(void* self, GLenum target, GLint level, GLint internalFormat,
4238                                GLsizei width, GLsizei height, GLsizei depth,
4239                                GLint border, GLenum format, GLenum type, const GLvoid* data) {
4240     GL2Encoder* ctx = (GL2Encoder*)self;
4241     GLClientState* state = ctx->m_state;
4242 
4243     SET_ERROR_IF(target != GL_TEXTURE_3D &&
4244                  target != GL_TEXTURE_2D_ARRAY,
4245                  GL_INVALID_ENUM);
4246     SET_ERROR_IF(!GLESv2Validation::pixelType(ctx, type), GL_INVALID_ENUM);
4247     SET_ERROR_IF(!GLESv2Validation::pixelFormat(ctx, format), GL_INVALID_ENUM);
4248     SET_ERROR_IF(!(GLESv2Validation::pixelOp(format,type)),GL_INVALID_OPERATION);
4249     SET_ERROR_IF(!GLESv2Validation::pixelSizedFormat(ctx, internalFormat, format, type), GL_INVALID_OPERATION);
4250     SET_ERROR_IF(target == GL_TEXTURE_3D &&
4251         ((format == GL_DEPTH_COMPONENT) ||
4252          (format == GL_DEPTH_STENCIL)), GL_INVALID_OPERATION);
4253 
4254     // If unpack buffer is nonzero, verify unmapped state.
4255     SET_ERROR_IF(ctx->isBufferTargetMapped(GL_PIXEL_UNPACK_BUFFER), GL_INVALID_OPERATION);
4256 
4257     GLint max_texture_size;
4258     GLint max_3d_texture_size;
4259     ctx->glGetIntegerv(ctx, GL_MAX_TEXTURE_SIZE, &max_texture_size);
4260     ctx->glGetIntegerv(ctx, GL_MAX_3D_TEXTURE_SIZE, &max_3d_texture_size);
4261     SET_ERROR_IF(level < 0, GL_INVALID_VALUE);
4262     SET_ERROR_IF(level > ilog2(max_texture_size), GL_INVALID_VALUE);
4263     SET_ERROR_IF(level > ilog2(max_3d_texture_size), GL_INVALID_VALUE);
4264 
4265     SET_ERROR_IF(width < 0 || height < 0 || depth < 0, GL_INVALID_VALUE);
4266     SET_ERROR_IF(width > max_texture_size, GL_INVALID_VALUE);
4267     SET_ERROR_IF(height > max_texture_size, GL_INVALID_VALUE);
4268     if (target == GL_TEXTURE_3D) {
4269         SET_ERROR_IF(depth > max_texture_size, GL_INVALID_VALUE);
4270     } else {
4271         GLint maxArrayTextureLayers;
4272         ctx->glGetIntegerv(ctx, GL_MAX_ARRAY_TEXTURE_LAYERS, &maxArrayTextureLayers);
4273         SET_ERROR_IF(depth > maxArrayTextureLayers, GL_INVALID_VALUE);
4274     }
4275     SET_ERROR_IF(width > max_3d_texture_size, GL_INVALID_VALUE);
4276     SET_ERROR_IF(height > max_3d_texture_size, GL_INVALID_VALUE);
4277     SET_ERROR_IF(depth > max_3d_texture_size, GL_INVALID_VALUE);
4278     SET_ERROR_IF(border != 0, GL_INVALID_VALUE);
4279     // If unpack buffer is nonzero, verify buffer data fits and is evenly divisible by the type.
4280     SET_ERROR_IF(ctx->boundBuffer(GL_PIXEL_UNPACK_BUFFER) &&
4281                  ctx->getBufferData(GL_PIXEL_UNPACK_BUFFER) &&
4282                  ((uintptr_t)data + ctx->m_state->pboNeededDataSize(width, height, depth, format, type, 0) >
4283                   ctx->getBufferData(GL_PIXEL_UNPACK_BUFFER)->m_size),
4284                  GL_INVALID_OPERATION);
4285     SET_ERROR_IF(ctx->boundBuffer(GL_PIXEL_UNPACK_BUFFER) &&
4286                  ctx->getBufferData(GL_PIXEL_UNPACK_BUFFER) &&
4287                  ((uintptr_t)data %
4288                   glSizeof(type)),
4289                  GL_INVALID_OPERATION);
4290     SET_ERROR_IF(state->isBoundTextureImmutableFormat(target), GL_INVALID_OPERATION);
4291 
4292     state->setBoundTextureInternalFormat(target, internalFormat);
4293     state->setBoundTextureFormat(target, format);
4294     state->setBoundTextureType(target, type);
4295     state->setBoundTextureDims(target, target, level, width, height, depth);
4296 
4297     if (ctx->boundBuffer(GL_PIXEL_UNPACK_BUFFER)) {
4298         ctx->glTexImage3DOffsetAEMU(
4299                 ctx, target, level, internalFormat,
4300                 width, height, depth,
4301                 border, format, type, (uintptr_t)data);
4302     } else {
4303         ctx->m_glTexImage3D_enc(ctx,
4304                 target, level, internalFormat,
4305                 width, height, depth,
4306                 border, format, type, data);
4307     }
4308 }
4309 
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)4310 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) {
4311     GL2Encoder* ctx = (GL2Encoder*)self;
4312     GLClientState* state = ctx->m_state;
4313 
4314     SET_ERROR_IF(target != GL_TEXTURE_3D &&
4315                  target != GL_TEXTURE_2D_ARRAY,
4316                  GL_INVALID_ENUM);
4317     SET_ERROR_IF(!GLESv2Validation::pixelType(ctx, type), GL_INVALID_ENUM);
4318     SET_ERROR_IF(!GLESv2Validation::pixelFormat(ctx, format), GL_INVALID_ENUM);
4319     // If unpack buffer is nonzero, verify unmapped state.
4320     SET_ERROR_IF(ctx->isBufferTargetMapped(GL_PIXEL_UNPACK_BUFFER), GL_INVALID_OPERATION);
4321     GLint max_texture_size;
4322     GLint max_3d_texture_size;
4323     ctx->glGetIntegerv(ctx, GL_MAX_TEXTURE_SIZE, &max_texture_size);
4324     ctx->glGetIntegerv(ctx, GL_MAX_3D_TEXTURE_SIZE, &max_3d_texture_size);
4325     SET_ERROR_IF(level < 0, GL_INVALID_VALUE);
4326     SET_ERROR_IF(level > ilog2(max_texture_size), GL_INVALID_VALUE);
4327     SET_ERROR_IF(level > ilog2(max_3d_texture_size), GL_INVALID_VALUE);
4328     SET_ERROR_IF(width < 0 || height < 0 || depth < 0, GL_INVALID_VALUE);
4329     SET_ERROR_IF(xoffset < 0 || yoffset < 0 || zoffset < 0, GL_INVALID_VALUE);
4330     GLuint tex = state->getBoundTexture(target);
4331     GLsizei neededWidth = xoffset + width;
4332     GLsizei neededHeight = yoffset + height;
4333     GLsizei neededDepth = zoffset + depth;
4334 
4335     SET_ERROR_IF(tex &&
4336                  (neededWidth > state->queryTexWidth(level, tex) ||
4337                   neededHeight > state->queryTexHeight(level, tex) ||
4338                   neededDepth > state->queryTexDepth(level, tex)),
4339                  GL_INVALID_VALUE);
4340     // If unpack buffer is nonzero, verify buffer data fits and is evenly divisible by the type.
4341     SET_ERROR_IF(ctx->boundBuffer(GL_PIXEL_UNPACK_BUFFER) &&
4342                  ctx->getBufferData(GL_PIXEL_UNPACK_BUFFER) &&
4343                  ((uintptr_t)data + ctx->m_state->pboNeededDataSize(width, height, depth, format, type, 0) >
4344                   ctx->getBufferData(GL_PIXEL_UNPACK_BUFFER)->m_size),
4345                  GL_INVALID_OPERATION);
4346     SET_ERROR_IF(ctx->boundBuffer(GL_PIXEL_UNPACK_BUFFER) &&
4347                  ctx->getBufferData(GL_PIXEL_UNPACK_BUFFER) &&
4348                  ((uintptr_t)data % glSizeof(type)),
4349                  GL_INVALID_OPERATION);
4350     SET_ERROR_IF(!ctx->boundBuffer(GL_PIXEL_UNPACK_BUFFER) && !data, GL_INVALID_OPERATION);
4351     SET_ERROR_IF(xoffset < 0 || yoffset < 0 || zoffset < 0, GL_INVALID_VALUE);
4352 
4353     if (ctx->boundBuffer(GL_PIXEL_UNPACK_BUFFER)) {
4354         ctx->glTexSubImage3DOffsetAEMU(ctx,
4355                 target, level,
4356                 xoffset, yoffset, zoffset,
4357                 width, height, depth,
4358                 format, type, (uintptr_t)data);
4359     } else {
4360         ctx->m_glTexSubImage3D_enc(ctx,
4361                 target, level,
4362                 xoffset, yoffset, zoffset,
4363                 width, height, depth,
4364                 format, type, data);
4365     }
4366 }
4367 
s_glCompressedTexImage3D(void * self,GLenum target,GLint level,GLenum internalformat,GLsizei width,GLsizei height,GLsizei depth,GLint border,GLsizei imageSize,const GLvoid * data)4368 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) {
4369     GL2Encoder* ctx = (GL2Encoder*)self;
4370     GLClientState* state = ctx->m_state;
4371 
4372     SET_ERROR_IF(target != GL_TEXTURE_3D &&
4373                  target != GL_TEXTURE_2D_ARRAY,
4374                  GL_INVALID_ENUM);
4375     // Filter compressed formats support.
4376     SET_ERROR_IF(!GLESv2Validation::supportedCompressedFormat(ctx, internalformat), GL_INVALID_ENUM);
4377     SET_ERROR_IF(target == GL_TEXTURE_CUBE_MAP, GL_INVALID_ENUM);
4378     // If unpack buffer is nonzero, verify unmapped state.
4379     SET_ERROR_IF(ctx->isBufferTargetMapped(GL_PIXEL_UNPACK_BUFFER), GL_INVALID_OPERATION);
4380     SET_ERROR_IF(width < 0 || height < 0 || depth < 0, GL_INVALID_VALUE);
4381     SET_ERROR_IF(border, GL_INVALID_VALUE);
4382 
4383     GLint max_texture_size;
4384     GLint max_3d_texture_size;
4385     ctx->glGetIntegerv(ctx, GL_MAX_TEXTURE_SIZE, &max_texture_size);
4386     ctx->glGetIntegerv(ctx, GL_MAX_3D_TEXTURE_SIZE, &max_3d_texture_size);
4387     SET_ERROR_IF(level < 0, GL_INVALID_VALUE);
4388     SET_ERROR_IF(level > ilog2(max_texture_size), GL_INVALID_VALUE);
4389     SET_ERROR_IF(level > ilog2(max_3d_texture_size), GL_INVALID_VALUE);
4390 
4391     SET_ERROR_IF(width < 0 || height < 0 || depth < 0, GL_INVALID_VALUE);
4392     SET_ERROR_IF(width > max_texture_size, GL_INVALID_VALUE);
4393     SET_ERROR_IF(height > max_texture_size, GL_INVALID_VALUE);
4394     if (target == GL_TEXTURE_3D) {
4395         SET_ERROR_IF(depth > max_texture_size, GL_INVALID_VALUE);
4396     } else {
4397         GLint maxArrayTextureLayers;
4398         ctx->glGetIntegerv(ctx, GL_MAX_ARRAY_TEXTURE_LAYERS, &maxArrayTextureLayers);
4399         SET_ERROR_IF(depth > maxArrayTextureLayers, GL_INVALID_VALUE);
4400     }
4401     SET_ERROR_IF(width > max_3d_texture_size, GL_INVALID_VALUE);
4402     SET_ERROR_IF(height > max_3d_texture_size, GL_INVALID_VALUE);
4403     SET_ERROR_IF(depth > max_3d_texture_size, GL_INVALID_VALUE);
4404     SET_ERROR_IF(GLESTextureUtils::isAstcFormat(internalformat) && GL_TEXTURE_3D == target, GL_INVALID_OPERATION);
4405 
4406     // If unpack buffer is nonzero, verify buffer data fits.
4407     SET_ERROR_IF(ctx->boundBuffer(GL_PIXEL_UNPACK_BUFFER) &&
4408                  ctx->getBufferData(GL_PIXEL_UNPACK_BUFFER) &&
4409                  (imageSize > ctx->getBufferData(GL_PIXEL_UNPACK_BUFFER)->m_size),
4410                  GL_INVALID_OPERATION);
4411     SET_ERROR_IF(!ctx->m_state->compressedTexImageSizeCompatible(internalformat, width, height, depth, imageSize), GL_INVALID_VALUE);
4412     state->setBoundTextureInternalFormat(target, (GLint)internalformat);
4413     state->setBoundTextureDims(target, target, level, width, height, depth);
4414 
4415     if (ctx->boundBuffer(GL_PIXEL_UNPACK_BUFFER)) {
4416         ctx->glCompressedTexImage3DOffsetAEMU(
4417                 ctx, target, level, internalformat,
4418                 width, height, depth, border,
4419                 imageSize, (uintptr_t)data);
4420     } else {
4421         ctx->m_glCompressedTexImage3D_enc(
4422                 ctx, target, level, internalformat,
4423                 width, height, depth, border,
4424                 imageSize, data);
4425     }
4426 }
4427 
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)4428 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) {
4429     GL2Encoder* ctx = (GL2Encoder*)self;
4430 
4431     SET_ERROR_IF(!GLESv2Validation::textureTarget(ctx, target), GL_INVALID_ENUM);
4432     SET_ERROR_IF(target == GL_TEXTURE_CUBE_MAP, GL_INVALID_ENUM);
4433     // If unpack buffer is nonzero, verify unmapped state.
4434     SET_ERROR_IF(ctx->isBufferTargetMapped(GL_PIXEL_UNPACK_BUFFER), GL_INVALID_OPERATION);
4435     SET_ERROR_IF(width < 0 || height < 0 || depth < 0, GL_INVALID_VALUE);
4436     // If unpack buffer is nonzero, verify buffer data fits.
4437     SET_ERROR_IF(ctx->boundBuffer(GL_PIXEL_UNPACK_BUFFER) &&
4438                  ctx->getBufferData(GL_PIXEL_UNPACK_BUFFER) &&
4439                  (imageSize > ctx->getBufferData(GL_PIXEL_UNPACK_BUFFER)->m_size),
4440                  GL_INVALID_OPERATION);
4441     SET_ERROR_IF(xoffset < 0 || yoffset < 0 || zoffset < 0, GL_INVALID_VALUE);
4442 
4443     GLint max_texture_size;
4444     GLint max_3d_texture_size;
4445     ctx->glGetIntegerv(ctx, GL_MAX_TEXTURE_SIZE, &max_texture_size);
4446     ctx->glGetIntegerv(ctx, GL_MAX_3D_TEXTURE_SIZE, &max_3d_texture_size);
4447     SET_ERROR_IF(level < 0, GL_INVALID_VALUE);
4448     SET_ERROR_IF(level > ilog2(max_texture_size), GL_INVALID_VALUE);
4449     SET_ERROR_IF(level > ilog2(max_3d_texture_size), GL_INVALID_VALUE);
4450     SET_ERROR_IF(width < 0 || height < 0 || depth < 0, GL_INVALID_VALUE);
4451     SET_ERROR_IF(xoffset < 0 || yoffset < 0 || zoffset < 0, GL_INVALID_VALUE);
4452     GLenum stateTarget = target;
4453     if (target == GL_TEXTURE_CUBE_MAP_POSITIVE_X ||
4454         target == GL_TEXTURE_CUBE_MAP_POSITIVE_Y ||
4455         target == GL_TEXTURE_CUBE_MAP_POSITIVE_Z ||
4456         target == GL_TEXTURE_CUBE_MAP_NEGATIVE_X ||
4457         target == GL_TEXTURE_CUBE_MAP_NEGATIVE_Y ||
4458         target == GL_TEXTURE_CUBE_MAP_NEGATIVE_Z)
4459         stateTarget = GL_TEXTURE_CUBE_MAP;
4460 
4461     GLuint tex = ctx->m_state->getBoundTexture(stateTarget);
4462     GLsizei neededWidth = xoffset + width;
4463     GLsizei neededHeight = yoffset + height;
4464     GLsizei neededDepth = zoffset + depth;
4465 
4466     SET_ERROR_IF(tex &&
4467                  (neededWidth > ctx->m_state->queryTexWidth(level, tex) ||
4468                   neededHeight > ctx->m_state->queryTexHeight(level, tex) ||
4469                   neededDepth > ctx->m_state->queryTexDepth(level, tex)),
4470                  GL_INVALID_VALUE);
4471 
4472     GLint internalFormat = ctx->m_state->queryTexInternalFormat(tex);
4473     SET_ERROR_IF(internalFormat != format, GL_INVALID_OPERATION);
4474 
4475     GLint totalWidth = ctx->m_state->queryTexWidth(level, tex);
4476     GLint totalHeight = ctx->m_state->queryTexHeight(level, tex);
4477 
4478     if (GLESTextureUtils::isEtc2Format(internalFormat)) {
4479         SET_ERROR_IF((width % 4) && (totalWidth != xoffset + width), GL_INVALID_OPERATION);
4480         SET_ERROR_IF((height % 4) && (totalHeight != yoffset + height), GL_INVALID_OPERATION);
4481         SET_ERROR_IF((xoffset % 4) || (yoffset % 4), GL_INVALID_OPERATION);
4482     }
4483 
4484     SET_ERROR_IF(totalWidth < xoffset + width, GL_INVALID_VALUE);
4485     SET_ERROR_IF(totalHeight < yoffset + height, GL_INVALID_VALUE);
4486 
4487     SET_ERROR_IF(!ctx->m_state->compressedTexImageSizeCompatible(internalFormat, width, height, depth, imageSize), GL_INVALID_VALUE);
4488 
4489     if (ctx->boundBuffer(GL_PIXEL_UNPACK_BUFFER)) {
4490         ctx->glCompressedTexSubImage3DOffsetAEMU(
4491                 ctx, target, level,
4492                 xoffset, yoffset, zoffset,
4493                 width, height, depth,
4494                 format, imageSize, (uintptr_t)data);
4495     } else {
4496         ctx->m_glCompressedTexSubImage3D_enc(
4497                 ctx, target, level,
4498                 xoffset, yoffset, zoffset,
4499                 width, height, depth,
4500                 format, imageSize, data);
4501 
4502     }
4503 }
4504 
s_glTexStorage3D(void * self,GLenum target,GLsizei levels,GLenum internalformat,GLsizei width,GLsizei height,GLsizei depth)4505 void GL2Encoder::s_glTexStorage3D(void* self, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth) {
4506     GL2Encoder* ctx = (GL2Encoder*)self;
4507     GLClientState* state = ctx->m_state;
4508     SET_ERROR_IF(target != GL_TEXTURE_3D &&
4509                  target != GL_TEXTURE_2D_ARRAY,
4510                  GL_INVALID_ENUM);
4511     SET_ERROR_IF(!GLESv2Validation::pixelInternalFormat(internalformat), GL_INVALID_ENUM);
4512     SET_ERROR_IF(!state->getBoundTexture(target), GL_INVALID_OPERATION);
4513     SET_ERROR_IF(levels < 1 || width < 1 || height < 1 || depth < 1, GL_INVALID_VALUE);
4514     GLint max_texture_size;
4515     GLint max_3d_texture_size;
4516     ctx->glGetIntegerv(ctx, GL_MAX_TEXTURE_SIZE, &max_texture_size);
4517     ctx->glGetIntegerv(ctx, GL_MAX_3D_TEXTURE_SIZE, &max_3d_texture_size);
4518     SET_ERROR_IF(width > max_texture_size, GL_INVALID_VALUE);
4519     SET_ERROR_IF(height > max_texture_size, GL_INVALID_VALUE);
4520     if (target == GL_TEXTURE_3D) {
4521         SET_ERROR_IF(depth > max_texture_size, GL_INVALID_VALUE);
4522     } else {
4523         GLint maxArrayTextureLayers;
4524         ctx->glGetIntegerv(ctx, GL_MAX_ARRAY_TEXTURE_LAYERS, &maxArrayTextureLayers);
4525         SET_ERROR_IF(depth > maxArrayTextureLayers, GL_INVALID_VALUE);
4526     }
4527 
4528     SET_ERROR_IF(width > max_3d_texture_size, GL_INVALID_VALUE);
4529     SET_ERROR_IF(height > max_3d_texture_size, GL_INVALID_VALUE);
4530     SET_ERROR_IF(depth > max_3d_texture_size, GL_INVALID_VALUE);
4531 
4532     SET_ERROR_IF(GLESTextureUtils::isAstcFormat(internalformat) && GL_TEXTURE_3D == target, GL_INVALID_OPERATION);
4533 
4534     SET_ERROR_IF(target == GL_TEXTURE_3D && (levels > ilog2((uint32_t)std::max(width, std::max(height, depth))) + 1),
4535                  GL_INVALID_OPERATION);
4536     SET_ERROR_IF(target == GL_TEXTURE_2D_ARRAY && (levels > ilog2((uint32_t)std::max(width, height)) + 1),
4537                  GL_INVALID_OPERATION);
4538     SET_ERROR_IF(state->isBoundTextureImmutableFormat(target), GL_INVALID_OPERATION);
4539 
4540     state->setBoundTextureInternalFormat(target, internalformat);
4541     state->setBoundTextureDims(target, target, -1, width, height, depth);
4542     state->setBoundTextureImmutableFormat(target);
4543     ctx->m_glTexStorage3D_enc(ctx, target, levels, internalformat, width, height, depth);
4544     state->setBoundTextureImmutableFormat(target);
4545 }
4546 
s_glDrawArraysInstanced(void * self,GLenum mode,GLint first,GLsizei count,GLsizei primcount)4547 void GL2Encoder::s_glDrawArraysInstanced(void* self, GLenum mode, GLint first, GLsizei count, GLsizei primcount) {
4548     GL2Encoder *ctx = (GL2Encoder *)self;
4549     assert(ctx->m_state != NULL);
4550     SET_ERROR_IF(!isValidDrawMode(mode), GL_INVALID_ENUM);
4551     SET_ERROR_IF(count < 0, GL_INVALID_VALUE);
4552     SET_ERROR_IF(primcount < 0, GL_INVALID_VALUE);
4553     SET_ERROR_IF(ctx->m_state->checkFramebufferCompleteness(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE, GL_INVALID_FRAMEBUFFER_OPERATION);
4554 
4555     bool has_client_vertex_arrays = false;
4556     bool has_indirect_arrays = false;
4557     ctx->getVBOUsage(&has_client_vertex_arrays,
4558                      &has_indirect_arrays);
4559 
4560     if (has_client_vertex_arrays ||
4561         (!has_client_vertex_arrays &&
4562          !has_indirect_arrays)) {
4563         ctx->sendVertexAttributes(first, count, true, primcount);
4564         ctx->m_glDrawArraysInstanced_enc(ctx, mode, 0, count, primcount);
4565     } else {
4566         ctx->sendVertexAttributes(0, count, false, primcount);
4567         ctx->m_glDrawArraysInstanced_enc(ctx, mode, first, count, primcount);
4568     }
4569     ctx->m_stream->flush();
4570     ctx->m_state->postDraw();
4571 }
4572 
s_glDrawElementsInstanced(void * self,GLenum mode,GLsizei count,GLenum type,const void * indices,GLsizei primcount)4573 void GL2Encoder::s_glDrawElementsInstanced(void* self, GLenum mode, GLsizei count, GLenum type, const void* indices, GLsizei primcount)
4574 {
4575 
4576     GL2Encoder *ctx = (GL2Encoder *)self;
4577     assert(ctx->m_state != NULL);
4578     SET_ERROR_IF(!isValidDrawMode(mode), GL_INVALID_ENUM);
4579     SET_ERROR_IF(count < 0, GL_INVALID_VALUE);
4580     SET_ERROR_IF(primcount < 0, GL_INVALID_VALUE);
4581     SET_ERROR_IF(!(type == GL_UNSIGNED_BYTE || type == GL_UNSIGNED_SHORT || type == GL_UNSIGNED_INT), GL_INVALID_ENUM);
4582     SET_ERROR_IF(ctx->m_state->getTransformFeedbackActiveUnpaused(), GL_INVALID_OPERATION);
4583     SET_ERROR_IF(ctx->m_state->checkFramebufferCompleteness(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE, GL_INVALID_FRAMEBUFFER_OPERATION);
4584 
4585     bool has_client_vertex_arrays = false;
4586     bool has_indirect_arrays = false;
4587     GLintptr offset = 0;
4588 
4589     ctx->getVBOUsage(&has_client_vertex_arrays, &has_indirect_arrays);
4590 
4591     if (!has_client_vertex_arrays && !has_indirect_arrays) {
4592         // ALOGW("glDrawElements: no vertex arrays / buffers bound to the command\n");
4593         GLenum status = ctx->glCheckFramebufferStatus(self, GL_FRAMEBUFFER);
4594         SET_ERROR_IF(status != GL_FRAMEBUFFER_COMPLETE, GL_INVALID_FRAMEBUFFER_OPERATION);
4595     }
4596 
4597     BufferData* buf = NULL;
4598     int minIndex = 0, maxIndex = 0;
4599 
4600     // For validation/immediate index array purposes,
4601     // we need the min/max vertex index of the index array.
4602     // If the VBO != 0, this may not be the first time we have
4603     // used this particular index buffer. getBufferIndexRange
4604     // can more quickly get min/max vertex index by
4605     // caching previous results.
4606     if (ctx->m_state->currentIndexVbo() != 0) {
4607         buf = ctx->m_shared->getBufferData(ctx->m_state->currentIndexVbo());
4608         offset = (GLintptr)indices;
4609         indices = &buf->m_fixedBuffer[offset];
4610         ctx->getBufferIndexRange(buf,
4611                                  indices,
4612                                  type,
4613                                  (size_t)count,
4614                                  (size_t)offset,
4615                                  &minIndex, &maxIndex);
4616     } else {
4617         // In this case, the |indices| field holds a real
4618         // array, so calculate the indices now. They will
4619         // also be needed to know how much data to
4620         // transfer to host.
4621         ctx->calcIndexRange(indices,
4622                             type,
4623                             count,
4624                             &minIndex,
4625                             &maxIndex);
4626     }
4627 
4628     if (count == 0) return;
4629 
4630     bool adjustIndices = true;
4631     if (ctx->m_state->currentIndexVbo() != 0) {
4632         if (!has_client_vertex_arrays) {
4633             ctx->sendVertexAttributes(0, maxIndex + 1, false, primcount);
4634             ctx->doBindBufferEncodeCached(GL_ELEMENT_ARRAY_BUFFER, ctx->m_state->currentIndexVbo());
4635             ctx->glDrawElementsInstancedOffsetAEMU(ctx, mode, count, type, offset, primcount);
4636             ctx->flushDrawCall();
4637             adjustIndices = false;
4638         } else {
4639             ctx->doBindBufferEncodeCached(GL_ELEMENT_ARRAY_BUFFER, 0);
4640         }
4641     }
4642     if (adjustIndices) {
4643         void *adjustedIndices =
4644             ctx->recenterIndices(indices,
4645                                  type,
4646                                  count,
4647                                  minIndex);
4648 
4649         if (has_indirect_arrays || 1) {
4650             ctx->sendVertexAttributes(minIndex, maxIndex - minIndex + 1, true, primcount);
4651             ctx->glDrawElementsInstancedDataAEMU(ctx, mode, count, type, adjustedIndices, primcount, count * glSizeof(type));
4652             ctx->m_stream->flush();
4653             // XXX - OPTIMIZATION (see the other else branch) should be implemented
4654             if(!has_indirect_arrays) {
4655                 //ALOGD("unoptimized drawelements !!!\n");
4656             }
4657         } else {
4658             // we are all direct arrays and immidate mode index array -
4659             // rebuild the arrays and the index array;
4660             ALOGE("glDrawElements: direct index & direct buffer data - will be implemented in later versions;\n");
4661         }
4662     }
4663     ctx->m_state->postDraw();
4664 }
4665 
s_glDrawRangeElements(void * self,GLenum mode,GLuint start,GLuint end,GLsizei count,GLenum type,const void * indices)4666 void GL2Encoder::s_glDrawRangeElements(void* self, GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void* indices)
4667 {
4668 
4669     GL2Encoder *ctx = (GL2Encoder *)self;
4670     assert(ctx->m_state != NULL);
4671     SET_ERROR_IF(!isValidDrawMode(mode), GL_INVALID_ENUM);
4672     SET_ERROR_IF(end < start, GL_INVALID_VALUE);
4673     SET_ERROR_IF(count < 0, GL_INVALID_VALUE);
4674     SET_ERROR_IF(!(type == GL_UNSIGNED_BYTE || type == GL_UNSIGNED_SHORT || type == GL_UNSIGNED_INT), GL_INVALID_ENUM);
4675     SET_ERROR_IF(ctx->m_state->getTransformFeedbackActiveUnpaused(), GL_INVALID_OPERATION);
4676     SET_ERROR_IF(ctx->m_state->checkFramebufferCompleteness(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE, GL_INVALID_FRAMEBUFFER_OPERATION);
4677 
4678     bool has_client_vertex_arrays = false;
4679     bool has_indirect_arrays = false;
4680     GLintptr offset = 0;
4681 
4682     ctx->getVBOUsage(&has_client_vertex_arrays, &has_indirect_arrays);
4683 
4684     if (!has_client_vertex_arrays && !has_indirect_arrays) {
4685         // ALOGW("glDrawElements: no vertex arrays / buffers bound to the command\n");
4686         GLenum status = ctx->glCheckFramebufferStatus(self, GL_FRAMEBUFFER);
4687         SET_ERROR_IF(status != GL_FRAMEBUFFER_COMPLETE, GL_INVALID_FRAMEBUFFER_OPERATION);
4688     }
4689 
4690     BufferData* buf = NULL;
4691     int minIndex = 0, maxIndex = 0;
4692 
4693     // For validation/immediate index array purposes,
4694     // we need the min/max vertex index of the index array.
4695     // If the VBO != 0, this may not be the first time we have
4696     // used this particular index buffer. getBufferIndexRange
4697     // can more quickly get min/max vertex index by
4698     // caching previous results.
4699     if (ctx->m_state->currentIndexVbo() != 0) {
4700         buf = ctx->m_shared->getBufferData(ctx->m_state->currentIndexVbo());
4701         ALOGV("%s: current index vbo: %p len %zu count %zu\n", __func__, buf, buf->m_fixedBuffer.size(), (size_t)count);
4702         offset = (GLintptr)indices;
4703         void* oldIndices = (void*)indices;
4704         indices = &buf->m_fixedBuffer[offset];
4705         ALOGV("%s: indices arg: %p buffer start: %p indices: %p\n", __func__,
4706                 (void*)(uintptr_t)(oldIndices),
4707                 buf->m_fixedBuffer.data(),
4708                 indices);
4709         ctx->getBufferIndexRange(buf,
4710                                  indices,
4711                                  type,
4712                                  (size_t)count,
4713                                  (size_t)offset,
4714                                  &minIndex, &maxIndex);
4715     } else {
4716         // In this case, the |indices| field holds a real
4717         // array, so calculate the indices now. They will
4718         // also be needed to know how much data to
4719         // transfer to host.
4720         ctx->calcIndexRange(indices,
4721                             type,
4722                             count,
4723                             &minIndex,
4724                             &maxIndex);
4725     }
4726 
4727     if (count == 0) return;
4728 
4729     bool adjustIndices = true;
4730     if (ctx->m_state->currentIndexVbo() != 0) {
4731         if (!has_client_vertex_arrays) {
4732             ctx->sendVertexAttributes(0, maxIndex + 1, false);
4733             ctx->doBindBufferEncodeCached(GL_ELEMENT_ARRAY_BUFFER, ctx->m_state->currentIndexVbo());
4734             ctx->glDrawElementsOffset(ctx, mode, count, type, offset);
4735             ctx->flushDrawCall();
4736             adjustIndices = false;
4737         } else {
4738             ctx->doBindBufferEncodeCached(GL_ELEMENT_ARRAY_BUFFER, 0);
4739         }
4740     }
4741     if (adjustIndices) {
4742         void *adjustedIndices =
4743             ctx->recenterIndices(indices,
4744                                  type,
4745                                  count,
4746                                  minIndex);
4747 
4748         if (has_indirect_arrays || 1) {
4749             ctx->sendVertexAttributes(minIndex, maxIndex - minIndex + 1, true);
4750             ctx->glDrawElementsData(ctx, mode, count, type, adjustedIndices, count * glSizeof(type));
4751             ctx->m_stream->flush();
4752             // XXX - OPTIMIZATION (see the other else branch) should be implemented
4753             if(!has_indirect_arrays) {
4754                 //ALOGD("unoptimized drawelements !!!\n");
4755             }
4756         } else {
4757             // we are all direct arrays and immidate mode index array -
4758             // rebuild the arrays and the index array;
4759             ALOGE("glDrawElements: direct index & direct buffer data - will be implemented in later versions;\n");
4760         }
4761     }
4762     ctx->m_state->postDraw();
4763 }
4764 
s_glGetStringi(void * self,GLenum name,GLuint index)4765 const GLubyte* GL2Encoder::s_glGetStringi(void* self, GLenum name, GLuint index) {
4766     GL2Encoder *ctx = (GL2Encoder *)self;
4767     const GLubyte *retval =  (GLubyte *) "";
4768 
4769     RET_AND_SET_ERROR_IF(
4770         name != GL_VENDOR &&
4771         name != GL_RENDERER &&
4772         name != GL_VERSION &&
4773         name != GL_EXTENSIONS,
4774         GL_INVALID_ENUM,
4775         retval);
4776 
4777     RET_AND_SET_ERROR_IF(
4778         (name == GL_VENDOR ||
4779          name == GL_RENDERER ||
4780          name == GL_VERSION) &&
4781         index != 0,
4782         GL_INVALID_VALUE,
4783         retval);
4784 
4785     RET_AND_SET_ERROR_IF(
4786         name == GL_EXTENSIONS &&
4787         index >= ctx->m_currExtensionsArray.size(),
4788         GL_INVALID_VALUE,
4789         retval);
4790 
4791     switch (name) {
4792     case GL_VENDOR:
4793         retval = gVendorString;
4794         break;
4795     case GL_RENDERER:
4796         retval = gRendererString;
4797         break;
4798     case GL_VERSION:
4799         retval = gVersionString;
4800         break;
4801     case GL_EXTENSIONS:
4802         retval = (const GLubyte*)(ctx->m_currExtensionsArray[index].c_str());
4803         break;
4804     }
4805 
4806     return retval;
4807 }
4808 
s_glGetProgramBinary(void * self,GLuint program,GLsizei bufSize,GLsizei * length,GLenum * binaryFormat,void * binary)4809 void GL2Encoder::s_glGetProgramBinary(void* self, GLuint program, GLsizei bufSize, GLsizei* length, GLenum* binaryFormat, void* binary) {
4810     GL2Encoder *ctx = (GL2Encoder *)self;
4811 
4812     VALIDATE_PROGRAM_NAME(program);
4813 
4814     GLint linkStatus = 0;
4815     ctx->m_glGetProgramiv_enc(self, program, GL_LINK_STATUS, &linkStatus);
4816     GLint properLength = 0;
4817     ctx->m_glGetProgramiv_enc(self, program, GL_PROGRAM_BINARY_LENGTH, &properLength);
4818 
4819     SET_ERROR_IF(!linkStatus, GL_INVALID_OPERATION);
4820     SET_ERROR_IF(bufSize < properLength, GL_INVALID_OPERATION);
4821 
4822     ctx->m_glGetProgramBinary_enc(ctx, program, bufSize, length, binaryFormat, binary);
4823 }
4824 
s_glReadPixels(void * self,GLint x,GLint y,GLsizei width,GLsizei height,GLenum format,GLenum type,GLvoid * pixels)4825 void GL2Encoder::s_glReadPixels(void* self, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels) {
4826     GL2Encoder *ctx = (GL2Encoder *)self;
4827 
4828     SET_ERROR_IF(!GLESv2Validation::readPixelsFormat(format), GL_INVALID_ENUM);
4829     SET_ERROR_IF(!GLESv2Validation::readPixelsType(type), GL_INVALID_ENUM);
4830     SET_ERROR_IF(!(GLESv2Validation::pixelOp(format,type)),GL_INVALID_OPERATION);
4831     SET_ERROR_IF(width < 0 || height < 0, GL_INVALID_VALUE);
4832     SET_ERROR_IF(ctx->isBufferTargetMapped(GL_PIXEL_PACK_BUFFER), GL_INVALID_OPERATION);
4833     SET_ERROR_IF(ctx->boundBuffer(GL_PIXEL_PACK_BUFFER) &&
4834                  ctx->getBufferData(GL_PIXEL_PACK_BUFFER) &&
4835                  (ctx->m_state->pboNeededDataSize(width, height, 1, format, type, 1) >
4836                   ctx->getBufferData(GL_PIXEL_PACK_BUFFER)->m_size),
4837                  GL_INVALID_OPERATION);
4838     SET_ERROR_IF(ctx->s_glCheckFramebufferStatus(ctx, GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE, GL_INVALID_FRAMEBUFFER_OPERATION);
4839 
4840     // now is complete
4841     // GL_INVALID_OPERATION is generated if GL_READ_FRAMEBUFFER_BINDING is nonzero, the read fbo is complete, and the value of
4842     // GL_SAMPLE_BUFFERS for the read framebuffer is greater than zero
4843     if (ctx->m_state->boundFramebuffer(GL_READ_FRAMEBUFFER) &&
4844         ctx->s_glCheckFramebufferStatus(ctx, GL_READ_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE) {
4845         FboFormatInfo resInfo;
4846         ctx->m_state->getBoundFramebufferFormat(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, &resInfo);
4847         if (resInfo.type == FBO_ATTACHMENT_RENDERBUFFER) {
4848             SET_ERROR_IF(resInfo.rb_multisamples > 0, GL_INVALID_OPERATION);
4849         }
4850         if (resInfo.type == FBO_ATTACHMENT_TEXTURE) {
4851             SET_ERROR_IF(resInfo.tex_multisamples > 0, GL_INVALID_OPERATION);
4852         }
4853     }
4854 
4855 
4856     /*
4857 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.
4858 
4859 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.
4860 
4861 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.
4862 
4863 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.
4864 */
4865 
4866     FboFormatInfo fbo_format_info;
4867     ctx->m_state->getBoundFramebufferFormat(
4868             GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, &fbo_format_info);
4869     SET_ERROR_IF(
4870         fbo_format_info.type == FBO_ATTACHMENT_TEXTURE &&
4871         !GLESv2Validation::readPixelsFboFormatMatch(
4872             format, type, fbo_format_info.tex_type),
4873         GL_INVALID_OPERATION);
4874 
4875     if (ctx->boundBuffer(GL_PIXEL_PACK_BUFFER)) {
4876         ctx->glReadPixelsOffsetAEMU(
4877                 ctx, x, y, width, height,
4878                 format, type, (uintptr_t)pixels);
4879     } else {
4880         ctx->m_glReadPixels_enc(
4881                 ctx, x, y, width, height,
4882                 format, type, pixels);
4883     }
4884     ctx->m_state->postReadPixels();
4885 }
4886 
4887 // Track enabled state for some things like:
4888 // - Primitive restart
s_glEnable(void * self,GLenum what)4889 void GL2Encoder::s_glEnable(void* self, GLenum what) {
4890     GL2Encoder *ctx = (GL2Encoder *)self;
4891 
4892 	SET_ERROR_IF(!GLESv2Validation::allowedEnable(ctx->majorVersion(), ctx->minorVersion(), what), GL_INVALID_ENUM);
4893     if (!ctx->m_state) return;
4894 
4895     switch (what) {
4896     case GL_PRIMITIVE_RESTART_FIXED_INDEX:
4897         ctx->m_primitiveRestartEnabled = true;
4898         break;
4899     case GL_STENCIL_TEST:
4900         ctx->m_state->state_GL_STENCIL_TEST = true;
4901         break;
4902     }
4903 
4904     ctx->m_glEnable_enc(ctx, what);
4905 }
4906 
s_glDisable(void * self,GLenum what)4907 void GL2Encoder::s_glDisable(void* self, GLenum what) {
4908     GL2Encoder *ctx = (GL2Encoder *)self;
4909 
4910 	SET_ERROR_IF(!GLESv2Validation::allowedEnable(ctx->majorVersion(), ctx->minorVersion(), what), GL_INVALID_ENUM);
4911     if (!ctx->m_state) return;
4912 
4913     switch (what) {
4914     case GL_PRIMITIVE_RESTART_FIXED_INDEX:
4915         ctx->m_primitiveRestartEnabled = false;
4916         break;
4917     case GL_STENCIL_TEST:
4918         ctx->m_state->state_GL_STENCIL_TEST = false;
4919         break;
4920     }
4921 
4922     ctx->m_glDisable_enc(ctx, what);
4923 }
4924 
s_glClearBufferiv(void * self,GLenum buffer,GLint drawBuffer,const GLint * value)4925 void GL2Encoder::s_glClearBufferiv(void* self, GLenum buffer, GLint drawBuffer, const GLint * value) {
4926     GL2Encoder *ctx = (GL2Encoder *)self;
4927 
4928     SET_ERROR_IF(buffer != GL_COLOR && buffer != GL_STENCIL, GL_INVALID_ENUM);
4929 
4930     GLint maxDrawBuffers;
4931     ctx->glGetIntegerv(ctx, GL_MAX_DRAW_BUFFERS, &maxDrawBuffers);
4932 
4933     SET_ERROR_IF(!value, GL_INVALID_VALUE);
4934 
4935     if (buffer == GL_COLOR) {
4936         SET_ERROR_IF(drawBuffer < 0 || drawBuffer>= maxDrawBuffers, GL_INVALID_VALUE);
4937     } else {
4938         SET_ERROR_IF(drawBuffer != 0, GL_INVALID_VALUE);
4939     }
4940 
4941     ctx->m_glClearBufferiv_enc(ctx, buffer, drawBuffer, value);
4942 }
4943 
s_glClearBufferuiv(void * self,GLenum buffer,GLint drawBuffer,const GLuint * value)4944 void GL2Encoder::s_glClearBufferuiv(void* self, GLenum buffer, GLint drawBuffer, const GLuint * value) {
4945     GL2Encoder *ctx = (GL2Encoder *)self;
4946 
4947     SET_ERROR_IF(buffer != GL_COLOR, GL_INVALID_ENUM);
4948     SET_ERROR_IF(!value, GL_INVALID_VALUE);
4949 
4950     GLint maxDrawBuffers;
4951     ctx->glGetIntegerv(ctx, GL_MAX_DRAW_BUFFERS, &maxDrawBuffers);
4952     SET_ERROR_IF(drawBuffer < 0 || drawBuffer>= maxDrawBuffers, GL_INVALID_VALUE);
4953 
4954     ctx->m_glClearBufferuiv_enc(ctx, buffer, drawBuffer, value);
4955 }
4956 
s_glClearBufferfv(void * self,GLenum buffer,GLint drawBuffer,const GLfloat * value)4957 void GL2Encoder::s_glClearBufferfv(void* self, GLenum buffer, GLint drawBuffer, const GLfloat * value) {
4958     GL2Encoder *ctx = (GL2Encoder *)self;
4959 
4960     SET_ERROR_IF(buffer != GL_COLOR && buffer != GL_DEPTH, GL_INVALID_ENUM);
4961 
4962     SET_ERROR_IF(!value, GL_INVALID_VALUE);
4963 
4964     GLint maxDrawBuffers;
4965     ctx->glGetIntegerv(ctx, GL_MAX_DRAW_BUFFERS, &maxDrawBuffers);
4966 
4967     if (buffer == GL_COLOR) {
4968         SET_ERROR_IF(drawBuffer < 0 || drawBuffer>= maxDrawBuffers, GL_INVALID_VALUE);
4969     } else {
4970         SET_ERROR_IF(drawBuffer != 0, GL_INVALID_VALUE);
4971     }
4972 
4973     ctx->m_glClearBufferfv_enc(ctx, buffer, drawBuffer, value);
4974 }
4975 
s_glClearBufferfi(void * self,GLenum buffer,GLint drawBuffer,float depth,int stencil)4976 void GL2Encoder::s_glClearBufferfi(void* self, GLenum buffer, GLint drawBuffer, float depth, int stencil) {
4977     GL2Encoder *ctx = (GL2Encoder *)self;
4978 
4979     SET_ERROR_IF(buffer != GL_DEPTH_STENCIL, GL_INVALID_ENUM);
4980     SET_ERROR_IF(drawBuffer != 0, GL_INVALID_VALUE);
4981 
4982     ctx->m_glClearBufferfi_enc(ctx, buffer, drawBuffer, depth, stencil);
4983 }
4984 
s_glBlitFramebuffer(void * self,GLint srcX0,GLint srcY0,GLint srcX1,GLint srcY1,GLint dstX0,GLint dstY0,GLint dstX1,GLint dstY1,GLbitfield mask,GLenum filter)4985 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) {
4986     GL2Encoder *ctx = (GL2Encoder *)self;
4987     GLClientState* state = ctx->m_state;
4988 
4989     bool validateColor = mask & GL_COLOR_BUFFER_BIT;
4990     bool validateDepth = mask & GL_DEPTH_BUFFER_BIT;
4991     bool validateStencil = mask & GL_STENCIL_BUFFER_BIT;
4992     bool validateDepthOrStencil = validateDepth || validateStencil;
4993 
4994     FboFormatInfo read_fbo_format_info;
4995     FboFormatInfo draw_fbo_format_info;
4996     if (validateColor) {
4997         state->getBoundFramebufferFormat(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, &read_fbo_format_info);
4998         state->getBoundFramebufferFormat(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, &draw_fbo_format_info);
4999 
5000         if (read_fbo_format_info.type == FBO_ATTACHMENT_TEXTURE) {
5001             SET_ERROR_IF(
5002                 GL_LINEAR == filter &&
5003                 GLESv2Validation::isIntegerFormat(read_fbo_format_info.tex_format),
5004                     GL_INVALID_OPERATION);
5005         }
5006 
5007         if (read_fbo_format_info.type == FBO_ATTACHMENT_TEXTURE &&
5008             draw_fbo_format_info.type == FBO_ATTACHMENT_TEXTURE) {
5009             SET_ERROR_IF(
5010                     state->boundFramebuffer(GL_READ_FRAMEBUFFER) &&
5011                     state->boundFramebuffer(GL_DRAW_FRAMEBUFFER) &&
5012                     !GLESv2Validation::blitFramebufferFormat(
5013                         read_fbo_format_info.tex_type,
5014                         draw_fbo_format_info.tex_type),
5015                     GL_INVALID_OPERATION);
5016         }
5017     }
5018 
5019     if (validateDepth) {
5020         state->getBoundFramebufferFormat(GL_READ_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, &read_fbo_format_info);
5021         state->getBoundFramebufferFormat(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, &draw_fbo_format_info);
5022 
5023         if (read_fbo_format_info.type == FBO_ATTACHMENT_RENDERBUFFER &&
5024             draw_fbo_format_info.type == FBO_ATTACHMENT_RENDERBUFFER) {
5025             SET_ERROR_IF(
5026                     state->boundFramebuffer(GL_READ_FRAMEBUFFER) &&
5027                     state->boundFramebuffer(GL_DRAW_FRAMEBUFFER) &&
5028                     !GLESv2Validation::blitFramebufferFormat(
5029                         read_fbo_format_info.rb_format,
5030                         draw_fbo_format_info.rb_format),
5031                     GL_INVALID_OPERATION);
5032         }
5033     }
5034 
5035     if (validateStencil) {
5036         state->getBoundFramebufferFormat(GL_READ_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, &read_fbo_format_info);
5037         state->getBoundFramebufferFormat(GL_DRAW_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, &draw_fbo_format_info);
5038 
5039         if (read_fbo_format_info.type == FBO_ATTACHMENT_RENDERBUFFER &&
5040             draw_fbo_format_info.type == FBO_ATTACHMENT_RENDERBUFFER) {
5041             SET_ERROR_IF(
5042                     state->boundFramebuffer(GL_READ_FRAMEBUFFER) &&
5043                     state->boundFramebuffer(GL_DRAW_FRAMEBUFFER) &&
5044                     !GLESv2Validation::blitFramebufferFormat(
5045                         read_fbo_format_info.rb_format,
5046                         draw_fbo_format_info.rb_format),
5047                     GL_INVALID_OPERATION);
5048         }
5049     }
5050 
5051     if (validateDepthOrStencil) {
5052         SET_ERROR_IF(filter != GL_NEAREST, GL_INVALID_OPERATION);
5053     }
5054 
5055     state->getBoundFramebufferFormat(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, &draw_fbo_format_info);
5056     SET_ERROR_IF(
5057             draw_fbo_format_info.type == FBO_ATTACHMENT_RENDERBUFFER &&
5058             draw_fbo_format_info.rb_multisamples > 0,
5059             GL_INVALID_OPERATION);
5060     SET_ERROR_IF(
5061             draw_fbo_format_info.type == FBO_ATTACHMENT_TEXTURE &&
5062             draw_fbo_format_info.tex_multisamples > 0,
5063             GL_INVALID_OPERATION);
5064 
5065     state->getBoundFramebufferFormat(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, &read_fbo_format_info);
5066     SET_ERROR_IF(
5067             read_fbo_format_info.type == FBO_ATTACHMENT_RENDERBUFFER &&
5068             read_fbo_format_info.rb_multisamples > 0 &&
5069             draw_fbo_format_info.type == FBO_ATTACHMENT_RENDERBUFFER &&
5070             state->boundFramebuffer(GL_READ_FRAMEBUFFER) &&
5071             state->boundFramebuffer(GL_DRAW_FRAMEBUFFER) &&
5072             (read_fbo_format_info.rb_format !=
5073              draw_fbo_format_info.rb_format),
5074             GL_INVALID_OPERATION);
5075     SET_ERROR_IF(
5076             read_fbo_format_info.type == FBO_ATTACHMENT_RENDERBUFFER &&
5077             read_fbo_format_info.rb_multisamples > 0 &&
5078             draw_fbo_format_info.type == FBO_ATTACHMENT_RENDERBUFFER &&
5079             (srcX0 != dstX0 || srcY0 != dstY0 ||
5080              srcX1 != dstX1 || srcY1 != dstY1),
5081             GL_INVALID_OPERATION);
5082 
5083 	ctx->m_glBlitFramebuffer_enc(ctx,
5084             srcX0, srcY0, srcX1, srcY1,
5085             dstX0, dstY0, dstX1, dstY1,
5086             mask, filter);
5087 }
5088 
s_glGetInternalformativ(void * self,GLenum target,GLenum internalformat,GLenum pname,GLsizei bufSize,GLint * params)5089 void GL2Encoder::s_glGetInternalformativ(void* self, GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint *params) {
5090     GL2Encoder *ctx = (GL2Encoder *)self;
5091 
5092     SET_ERROR_IF(pname != GL_NUM_SAMPLE_COUNTS &&
5093                  pname != GL_SAMPLES,
5094                  GL_INVALID_ENUM);
5095     SET_ERROR_IF(!GLESv2Validation::internalFormatTarget(ctx, target), GL_INVALID_ENUM);
5096     SET_ERROR_IF(!GLESv2Validation::unsizedFormat(internalformat) &&
5097                  !GLESv2Validation::colorRenderableFormat(ctx, internalformat) &&
5098                  !GLESv2Validation::depthRenderableFormat(ctx, internalformat) &&
5099                  !GLESv2Validation::stencilRenderableFormat(ctx, internalformat),
5100                  GL_INVALID_ENUM);
5101     SET_ERROR_IF(bufSize < 0, GL_INVALID_VALUE);
5102 
5103     if (bufSize < 1) return;
5104 
5105     // Desktop OpenGL can allow a mindboggling # samples per pixel (such as 64).
5106     // Limit to 4 (spec minimum) to keep dEQP tests from timing out.
5107     switch (pname) {
5108         case GL_NUM_SAMPLE_COUNTS:
5109             *params = 3;
5110             break;
5111         case GL_SAMPLES:
5112             params[0] = 4;
5113             if (bufSize > 1) params[1] = 2;
5114             if (bufSize > 2) params[2] = 1;
5115             break;
5116         default:
5117             break;
5118     }
5119 }
5120 
s_glGenerateMipmap(void * self,GLenum target)5121 void GL2Encoder::s_glGenerateMipmap(void* self, GLenum target) {
5122     GL2Encoder *ctx = (GL2Encoder *)self;
5123     GLClientState* state = ctx->m_state;
5124 
5125     SET_ERROR_IF(target != GL_TEXTURE_2D &&
5126                  target != GL_TEXTURE_3D &&
5127                  target != GL_TEXTURE_CUBE_MAP &&
5128                  target != GL_TEXTURE_2D_ARRAY,
5129                  GL_INVALID_ENUM);
5130 
5131     GLuint tex = state->getBoundTexture(target);
5132     GLenum internalformat = state->queryTexInternalFormat(tex);
5133 
5134     SET_ERROR_IF(tex && GLESv2Validation::isCompressedFormat(internalformat),
5135                  GL_INVALID_OPERATION);
5136     SET_ERROR_IF(tex &&
5137                  !GLESv2Validation::unsizedFormat(internalformat) &&
5138                  !(GLESv2Validation::colorRenderableFormat(ctx, internalformat) &&
5139                    GLESv2Validation::filterableTexFormat(ctx, internalformat)),
5140                  GL_INVALID_OPERATION);
5141 
5142     GLenum stateTarget = target;
5143     if (target == GL_TEXTURE_CUBE_MAP_POSITIVE_X ||
5144         target == GL_TEXTURE_CUBE_MAP_POSITIVE_Y ||
5145         target == GL_TEXTURE_CUBE_MAP_POSITIVE_Z ||
5146         target == GL_TEXTURE_CUBE_MAP_NEGATIVE_X ||
5147         target == GL_TEXTURE_CUBE_MAP_NEGATIVE_Y ||
5148         target == GL_TEXTURE_CUBE_MAP_NEGATIVE_Z)
5149         stateTarget = GL_TEXTURE_CUBE_MAP;
5150 
5151     SET_ERROR_IF(!ctx->m_state->isBoundTextureComplete(stateTarget), GL_INVALID_OPERATION);
5152 
5153     if (target == GL_TEXTURE_2D) {
5154         ctx->override2DTextureTarget(target);
5155     }
5156 
5157     ctx->m_glGenerateMipmap_enc(ctx, target);
5158 
5159     if (target == GL_TEXTURE_2D) {
5160         ctx->restore2DTextureTarget(target);
5161     }
5162 }
5163 
s_glBindSampler(void * self,GLuint unit,GLuint sampler)5164 void GL2Encoder::s_glBindSampler(void* self, GLuint unit, GLuint sampler) {
5165     GL2Encoder *ctx = (GL2Encoder *)self;
5166     GLint maxCombinedUnits;
5167     ctx->glGetIntegerv(ctx, GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &maxCombinedUnits);
5168     SET_ERROR_IF(unit >= maxCombinedUnits, GL_INVALID_VALUE);
5169     SET_ERROR_IF(!ctx->m_state->samplerExists(sampler), GL_INVALID_OPERATION);
5170     if (ctx->m_state->isSamplerBindNoOp(unit, sampler)) return;
5171     ctx->m_glBindSampler_enc(ctx, unit, sampler);
5172     ctx->m_state->bindSampler(unit, sampler);
5173 }
5174 
s_glDeleteSamplers(void * self,GLsizei n,const GLuint * samplers)5175 void GL2Encoder::s_glDeleteSamplers(void* self, GLsizei n, const GLuint* samplers) {
5176     GL2Encoder *ctx = (GL2Encoder *)self;
5177     ctx->m_state->onDeleteSamplers(n, samplers);
5178     ctx->m_state->setExistence(GLClientState::ObjectType::Sampler, false, n, samplers);
5179     ctx->m_glDeleteSamplers_enc(ctx, n, samplers);
5180 }
5181 
s_glFenceSync(void * self,GLenum condition,GLbitfield flags)5182 GLsync GL2Encoder::s_glFenceSync(void* self, GLenum condition, GLbitfield flags) {
5183     GL2Encoder *ctx = (GL2Encoder *)self;
5184     RET_AND_SET_ERROR_IF(condition != GL_SYNC_GPU_COMMANDS_COMPLETE, GL_INVALID_ENUM, 0);
5185     RET_AND_SET_ERROR_IF(flags != 0, GL_INVALID_VALUE, 0);
5186     uint64_t syncHandle = ctx->glFenceSyncAEMU(ctx, condition, flags);
5187 
5188     GLsync res = (GLsync)(uintptr_t)syncHandle;
5189     GLClientState::onFenceCreated(res);
5190     return res;
5191 }
5192 
s_glClientWaitSync(void * self,GLsync wait_on,GLbitfield flags,GLuint64 timeout)5193 GLenum GL2Encoder::s_glClientWaitSync(void* self, GLsync wait_on, GLbitfield flags, GLuint64 timeout) {
5194     GL2Encoder *ctx = (GL2Encoder *)self;
5195     RET_AND_SET_ERROR_IF(!GLClientState::fenceExists(wait_on), GL_INVALID_VALUE, GL_WAIT_FAILED);
5196     RET_AND_SET_ERROR_IF(flags && !(flags & GL_SYNC_FLUSH_COMMANDS_BIT), GL_INVALID_VALUE, GL_WAIT_FAILED);
5197     return ctx->glClientWaitSyncAEMU(ctx, (uint64_t)(uintptr_t)wait_on, flags, timeout);
5198 }
5199 
s_glWaitSync(void * self,GLsync wait_on,GLbitfield flags,GLuint64 timeout)5200 void GL2Encoder::s_glWaitSync(void* self, GLsync wait_on, GLbitfield flags, GLuint64 timeout) {
5201     GL2Encoder *ctx = (GL2Encoder *)self;
5202     SET_ERROR_IF(flags != 0, GL_INVALID_VALUE);
5203     SET_ERROR_IF(timeout != GL_TIMEOUT_IGNORED, GL_INVALID_VALUE);
5204     SET_ERROR_IF(!GLClientState::fenceExists(wait_on), GL_INVALID_VALUE);
5205     ctx->glWaitSyncAEMU(ctx, (uint64_t)(uintptr_t)wait_on, flags, timeout);
5206 }
5207 
s_glDeleteSync(void * self,GLsync sync)5208 void GL2Encoder::s_glDeleteSync(void* self, GLsync sync) {
5209     GL2Encoder *ctx = (GL2Encoder *)self;
5210 
5211     if (!sync) return;
5212 
5213     SET_ERROR_IF(!GLClientState::fenceExists(sync), GL_INVALID_VALUE);
5214     GLClientState::onFenceDestroyed(sync);
5215     ctx->glDeleteSyncAEMU(ctx, (uint64_t)(uintptr_t)sync);
5216 }
5217 
s_glIsSync(void * self,GLsync sync)5218 GLboolean GL2Encoder::s_glIsSync(void* self, GLsync sync) {
5219     GL2Encoder *ctx = (GL2Encoder *)self;
5220     return ctx->glIsSyncAEMU(ctx, (uint64_t)(uintptr_t)sync);
5221 }
5222 
s_glGetSynciv(void * self,GLsync sync,GLenum pname,GLsizei bufSize,GLsizei * length,GLint * values)5223 void GL2Encoder::s_glGetSynciv(void* self, GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values) {
5224     GL2Encoder *ctx = (GL2Encoder *)self;
5225 
5226     SET_ERROR_IF(!GLESv2Validation::allowedGetSyncParam(pname), GL_INVALID_ENUM);
5227     SET_ERROR_IF(bufSize < 0, GL_INVALID_VALUE);
5228     SET_ERROR_IF(!GLClientState::fenceExists(sync), GL_INVALID_VALUE);
5229 
5230     return ctx->glGetSyncivAEMU(ctx, (uint64_t)(uintptr_t)sync, pname, bufSize, length, values);
5231 }
5232 
5233 #define LIMIT_CASE(target, lim) \
5234     case target: \
5235         ctx->glGetIntegerv(ctx, lim, &limit); \
5236         SET_ERROR_IF(index < 0 || index >= limit, GL_INVALID_VALUE); \
5237         break; \
5238 
s_glGetIntegeri_v(void * self,GLenum target,GLuint index,GLint * params)5239 void GL2Encoder::s_glGetIntegeri_v(void* self, GLenum target, GLuint index, GLint* params) {
5240     GL2Encoder *ctx = (GL2Encoder *)self;
5241     GLClientState* state = ctx->m_state;
5242 
5243     GLint limit;
5244 
5245     switch (target) {
5246     LIMIT_CASE(GL_TRANSFORM_FEEDBACK_BUFFER_BINDING, GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS)
5247     LIMIT_CASE(GL_UNIFORM_BUFFER_BINDING, GL_MAX_UNIFORM_BUFFER_BINDINGS)
5248     LIMIT_CASE(GL_ATOMIC_COUNTER_BUFFER_BINDING, GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS)
5249     LIMIT_CASE(GL_SHADER_STORAGE_BUFFER_BINDING, GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS)
5250     default:
5251         break;
5252     }
5253 
5254     const GLClientState::VertexAttribBindingVector& currBindings =
5255         state->currentVertexBufferBindings();
5256 
5257     switch (target) {
5258     case GL_VERTEX_BINDING_DIVISOR:
5259     case GL_VERTEX_BINDING_OFFSET:
5260     case GL_VERTEX_BINDING_STRIDE:
5261     case GL_VERTEX_BINDING_BUFFER:
5262         SET_ERROR_IF(index < 0 || index > currBindings.size(), GL_INVALID_VALUE);
5263         break;
5264     default:
5265         break;
5266     }
5267 
5268     switch (target) {
5269     case GL_VERTEX_BINDING_DIVISOR:
5270         *params = currBindings[index].divisor;
5271         return;
5272     case GL_VERTEX_BINDING_OFFSET:
5273         *params = currBindings[index].offset;
5274         return;
5275     case GL_VERTEX_BINDING_STRIDE:
5276         *params = currBindings[index].effectiveStride;
5277         return;
5278     case GL_VERTEX_BINDING_BUFFER:
5279         *params = currBindings[index].buffer;
5280         return;
5281     default:
5282         break;
5283     }
5284 
5285     ctx->safe_glGetIntegeri_v(target, index, params);
5286 }
5287 
s_glGetInteger64i_v(void * self,GLenum target,GLuint index,GLint64 * params)5288 void GL2Encoder::s_glGetInteger64i_v(void* self, GLenum target, GLuint index, GLint64* params) {
5289     GL2Encoder *ctx = (GL2Encoder *)self;
5290     GLClientState* state = ctx->m_state;
5291 
5292     GLint limit;
5293 
5294     switch (target) {
5295     LIMIT_CASE(GL_TRANSFORM_FEEDBACK_BUFFER_BINDING, GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS)
5296     LIMIT_CASE(GL_UNIFORM_BUFFER_BINDING, GL_MAX_UNIFORM_BUFFER_BINDINGS)
5297     LIMIT_CASE(GL_ATOMIC_COUNTER_BUFFER_BINDING, GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS)
5298     LIMIT_CASE(GL_SHADER_STORAGE_BUFFER_BINDING, GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS)
5299     default:
5300         break;
5301     }
5302 
5303     const GLClientState::VertexAttribBindingVector& currBindings =
5304         state->currentVertexBufferBindings();
5305 
5306     switch (target) {
5307     case GL_VERTEX_BINDING_DIVISOR:
5308     case GL_VERTEX_BINDING_OFFSET:
5309     case GL_VERTEX_BINDING_STRIDE:
5310     case GL_VERTEX_BINDING_BUFFER:
5311         SET_ERROR_IF(index < 0 || index > currBindings.size(), GL_INVALID_VALUE);
5312         break;
5313     default:
5314         break;
5315     }
5316 
5317     switch (target) {
5318     case GL_VERTEX_BINDING_DIVISOR:
5319         *params = currBindings[index].divisor;
5320         return;
5321     case GL_VERTEX_BINDING_OFFSET:
5322         *params = currBindings[index].offset;
5323         return;
5324     case GL_VERTEX_BINDING_STRIDE:
5325         *params = currBindings[index].effectiveStride;
5326         return;
5327     case GL_VERTEX_BINDING_BUFFER:
5328         *params = currBindings[index].buffer;
5329         return;
5330     default:
5331         break;
5332     }
5333 
5334     ctx->safe_glGetInteger64i_v(target, index, params);
5335 }
5336 
s_glGetInteger64v(void * self,GLenum param,GLint64 * val)5337 void GL2Encoder::s_glGetInteger64v(void* self, GLenum param, GLint64* val) {
5338     GL2Encoder *ctx = (GL2Encoder *)self;
5339     ctx->safe_glGetInteger64v(param, val);
5340 }
5341 
s_glGetBooleani_v(void * self,GLenum param,GLuint index,GLboolean * val)5342 void GL2Encoder::s_glGetBooleani_v(void* self, GLenum param, GLuint index, GLboolean* val) {
5343     GL2Encoder *ctx = (GL2Encoder *)self;
5344     ctx->safe_glGetBooleani_v(param, index, val);
5345 }
5346 
s_glGetShaderiv(void * self,GLuint shader,GLenum pname,GLint * params)5347 void GL2Encoder::s_glGetShaderiv(void* self, GLuint shader, GLenum pname, GLint* params) {
5348     GL2Encoder *ctx = (GL2Encoder *)self;
5349     ctx->m_glGetShaderiv_enc(self, shader, pname, params);
5350 
5351     SET_ERROR_IF(!GLESv2Validation::allowedGetShader(pname), GL_INVALID_ENUM);
5352     VALIDATE_SHADER_NAME(shader);
5353 
5354     if (pname == GL_SHADER_SOURCE_LENGTH) {
5355         ShaderData* shaderData = ctx->m_shared->getShaderData(shader);
5356         if (shaderData) {
5357             int totalLen = 0;
5358             for (int i = 0; i < shaderData->sources.size(); i++) {
5359                 totalLen += shaderData->sources[i].size();
5360             }
5361             if (totalLen != 0) {
5362                 *params = totalLen + 1; // account for null terminator
5363             }
5364         }
5365     }
5366 }
5367 
s_glActiveShaderProgram(void * self,GLuint pipeline,GLuint program)5368 void GL2Encoder::s_glActiveShaderProgram(void* self, GLuint pipeline, GLuint program) {
5369     GL2Encoder *ctx = (GL2Encoder*)self;
5370     GLClientState* state = ctx->m_state;
5371     GLSharedGroupPtr shared = ctx->m_shared;
5372 
5373     SET_ERROR_IF(!pipeline, GL_INVALID_OPERATION);
5374     SET_ERROR_IF(program && !shared->isShaderOrProgramObject(program), GL_INVALID_VALUE);
5375     SET_ERROR_IF(program && !shared->isProgram(program), GL_INVALID_OPERATION);
5376 
5377     ctx->m_glActiveShaderProgram_enc(ctx, pipeline, program);
5378     if (!state->currentProgram()) {
5379         state->setCurrentShaderProgram(program);
5380     }
5381 }
5382 
s_glCreateShaderProgramv(void * self,GLenum shaderType,GLsizei count,const char ** strings)5383 GLuint GL2Encoder::s_glCreateShaderProgramv(void* self, GLenum shaderType, GLsizei count, const char** strings) {
5384 
5385     GLint* length = NULL;
5386     GL2Encoder* ctx = (GL2Encoder*)self;
5387 
5388     int len = glUtilsCalcShaderSourceLen((char**)strings, length, count);
5389     char *str = new char[len + 1];
5390     glUtilsPackStrings(str, (char**)strings, (GLint*)length, count);
5391 
5392     // Do GLSharedGroup and location WorkARound-specific initialization
5393     // Phase 1: create a ShaderData and initialize with replaceSamplerExternalWith2D()
5394     uint32_t spDataId = ctx->m_shared->addNewShaderProgramData();
5395     ShaderProgramData* spData = ctx->m_shared->getShaderProgramDataById(spDataId);
5396 
5397     if (!replaceSamplerExternalWith2D(str, &spData->shaderData)) {
5398         delete [] str;
5399         ctx->setError(GL_OUT_OF_MEMORY);
5400         ctx->m_shared->deleteShaderProgramDataById(spDataId);
5401         return -1;
5402     }
5403 
5404     GLuint res = ctx->glCreateShaderProgramvAEMU(ctx, shaderType, count, str, len + 1);
5405     delete [] str;
5406 
5407     // Phase 2: do glLinkProgram-related initialization for locationWorkARound
5408     GLint linkStatus = 0;
5409     ctx->m_glGetProgramiv_enc(self, res, GL_LINK_STATUS ,&linkStatus);
5410     ctx->m_shared->setProgramLinkStatus(res, linkStatus);
5411     if (!linkStatus) {
5412         ctx->m_shared->deleteShaderProgramDataById(spDataId);
5413         return -1;
5414     }
5415 
5416     ctx->m_shared->associateGLShaderProgram(res, spDataId);
5417 
5418     GLint numUniforms = 0;
5419     GLint numAttributes = 0;
5420     ctx->m_glGetProgramiv_enc(self, res, GL_ACTIVE_UNIFORMS, &numUniforms);
5421     ctx->m_glGetProgramiv_enc(self, res, GL_ACTIVE_ATTRIBUTES, &numAttributes);
5422     ctx->m_shared->initShaderProgramData(res, numUniforms, numAttributes);
5423 
5424     GLint maxLength=0;
5425     GLint maxAttribLength=0;
5426     ctx->m_glGetProgramiv_enc(self, res, GL_ACTIVE_UNIFORM_MAX_LENGTH, &maxLength);
5427     ctx->m_glGetProgramiv_enc(self, res, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &maxAttribLength);
5428 
5429     size_t bufLen = maxLength > maxAttribLength ? maxLength : maxAttribLength;
5430     GLint size; GLenum type; GLchar *name = new GLchar[bufLen + 1];
5431 
5432     for (GLint i = 0; i < numUniforms; ++i) {
5433         ctx->m_glGetActiveUniform_enc(self, res, i, maxLength, NULL, &size, &type, name);
5434         GLint location = ctx->m_glGetUniformLocation_enc(self, res, name);
5435         ctx->m_shared->setShaderProgramIndexInfo(res, i, location, size, type, name);
5436     }
5437 
5438     for (GLint i = 0; i < numAttributes; ++i) {
5439         ctx->m_glGetActiveAttrib_enc(self, res, i, maxAttribLength,  NULL, &size, &type, name);
5440         GLint location = ctx->m_glGetAttribLocation_enc(self, res, name);
5441         ctx->m_shared->setProgramAttribInfo(res, i, location, size, type, name);
5442     }
5443 
5444     GLint numBlocks;
5445     ctx->m_glGetProgramiv_enc(ctx, res, GL_ACTIVE_UNIFORM_BLOCKS, &numBlocks);
5446     ctx->m_shared->setActiveUniformBlockCountForProgram(res, numBlocks);
5447 
5448     GLint tfVaryingsCount;
5449     ctx->m_glGetProgramiv_enc(ctx, res, GL_TRANSFORM_FEEDBACK_VARYINGS, &tfVaryingsCount);
5450     ctx->m_shared->setTransformFeedbackVaryingsCountForProgram(res, tfVaryingsCount);
5451 
5452     delete [] name;
5453 
5454     return res;
5455 }
5456 
s_glProgramUniform1f(void * self,GLuint program,GLint location,GLfloat v0)5457 void GL2Encoder::s_glProgramUniform1f(void* self, GLuint program, GLint location, GLfloat v0)
5458 {
5459     GL2Encoder *ctx = (GL2Encoder*)self;
5460     ctx->m_glProgramUniform1f_enc(self, program, location, v0);
5461 }
5462 
s_glProgramUniform1fv(void * self,GLuint program,GLint location,GLsizei count,const GLfloat * value)5463 void GL2Encoder::s_glProgramUniform1fv(void* self, GLuint program, GLint location, GLsizei count, const GLfloat *value)
5464 {
5465     GL2Encoder *ctx = (GL2Encoder*)self;
5466     ctx->m_glProgramUniform1fv_enc(self, program, location, count, value);
5467 }
5468 
s_glProgramUniform1i(void * self,GLuint program,GLint location,GLint v0)5469 void GL2Encoder::s_glProgramUniform1i(void* self, GLuint program, GLint location, GLint v0)
5470 {
5471     GL2Encoder *ctx = (GL2Encoder*)self;
5472     ctx->m_glProgramUniform1i_enc(self, program, location, v0);
5473 
5474     GLClientState* state = ctx->m_state;
5475     GLSharedGroupPtr shared = ctx->m_shared;
5476     GLenum target;
5477 
5478     if (shared->setSamplerUniform(program, location, v0, &target)) {
5479         GLenum origActiveTexture = state->getActiveTextureUnit();
5480         if (ctx->updateHostTexture2DBinding(GL_TEXTURE0 + v0, target)) {
5481             ctx->m_glActiveTexture_enc(self, origActiveTexture);
5482         }
5483         state->setActiveTextureUnit(origActiveTexture);
5484     }
5485 }
5486 
s_glProgramUniform1iv(void * self,GLuint program,GLint location,GLsizei count,const GLint * value)5487 void GL2Encoder::s_glProgramUniform1iv(void* self, GLuint program, GLint location, GLsizei count, const GLint *value)
5488 {
5489     GL2Encoder *ctx = (GL2Encoder*)self;
5490     ctx->m_glProgramUniform1iv_enc(self, program, location, count, value);
5491 }
5492 
s_glProgramUniform1ui(void * self,GLuint program,GLint location,GLuint v0)5493 void GL2Encoder::s_glProgramUniform1ui(void* self, GLuint program, GLint location, GLuint v0)
5494 {
5495     GL2Encoder *ctx = (GL2Encoder*)self;
5496     ctx->m_glProgramUniform1ui_enc(self, program, location, v0);
5497 
5498     GLClientState* state = ctx->m_state;
5499     GLSharedGroupPtr shared = ctx->m_shared;
5500     GLenum target;
5501 
5502     if (shared->setSamplerUniform(program, location, v0, &target)) {
5503         GLenum origActiveTexture = state->getActiveTextureUnit();
5504         if (ctx->updateHostTexture2DBinding(GL_TEXTURE0 + v0, target)) {
5505             ctx->m_glActiveTexture_enc(self, origActiveTexture);
5506         }
5507         state->setActiveTextureUnit(origActiveTexture);
5508     }
5509 }
5510 
s_glProgramUniform1uiv(void * self,GLuint program,GLint location,GLsizei count,const GLuint * value)5511 void GL2Encoder::s_glProgramUniform1uiv(void* self, GLuint program, GLint location, GLsizei count, const GLuint *value)
5512 {
5513     GL2Encoder *ctx = (GL2Encoder*)self;
5514     ctx->m_glProgramUniform1uiv_enc(self, program, location, count, value);
5515 }
5516 
s_glProgramUniform2f(void * self,GLuint program,GLint location,GLfloat v0,GLfloat v1)5517 void GL2Encoder::s_glProgramUniform2f(void* self, GLuint program, GLint location, GLfloat v0, GLfloat v1)
5518 {
5519     GL2Encoder *ctx = (GL2Encoder*)self;
5520     ctx->m_glProgramUniform2f_enc(self, program, location, v0, v1);
5521 }
5522 
s_glProgramUniform2fv(void * self,GLuint program,GLint location,GLsizei count,const GLfloat * value)5523 void GL2Encoder::s_glProgramUniform2fv(void* self, GLuint program, GLint location, GLsizei count, const GLfloat *value)
5524 {
5525     GL2Encoder *ctx = (GL2Encoder*)self;
5526     ctx->m_glProgramUniform2fv_enc(self, program, location, count, value);
5527 }
5528 
s_glProgramUniform2i(void * self,GLuint program,GLint location,GLint v0,GLint v1)5529 void GL2Encoder::s_glProgramUniform2i(void* self, GLuint program, GLint location, GLint v0, GLint v1)
5530 {
5531     GL2Encoder *ctx = (GL2Encoder*)self;
5532     ctx->m_glProgramUniform2i_enc(self, program, location, v0, v1);
5533 }
5534 
s_glProgramUniform2iv(void * self,GLuint program,GLint location,GLsizei count,const GLint * value)5535 void GL2Encoder::s_glProgramUniform2iv(void* self, GLuint program, GLint location, GLsizei count, const GLint *value)
5536 {
5537     GL2Encoder *ctx = (GL2Encoder*)self;
5538     ctx->m_glProgramUniform2iv_enc(self, program, location, count, value);
5539 }
5540 
s_glProgramUniform2ui(void * self,GLuint program,GLint location,GLint v0,GLuint v1)5541 void GL2Encoder::s_glProgramUniform2ui(void* self, GLuint program, GLint location, GLint v0, GLuint v1)
5542 {
5543     GL2Encoder *ctx = (GL2Encoder*)self;
5544     ctx->m_glProgramUniform2ui_enc(self, program, location, v0, v1);
5545 }
5546 
s_glProgramUniform2uiv(void * self,GLuint program,GLint location,GLsizei count,const GLuint * value)5547 void GL2Encoder::s_glProgramUniform2uiv(void* self, GLuint program, GLint location, GLsizei count, const GLuint *value)
5548 {
5549     GL2Encoder *ctx = (GL2Encoder*)self;
5550     ctx->m_glProgramUniform2uiv_enc(self, program, location, count, value);
5551 }
5552 
s_glProgramUniform3f(void * self,GLuint program,GLint location,GLfloat v0,GLfloat v1,GLfloat v2)5553 void GL2Encoder::s_glProgramUniform3f(void* self, GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2)
5554 {
5555     GL2Encoder *ctx = (GL2Encoder*)self;
5556     ctx->m_glProgramUniform3f_enc(self, program, location, v0, v1, v2);
5557 }
5558 
s_glProgramUniform3fv(void * self,GLuint program,GLint location,GLsizei count,const GLfloat * value)5559 void GL2Encoder::s_glProgramUniform3fv(void* self, GLuint program, GLint location, GLsizei count, const GLfloat *value)
5560 {
5561     GL2Encoder *ctx = (GL2Encoder*)self;
5562     ctx->m_glProgramUniform3fv_enc(self, program, location, count, value);
5563 }
5564 
s_glProgramUniform3i(void * self,GLuint program,GLint location,GLint v0,GLint v1,GLint v2)5565 void GL2Encoder::s_glProgramUniform3i(void* self, GLuint program, GLint location, GLint v0, GLint v1, GLint v2)
5566 {
5567     GL2Encoder *ctx = (GL2Encoder*)self;
5568     ctx->m_glProgramUniform3i_enc(self, program, location, v0, v1, v2);
5569 }
5570 
s_glProgramUniform3iv(void * self,GLuint program,GLint location,GLsizei count,const GLint * value)5571 void GL2Encoder::s_glProgramUniform3iv(void* self, GLuint program, GLint location, GLsizei count, const GLint *value)
5572 {
5573     GL2Encoder *ctx = (GL2Encoder*)self;
5574     ctx->m_glProgramUniform3iv_enc(self, program, location, count, value);
5575 }
5576 
s_glProgramUniform3ui(void * self,GLuint program,GLint location,GLint v0,GLint v1,GLuint v2)5577 void GL2Encoder::s_glProgramUniform3ui(void* self, GLuint program, GLint location, GLint v0, GLint v1, GLuint v2)
5578 {
5579     GL2Encoder *ctx = (GL2Encoder*)self;
5580     ctx->m_glProgramUniform3ui_enc(self, program, location, v0, v1, v2);
5581 }
5582 
s_glProgramUniform3uiv(void * self,GLuint program,GLint location,GLsizei count,const GLuint * value)5583 void GL2Encoder::s_glProgramUniform3uiv(void* self, GLuint program, GLint location, GLsizei count, const GLuint *value)
5584 {
5585     GL2Encoder *ctx = (GL2Encoder*)self;
5586     ctx->m_glProgramUniform3uiv_enc(self, program, location, count, value);
5587 }
5588 
s_glProgramUniform4f(void * self,GLuint program,GLint location,GLfloat v0,GLfloat v1,GLfloat v2,GLfloat v3)5589 void GL2Encoder::s_glProgramUniform4f(void* self, GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3)
5590 {
5591     GL2Encoder *ctx = (GL2Encoder*)self;
5592     ctx->m_glProgramUniform4f_enc(self, program, location, v0, v1, v2, v3);
5593 }
5594 
s_glProgramUniform4fv(void * self,GLuint program,GLint location,GLsizei count,const GLfloat * value)5595 void GL2Encoder::s_glProgramUniform4fv(void* self, GLuint program, GLint location, GLsizei count, const GLfloat *value)
5596 {
5597     GL2Encoder *ctx = (GL2Encoder*)self;
5598     ctx->m_glProgramUniform4fv_enc(self, program, location, count, value);
5599 }
5600 
s_glProgramUniform4i(void * self,GLuint program,GLint location,GLint v0,GLint v1,GLint v2,GLint v3)5601 void GL2Encoder::s_glProgramUniform4i(void* self, GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLint v3)
5602 {
5603     GL2Encoder *ctx = (GL2Encoder*)self;
5604     ctx->m_glProgramUniform4i_enc(self, program, location, v0, v1, v2, v3);
5605 }
5606 
s_glProgramUniform4iv(void * self,GLuint program,GLint location,GLsizei count,const GLint * value)5607 void GL2Encoder::s_glProgramUniform4iv(void* self, GLuint program, GLint location, GLsizei count, const GLint *value)
5608 {
5609     GL2Encoder *ctx = (GL2Encoder*)self;
5610     ctx->m_glProgramUniform4iv_enc(self, program, location, count, value);
5611 }
5612 
s_glProgramUniform4ui(void * self,GLuint program,GLint location,GLint v0,GLint v1,GLint v2,GLuint v3)5613 void GL2Encoder::s_glProgramUniform4ui(void* self, GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLuint v3)
5614 {
5615     GL2Encoder *ctx = (GL2Encoder*)self;
5616     ctx->m_glProgramUniform4ui_enc(self, program, location, v0, v1, v2, v3);
5617 }
5618 
s_glProgramUniform4uiv(void * self,GLuint program,GLint location,GLsizei count,const GLuint * value)5619 void GL2Encoder::s_glProgramUniform4uiv(void* self, GLuint program, GLint location, GLsizei count, const GLuint *value)
5620 {
5621     GL2Encoder *ctx = (GL2Encoder*)self;
5622     ctx->m_glProgramUniform4uiv_enc(self, program, location, count, value);
5623 }
5624 
s_glProgramUniformMatrix2fv(void * self,GLuint program,GLint location,GLsizei count,GLboolean transpose,const GLfloat * value)5625 void GL2Encoder::s_glProgramUniformMatrix2fv(void* self, GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
5626 {
5627     GL2Encoder *ctx = (GL2Encoder*)self;
5628     ctx->m_glProgramUniformMatrix2fv_enc(self, program, location, count, transpose, value);
5629 }
5630 
s_glProgramUniformMatrix2x3fv(void * self,GLuint program,GLint location,GLsizei count,GLboolean transpose,const GLfloat * value)5631 void GL2Encoder::s_glProgramUniformMatrix2x3fv(void* self, GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
5632 {
5633     GL2Encoder *ctx = (GL2Encoder*)self;
5634     ctx->m_glProgramUniformMatrix2x3fv_enc(self, program, location, count, transpose, value);
5635 }
5636 
s_glProgramUniformMatrix2x4fv(void * self,GLuint program,GLint location,GLsizei count,GLboolean transpose,const GLfloat * value)5637 void GL2Encoder::s_glProgramUniformMatrix2x4fv(void* self, GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
5638 {
5639     GL2Encoder *ctx = (GL2Encoder*)self;
5640     ctx->m_glProgramUniformMatrix2x4fv_enc(self, program, location, count, transpose, value);
5641 }
5642 
s_glProgramUniformMatrix3fv(void * self,GLuint program,GLint location,GLsizei count,GLboolean transpose,const GLfloat * value)5643 void GL2Encoder::s_glProgramUniformMatrix3fv(void* self, GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
5644 {
5645     GL2Encoder *ctx = (GL2Encoder*)self;
5646     ctx->m_glProgramUniformMatrix3fv_enc(self, program, location, count, transpose, value);
5647 }
5648 
s_glProgramUniformMatrix3x2fv(void * self,GLuint program,GLint location,GLsizei count,GLboolean transpose,const GLfloat * value)5649 void GL2Encoder::s_glProgramUniformMatrix3x2fv(void* self, GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
5650 {
5651     GL2Encoder *ctx = (GL2Encoder*)self;
5652     ctx->m_glProgramUniformMatrix3x2fv_enc(self, program, location, count, transpose, value);
5653 }
5654 
s_glProgramUniformMatrix3x4fv(void * self,GLuint program,GLint location,GLsizei count,GLboolean transpose,const GLfloat * value)5655 void GL2Encoder::s_glProgramUniformMatrix3x4fv(void* self, GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
5656 {
5657     GL2Encoder *ctx = (GL2Encoder*)self;
5658     ctx->m_glProgramUniformMatrix3x4fv_enc(self, program, location, count, transpose, value);
5659 }
5660 
s_glProgramUniformMatrix4fv(void * self,GLuint program,GLint location,GLsizei count,GLboolean transpose,const GLfloat * value)5661 void GL2Encoder::s_glProgramUniformMatrix4fv(void* self, GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
5662 {
5663     GL2Encoder *ctx = (GL2Encoder*)self;
5664     ctx->m_glProgramUniformMatrix4fv_enc(self, program, location, count, transpose, value);
5665 }
5666 
s_glProgramUniformMatrix4x2fv(void * self,GLuint program,GLint location,GLsizei count,GLboolean transpose,const GLfloat * value)5667 void GL2Encoder::s_glProgramUniformMatrix4x2fv(void* self, GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
5668 {
5669     GL2Encoder *ctx = (GL2Encoder*)self;
5670     ctx->m_glProgramUniformMatrix4x2fv_enc(self, program, location, count, transpose, value);
5671 }
5672 
s_glProgramUniformMatrix4x3fv(void * self,GLuint program,GLint location,GLsizei count,GLboolean transpose,const GLfloat * value)5673 void GL2Encoder::s_glProgramUniformMatrix4x3fv(void* self, GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
5674 {
5675     GL2Encoder *ctx = (GL2Encoder*)self;
5676     ctx->m_glProgramUniformMatrix4x3fv_enc(self, program, location, count, transpose, value);
5677 }
5678 
s_glProgramParameteri(void * self,GLuint program,GLenum pname,GLint value)5679 void GL2Encoder::s_glProgramParameteri(void* self, GLuint program, GLenum pname, GLint value) {
5680     GL2Encoder* ctx = (GL2Encoder*)self;
5681     VALIDATE_PROGRAM_NAME(program);
5682     SET_ERROR_IF(pname != GL_PROGRAM_BINARY_RETRIEVABLE_HINT && pname != GL_PROGRAM_SEPARABLE, GL_INVALID_ENUM);
5683     SET_ERROR_IF(value != GL_FALSE && value != GL_TRUE, GL_INVALID_VALUE);
5684     ctx->m_glProgramParameteri_enc(self, program, pname, value);
5685 }
5686 
s_glUseProgramStages(void * self,GLuint pipeline,GLbitfield stages,GLuint program)5687 void GL2Encoder::s_glUseProgramStages(void *self, GLuint pipeline, GLbitfield stages, GLuint program)
5688 {
5689     GL2Encoder *ctx = (GL2Encoder*)self;
5690     GLClientState* state = ctx->m_state;
5691     GLSharedGroupPtr shared = ctx->m_shared;
5692 
5693     SET_ERROR_IF(!pipeline, GL_INVALID_OPERATION);
5694     SET_ERROR_IF(program && !shared->isShaderOrProgramObject(program), GL_INVALID_VALUE);
5695     SET_ERROR_IF(program && !shared->isProgram(program), GL_INVALID_OPERATION);
5696 
5697     ctx->m_glUseProgramStages_enc(self, pipeline, stages, program);
5698     state->associateProgramWithPipeline(program, pipeline);
5699 
5700     // There is an active non-separable shader program in effect; no need to update external/2D bindings.
5701     if (state->currentProgram()) {
5702         return;
5703     }
5704 
5705     // Otherwise, update host texture 2D bindings.
5706     ctx->updateHostTexture2DBindingsFromProgramData(program);
5707 
5708     if (program) {
5709         ctx->m_state->currentUniformValidationInfo = ctx->m_shared->getUniformValidationInfo(program);
5710         ctx->m_state->currentAttribValidationInfo = ctx->m_shared->getAttribValidationInfo(program);
5711     }
5712 }
5713 
s_glBindProgramPipeline(void * self,GLuint pipeline)5714 void GL2Encoder::s_glBindProgramPipeline(void* self, GLuint pipeline)
5715 {
5716     GL2Encoder *ctx = (GL2Encoder*)self;
5717     GLClientState* state = ctx->m_state;
5718 
5719     ctx->m_glBindProgramPipeline_enc(self, pipeline);
5720 
5721     // There is an active non-separable shader program in effect; no need to update external/2D bindings.
5722     if (!pipeline || state->currentProgram()) {
5723         return;
5724     }
5725 
5726     GLClientState::ProgramPipelineIterator it = state->programPipelineBegin();
5727     for (; it != state->programPipelineEnd(); ++it) {
5728         if (it->second == pipeline) {
5729             ctx->updateHostTexture2DBindingsFromProgramData(it->first);
5730         }
5731     }
5732 }
5733 
s_glGetProgramResourceiv(void * self,GLuint program,GLenum programInterface,GLuint index,GLsizei propCount,const GLenum * props,GLsizei bufSize,GLsizei * length,GLint * params)5734 void GL2Encoder::s_glGetProgramResourceiv(void* self, GLuint program, GLenum programInterface, GLuint index, GLsizei propCount, const GLenum * props, GLsizei bufSize, GLsizei * length, GLint * params) {
5735     GL2Encoder *ctx = (GL2Encoder*)self;
5736     SET_ERROR_IF(bufSize < 0, GL_INVALID_VALUE);
5737     if (bufSize == 0) {
5738         if (length) *length = 0;
5739         return;
5740     }
5741 
5742     // Avoid modifying |name| if |*length| < bufSize.
5743     GLint* intermediate = new GLint[bufSize];
5744     GLsizei* myLength = length ? length : new GLsizei;
5745     bool needFreeLength = length == NULL;
5746 
5747     ctx->m_glGetProgramResourceiv_enc(self, program, programInterface, index, propCount, props, bufSize, myLength, intermediate);
5748     GLsizei writtenInts = *myLength;
5749     memcpy(params, intermediate, writtenInts * sizeof(GLint));
5750 
5751     delete [] intermediate;
5752     if (needFreeLength)
5753         delete myLength;
5754 }
5755 
s_glGetProgramResourceIndex(void * self,GLuint program,GLenum programInterface,const char * name)5756 GLuint GL2Encoder::s_glGetProgramResourceIndex(void* self, GLuint program, GLenum programInterface, const char* name) {
5757     GL2Encoder *ctx = (GL2Encoder*)self;
5758     return ctx->m_glGetProgramResourceIndex_enc(self, program, programInterface, name);
5759 }
5760 
s_glGetProgramResourceLocation(void * self,GLuint program,GLenum programInterface,const char * name)5761 GLint GL2Encoder::s_glGetProgramResourceLocation(void* self, GLuint program, GLenum programInterface, const char* name) {
5762     GL2Encoder *ctx = (GL2Encoder*)self;
5763     return ctx->m_glGetProgramResourceLocation_enc(self, program, programInterface, name);
5764 }
5765 
s_glGetProgramResourceName(void * self,GLuint program,GLenum programInterface,GLuint index,GLsizei bufSize,GLsizei * length,char * name)5766 void GL2Encoder::s_glGetProgramResourceName(void* self, GLuint program, GLenum programInterface, GLuint index, GLsizei bufSize, GLsizei* length, char* name) {
5767     GL2Encoder *ctx = (GL2Encoder*)self;
5768     SET_ERROR_IF(bufSize < 0, GL_INVALID_VALUE);
5769     if (bufSize == 0) {
5770         if (length) *length = 0;
5771         return;
5772     }
5773 
5774     // Avoid modifying |name| if |*length| < bufSize.
5775     char* intermediate = new char[bufSize];
5776     GLsizei* myLength = length ? length : new GLsizei;
5777     bool needFreeLength = length == NULL;
5778 
5779     ctx->m_glGetProgramResourceName_enc(self, program, programInterface, index, bufSize, myLength, intermediate);
5780     GLsizei writtenStrLen = *myLength;
5781     memcpy(name, intermediate, writtenStrLen + 1);
5782 
5783     delete [] intermediate;
5784     if (needFreeLength)
5785         delete myLength;
5786 }
5787 
s_glGetProgramPipelineInfoLog(void * self,GLuint pipeline,GLsizei bufSize,GLsizei * length,GLchar * infoLog)5788 void GL2Encoder::s_glGetProgramPipelineInfoLog(void* self, GLuint pipeline, GLsizei bufSize, GLsizei* length, GLchar* infoLog) {
5789     GL2Encoder *ctx = (GL2Encoder*)self;
5790     SET_ERROR_IF(bufSize < 0, GL_INVALID_VALUE);
5791     if (bufSize == 0) {
5792         if (length) *length = 0;
5793         return;
5794     }
5795 
5796     // Avoid modifying |infoLog| if |*length| < bufSize.
5797     GLchar* intermediate = new GLchar[bufSize];
5798     GLsizei* myLength = length ? length : new GLsizei;
5799     bool needFreeLength = length == NULL;
5800 
5801     ctx->m_glGetProgramPipelineInfoLog_enc(self, pipeline, bufSize, myLength, intermediate);
5802     GLsizei writtenStrLen = *myLength;
5803     memcpy(infoLog, intermediate, writtenStrLen + 1);
5804 
5805     delete [] intermediate;
5806     if (needFreeLength)
5807         delete myLength;
5808 }
5809 
s_glVertexAttribFormat(void * self,GLuint attribindex,GLint size,GLenum type,GLboolean normalized,GLuint relativeoffset)5810 void GL2Encoder::s_glVertexAttribFormat(void* self, GLuint attribindex, GLint size, GLenum type, GLboolean normalized, GLuint relativeoffset) {
5811     GL2Encoder *ctx = (GL2Encoder*)self;
5812     GLClientState* state = ctx->m_state;
5813 
5814     VALIDATE_VERTEX_ATTRIB_INDEX(attribindex);
5815     SET_ERROR_IF(!state->currentVertexArrayObject(), GL_INVALID_OPERATION);
5816 
5817     state->setVertexAttribFormat(attribindex, size, type, normalized, relativeoffset, false);
5818     ctx->m_glVertexAttribFormat_enc(ctx, attribindex, size, type, normalized, relativeoffset);
5819 }
5820 
s_glVertexAttribIFormat(void * self,GLuint attribindex,GLint size,GLenum type,GLuint relativeoffset)5821 void GL2Encoder::s_glVertexAttribIFormat(void* self, GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset) {
5822     GL2Encoder *ctx = (GL2Encoder*)self;
5823     GLClientState* state = ctx->m_state;
5824 
5825     VALIDATE_VERTEX_ATTRIB_INDEX(attribindex);
5826     SET_ERROR_IF(!state->currentVertexArrayObject(), GL_INVALID_OPERATION);
5827 
5828     state->setVertexAttribFormat(attribindex, size, type, GL_FALSE, relativeoffset, true);
5829     ctx->m_glVertexAttribIFormat_enc(ctx, attribindex, size, type, relativeoffset);
5830 }
5831 
s_glVertexBindingDivisor(void * self,GLuint bindingindex,GLuint divisor)5832 void GL2Encoder::s_glVertexBindingDivisor(void* self, GLuint bindingindex, GLuint divisor) {
5833     GL2Encoder *ctx = (GL2Encoder*)self;
5834     GLClientState* state = ctx->m_state;
5835 
5836     SET_ERROR_IF(!state->currentVertexArrayObject(), GL_INVALID_OPERATION);
5837 
5838     state->setVertexBindingDivisor(bindingindex, divisor);
5839     ctx->m_glVertexBindingDivisor_enc(ctx, bindingindex, divisor);
5840 }
5841 
s_glVertexAttribBinding(void * self,GLuint attribindex,GLuint bindingindex)5842 void GL2Encoder::s_glVertexAttribBinding(void* self, GLuint attribindex, GLuint bindingindex) {
5843     GL2Encoder *ctx = (GL2Encoder*)self;
5844     GLClientState* state = ctx->m_state;
5845     VALIDATE_VERTEX_ATTRIB_INDEX(attribindex);
5846     SET_ERROR_IF(!state->currentVertexArrayObject(), GL_INVALID_OPERATION);
5847 
5848     state->setVertexAttribBinding(attribindex, bindingindex);
5849     ctx->m_glVertexAttribBinding_enc(ctx, attribindex, bindingindex);
5850 }
5851 
s_glBindVertexBuffer(void * self,GLuint bindingindex,GLuint buffer,GLintptr offset,GLintptr stride)5852 void GL2Encoder::s_glBindVertexBuffer(void* self, GLuint bindingindex, GLuint buffer, GLintptr offset, GLintptr stride) {
5853     GL2Encoder *ctx = (GL2Encoder*)self;
5854     GLClientState* state = ctx->m_state;
5855 
5856     SET_ERROR_IF(offset < 0, GL_INVALID_VALUE);
5857 
5858     GLint maxStride;
5859     ctx->glGetIntegerv(ctx, GL_MAX_VERTEX_ATTRIB_STRIDE, &maxStride);
5860     SET_ERROR_IF(stride < 0 || stride > maxStride, GL_INVALID_VALUE);
5861 
5862     SET_ERROR_IF(!state->currentVertexArrayObject(), GL_INVALID_OPERATION);
5863 
5864     state->bindIndexedBuffer(0, bindingindex, buffer, offset, 0, stride, stride);
5865     ctx->m_glBindVertexBuffer_enc(ctx, bindingindex, buffer, offset, stride);
5866 }
5867 
s_glDrawArraysIndirect(void * self,GLenum mode,const void * indirect)5868 void GL2Encoder::s_glDrawArraysIndirect(void* self, GLenum mode, const void* indirect) {
5869     GL2Encoder *ctx = (GL2Encoder*)self;
5870     GLClientState* state = ctx->m_state;
5871 
5872     bool hasClientArrays = false;
5873     bool hasVBOs = false;
5874     ctx->getVBOUsage(&hasClientArrays, &hasVBOs);
5875 
5876     SET_ERROR_IF(hasClientArrays, GL_INVALID_OPERATION);
5877     SET_ERROR_IF(!state->currentVertexArrayObject(), GL_INVALID_OPERATION);
5878     SET_ERROR_IF(!ctx->boundBuffer(GL_DRAW_INDIRECT_BUFFER), GL_INVALID_OPERATION);
5879     SET_ERROR_IF(ctx->m_state->checkFramebufferCompleteness(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE, GL_INVALID_FRAMEBUFFER_OPERATION);
5880 
5881     GLuint indirectStructSize = glUtilsIndirectStructSize(INDIRECT_COMMAND_DRAWARRAYS);
5882     if (ctx->boundBuffer(GL_DRAW_INDIRECT_BUFFER)) {
5883         // BufferData* buf = ctx->getBufferData(target);
5884         // if (buf) {
5885         //     SET_ERROR_IF((GLuint)(uintptr_t)indirect + indirectStructSize > buf->m_size, GL_INVALID_VALUE);
5886         // }
5887         ctx->glDrawArraysIndirectOffsetAEMU(ctx, mode, (uintptr_t)indirect);
5888     } else {
5889         // Client command structs are technically allowed in desktop OpenGL, but not in ES.
5890         // This is purely for debug/dev purposes.
5891         ctx->glDrawArraysIndirectDataAEMU(ctx, mode, indirect, indirectStructSize);
5892     }
5893     ctx->m_state->postDraw();
5894 }
5895 
s_glDrawElementsIndirect(void * self,GLenum mode,GLenum type,const void * indirect)5896 void GL2Encoder::s_glDrawElementsIndirect(void* self, GLenum mode, GLenum type, const void* indirect) {
5897     GL2Encoder *ctx = (GL2Encoder*)self;
5898 
5899     GLClientState* state = ctx->m_state;
5900 
5901     bool hasClientArrays = false;
5902     bool hasVBOs = false;
5903     ctx->getVBOUsage(&hasClientArrays, &hasVBOs);
5904 
5905     SET_ERROR_IF(hasClientArrays, GL_INVALID_OPERATION);
5906     SET_ERROR_IF(!state->currentVertexArrayObject(), GL_INVALID_OPERATION);
5907     SET_ERROR_IF(!ctx->boundBuffer(GL_DRAW_INDIRECT_BUFFER), GL_INVALID_OPERATION);
5908 
5909     SET_ERROR_IF(ctx->m_state->getTransformFeedbackActiveUnpaused(), GL_INVALID_OPERATION);
5910     SET_ERROR_IF(ctx->m_state->checkFramebufferCompleteness(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE, GL_INVALID_FRAMEBUFFER_OPERATION);
5911 
5912     GLuint indirectStructSize = glUtilsIndirectStructSize(INDIRECT_COMMAND_DRAWELEMENTS);
5913     if (ctx->boundBuffer(GL_DRAW_INDIRECT_BUFFER)) {
5914         // BufferData* buf = ctx->getBufferData(target);
5915         // if (buf) {
5916         //     SET_ERROR_IF((GLuint)(uintptr_t)indirect + indirectStructSize > buf->m_size, GL_INVALID_VALUE);
5917         // }
5918         ctx->glDrawElementsIndirectOffsetAEMU(ctx, mode, type, (uintptr_t)indirect);
5919     } else {
5920         // Client command structs are technically allowed in desktop OpenGL, but not in ES.
5921         // This is purely for debug/dev purposes.
5922         ctx->glDrawElementsIndirectDataAEMU(ctx, mode, type, indirect, indirectStructSize);
5923     }
5924     ctx->m_state->postDraw();
5925 }
5926 
s_glTexStorage2DMultisample(void * self,GLenum target,GLsizei samples,GLenum internalformat,GLsizei width,GLsizei height,GLboolean fixedsamplelocations)5927 void GL2Encoder::s_glTexStorage2DMultisample(void* self, GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations) {
5928     GL2Encoder *ctx = (GL2Encoder*)self;
5929     GLClientState* state = ctx->m_state;
5930 
5931     SET_ERROR_IF(target != GL_TEXTURE_2D_MULTISAMPLE, GL_INVALID_ENUM);
5932     SET_ERROR_IF(!GLESv2Validation::pixelInternalFormat(internalformat), GL_INVALID_ENUM);
5933     SET_ERROR_IF(!state->getBoundTexture(target), GL_INVALID_OPERATION);
5934     SET_ERROR_IF(width < 1 || height < 1, GL_INVALID_VALUE);
5935     SET_ERROR_IF(state->isBoundTextureImmutableFormat(target), GL_INVALID_OPERATION);
5936     GLint max_samples;
5937     ctx->s_glGetInternalformativ(ctx, target, internalformat, GL_SAMPLES, 1, &max_samples);
5938     SET_ERROR_IF(samples > max_samples, GL_INVALID_OPERATION);
5939 
5940     state->setBoundTextureInternalFormat(target, internalformat);
5941     state->setBoundTextureDims(target, target, 0, width, height, 1);
5942     state->setBoundTextureImmutableFormat(target);
5943     state->setBoundTextureSamples(target, samples);
5944 
5945     ctx->m_glTexStorage2DMultisample_enc(ctx, target, samples, internalformat, width, height, fixedsamplelocations);
5946 }
5947 
s_glGetGraphicsResetStatusEXT(void * self)5948 GLenum GL2Encoder::s_glGetGraphicsResetStatusEXT(void* self) {
5949     (void)self;
5950     return GL_NO_ERROR;
5951 }
5952 
s_glReadnPixelsEXT(void * self,GLint x,GLint y,GLsizei width,GLsizei height,GLenum format,GLenum type,GLsizei bufSize,GLvoid * pixels)5953 void GL2Encoder::s_glReadnPixelsEXT(void* self, GLint x, GLint y, GLsizei width,
5954         GLsizei height, GLenum format, GLenum type, GLsizei bufSize,
5955         GLvoid* pixels) {
5956     GL2Encoder *ctx = (GL2Encoder*)self;
5957     SET_ERROR_IF(bufSize < glesv2_enc::pixelDataSize(self, width, height, format,
5958         type, 1), GL_INVALID_OPERATION);
5959     s_glReadPixels(self, x, y, width, height, format, type, pixels);
5960     ctx->m_state->postReadPixels();
5961 }
5962 
s_glGetnUniformfvEXT(void * self,GLuint program,GLint location,GLsizei bufSize,GLfloat * params)5963 void GL2Encoder::s_glGetnUniformfvEXT(void *self, GLuint program, GLint location,
5964         GLsizei bufSize, GLfloat* params) {
5965     GL2Encoder *ctx = (GL2Encoder*)self;
5966     SET_ERROR_IF(bufSize < glSizeof(glesv2_enc::uniformType(self, program,
5967         location)), GL_INVALID_OPERATION);
5968     s_glGetUniformfv(self, program, location, params);
5969 }
5970 
s_glGetnUniformivEXT(void * self,GLuint program,GLint location,GLsizei bufSize,GLint * params)5971 void GL2Encoder::s_glGetnUniformivEXT(void *self, GLuint program, GLint location,
5972         GLsizei bufSize, GLint* params) {
5973     GL2Encoder *ctx = (GL2Encoder*)self;
5974     SET_ERROR_IF(bufSize < glSizeof(glesv2_enc::uniformType(self, program,
5975         location)), GL_INVALID_OPERATION);
5976     s_glGetUniformiv(self, program, location, params);
5977 }
5978 
s_glInvalidateFramebuffer(void * self,GLenum target,GLsizei numAttachments,const GLenum * attachments)5979 void GL2Encoder::s_glInvalidateFramebuffer(void* self, GLenum target, GLsizei numAttachments, const GLenum *attachments) {
5980     GL2Encoder *ctx = (GL2Encoder*)self;
5981     SET_ERROR_IF((target != GL_FRAMEBUFFER) &&
5982                  (target != GL_READ_FRAMEBUFFER) &&
5983                  (target != GL_DRAW_FRAMEBUFFER), GL_INVALID_ENUM);
5984     SET_ERROR_IF(numAttachments < 0, GL_INVALID_VALUE);
5985 
5986     GLint maxColorAttachments;
5987     ctx->glGetIntegerv(ctx, GL_MAX_COLOR_ATTACHMENTS, &maxColorAttachments);
5988     for (GLsizei i = 0; i < numAttachments; ++i) {
5989         if (attachments[i] != GL_DEPTH_ATTACHMENT && attachments[i] != GL_STENCIL_ATTACHMENT && attachments[i] != GL_DEPTH_STENCIL_ATTACHMENT) {
5990             SET_ERROR_IF(attachments[i] >= GL_COLOR_ATTACHMENT0 + maxColorAttachments, GL_INVALID_OPERATION);
5991         }
5992     }
5993 
5994     ctx->m_glInvalidateFramebuffer_enc(ctx, target, numAttachments, attachments);
5995 }
5996 
s_glInvalidateSubFramebuffer(void * self,GLenum target,GLsizei numAttachments,const GLenum * attachments,GLint x,GLint y,GLsizei width,GLsizei height)5997 void GL2Encoder::s_glInvalidateSubFramebuffer(void* self, GLenum target, GLsizei numAttachments, const GLenum *attachments, GLint x, GLint y, GLsizei width, GLsizei height) {
5998     GL2Encoder *ctx = (GL2Encoder*)self;
5999     SET_ERROR_IF(target != GL_FRAMEBUFFER && target != GL_READ_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER, GL_INVALID_ENUM);
6000     SET_ERROR_IF(numAttachments < 0, GL_INVALID_VALUE);
6001     SET_ERROR_IF(width < 0, GL_INVALID_VALUE);
6002     SET_ERROR_IF(height < 0, GL_INVALID_VALUE);
6003     GLint maxColorAttachments;
6004     ctx->glGetIntegerv(ctx, GL_MAX_COLOR_ATTACHMENTS, &maxColorAttachments);
6005     for (GLsizei i = 0; i < numAttachments; ++i) {
6006         if (attachments[i] != GL_DEPTH_ATTACHMENT && attachments[i] != GL_STENCIL_ATTACHMENT && attachments[i] != GL_DEPTH_STENCIL_ATTACHMENT) {
6007             SET_ERROR_IF(attachments[i] >= GL_COLOR_ATTACHMENT0 + maxColorAttachments, GL_INVALID_OPERATION);
6008         }
6009     }
6010     ctx->m_glInvalidateSubFramebuffer_enc(ctx, target, numAttachments, attachments, x, y, width, height);
6011 }
6012 
s_glDispatchCompute(void * self,GLuint num_groups_x,GLuint num_groups_y,GLuint num_groups_z)6013 void GL2Encoder::s_glDispatchCompute(void* self, GLuint num_groups_x, GLuint num_groups_y, GLuint num_groups_z) {
6014     GL2Encoder *ctx = (GL2Encoder*)self;
6015     ctx->m_glDispatchCompute_enc(ctx, num_groups_x, num_groups_y, num_groups_z);
6016     ctx->m_state->postDispatchCompute();
6017 }
6018 
s_glDispatchComputeIndirect(void * self,GLintptr indirect)6019 void GL2Encoder::s_glDispatchComputeIndirect(void* self, GLintptr indirect) {
6020     GL2Encoder *ctx = (GL2Encoder*)self;
6021     ctx->m_glDispatchComputeIndirect_enc(ctx, indirect);
6022     ctx->m_state->postDispatchCompute();
6023 }
6024 
s_glGenTransformFeedbacks(void * self,GLsizei n,GLuint * ids)6025 void GL2Encoder::s_glGenTransformFeedbacks(void* self, GLsizei n, GLuint* ids) {
6026     GL2Encoder *ctx = (GL2Encoder*)self;
6027     ctx->m_glGenTransformFeedbacks_enc(ctx, n, ids);
6028     ctx->m_state->setExistence(GLClientState::ObjectType::TransformFeedback, true, n, ids);
6029 }
6030 
s_glDeleteTransformFeedbacks(void * self,GLsizei n,const GLuint * ids)6031 void GL2Encoder::s_glDeleteTransformFeedbacks(void* self, GLsizei n, const GLuint* ids) {
6032     GL2Encoder *ctx = (GL2Encoder*)self;
6033     SET_ERROR_IF(ctx->m_state->getTransformFeedbackActive(), GL_INVALID_OPERATION);
6034 
6035     ctx->m_state->setExistence(GLClientState::ObjectType::TransformFeedback, false, n, ids);
6036     ctx->m_glDeleteTransformFeedbacks_enc(ctx, n, ids);
6037 }
6038 
s_glGenSamplers(void * self,GLsizei n,GLuint * ids)6039 void GL2Encoder::s_glGenSamplers(void* self, GLsizei n, GLuint* ids) {
6040     GL2Encoder *ctx = (GL2Encoder*)self;
6041     ctx->m_glGenSamplers_enc(ctx, n, ids);
6042     ctx->m_state->setExistence(GLClientState::ObjectType::Sampler, true, n, ids);
6043 }
6044 
s_glGenQueries(void * self,GLsizei n,GLuint * ids)6045 void GL2Encoder::s_glGenQueries(void* self, GLsizei n, GLuint* ids) {
6046     GL2Encoder *ctx = (GL2Encoder*)self;
6047     ctx->m_glGenQueries_enc(ctx, n, ids);
6048     ctx->m_state->setExistence(GLClientState::ObjectType::Query, true, n, ids);
6049 }
6050 
s_glDeleteQueries(void * self,GLsizei n,const GLuint * ids)6051 void GL2Encoder::s_glDeleteQueries(void* self, GLsizei n, const GLuint* ids) {
6052     GL2Encoder *ctx = (GL2Encoder*)self;
6053     ctx->m_state->setExistence(GLClientState::ObjectType::Query, false, n, ids);
6054     ctx->m_glDeleteQueries_enc(ctx, n, ids);
6055 }
6056 
s_glBindTransformFeedback(void * self,GLenum target,GLuint id)6057 void GL2Encoder::s_glBindTransformFeedback(void* self, GLenum target, GLuint id) {
6058     GL2Encoder *ctx = (GL2Encoder*)self;
6059     SET_ERROR_IF(GL_TRANSFORM_FEEDBACK != target, GL_INVALID_ENUM);
6060     SET_ERROR_IF(ctx->m_state->getTransformFeedbackActiveUnpaused(), GL_INVALID_OPERATION);
6061     SET_ERROR_IF(!ctx->m_state->tryBind(target, id), GL_INVALID_OPERATION);
6062     ctx->m_glBindTransformFeedback_enc(ctx, target, id);
6063 }
6064 
s_glBeginQuery(void * self,GLenum target,GLuint query)6065 void GL2Encoder::s_glBeginQuery(void* self, GLenum target, GLuint query) {
6066     GL2Encoder *ctx = (GL2Encoder*)self;
6067     SET_ERROR_IF(!GLESv2Validation::allowedQueryTarget(target), GL_INVALID_ENUM);
6068 
6069     if (target != GL_ANY_SAMPLES_PASSED_CONSERVATIVE &&
6070         target != GL_ANY_SAMPLES_PASSED) {
6071         SET_ERROR_IF(ctx->m_state->isQueryBound(target), GL_INVALID_OPERATION);
6072     } else {
6073         SET_ERROR_IF(ctx->m_state->isQueryBound(GL_ANY_SAMPLES_PASSED_CONSERVATIVE), GL_INVALID_OPERATION);
6074         SET_ERROR_IF(ctx->m_state->isQueryBound(GL_ANY_SAMPLES_PASSED), GL_INVALID_OPERATION);
6075     }
6076 
6077     GLenum lastTarget = ctx->m_state->getLastQueryTarget(query);
6078 
6079     if (lastTarget) {
6080         SET_ERROR_IF(target != lastTarget, GL_INVALID_OPERATION);
6081     }
6082 
6083     SET_ERROR_IF(!query, GL_INVALID_OPERATION);
6084     SET_ERROR_IF(!ctx->m_state->tryBind(target, query), GL_INVALID_OPERATION);
6085     ctx->m_state->setLastQueryTarget(target, query);
6086     ctx->m_glBeginQuery_enc(ctx, target, query);
6087 }
6088 
s_glEndQuery(void * self,GLenum target)6089 void GL2Encoder::s_glEndQuery(void* self, GLenum target) {
6090     GL2Encoder *ctx = (GL2Encoder*)self;
6091     SET_ERROR_IF(!GLESv2Validation::allowedQueryTarget(target), GL_INVALID_ENUM);
6092     SET_ERROR_IF(!ctx->m_state->isBoundTargetValid(target), GL_INVALID_OPERATION);
6093     SET_ERROR_IF(!ctx->m_state->tryBind(target, 0), GL_INVALID_OPERATION);
6094     ctx->m_glEndQuery_enc(ctx, target);
6095 }
6096 
s_glClear(void * self,GLbitfield mask)6097 void GL2Encoder::s_glClear(void* self, GLbitfield mask) {
6098     GL2Encoder *ctx = (GL2Encoder*)self;
6099 
6100     GLbitfield allowed_bits = GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT;
6101     GLbitfield has_disallowed_bits = (mask & ~allowed_bits);
6102     SET_ERROR_IF(has_disallowed_bits, GL_INVALID_VALUE);
6103 
6104     ctx->m_glClear_enc(ctx, mask);
6105 }
6106 
s_glCopyTexSubImage2D(void * self,GLenum target,GLint level,GLint xoffset,GLint yoffset,GLint x,GLint y,GLsizei width,GLsizei height)6107 void GL2Encoder::s_glCopyTexSubImage2D(void *self , GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height) {
6108     GL2Encoder *ctx = (GL2Encoder*)self;
6109     SET_ERROR_IF(!GLESv2Validation::textureTarget(ctx, target), GL_INVALID_ENUM);
6110     SET_ERROR_IF(level < 0, GL_INVALID_VALUE);
6111     GLint max_texture_size;
6112     GLint max_cube_map_texture_size;
6113     ctx->glGetIntegerv(ctx, GL_MAX_TEXTURE_SIZE, &max_texture_size);
6114     ctx->glGetIntegerv(ctx, GL_MAX_CUBE_MAP_TEXTURE_SIZE, &max_cube_map_texture_size);
6115     SET_ERROR_IF(level > ilog2(max_texture_size), GL_INVALID_VALUE);
6116     SET_ERROR_IF((target == GL_TEXTURE_CUBE_MAP) &&
6117                  (level > ilog2(max_cube_map_texture_size)), GL_INVALID_VALUE);
6118     SET_ERROR_IF(xoffset < 0 || yoffset < 0, GL_INVALID_VALUE);
6119     SET_ERROR_IF(width < 0 || height < 0, GL_INVALID_VALUE);
6120     SET_ERROR_IF(width > max_texture_size, GL_INVALID_VALUE);
6121     SET_ERROR_IF(height > max_texture_size, GL_INVALID_VALUE);
6122     SET_ERROR_IF(GLESv2Validation::isCubeMapTarget(target) && width > max_cube_map_texture_size, GL_INVALID_VALUE);
6123     SET_ERROR_IF(GLESv2Validation::isCubeMapTarget(target) && height > max_cube_map_texture_size, GL_INVALID_VALUE);
6124     GLuint tex = ctx->m_state->getBoundTexture(target);
6125     GLsizei neededWidth = xoffset + width;
6126     GLsizei neededHeight = yoffset + height;
6127     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__,
6128             tex,
6129             neededWidth,
6130             neededHeight,
6131             xoffset,
6132             width,
6133             yoffset,
6134             height,
6135             ctx->m_state->queryTexWidth(level, tex),
6136             ctx->m_state->queryTexWidth(level, tex),
6137             level);
6138 
6139     SET_ERROR_IF(tex &&
6140                  (neededWidth > ctx->m_state->queryTexWidth(level, tex) ||
6141                   neededHeight > ctx->m_state->queryTexHeight(level, tex)),
6142                  GL_INVALID_VALUE);
6143     SET_ERROR_IF(ctx->glCheckFramebufferStatus(ctx, GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE,
6144                  GL_INVALID_FRAMEBUFFER_OPERATION);
6145 
6146     ctx->m_glCopyTexSubImage2D_enc(ctx, target, level, xoffset, yoffset, x, y, width, height);
6147 }
6148 
s_glCopyTexSubImage3D(void * self,GLenum target,GLint level,GLint xoffset,GLint yoffset,GLint zoffset,GLint x,GLint y,GLsizei width,GLsizei height)6149 void GL2Encoder::s_glCopyTexSubImage3D(void *self , GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height) {
6150     GL2Encoder *ctx = (GL2Encoder*)self;
6151     SET_ERROR_IF(target != GL_TEXTURE_3D &&
6152                  target != GL_TEXTURE_2D_ARRAY,
6153                  GL_INVALID_ENUM);
6154     GLint max_texture_size;
6155     GLint max_3d_texture_size;
6156     ctx->glGetIntegerv(ctx, GL_MAX_TEXTURE_SIZE, &max_texture_size);
6157     ctx->glGetIntegerv(ctx, GL_MAX_3D_TEXTURE_SIZE, &max_3d_texture_size);
6158     SET_ERROR_IF(level < 0, GL_INVALID_VALUE);
6159     SET_ERROR_IF(level > ilog2(max_texture_size), GL_INVALID_VALUE);
6160     SET_ERROR_IF(level > ilog2(max_3d_texture_size), GL_INVALID_VALUE);
6161     SET_ERROR_IF(width < 0 || height < 0, GL_INVALID_VALUE);
6162     SET_ERROR_IF(xoffset < 0 || yoffset < 0 || zoffset < 0, GL_INVALID_VALUE);
6163     GLuint tex = ctx->m_state->getBoundTexture(target);
6164     GLsizei neededWidth = xoffset + width;
6165     GLsizei neededHeight = yoffset + height;
6166     GLsizei neededDepth = zoffset + 1;
6167     SET_ERROR_IF(tex &&
6168                  (neededWidth > ctx->m_state->queryTexWidth(level, tex) ||
6169                   neededHeight > ctx->m_state->queryTexHeight(level, tex) ||
6170                   neededDepth > ctx->m_state->queryTexDepth(level, tex)),
6171                  GL_INVALID_VALUE);
6172     SET_ERROR_IF(ctx->glCheckFramebufferStatus(ctx, GL_READ_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE,
6173                  GL_INVALID_FRAMEBUFFER_OPERATION);
6174 
6175     ctx->m_glCopyTexSubImage3D_enc(ctx, target, level, xoffset, yoffset, zoffset, x, y, width, height);
6176 }
6177 
s_glCompileShader(void * self,GLuint shader)6178 void GL2Encoder::s_glCompileShader(void* self, GLuint shader) {
6179     GL2Encoder *ctx = (GL2Encoder*)self;
6180     bool isShaderOrProgramObject =
6181         ctx->m_shared->isShaderOrProgramObject(shader);
6182     bool isShader =
6183         ctx->m_shared->isShader(shader);
6184 
6185     SET_ERROR_IF(isShaderOrProgramObject && !isShader, GL_INVALID_OPERATION);
6186     SET_ERROR_IF(!isShaderOrProgramObject && !isShader, GL_INVALID_VALUE);
6187 
6188     ctx->m_glCompileShader_enc(ctx, shader);
6189 }
6190 
s_glValidateProgram(void * self,GLuint program)6191 void GL2Encoder::s_glValidateProgram(void* self, GLuint program ) {
6192     GL2Encoder *ctx = (GL2Encoder*)self;
6193 
6194     VALIDATE_PROGRAM_NAME(program);
6195 
6196     ctx->m_glValidateProgram_enc(self, program);
6197 }
6198 
s_glProgramBinary(void * self,GLuint program,GLenum binaryFormat,const void * binary,GLsizei length)6199 void GL2Encoder::s_glProgramBinary(void *self , GLuint program, GLenum binaryFormat, const void* binary, GLsizei length) {
6200     GL2Encoder *ctx = (GL2Encoder*)self;
6201 
6202     VALIDATE_PROGRAM_NAME(program);
6203 
6204     SET_ERROR_IF(~0 == binaryFormat, GL_INVALID_ENUM);
6205 
6206     ctx->m_glProgramBinary_enc(self, program, binaryFormat, binary, length);
6207 }
6208 
s_glGetSamplerParameterfv(void * self,GLuint sampler,GLenum pname,GLfloat * params)6209 void GL2Encoder::s_glGetSamplerParameterfv(void *self, GLuint sampler, GLenum pname, GLfloat* params) {
6210     GL2Encoder *ctx = (GL2Encoder*)self;
6211 
6212     SET_ERROR_IF(!ctx->m_state->samplerExists(sampler), GL_INVALID_OPERATION);
6213     SET_ERROR_IF(!GLESv2Validation::samplerParams(ctx, pname), GL_INVALID_ENUM);
6214 
6215     if (!params) return;
6216 
6217     ctx->m_glGetSamplerParameterfv_enc(ctx, sampler, pname, params);
6218 }
6219 
s_glGetSamplerParameteriv(void * self,GLuint sampler,GLenum pname,GLint * params)6220 void GL2Encoder::s_glGetSamplerParameteriv(void *self, GLuint sampler, GLenum pname, GLint* params) {
6221     GL2Encoder *ctx = (GL2Encoder*)self;
6222     SET_ERROR_IF(!ctx->m_state->samplerExists(sampler), GL_INVALID_OPERATION);
6223     SET_ERROR_IF(!GLESv2Validation::samplerParams(ctx, pname), GL_INVALID_ENUM);
6224 
6225     if (!params) return;
6226 
6227     ctx->m_glGetSamplerParameteriv_enc(ctx, sampler, pname, params);
6228 }
6229 
s_glSamplerParameterf(void * self,GLuint sampler,GLenum pname,GLfloat param)6230 void GL2Encoder::s_glSamplerParameterf(void *self , GLuint sampler, GLenum pname, GLfloat param) {
6231     GL2Encoder *ctx = (GL2Encoder*)self;
6232     SET_ERROR_IF(!ctx->m_state->samplerExists(sampler), GL_INVALID_OPERATION);
6233     SET_ERROR_IF(!GLESv2Validation::samplerParams(ctx, pname), GL_INVALID_ENUM);
6234     SET_ERROR_IF(!GLESv2Validation::textureParamValue(ctx, pname, (GLint)param, param, (GLenum)param), GL_INVALID_ENUM);
6235 
6236     ctx->m_glSamplerParameterf_enc(ctx, sampler, pname, param);
6237 }
6238 
s_glSamplerParameteri(void * self,GLuint sampler,GLenum pname,GLint param)6239 void GL2Encoder::s_glSamplerParameteri(void *self , GLuint sampler, GLenum pname, GLint param) {
6240     GL2Encoder *ctx = (GL2Encoder*)self;
6241     SET_ERROR_IF(!ctx->m_state->samplerExists(sampler), GL_INVALID_OPERATION);
6242     SET_ERROR_IF(!GLESv2Validation::samplerParams(ctx, pname), GL_INVALID_ENUM);
6243     SET_ERROR_IF(!GLESv2Validation::textureParamValue(ctx, pname, param, (GLfloat)param, (GLenum)param), GL_INVALID_ENUM);
6244 
6245     ctx->m_glSamplerParameteri_enc(ctx, sampler, pname, param);
6246 }
6247 
s_glSamplerParameterfv(void * self,GLuint sampler,GLenum pname,const GLfloat * params)6248 void GL2Encoder::s_glSamplerParameterfv(void *self , GLuint sampler, GLenum pname, const GLfloat* params) {
6249     GL2Encoder *ctx = (GL2Encoder*)self;
6250     SET_ERROR_IF(!ctx->m_state->samplerExists(sampler), GL_INVALID_OPERATION);
6251     SET_ERROR_IF(!GLESv2Validation::samplerParams(ctx, pname), GL_INVALID_ENUM);
6252     SET_ERROR_IF(!params, GL_INVALID_VALUE);
6253     GLfloat param = *params;
6254     SET_ERROR_IF(!GLESv2Validation::textureParamValue(ctx, pname, (GLint)param, param, (GLenum)param), GL_INVALID_ENUM);
6255 
6256     ctx->m_glSamplerParameterfv_enc(ctx, sampler, pname, params);
6257 }
6258 
s_glSamplerParameteriv(void * self,GLuint sampler,GLenum pname,const GLint * params)6259 void GL2Encoder::s_glSamplerParameteriv(void *self , GLuint sampler, GLenum pname, const GLint* params) {
6260     GL2Encoder *ctx = (GL2Encoder*)self;
6261     SET_ERROR_IF(!ctx->m_state->samplerExists(sampler), GL_INVALID_OPERATION);
6262     SET_ERROR_IF(!GLESv2Validation::samplerParams(ctx, pname), GL_INVALID_ENUM);
6263     SET_ERROR_IF(!params, GL_INVALID_VALUE);
6264     GLint param = *params;
6265     SET_ERROR_IF(!GLESv2Validation::textureParamValue(ctx, pname, (GLint)param, param, (GLenum)param), GL_INVALID_ENUM);
6266 
6267     ctx->m_glSamplerParameteriv_enc(ctx, sampler, pname, params);
6268 }
6269 
s_glGetAttribLocation(void * self,GLuint program,const GLchar * name)6270 int GL2Encoder::s_glGetAttribLocation(void *self , GLuint program, const GLchar* name) {
6271     GL2Encoder *ctx = (GL2Encoder*)self;
6272 
6273     bool isShaderOrProgramObject =
6274         ctx->m_shared->isShaderOrProgramObject(program);
6275     bool isProgram =
6276         ctx->m_shared->isProgram(program);
6277 
6278     RET_AND_SET_ERROR_IF(!isShaderOrProgramObject, GL_INVALID_VALUE, -1);
6279     RET_AND_SET_ERROR_IF(!isProgram, GL_INVALID_OPERATION, -1);
6280     RET_AND_SET_ERROR_IF(!ctx->m_shared->getProgramLinkStatus(program), GL_INVALID_OPERATION, -1);
6281 
6282     return ctx->m_glGetAttribLocation_enc(ctx, program, name);
6283 }
6284 
s_glBindAttribLocation(void * self,GLuint program,GLuint index,const GLchar * name)6285 void GL2Encoder::s_glBindAttribLocation(void *self , GLuint program, GLuint index, const GLchar* name) {
6286     GL2Encoder* ctx = (GL2Encoder*)self;
6287 
6288     VALIDATE_PROGRAM_NAME(program);
6289 
6290     GLint maxVertexAttribs;
6291     ctx->glGetIntegerv(self, GL_MAX_VERTEX_ATTRIBS, &maxVertexAttribs);
6292     SET_ERROR_IF(!(index < maxVertexAttribs), GL_INVALID_VALUE);
6293     SET_ERROR_IF(index > maxVertexAttribs, GL_INVALID_VALUE);
6294     SET_ERROR_IF(name && !strncmp("gl_", name, 3), GL_INVALID_OPERATION);
6295 
6296     fprintf(stderr, "%s: bind attrib %u name %s\n", __func__, index, name);
6297     ctx->m_glBindAttribLocation_enc(ctx, program, index, name);
6298 }
6299 
6300 // TODO-SLOW
s_glUniformBlockBinding(void * self,GLuint program,GLuint uniformBlockIndex,GLuint uniformBlockBinding)6301 void GL2Encoder::s_glUniformBlockBinding(void *self , GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding) {
6302     GL2Encoder* ctx = (GL2Encoder*)self;
6303 
6304     VALIDATE_PROGRAM_NAME(program);
6305     SET_ERROR_IF(uniformBlockIndex >= ctx->m_shared->getActiveUniformBlockCount(program), GL_INVALID_VALUE);
6306 
6307     GLint maxUniformBufferBindings;
6308     ctx->glGetIntegerv(ctx, GL_MAX_UNIFORM_BUFFER_BINDINGS, &maxUniformBufferBindings);
6309     SET_ERROR_IF(uniformBlockBinding >= maxUniformBufferBindings, GL_INVALID_VALUE);
6310 
6311     ctx->m_glUniformBlockBinding_enc(ctx, program, uniformBlockIndex, uniformBlockBinding);
6312 }
6313 
s_glGetTransformFeedbackVarying(void * self,GLuint program,GLuint index,GLsizei bufSize,GLsizei * length,GLsizei * size,GLenum * type,char * name)6314 void GL2Encoder::s_glGetTransformFeedbackVarying(void *self , GLuint program, GLuint index, GLsizei bufSize, GLsizei* length, GLsizei* size, GLenum* type, char* name) {
6315     GL2Encoder* ctx = (GL2Encoder*)self;
6316 
6317     VALIDATE_PROGRAM_NAME(program);
6318     SET_ERROR_IF(!ctx->m_shared->getProgramLinkStatus(program), GL_INVALID_OPERATION);
6319     SET_ERROR_IF(index >= ctx->m_shared->getTransformFeedbackVaryingsCountForProgram(program), GL_INVALID_VALUE);
6320 
6321     ctx->m_glGetTransformFeedbackVarying_enc(ctx, program, index, bufSize, length, size, type, name);
6322 }
6323 
s_glScissor(void * self,GLint x,GLint y,GLsizei width,GLsizei height)6324 void GL2Encoder::s_glScissor(void *self , GLint x, GLint y, GLsizei width, GLsizei height) {
6325     GL2Encoder* ctx = (GL2Encoder*)self;
6326     SET_ERROR_IF(width < 0 || height < 0, GL_INVALID_VALUE);
6327     ctx->m_glScissor_enc(ctx, x, y, width, height);
6328 }
6329 
s_glDepthFunc(void * self,GLenum func)6330 void GL2Encoder::s_glDepthFunc(void *self , GLenum func) {
6331     GL2Encoder* ctx = (GL2Encoder*)self;
6332     SET_ERROR_IF(
6333         (func != GL_NEVER) &&
6334         (func != GL_ALWAYS) &&
6335         (func != GL_LESS) &&
6336         (func != GL_LEQUAL) &&
6337         (func != GL_EQUAL) &&
6338         (func != GL_GREATER) &&
6339         (func != GL_GEQUAL) &&
6340         (func != GL_NOTEQUAL),
6341         GL_INVALID_ENUM);
6342     ctx->m_glDepthFunc_enc(ctx, func);
6343 }
6344 
s_glViewport(void * self,GLint x,GLint y,GLsizei width,GLsizei height)6345 void GL2Encoder::s_glViewport(void *self , GLint x, GLint y, GLsizei width, GLsizei height) {
6346     GL2Encoder* ctx = (GL2Encoder*)self;
6347     SET_ERROR_IF(width < 0 || height < 0, GL_INVALID_VALUE);
6348     ctx->m_glViewport_enc(ctx, x, y, width, height);
6349 }
6350 
s_glStencilFunc(void * self,GLenum func,GLint ref,GLuint mask)6351 void GL2Encoder::s_glStencilFunc(void *self , GLenum func, GLint ref, GLuint mask) {
6352     GL2Encoder* ctx = (GL2Encoder*)self;
6353     SET_ERROR_IF(!GLESv2Validation::allowedFunc(func), GL_INVALID_ENUM);
6354     if (!ctx->m_state) return;
6355     ctx->m_state->stencilFuncSeparate(GL_FRONT_AND_BACK, func, ref, mask);
6356     ctx->m_glStencilFunc_enc(ctx, func, ref, mask);
6357 }
6358 
s_glStencilFuncSeparate(void * self,GLenum face,GLenum func,GLint ref,GLuint mask)6359 void GL2Encoder::s_glStencilFuncSeparate(void *self , GLenum face, GLenum func, GLint ref, GLuint mask) {
6360     GL2Encoder* ctx = (GL2Encoder*)self;
6361     SET_ERROR_IF(!GLESv2Validation::allowedFace(face) || !GLESv2Validation::allowedFunc(func), GL_INVALID_ENUM);
6362     if (!ctx->m_state) return;
6363     ctx->m_state->stencilFuncSeparate(face, func, ref, mask);
6364     ctx->m_glStencilFuncSeparate_enc(ctx, face, func, ref, mask);
6365 }
6366 
s_glStencilOp(void * self,GLenum fail,GLenum zfail,GLenum zpass)6367 void GL2Encoder::s_glStencilOp(void *self , GLenum fail, GLenum zfail, GLenum zpass) {
6368     GL2Encoder* ctx = (GL2Encoder*)self;
6369     SET_ERROR_IF(
6370         !GLESv2Validation::allowedStencilOp(fail) ||
6371         !GLESv2Validation::allowedStencilOp(zfail) ||
6372         !GLESv2Validation::allowedStencilOp(zpass),
6373         GL_INVALID_ENUM);
6374     if (!ctx->m_state) return;
6375     ctx->m_state->stencilOpSeparate(GL_FRONT_AND_BACK, fail, zfail, zpass);
6376     ctx->m_glStencilOp_enc(ctx, fail, zfail, zpass);
6377 }
6378 
s_glStencilOpSeparate(void * self,GLenum face,GLenum fail,GLenum zfail,GLenum zpass)6379 void GL2Encoder::s_glStencilOpSeparate(void *self , GLenum face, GLenum fail, GLenum zfail, GLenum zpass) {
6380     GL2Encoder* ctx = (GL2Encoder*)self;
6381     SET_ERROR_IF(
6382         !GLESv2Validation::allowedFace(face) ||
6383         !GLESv2Validation::allowedStencilOp(fail) ||
6384         !GLESv2Validation::allowedStencilOp(zfail) ||
6385         !GLESv2Validation::allowedStencilOp(zpass),
6386         GL_INVALID_ENUM);
6387     if (!ctx->m_state) return;
6388     ctx->m_state->stencilOpSeparate(face, fail, zfail, zpass);
6389     ctx->m_glStencilOpSeparate_enc(ctx, face, fail, zfail, zpass);
6390 }
6391 
s_glStencilMaskSeparate(void * self,GLenum face,GLuint mask)6392 void GL2Encoder::s_glStencilMaskSeparate(void *self , GLenum face, GLuint mask) {
6393     GL2Encoder* ctx = (GL2Encoder*)self;
6394     SET_ERROR_IF(
6395         !GLESv2Validation::allowedFace(face),
6396         GL_INVALID_ENUM);
6397     if (!ctx->m_state) return;
6398     ctx->m_state->stencilMaskSeparate(face, mask);
6399     ctx->m_glStencilMaskSeparate_enc(ctx, face, mask);
6400 }
6401 
s_glBlendEquation(void * self,GLenum mode)6402 void GL2Encoder::s_glBlendEquation(void *self , GLenum mode) {
6403     GL2Encoder* ctx = (GL2Encoder*)self;
6404     SET_ERROR_IF(
6405         !GLESv2Validation::allowedBlendEquation(mode),
6406         GL_INVALID_ENUM);
6407     ctx->m_glBlendEquation_enc(ctx, mode);
6408 }
6409 
s_glBlendEquationSeparate(void * self,GLenum modeRGB,GLenum modeAlpha)6410 void GL2Encoder::s_glBlendEquationSeparate(void *self , GLenum modeRGB, GLenum modeAlpha) {
6411     GL2Encoder* ctx = (GL2Encoder*)self;
6412     SET_ERROR_IF(
6413         !GLESv2Validation::allowedBlendEquation(modeRGB) ||
6414         !GLESv2Validation::allowedBlendEquation(modeAlpha),
6415         GL_INVALID_ENUM);
6416     ctx->m_glBlendEquationSeparate_enc(ctx, modeRGB, modeAlpha);
6417 }
6418 
s_glBlendFunc(void * self,GLenum sfactor,GLenum dfactor)6419 void GL2Encoder::s_glBlendFunc(void *self , GLenum sfactor, GLenum dfactor) {
6420     GL2Encoder* ctx = (GL2Encoder*)self;
6421     SET_ERROR_IF(
6422         !GLESv2Validation::allowedBlendFunc(sfactor) ||
6423         !GLESv2Validation::allowedBlendFunc(dfactor),
6424         GL_INVALID_ENUM);
6425     ctx->m_glBlendFunc_enc(ctx, sfactor, dfactor);
6426 }
6427 
s_glBlendFuncSeparate(void * self,GLenum srcRGB,GLenum dstRGB,GLenum srcAlpha,GLenum dstAlpha)6428 void GL2Encoder::s_glBlendFuncSeparate(void *self , GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha) {
6429     GL2Encoder* ctx = (GL2Encoder*)self;
6430     SET_ERROR_IF(
6431         !GLESv2Validation::allowedBlendFunc(srcRGB) ||
6432         !GLESv2Validation::allowedBlendFunc(dstRGB) ||
6433         !GLESv2Validation::allowedBlendFunc(srcAlpha) ||
6434         !GLESv2Validation::allowedBlendFunc(dstAlpha),
6435         GL_INVALID_ENUM);
6436     ctx->m_glBlendFuncSeparate_enc(ctx, srcRGB, dstRGB, srcAlpha, dstAlpha);
6437 }
6438 
s_glCullFace(void * self,GLenum mode)6439 void GL2Encoder::s_glCullFace(void *self , GLenum mode) {
6440     GL2Encoder* ctx = (GL2Encoder*)self;
6441     SET_ERROR_IF(
6442         !GLESv2Validation::allowedCullFace(mode),
6443         GL_INVALID_ENUM);
6444     ctx->m_glCullFace_enc(ctx, mode);
6445 }
6446 
s_glFrontFace(void * self,GLenum mode)6447 void GL2Encoder::s_glFrontFace(void *self , GLenum mode) {
6448     GL2Encoder* ctx = (GL2Encoder*)self;
6449     SET_ERROR_IF(
6450         !GLESv2Validation::allowedFrontFace(mode),
6451         GL_INVALID_ENUM);
6452     ctx->m_glFrontFace_enc(ctx, mode);
6453 }
6454 
s_glLineWidth(void * self,GLfloat width)6455 void GL2Encoder::s_glLineWidth(void *self , GLfloat width) {
6456     GL2Encoder* ctx = (GL2Encoder*)self;
6457     SET_ERROR_IF(width <= 0.0f, GL_INVALID_VALUE);
6458     ctx->m_glLineWidth_enc(ctx, width);
6459 }
6460 
s_glVertexAttrib1f(void * self,GLuint indx,GLfloat x)6461 void GL2Encoder::s_glVertexAttrib1f(void *self , GLuint indx, GLfloat x) {
6462     GL2Encoder* ctx = (GL2Encoder*)self;
6463     VALIDATE_VERTEX_ATTRIB_INDEX(indx);
6464     ctx->m_glVertexAttrib1f_enc(ctx, indx, x);
6465 }
6466 
s_glVertexAttrib2f(void * self,GLuint indx,GLfloat x,GLfloat y)6467 void GL2Encoder::s_glVertexAttrib2f(void *self , GLuint indx, GLfloat x, GLfloat y) {
6468     GL2Encoder* ctx = (GL2Encoder*)self;
6469     VALIDATE_VERTEX_ATTRIB_INDEX(indx);
6470     ctx->m_glVertexAttrib2f_enc(ctx, indx, x, y);
6471 }
6472 
s_glVertexAttrib3f(void * self,GLuint indx,GLfloat x,GLfloat y,GLfloat z)6473 void GL2Encoder::s_glVertexAttrib3f(void *self , GLuint indx, GLfloat x, GLfloat y, GLfloat z) {
6474     GL2Encoder* ctx = (GL2Encoder*)self;
6475     VALIDATE_VERTEX_ATTRIB_INDEX(indx);
6476     ctx->m_glVertexAttrib3f_enc(ctx, indx, x, y, z);
6477 }
6478 
s_glVertexAttrib4f(void * self,GLuint indx,GLfloat x,GLfloat y,GLfloat z,GLfloat w)6479 void GL2Encoder::s_glVertexAttrib4f(void *self , GLuint indx, GLfloat x, GLfloat y, GLfloat z, GLfloat w) {
6480     GL2Encoder* ctx = (GL2Encoder*)self;
6481     VALIDATE_VERTEX_ATTRIB_INDEX(indx);
6482     ctx->m_glVertexAttrib4f_enc(ctx, indx, x, y, z, w);
6483 }
6484 
s_glVertexAttrib1fv(void * self,GLuint indx,const GLfloat * values)6485 void GL2Encoder::s_glVertexAttrib1fv(void *self , GLuint indx, const GLfloat* values) {
6486     GL2Encoder* ctx = (GL2Encoder*)self;
6487     VALIDATE_VERTEX_ATTRIB_INDEX(indx);
6488     ctx->m_glVertexAttrib1fv_enc(ctx, indx, values);
6489 }
6490 
s_glVertexAttrib2fv(void * self,GLuint indx,const GLfloat * values)6491 void GL2Encoder::s_glVertexAttrib2fv(void *self , GLuint indx, const GLfloat* values) {
6492     GL2Encoder* ctx = (GL2Encoder*)self;
6493     VALIDATE_VERTEX_ATTRIB_INDEX(indx);
6494     ctx->m_glVertexAttrib2fv_enc(ctx, indx, values);
6495 }
6496 
s_glVertexAttrib3fv(void * self,GLuint indx,const GLfloat * values)6497 void GL2Encoder::s_glVertexAttrib3fv(void *self , GLuint indx, const GLfloat* values) {
6498     GL2Encoder* ctx = (GL2Encoder*)self;
6499     VALIDATE_VERTEX_ATTRIB_INDEX(indx);
6500     ctx->m_glVertexAttrib3fv_enc(ctx, indx, values);
6501 }
6502 
s_glVertexAttrib4fv(void * self,GLuint indx,const GLfloat * values)6503 void GL2Encoder::s_glVertexAttrib4fv(void *self , GLuint indx, const GLfloat* values) {
6504     GL2Encoder* ctx = (GL2Encoder*)self;
6505     VALIDATE_VERTEX_ATTRIB_INDEX(indx);
6506     ctx->m_glVertexAttrib4fv_enc(ctx, indx, values);
6507 }
6508 
s_glVertexAttribI4i(void * self,GLuint index,GLint v0,GLint v1,GLint v2,GLint v3)6509 void GL2Encoder::s_glVertexAttribI4i(void *self , GLuint index, GLint v0, GLint v1, GLint v2, GLint v3) {
6510     GL2Encoder* ctx = (GL2Encoder*)self;
6511     VALIDATE_VERTEX_ATTRIB_INDEX(index);
6512     ctx->m_glVertexAttribI4i_enc(ctx, index, v0, v1, v2, v3);
6513 }
6514 
s_glVertexAttribI4ui(void * self,GLuint index,GLuint v0,GLuint v1,GLuint v2,GLuint v3)6515 void GL2Encoder::s_glVertexAttribI4ui(void *self , GLuint index, GLuint v0, GLuint v1, GLuint v2, GLuint v3) {
6516     GL2Encoder* ctx = (GL2Encoder*)self;
6517     VALIDATE_VERTEX_ATTRIB_INDEX(index);
6518     ctx->m_glVertexAttribI4ui_enc(ctx, index, v0, v1, v2, v3);
6519 }
6520 
s_glVertexAttribI4iv(void * self,GLuint index,const GLint * v)6521 void GL2Encoder::s_glVertexAttribI4iv(void *self , GLuint index, const GLint* v) {
6522     GL2Encoder* ctx = (GL2Encoder*)self;
6523     VALIDATE_VERTEX_ATTRIB_INDEX(index);
6524     ctx->m_glVertexAttribI4iv_enc(ctx, index, v);
6525 }
6526 
s_glVertexAttribI4uiv(void * self,GLuint index,const GLuint * v)6527 void GL2Encoder::s_glVertexAttribI4uiv(void *self , GLuint index, const GLuint* v) {
6528     GL2Encoder* ctx = (GL2Encoder*)self;
6529     VALIDATE_VERTEX_ATTRIB_INDEX(index);
6530     ctx->m_glVertexAttribI4uiv_enc(ctx, index, v);
6531 }
6532 
s_glGetShaderPrecisionFormat(void * self,GLenum shadertype,GLenum precisiontype,GLint * range,GLint * precision)6533 void GL2Encoder::s_glGetShaderPrecisionFormat(void *self , GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision) {
6534     GL2Encoder* ctx = (GL2Encoder*)self;
6535     SET_ERROR_IF(!GLESv2Validation::allowedShaderType(shadertype), GL_INVALID_ENUM);
6536     SET_ERROR_IF(!GLESv2Validation::allowedPrecisionType(precisiontype), GL_INVALID_ENUM);
6537     ctx->m_glGetShaderPrecisionFormat_enc(ctx, shadertype, precisiontype, range, precision);
6538 }
6539 
s_glGetProgramiv(void * self,GLuint program,GLenum pname,GLint * params)6540 void GL2Encoder::s_glGetProgramiv(void *self , GLuint program, GLenum pname, GLint* params) {
6541     GL2Encoder* ctx = (GL2Encoder*)self;
6542     SET_ERROR_IF(!GLESv2Validation::allowedGetProgram(ctx->majorVersion(), ctx->minorVersion(), pname), GL_INVALID_ENUM);
6543     VALIDATE_PROGRAM_NAME(program);
6544     ctx->m_glGetProgramiv_enc(ctx, program, pname, params);
6545 }
6546 
s_glGetActiveUniform(void * self,GLuint program,GLuint index,GLsizei bufsize,GLsizei * length,GLint * size,GLenum * type,GLchar * name)6547 void GL2Encoder::s_glGetActiveUniform(void *self , GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name) {
6548     GL2Encoder* ctx = (GL2Encoder*)self;
6549     VALIDATE_PROGRAM_NAME(program);
6550     SET_ERROR_IF(index >= ctx->m_shared->getActiveUniformsCountForProgram(program), GL_INVALID_VALUE);
6551     ctx->m_glGetActiveUniform_enc(ctx, program, index, bufsize, length, size, type, name);
6552 }
6553 
s_glGetActiveUniformsiv(void * self,GLuint program,GLsizei uniformCount,const GLuint * uniformIndices,GLenum pname,GLint * params)6554 void GL2Encoder::s_glGetActiveUniformsiv(void *self , GLuint program, GLsizei uniformCount, const GLuint* uniformIndices, GLenum pname, GLint* params) {
6555     GL2Encoder* ctx = (GL2Encoder*)self;
6556     VALIDATE_PROGRAM_NAME(program);
6557     SET_ERROR_IF(uniformCount < 0, GL_INVALID_VALUE);
6558     SET_ERROR_IF(!GLESv2Validation::allowedGetActiveUniforms(pname), GL_INVALID_ENUM);
6559     int activeUniformsCount = ctx->m_shared->getActiveUniformsCountForProgram(program);
6560     for (GLsizei i = 0; i < uniformCount; ++i) {
6561         SET_ERROR_IF(uniformIndices[i] >= activeUniformsCount, GL_INVALID_VALUE);
6562     }
6563     ctx->m_glGetActiveUniformsiv_enc(ctx, program, uniformCount, uniformIndices, pname, params);
6564 }
6565 
s_glGetActiveUniformBlockName(void * self,GLuint program,GLuint uniformBlockIndex,GLsizei bufSize,GLsizei * length,GLchar * uniformBlockName)6566 void GL2Encoder::s_glGetActiveUniformBlockName(void *self , GLuint program, GLuint uniformBlockIndex, GLsizei bufSize, GLsizei* length, GLchar* uniformBlockName) {
6567     GL2Encoder* ctx = (GL2Encoder*)self;
6568     VALIDATE_PROGRAM_NAME(program);
6569     SET_ERROR_IF(bufSize < 0, GL_INVALID_VALUE);
6570     SET_ERROR_IF(uniformBlockIndex >= ctx->m_shared->getActiveUniformBlockCount(program), GL_INVALID_VALUE);
6571     ctx->m_glGetActiveUniformBlockName_enc(ctx, program, uniformBlockIndex, bufSize, length, uniformBlockName);
6572 }
6573 
s_glGetActiveAttrib(void * self,GLuint program,GLuint index,GLsizei bufsize,GLsizei * length,GLint * size,GLenum * type,GLchar * name)6574 void GL2Encoder::s_glGetActiveAttrib(void *self , GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name) {
6575     GL2Encoder* ctx = (GL2Encoder*)self;
6576     VALIDATE_PROGRAM_NAME(program);
6577     VALIDATE_VERTEX_ATTRIB_INDEX(index);
6578     SET_ERROR_IF(bufsize < 0, GL_INVALID_VALUE);
6579     SET_ERROR_IF(index >= ctx->m_shared->getActiveAttributesCountForProgram(program), GL_INVALID_VALUE);
6580     ctx->m_glGetActiveAttrib_enc(ctx, program, index, bufsize, length, size, type, name);
6581 }
6582 
s_glGetRenderbufferParameteriv(void * self,GLenum target,GLenum pname,GLint * params)6583 void GL2Encoder::s_glGetRenderbufferParameteriv(void *self , GLenum target, GLenum pname, GLint* params) {
6584     GL2Encoder* ctx = (GL2Encoder*)self;
6585     SET_ERROR_IF(target != GL_RENDERBUFFER, GL_INVALID_ENUM);
6586     SET_ERROR_IF(!GLESv2Validation::allowedGetRenderbufferParameter(pname), GL_INVALID_ENUM);
6587     SET_ERROR_IF(0 == ctx->m_state->boundRenderbuffer(), GL_INVALID_OPERATION);
6588     ctx->m_glGetRenderbufferParameteriv_enc(ctx, target, pname, params);
6589 }
6590 
s_glGetQueryiv(void * self,GLenum target,GLenum pname,GLint * params)6591 void GL2Encoder::s_glGetQueryiv(void *self , GLenum target, GLenum pname, GLint* params) {
6592     GL2Encoder* ctx = (GL2Encoder*)self;
6593     SET_ERROR_IF(!GLESv2Validation::allowedQueryTarget(target), GL_INVALID_ENUM);
6594     SET_ERROR_IF(!GLESv2Validation::allowedQueryParam(pname), GL_INVALID_ENUM);
6595     ctx->m_glGetQueryiv_enc(ctx, target, pname, params);
6596 }
6597 
s_glGetQueryObjectuiv(void * self,GLuint query,GLenum pname,GLuint * params)6598 void GL2Encoder::s_glGetQueryObjectuiv(void *self , GLuint query, GLenum pname, GLuint* params) {
6599     GL2Encoder* ctx = (GL2Encoder*)self;
6600     GLClientState* state = ctx->m_state;
6601     SET_ERROR_IF(!GLESv2Validation::allowedQueryObjectParam(pname), GL_INVALID_ENUM);
6602     SET_ERROR_IF(!state->queryExistence(GLClientState::ObjectType::Query, query), GL_INVALID_OPERATION);
6603     SET_ERROR_IF(!state->getLastQueryTarget(query), GL_INVALID_OPERATION);
6604     SET_ERROR_IF(ctx->m_state->isQueryObjectActive(query), GL_INVALID_OPERATION);
6605 
6606     ctx->m_glGetQueryObjectuiv_enc(ctx, query, pname, params);
6607 }
6608 
s_glIsEnabled(void * self,GLenum cap)6609 GLboolean GL2Encoder::s_glIsEnabled(void *self , GLenum cap) {
6610     GL2Encoder* ctx = (GL2Encoder*)self;
6611 	RET_AND_SET_ERROR_IF(!GLESv2Validation::allowedEnable(ctx->majorVersion(), ctx->minorVersion(), cap), GL_INVALID_ENUM, 0);
6612     return ctx->m_glIsEnabled_enc(ctx, cap);
6613 }
6614 
s_glHint(void * self,GLenum target,GLenum mode)6615 void GL2Encoder::s_glHint(void *self , GLenum target, GLenum mode) {
6616     GL2Encoder* ctx = (GL2Encoder*)self;
6617     SET_ERROR_IF(!GLESv2Validation::allowedHintTarget(target), GL_INVALID_ENUM);
6618     SET_ERROR_IF(!GLESv2Validation::allowedHintMode(mode), GL_INVALID_ENUM);
6619     ctx->m_glHint_enc(ctx, target, mode);
6620 }
6621 
s_glGetFragDataLocation(void * self,GLuint program,const char * name)6622 GLint GL2Encoder::s_glGetFragDataLocation (void *self , GLuint program, const char* name) {
6623     GL2Encoder* ctx = (GL2Encoder*)self;
6624     VALIDATE_PROGRAM_NAME_RET(program, -1);
6625     RET_AND_SET_ERROR_IF(!ctx->m_shared->getProgramLinkStatus(program), GL_INVALID_OPERATION, -1);
6626     return ctx->m_glGetFragDataLocation_enc(ctx, program, name);
6627 }
6628 
s_glStencilMask(void * self,GLuint mask)6629 void GL2Encoder::s_glStencilMask(void* self, GLuint mask) {
6630     GL2Encoder* ctx = (GL2Encoder*)self;
6631     if (!ctx->m_state) return;
6632     ctx->m_state->stencilMaskSeparate(GL_FRONT_AND_BACK, mask);
6633     ctx->m_glStencilMask_enc(ctx, mask);
6634 }
6635 
s_glClearStencil(void * self,int v)6636 void GL2Encoder::s_glClearStencil(void* self, int v) {
6637     GL2Encoder* ctx = (GL2Encoder*)self;
6638     if (!ctx->m_state) return;
6639     ctx->m_state->state_GL_STENCIL_CLEAR_VALUE = v;
6640     ctx->m_glClearStencil_enc(ctx, v);
6641 }
6642