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 
20 #include <string>
21 #include <map>
22 
23 #include <assert.h>
24 #include <ctype.h>
25 
26 #include <GLES2/gl2.h>
27 #include <GLES2/gl2ext.h>
28 #include <GLES2/gl2platform.h>
29 
30 #include <GLES3/gl3.h>
31 #include <GLES3/gl31.h>
32 
33 #ifndef MIN
34 #define MIN(a, b) ((a) < (b) ? (a) : (b))
35 #endif
36 
37 static GLubyte *gVendorString= (GLubyte *) "Android";
38 static GLubyte *gRendererString= (GLubyte *) "Android HW-GLES 3.0";
39 static GLubyte *gVersionString= (GLubyte *) "OpenGL ES 3.0";
40 static GLubyte *gExtensionsString= (GLubyte *) "GL_OES_EGL_image_external ";
41 
42 #define SET_ERROR_IF(condition, err) if((condition)) { \
43         ALOGE("%s:%s:%d GL error 0x%x\n", __FILE__, __FUNCTION__, __LINE__, err); \
44         ctx->setError(err); \
45         return; \
46     }
47 
48 #define SET_ERROR_WITH_MESSAGE_IF(condition, err, generator, genargs) if ((condition)) { \
49         std::string msg = generator genargs; \
50         ALOGE("%s:%s:%d GL error 0x%x\n" \
51               "Info: %s\n", __FILE__, __FUNCTION__, __LINE__, err, msg.c_str()); \
52         ctx->setError(err); \
53         return; \
54     } \
55 
56 #define RET_AND_SET_ERROR_IF(condition, err, ret) if((condition)) { \
57         ALOGE("%s:%s:%d GL error 0x%x\n", __FILE__, __FUNCTION__, __LINE__, err); \
58         ctx->setError(err);  \
59         return ret; \
60     } \
61 
62 #define RET_AND_SET_ERROR_WITH_MESSAGE_IF(condition, err, ret, generator, genargs) if((condition)) { \
63         std::string msg = generator genargs; \
64         ALOGE("%s:%s:%d GL error 0x%x\n" \
65               "Info: %s\n", __FILE__, __FUNCTION__, __LINE__, err, msg.c_str()); \
66         ctx->setError(err);   \
67         return ret; \
68     } \
69 
GL2Encoder(IOStream * stream,ChecksumCalculator * protocol)70 GL2Encoder::GL2Encoder(IOStream *stream, ChecksumCalculator *protocol)
71         : gl2_encoder_context_t(stream, protocol)
72 {
73     m_currMajorVersion = 2;
74     m_currMinorVersion = 0;
75     m_initialized = false;
76     m_state = NULL;
77     m_error = GL_NO_ERROR;
78     m_num_compressedTextureFormats = 0;
79     m_max_cubeMapTextureSize = 0;
80     m_max_renderBufferSize = 0;
81     m_max_textureSize = 0;
82     m_max_3d_textureSize = 0;
83     m_max_vertexAttribStride = 0;
84     m_compressedTextureFormats = NULL;
85 
86     m_ssbo_offset_align = 0;
87     m_ubo_offset_align = 0;
88 
89     m_drawCallFlushCount = 0;
90     m_primitiveRestartEnabled = false;
91     m_primitiveRestartIndex = 0;
92 
93     // overrides
94 #define OVERRIDE(name)  m_##name##_enc = this-> name ; this-> name = &s_##name
95 #define OVERRIDE_CUSTOM(name)  this-> name = &s_##name
96 #define OVERRIDEWITH(name, target)  do { \
97     m_##target##_enc = this-> target; \
98     this-> target = &s_##name; \
99 } while(0)
100 #define OVERRIDEOES(name) OVERRIDEWITH(name, name##OES)
101 
102     OVERRIDE(glFlush);
103     OVERRIDE(glPixelStorei);
104     OVERRIDE(glGetString);
105     OVERRIDE(glBindBuffer);
106     OVERRIDE(glBufferData);
107     OVERRIDE(glBufferSubData);
108     OVERRIDE(glDeleteBuffers);
109     OVERRIDE(glDrawArrays);
110     OVERRIDE(glDrawElements);
111     OVERRIDE(glGetIntegerv);
112     OVERRIDE(glGetFloatv);
113     OVERRIDE(glGetBooleanv);
114     OVERRIDE(glVertexAttribPointer);
115     OVERRIDE(glEnableVertexAttribArray);
116     OVERRIDE(glDisableVertexAttribArray);
117     OVERRIDE(glGetVertexAttribiv);
118     OVERRIDE(glGetVertexAttribfv);
119     OVERRIDE(glGetVertexAttribPointerv);
120 
121     this->glShaderBinary = &s_glShaderBinary;
122     this->glShaderSource = &s_glShaderSource;
123     this->glFinish = &s_glFinish;
124 
125     OVERRIDE(glGetError);
126     OVERRIDE(glLinkProgram);
127     OVERRIDE(glDeleteProgram);
128     OVERRIDE(glGetUniformiv);
129     OVERRIDE(glGetUniformfv);
130     OVERRIDE(glCreateProgram);
131     OVERRIDE(glCreateShader);
132     OVERRIDE(glDeleteShader);
133     OVERRIDE(glAttachShader);
134     OVERRIDE(glDetachShader);
135     OVERRIDE(glGetAttachedShaders);
136     OVERRIDE(glGetShaderSource);
137     OVERRIDE(glGetShaderInfoLog);
138     OVERRIDE(glGetProgramInfoLog);
139 
140     OVERRIDE(glGetUniformLocation);
141     OVERRIDE(glUseProgram);
142 
143     OVERRIDE(glUniform1f);
144     OVERRIDE(glUniform1fv);
145     OVERRIDE(glUniform1i);
146     OVERRIDE(glUniform1iv);
147     OVERRIDE(glUniform2f);
148     OVERRIDE(glUniform2fv);
149     OVERRIDE(glUniform2i);
150     OVERRIDE(glUniform2iv);
151     OVERRIDE(glUniform3f);
152     OVERRIDE(glUniform3fv);
153     OVERRIDE(glUniform3i);
154     OVERRIDE(glUniform3iv);
155     OVERRIDE(glUniform4f);
156     OVERRIDE(glUniform4fv);
157     OVERRIDE(glUniform4i);
158     OVERRIDE(glUniform4iv);
159     OVERRIDE(glUniformMatrix2fv);
160     OVERRIDE(glUniformMatrix3fv);
161     OVERRIDE(glUniformMatrix4fv);
162 
163     OVERRIDE(glActiveTexture);
164     OVERRIDE(glBindTexture);
165     OVERRIDE(glDeleteTextures);
166     OVERRIDE(glGetTexParameterfv);
167     OVERRIDE(glGetTexParameteriv);
168     OVERRIDE(glTexParameterf);
169     OVERRIDE(glTexParameterfv);
170     OVERRIDE(glTexParameteri);
171     OVERRIDE(glTexParameteriv);
172     OVERRIDE(glTexImage2D);
173     OVERRIDE(glTexSubImage2D);
174     OVERRIDE(glCopyTexImage2D);
175 
176     OVERRIDE(glGenRenderbuffers);
177     OVERRIDE(glDeleteRenderbuffers);
178     OVERRIDE(glBindRenderbuffer);
179     OVERRIDE(glRenderbufferStorage);
180     OVERRIDE(glFramebufferRenderbuffer);
181 
182     OVERRIDE(glGenFramebuffers);
183     OVERRIDE(glDeleteFramebuffers);
184     OVERRIDE(glBindFramebuffer);
185     OVERRIDE(glFramebufferTexture2D);
186     OVERRIDE(glFramebufferTexture3DOES);
187     OVERRIDE(glGetFramebufferAttachmentParameteriv);
188 
189     OVERRIDE(glCheckFramebufferStatus);
190 
191     OVERRIDE(glGenVertexArrays);
192     OVERRIDE(glDeleteVertexArrays);
193     OVERRIDE(glBindVertexArray);
194     OVERRIDEOES(glGenVertexArrays);
195     OVERRIDEOES(glDeleteVertexArrays);
196     OVERRIDEOES(glBindVertexArray);
197 
198     OVERRIDE_CUSTOM(glMapBufferRange);
199     OVERRIDE_CUSTOM(glUnmapBuffer);
200     OVERRIDE_CUSTOM(glFlushMappedBufferRange);
201 
202     OVERRIDE(glCompressedTexImage2D);
203     OVERRIDE(glCompressedTexSubImage2D);
204 
205     OVERRIDE(glBindBufferRange);
206     OVERRIDE(glBindBufferBase);
207 
208     OVERRIDE(glCopyBufferSubData);
209 
210     OVERRIDE(glGetBufferParameteriv);
211     OVERRIDE(glGetBufferParameteri64v);
212     OVERRIDE(glGetBufferPointerv);
213 
214     OVERRIDE_CUSTOM(glGetUniformIndices);
215 
216     OVERRIDE(glUniform1ui);
217     OVERRIDE(glUniform2ui);
218     OVERRIDE(glUniform3ui);
219     OVERRIDE(glUniform4ui);
220     OVERRIDE(glUniform1uiv);
221     OVERRIDE(glUniform2uiv);
222     OVERRIDE(glUniform3uiv);
223     OVERRIDE(glUniform4uiv);
224     OVERRIDE(glUniformMatrix2x3fv);
225     OVERRIDE(glUniformMatrix3x2fv);
226     OVERRIDE(glUniformMatrix2x4fv);
227     OVERRIDE(glUniformMatrix4x2fv);
228     OVERRIDE(glUniformMatrix3x4fv);
229     OVERRIDE(glUniformMatrix4x3fv);
230 
231     OVERRIDE(glGetUniformuiv);
232     OVERRIDE(glGetActiveUniformBlockiv);
233 
234     OVERRIDE(glGetVertexAttribIiv);
235     OVERRIDE(glGetVertexAttribIuiv);
236 
237     OVERRIDE_CUSTOM(glVertexAttribIPointer);
238 
239     OVERRIDE(glVertexAttribDivisor);
240 
241     OVERRIDE(glRenderbufferStorageMultisample);
242     OVERRIDE(glDrawBuffers);
243     OVERRIDE(glReadBuffer);
244     OVERRIDE(glFramebufferTextureLayer);
245     OVERRIDE(glTexStorage2D);
246 
247     OVERRIDE_CUSTOM(glTransformFeedbackVaryings);
248     OVERRIDE(glBeginTransformFeedback);
249     OVERRIDE(glEndTransformFeedback);
250     OVERRIDE(glPauseTransformFeedback);
251     OVERRIDE(glResumeTransformFeedback);
252 
253     OVERRIDE(glTexImage3D);
254     OVERRIDE(glTexSubImage3D);
255     OVERRIDE(glTexStorage3D);
256     OVERRIDE(glCompressedTexImage3D);
257     OVERRIDE(glCompressedTexSubImage3D);
258 
259     OVERRIDE(glDrawArraysInstanced);
260     OVERRIDE_CUSTOM(glDrawElementsInstanced);
261     OVERRIDE_CUSTOM(glDrawRangeElements);
262 
263     OVERRIDE_CUSTOM(glGetStringi);
264     OVERRIDE(glGetProgramBinary);
265     OVERRIDE(glReadPixels);
266 
267     OVERRIDE(glEnable);
268     OVERRIDE(glDisable);
269     OVERRIDE(glClearBufferiv);
270     OVERRIDE(glClearBufferuiv);
271     OVERRIDE(glClearBufferfv);
272     OVERRIDE(glBlitFramebuffer);
273     OVERRIDE_CUSTOM(glGetInternalformativ);
274 
275     OVERRIDE(glGenerateMipmap);
276 
277     OVERRIDE(glBindSampler);
278 
279     OVERRIDE_CUSTOM(glFenceSync);
280     OVERRIDE_CUSTOM(glClientWaitSync);
281     OVERRIDE_CUSTOM(glWaitSync);
282     OVERRIDE_CUSTOM(glDeleteSync);
283     OVERRIDE_CUSTOM(glIsSync);
284     OVERRIDE_CUSTOM(glGetSynciv);
285 
286     OVERRIDE(glGetIntegeri_v);
287     OVERRIDE(glGetInteger64i_v);
288 
289     OVERRIDE(glGetShaderiv);
290 
291     OVERRIDE(glActiveShaderProgram);
292     OVERRIDE_CUSTOM(glCreateShaderProgramv);
293     OVERRIDE(glProgramUniform1f);
294     OVERRIDE(glProgramUniform1fv);
295     OVERRIDE(glProgramUniform1i);
296     OVERRIDE(glProgramUniform1iv);
297     OVERRIDE(glProgramUniform1ui);
298     OVERRIDE(glProgramUniform1uiv);
299     OVERRIDE(glProgramUniform2f);
300     OVERRIDE(glProgramUniform2fv);
301     OVERRIDE(glProgramUniform2i);
302     OVERRIDE(glProgramUniform2iv);
303     OVERRIDE(glProgramUniform2ui);
304     OVERRIDE(glProgramUniform2uiv);
305     OVERRIDE(glProgramUniform3f);
306     OVERRIDE(glProgramUniform3fv);
307     OVERRIDE(glProgramUniform3i);
308     OVERRIDE(glProgramUniform3iv);
309     OVERRIDE(glProgramUniform3ui);
310     OVERRIDE(glProgramUniform3uiv);
311     OVERRIDE(glProgramUniform4f);
312     OVERRIDE(glProgramUniform4fv);
313     OVERRIDE(glProgramUniform4i);
314     OVERRIDE(glProgramUniform4iv);
315     OVERRIDE(glProgramUniform4ui);
316     OVERRIDE(glProgramUniform4uiv);
317     OVERRIDE(glProgramUniformMatrix2fv);
318     OVERRIDE(glProgramUniformMatrix2x3fv);
319     OVERRIDE(glProgramUniformMatrix2x4fv);
320     OVERRIDE(glProgramUniformMatrix3fv);
321     OVERRIDE(glProgramUniformMatrix3x2fv);
322     OVERRIDE(glProgramUniformMatrix3x4fv);
323     OVERRIDE(glProgramUniformMatrix4fv);
324     OVERRIDE(glProgramUniformMatrix4x2fv);
325     OVERRIDE(glProgramUniformMatrix4x3fv);
326 
327     OVERRIDE(glProgramParameteri);
328     OVERRIDE(glUseProgramStages);
329     OVERRIDE(glBindProgramPipeline);
330 
331     OVERRIDE(glGetProgramResourceiv);
332     OVERRIDE(glGetProgramResourceIndex);
333     OVERRIDE(glGetProgramResourceLocation);
334     OVERRIDE(glGetProgramResourceName);
335     OVERRIDE(glGetProgramPipelineInfoLog);
336 
337     OVERRIDE(glVertexAttribFormat);
338     OVERRIDE(glVertexAttribIFormat);
339     OVERRIDE(glVertexBindingDivisor);
340     OVERRIDE(glVertexAttribBinding);
341     OVERRIDE(glBindVertexBuffer);
342 
343     OVERRIDE_CUSTOM(glDrawArraysIndirect);
344     OVERRIDE_CUSTOM(glDrawElementsIndirect);
345 
346     OVERRIDE(glTexStorage2DMultisample);
347 }
348 
~GL2Encoder()349 GL2Encoder::~GL2Encoder()
350 {
351     delete m_compressedTextureFormats;
352 }
353 
s_glGetError(void * self)354 GLenum GL2Encoder::s_glGetError(void * self)
355 {
356     GL2Encoder *ctx = (GL2Encoder *)self;
357     GLenum err = ctx->getError();
358     if(err != GL_NO_ERROR) {
359         ctx->setError(GL_NO_ERROR);
360         return err;
361     }
362 
363     return ctx->m_glGetError_enc(self);
364 
365 }
366 
s_glFlush(void * self)367 void GL2Encoder::s_glFlush(void *self)
368 {
369     GL2Encoder *ctx = (GL2Encoder *) self;
370     ctx->m_glFlush_enc(self);
371     ctx->m_stream->flush();
372 }
373 
s_glGetString(void * self,GLenum name)374 const GLubyte *GL2Encoder::s_glGetString(void *self, GLenum name)
375 {
376     GL2Encoder *ctx = (GL2Encoder *)self;
377 
378     GLubyte *retval =  (GLubyte *) "";
379     RET_AND_SET_ERROR_IF(
380         name != GL_VENDOR &&
381         name != GL_RENDERER &&
382         name != GL_VERSION &&
383         name != GL_EXTENSIONS,
384         GL_INVALID_ENUM,
385         retval);
386     switch(name) {
387     case GL_VENDOR:
388         retval = gVendorString;
389         break;
390     case GL_RENDERER:
391         retval = gRendererString;
392         break;
393     case GL_VERSION:
394         retval = gVersionString;
395         break;
396     case GL_EXTENSIONS:
397         retval = gExtensionsString;
398         break;
399     }
400     return retval;
401 }
402 
s_glPixelStorei(void * self,GLenum param,GLint value)403 void GL2Encoder::s_glPixelStorei(void *self, GLenum param, GLint value)
404 {
405     GL2Encoder *ctx = (GL2Encoder *)self;
406     SET_ERROR_IF(!GLESv2Validation::pixelStoreParam(ctx, param), GL_INVALID_ENUM);
407     SET_ERROR_IF(!GLESv2Validation::pixelStoreValue(param, value), GL_INVALID_VALUE);
408     ctx->m_glPixelStorei_enc(ctx, param, value);
409     assert(ctx->m_state != NULL);
410     ctx->m_state->setPixelStore(param, value);
411 }
s_glBindBuffer(void * self,GLenum target,GLuint id)412 void GL2Encoder::s_glBindBuffer(void *self, GLenum target, GLuint id)
413 {
414     GL2Encoder *ctx = (GL2Encoder *) self;
415     assert(ctx->m_state != NULL);
416     ctx->m_state->bindBuffer(target, id);
417     ctx->m_state->addBuffer(id);
418     // TODO set error state if needed;
419     ctx->m_glBindBuffer_enc(self, target, id);
420 }
421 
s_glBufferData(void * self,GLenum target,GLsizeiptr size,const GLvoid * data,GLenum usage)422 void GL2Encoder::s_glBufferData(void * self, GLenum target, GLsizeiptr size, const GLvoid * data, GLenum usage)
423 {
424     GL2Encoder *ctx = (GL2Encoder *) self;
425     SET_ERROR_IF(!GLESv2Validation::bufferTarget(ctx, target), GL_INVALID_ENUM);
426     GLuint bufferId = ctx->m_state->getBuffer(target);
427     SET_ERROR_IF(bufferId==0, GL_INVALID_OPERATION);
428     SET_ERROR_IF(size<0, GL_INVALID_VALUE);
429 
430     ctx->m_shared->updateBufferData(bufferId, size, (void*)data);
431     ctx->m_shared->setBufferUsage(bufferId, usage);
432     ctx->m_glBufferData_enc(self, target, size, data, usage);
433 }
434 
s_glBufferSubData(void * self,GLenum target,GLintptr offset,GLsizeiptr size,const GLvoid * data)435 void GL2Encoder::s_glBufferSubData(void * self, GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid * data)
436 {
437     GL2Encoder *ctx = (GL2Encoder *) self;
438     SET_ERROR_IF(!GLESv2Validation::bufferTarget(ctx, target), GL_INVALID_ENUM);
439     GLuint bufferId = ctx->m_state->getBuffer(target);
440     SET_ERROR_IF(bufferId==0, GL_INVALID_OPERATION);
441     SET_ERROR_IF(ctx->isBufferTargetMapped(target), GL_INVALID_OPERATION);
442 
443     GLenum res = ctx->m_shared->subUpdateBufferData(bufferId, offset, size, (void*)data);
444     SET_ERROR_IF(res, res);
445 
446     ctx->m_glBufferSubData_enc(self, target, offset, size, data);
447 }
448 
s_glGenBuffers(void * self,GLsizei n,GLuint * buffers)449 void GL2Encoder::s_glGenBuffers(void* self, GLsizei n, GLuint* buffers) {
450     GL2Encoder *ctx = (GL2Encoder *) self;
451     SET_ERROR_IF(n<0, GL_INVALID_VALUE);
452     ctx->m_glGenBuffers_enc(self, n, buffers);
453     for (int i = 0; i < n; i++) {
454         ctx->m_state->addBuffer(buffers[i]);
455     }
456 }
457 
s_glDeleteBuffers(void * self,GLsizei n,const GLuint * buffers)458 void GL2Encoder::s_glDeleteBuffers(void * self, GLsizei n, const GLuint * buffers)
459 {
460     GL2Encoder *ctx = (GL2Encoder *) self;
461     SET_ERROR_IF(n<0, GL_INVALID_VALUE);
462     for (int i=0; i<n; i++) {
463         // Technically if the buffer is mapped, we should unmap it, but we won't
464         // use it anymore after this :)
465         ctx->m_shared->deleteBufferData(buffers[i]);
466         ctx->m_state->unBindBuffer(buffers[i]);
467         ctx->m_state->removeBuffer(buffers[i]);
468         ctx->m_glDeleteBuffers_enc(self,1,&buffers[i]);
469     }
470 }
471 
isValidVertexAttribIndex(void * self,GLuint indx)472 static bool isValidVertexAttribIndex(void *self, GLuint indx)
473 {
474     GL2Encoder *ctx = (GL2Encoder *)self;
475     GLint maxIndex;
476     ctx->glGetIntegerv(self, GL_MAX_VERTEX_ATTRIBS, &maxIndex);
477     return indx < maxIndex;
478 }
479 
480 #define VALIDATE_VERTEX_ATTRIB_INDEX(index) \
481     SET_ERROR_WITH_MESSAGE_IF( \
482             !isValidVertexAttribIndex(self, index), GL_INVALID_VALUE, \
483             GLESv2Validation::vertexAttribIndexRangeErrorMsg, (ctx, index)); \
484 
s_glVertexAttribPointer(void * self,GLuint indx,GLint size,GLenum type,GLboolean normalized,GLsizei stride,const GLvoid * ptr)485 void GL2Encoder::s_glVertexAttribPointer(void *self, GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid * ptr)
486 {
487     GL2Encoder *ctx = (GL2Encoder *)self;
488     assert(ctx->m_state != NULL);
489     VALIDATE_VERTEX_ATTRIB_INDEX(indx);
490     SET_ERROR_IF((size < 1 || size > 4), GL_INVALID_VALUE);
491     SET_ERROR_IF(!GLESv2Validation::vertexAttribType(ctx, type), GL_INVALID_ENUM);
492     SET_ERROR_IF(stride < 0, GL_INVALID_VALUE);
493     SET_ERROR_IF((type == GL_INT_2_10_10_10_REV ||
494                   type == GL_UNSIGNED_INT_2_10_10_10_REV) &&
495                  size != 4,
496                  GL_INVALID_OPERATION);
497     ctx->m_state->setVertexAttribBinding(indx, indx);
498     ctx->m_state->setVertexAttribFormat(indx, size, type, normalized, 0, false);
499 
500     GLsizei effectiveStride = stride;
501     if (stride == 0) {
502         effectiveStride = glSizeof(type) * size;
503         switch (type) {
504             case GL_INT_2_10_10_10_REV:
505             case GL_UNSIGNED_INT_2_10_10_10_REV:
506                 effectiveStride /= 4;
507                 break;
508             default:
509                 break;
510         }
511     }
512 
513     ctx->m_state->bindIndexedBuffer(0, indx, ctx->m_state->currentArrayVbo(), (uintptr_t)ptr, 0, stride, effectiveStride);
514 
515     if (ctx->m_state->currentArrayVbo() != 0) {
516         ctx->glVertexAttribPointerOffset(ctx, indx, size, type, normalized, stride, (uintptr_t)ptr);
517     } else {
518         SET_ERROR_IF(ctx->m_state->currentVertexArrayObject() != 0 && ptr, GL_INVALID_OPERATION);
519         // wait for client-array handler
520     }
521 }
522 
s_glGetIntegerv(void * self,GLenum param,GLint * ptr)523 void GL2Encoder::s_glGetIntegerv(void *self, GLenum param, GLint *ptr)
524 {
525     GL2Encoder *ctx = (GL2Encoder *) self;
526     assert(ctx->m_state != NULL);
527     GLClientState* state = ctx->m_state;
528 
529     switch (param) {
530     case GL_MAJOR_VERSION:
531         *ptr = ctx->m_deviceMajorVersion;
532         break;
533     case GL_MINOR_VERSION:
534         *ptr = ctx->m_deviceMinorVersion;
535         break;
536     case GL_NUM_SHADER_BINARY_FORMATS:
537         *ptr = 0;
538         break;
539     case GL_SHADER_BINARY_FORMATS:
540         // do nothing
541         break;
542 
543     case GL_COMPRESSED_TEXTURE_FORMATS: {
544         GLint *compressedTextureFormats = ctx->getCompressedTextureFormats();
545         if (ctx->m_num_compressedTextureFormats > 0 &&
546                 compressedTextureFormats != NULL) {
547             memcpy(ptr, compressedTextureFormats,
548                     ctx->m_num_compressedTextureFormats * sizeof(GLint));
549         }
550         break;
551     }
552 
553     case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS:
554     case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:
555     case GL_MAX_TEXTURE_IMAGE_UNITS:
556         ctx->m_glGetIntegerv_enc(self, param, ptr);
557         *ptr = MIN(*ptr, GLClientState::MAX_TEXTURE_UNITS);
558         break;
559 
560     case GL_TEXTURE_BINDING_2D:
561         *ptr = state->getBoundTexture(GL_TEXTURE_2D);
562         break;
563     case GL_TEXTURE_BINDING_EXTERNAL_OES:
564         *ptr = state->getBoundTexture(GL_TEXTURE_EXTERNAL_OES);
565         break;
566 
567     case GL_MAX_VERTEX_ATTRIBS:
568         if (!ctx->m_state->getClientStateParameter<GLint>(param, ptr)) {
569             ctx->m_glGetIntegerv_enc(self, param, ptr);
570             ctx->m_state->setMaxVertexAttribs(*ptr);
571         }
572         break;
573     case GL_MAX_VERTEX_ATTRIB_STRIDE:
574         if (ctx->m_max_vertexAttribStride != 0) {
575             *ptr = ctx->m_max_vertexAttribStride;
576         } else {
577             ctx->m_glGetIntegerv_enc(self, param, ptr);
578             ctx->m_max_vertexAttribStride = *ptr;
579         }
580         break;
581     case GL_MAX_CUBE_MAP_TEXTURE_SIZE:
582         if (ctx->m_max_cubeMapTextureSize != 0) {
583             *ptr = ctx->m_max_cubeMapTextureSize;
584         } else {
585             ctx->m_glGetIntegerv_enc(self, param, ptr);
586             ctx->m_max_cubeMapTextureSize = *ptr;
587         }
588         break;
589     case GL_MAX_RENDERBUFFER_SIZE:
590         if (ctx->m_max_renderBufferSize != 0) {
591             *ptr = ctx->m_max_renderBufferSize;
592         } else {
593             ctx->m_glGetIntegerv_enc(self, param, ptr);
594             ctx->m_max_renderBufferSize = *ptr;
595         }
596         break;
597     case GL_MAX_TEXTURE_SIZE:
598         if (ctx->m_max_textureSize != 0) {
599             *ptr = ctx->m_max_textureSize;
600         } else {
601             ctx->m_glGetIntegerv_enc(self, param, ptr);
602             ctx->m_max_textureSize = *ptr;
603         }
604         break;
605     case GL_MAX_3D_TEXTURE_SIZE:
606         if (ctx->m_max_3d_textureSize != 0) {
607             *ptr = ctx->m_max_3d_textureSize;
608         } else {
609             ctx->m_glGetIntegerv_enc(self, param, ptr);
610             ctx->m_max_3d_textureSize = *ptr;
611         }
612         break;
613     case GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT:
614         if (ctx->m_ssbo_offset_align != 0) {
615             *ptr = ctx->m_ssbo_offset_align;
616         } else {
617             ctx->m_glGetIntegerv_enc(self, param, ptr);
618             ctx->m_ssbo_offset_align = *ptr;
619         }
620         break;
621     case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT:
622         if (ctx->m_ubo_offset_align != 0) {
623             *ptr = ctx->m_ubo_offset_align;
624         } else {
625             ctx->m_glGetIntegerv_enc(self, param, ptr);
626             ctx->m_ubo_offset_align = *ptr;
627         }
628         break;
629     // Desktop OpenGL can allow a mindboggling # samples per pixel (such as 64).
630     // Limit to 4 (spec minimum) to keep dEQP tests from timing out.
631     case GL_MAX_SAMPLES:
632     case GL_MAX_COLOR_TEXTURE_SAMPLES:
633     case GL_MAX_INTEGER_SAMPLES:
634     case GL_MAX_DEPTH_TEXTURE_SAMPLES:
635         *ptr = 4;
636         break;
637     default:
638         if (!ctx->m_state->getClientStateParameter<GLint>(param, ptr)) {
639             ctx->m_glGetIntegerv_enc(self, param, ptr);
640         }
641         break;
642     }
643 }
644 
645 
s_glGetFloatv(void * self,GLenum param,GLfloat * ptr)646 void GL2Encoder::s_glGetFloatv(void *self, GLenum param, GLfloat *ptr)
647 {
648     GL2Encoder *ctx = (GL2Encoder *)self;
649     assert(ctx->m_state != NULL);
650     GLClientState* state = ctx->m_state;
651 
652     switch (param) {
653     case GL_NUM_SHADER_BINARY_FORMATS:
654         *ptr = 0;
655         break;
656     case GL_SHADER_BINARY_FORMATS:
657         // do nothing
658         break;
659 
660     case GL_COMPRESSED_TEXTURE_FORMATS: {
661         GLint *compressedTextureFormats = ctx->getCompressedTextureFormats();
662         if (ctx->m_num_compressedTextureFormats > 0 &&
663                 compressedTextureFormats != NULL) {
664             for (int i = 0; i < ctx->m_num_compressedTextureFormats; i++) {
665                 ptr[i] = (GLfloat) compressedTextureFormats[i];
666             }
667         }
668         break;
669     }
670 
671     case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS:
672     case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:
673     case GL_MAX_TEXTURE_IMAGE_UNITS:
674         ctx->m_glGetFloatv_enc(self, param, ptr);
675         *ptr = MIN(*ptr, (GLfloat)GLClientState::MAX_TEXTURE_UNITS);
676         break;
677 
678     case GL_TEXTURE_BINDING_2D:
679         *ptr = (GLfloat)state->getBoundTexture(GL_TEXTURE_2D);
680         break;
681     case GL_TEXTURE_BINDING_EXTERNAL_OES:
682         *ptr = (GLfloat)state->getBoundTexture(GL_TEXTURE_EXTERNAL_OES);
683         break;
684 
685     default:
686         if (!ctx->m_state->getClientStateParameter<GLfloat>(param, ptr)) {
687             ctx->m_glGetFloatv_enc(self, param, ptr);
688         }
689         break;
690     }
691 }
692 
693 
s_glGetBooleanv(void * self,GLenum param,GLboolean * ptr)694 void GL2Encoder::s_glGetBooleanv(void *self, GLenum param, GLboolean *ptr)
695 {
696     GL2Encoder *ctx = (GL2Encoder *)self;
697     assert(ctx->m_state != NULL);
698     GLClientState* state = ctx->m_state;
699 
700     switch (param) {
701     case GL_NUM_SHADER_BINARY_FORMATS:
702         *ptr = GL_FALSE;
703         break;
704     case GL_SHADER_BINARY_FORMATS:
705         // do nothing
706         break;
707 
708     case GL_COMPRESSED_TEXTURE_FORMATS: {
709         GLint *compressedTextureFormats = ctx->getCompressedTextureFormats();
710         if (ctx->m_num_compressedTextureFormats > 0 &&
711                 compressedTextureFormats != NULL) {
712             for (int i = 0; i < ctx->m_num_compressedTextureFormats; i++) {
713                 ptr[i] = compressedTextureFormats[i] != 0 ? GL_TRUE : GL_FALSE;
714             }
715         }
716         break;
717     }
718 
719     case GL_TEXTURE_BINDING_2D:
720         *ptr = state->getBoundTexture(GL_TEXTURE_2D) != 0 ? GL_TRUE : GL_FALSE;
721         break;
722     case GL_TEXTURE_BINDING_EXTERNAL_OES:
723         *ptr = state->getBoundTexture(GL_TEXTURE_EXTERNAL_OES) != 0
724                 ? GL_TRUE : GL_FALSE;
725         break;
726 
727     default:
728         if (!ctx->m_state->getClientStateParameter<GLboolean>(param, ptr)) {
729             ctx->m_glGetBooleanv_enc(self, param, ptr);
730         }
731         *ptr = (*ptr != 0) ? GL_TRUE : GL_FALSE;
732         break;
733     }
734 }
735 
736 
s_glEnableVertexAttribArray(void * self,GLuint index)737 void GL2Encoder::s_glEnableVertexAttribArray(void *self, GLuint index)
738 {
739     GL2Encoder *ctx = (GL2Encoder *)self;
740     assert(ctx->m_state);
741     VALIDATE_VERTEX_ATTRIB_INDEX(index);
742     ctx->m_glEnableVertexAttribArray_enc(ctx, index);
743     ctx->m_state->enable(index, 1);
744 }
745 
s_glDisableVertexAttribArray(void * self,GLuint index)746 void GL2Encoder::s_glDisableVertexAttribArray(void *self, GLuint index)
747 {
748     GL2Encoder *ctx = (GL2Encoder *)self;
749     assert(ctx->m_state);
750     VALIDATE_VERTEX_ATTRIB_INDEX(index);
751     ctx->m_glDisableVertexAttribArray_enc(ctx, index);
752     ctx->m_state->enable(index, 0);
753 }
754 
755 
s_glGetVertexAttribiv(void * self,GLuint index,GLenum pname,GLint * params)756 void GL2Encoder::s_glGetVertexAttribiv(void *self, GLuint index, GLenum pname, GLint *params)
757 {
758     GL2Encoder *ctx = (GL2Encoder *)self;
759     assert(ctx->m_state);
760     GLint maxIndex;
761     ctx->glGetIntegerv(self, GL_MAX_VERTEX_ATTRIBS, &maxIndex);
762     SET_ERROR_IF(!(index < maxIndex), GL_INVALID_VALUE);
763 
764     if (!ctx->m_state->getVertexAttribParameter<GLint>(index, pname, params)) {
765         ctx->m_glGetVertexAttribiv_enc(self, index, pname, params);
766     }
767 }
768 
s_glGetVertexAttribfv(void * self,GLuint index,GLenum pname,GLfloat * params)769 void GL2Encoder::s_glGetVertexAttribfv(void *self, GLuint index, GLenum pname, GLfloat *params)
770 {
771     GL2Encoder *ctx = (GL2Encoder *)self;
772     assert(ctx->m_state);
773     GLint maxIndex;
774     ctx->glGetIntegerv(self, GL_MAX_VERTEX_ATTRIBS, &maxIndex);
775     SET_ERROR_IF(!(index < maxIndex), GL_INVALID_VALUE);
776 
777     if (!ctx->m_state->getVertexAttribParameter<GLfloat>(index, pname, params)) {
778         ctx->m_glGetVertexAttribfv_enc(self, index, pname, params);
779     }
780 }
781 
s_glGetVertexAttribPointerv(void * self,GLuint index,GLenum pname,GLvoid ** pointer)782 void GL2Encoder::s_glGetVertexAttribPointerv(void *self, GLuint index, GLenum pname, GLvoid **pointer)
783 {
784     GL2Encoder *ctx = (GL2Encoder *)self;
785     if (ctx->m_state == NULL) return;
786     GLint maxIndex;
787     ctx->glGetIntegerv(self, GL_MAX_VERTEX_ATTRIBS, &maxIndex);
788     SET_ERROR_IF(!(index < maxIndex), GL_INVALID_VALUE);
789     SET_ERROR_IF(pname != GL_VERTEX_ATTRIB_ARRAY_POINTER, GL_INVALID_ENUM);
790     (void)pname;
791 
792     *pointer = (GLvoid*)(ctx->m_state->getCurrAttributeBindingInfo(index).offset);
793 }
794 
calcIndexRange(const void * indices,GLenum type,GLsizei count,int * minIndex_out,int * maxIndex_out)795 void GL2Encoder::calcIndexRange(const void* indices,
796                                 GLenum type,
797                                 GLsizei count,
798                                 int* minIndex_out,
799                                 int* maxIndex_out) {
800     switch(type) {
801     case GL_BYTE:
802     case GL_UNSIGNED_BYTE:
803         GLUtils::minmaxExcept(
804                 (unsigned char *)indices, count,
805                 minIndex_out, maxIndex_out,
806                 m_primitiveRestartEnabled, GLUtils::primitiveRestartIndex<unsigned char>());
807         break;
808     case GL_SHORT:
809     case GL_UNSIGNED_SHORT:
810         GLUtils::minmaxExcept(
811                 (unsigned short *)indices, count,
812                 minIndex_out, maxIndex_out,
813                 m_primitiveRestartEnabled, GLUtils::primitiveRestartIndex<unsigned short>());
814         break;
815     case GL_INT:
816     case GL_UNSIGNED_INT:
817         GLUtils::minmaxExcept(
818                 (unsigned int *)indices, count,
819                 minIndex_out, maxIndex_out,
820                 m_primitiveRestartEnabled, GLUtils::primitiveRestartIndex<unsigned int>());
821         break;
822     default:
823         ALOGE("unsupported index buffer type %d\n", type);
824     }
825 }
826 
recenterIndices(const void * src,GLenum type,GLsizei count,int minIndex)827 void* GL2Encoder::recenterIndices(const void* src,
828                                   GLenum type,
829                                   GLsizei count,
830                                   int minIndex) {
831 
832     void* adjustedIndices = (void*)src;
833 
834     if (minIndex != 0) {
835         adjustedIndices = m_fixedBuffer.alloc(glSizeof(type) * count);
836         switch(type) {
837         case GL_BYTE:
838         case GL_UNSIGNED_BYTE:
839             GLUtils::shiftIndicesExcept(
840                     (unsigned char *)src,
841                     (unsigned char *)adjustedIndices,
842                     count, -minIndex,
843                     m_primitiveRestartEnabled,
844                     (unsigned char)m_primitiveRestartIndex);
845             break;
846         case GL_SHORT:
847         case GL_UNSIGNED_SHORT:
848             GLUtils::shiftIndicesExcept(
849                     (unsigned short *)src,
850                     (unsigned short *)adjustedIndices,
851                     count, -minIndex,
852                     m_primitiveRestartEnabled,
853                     (unsigned short)m_primitiveRestartIndex);
854             break;
855         case GL_INT:
856         case GL_UNSIGNED_INT:
857             GLUtils::shiftIndicesExcept(
858                     (unsigned int *)src,
859                     (unsigned int *)adjustedIndices,
860                     count, -minIndex,
861                     m_primitiveRestartEnabled,
862                     (unsigned int)m_primitiveRestartIndex);
863             break;
864         default:
865             ALOGE("unsupported index buffer type %d\n", type);
866         }
867     }
868 
869     return adjustedIndices;
870 }
871 
getBufferIndexRange(BufferData * buf,const void * dataWithOffset,GLenum type,size_t count,size_t offset,int * minIndex_out,int * maxIndex_out)872 void GL2Encoder::getBufferIndexRange(BufferData* buf,
873                                      const void* dataWithOffset,
874                                      GLenum type,
875                                      size_t count,
876                                      size_t offset,
877                                      int* minIndex_out,
878                                      int* maxIndex_out) {
879 
880     if (buf->m_indexRangeCache.findRange(
881                 type, offset, count,
882                 m_primitiveRestartEnabled,
883                 minIndex_out,
884                 maxIndex_out)) {
885         return;
886     }
887 
888     calcIndexRange(dataWithOffset, type, count, minIndex_out, maxIndex_out);
889 
890     buf->m_indexRangeCache.addRange(
891             type, offset, count, m_primitiveRestartEnabled,
892             *minIndex_out, *maxIndex_out);
893 
894     ALOGV("%s: got range [%u %u] pr? %d", __FUNCTION__, *minIndex_out, *maxIndex_out, m_primitiveRestartEnabled);
895 }
896 
897 // For detecting legacy usage of glVertexAttribPointer
getVBOUsage(bool * hasClientArrays,bool * hasVBOs) const898 void GL2Encoder::getVBOUsage(bool* hasClientArrays, bool* hasVBOs) const {
899     if (hasClientArrays) *hasClientArrays = false;
900     if (hasVBOs) *hasVBOs = false;
901 
902     for (int i = 0; i < m_state->nLocations(); i++) {
903         const GLClientState::VertexAttribState& state = m_state->getState(i);
904         if (state.enabled) {
905             const GLClientState::BufferBinding& curr_binding = m_state->getCurrAttributeBindingInfo(i);
906             GLuint bufferObject = curr_binding.buffer;
907             if (bufferObject == 0 && curr_binding.offset && hasClientArrays) {
908                 *hasClientArrays = true;
909             }
910             if (bufferObject != 0 && hasVBOs) {
911                 *hasVBOs = true;
912             }
913         }
914     }
915 }
916 
sendVertexAttributes(GLint first,GLsizei count,bool hasClientArrays,GLsizei primcount)917 void GL2Encoder::sendVertexAttributes(GLint first, GLsizei count, bool hasClientArrays, GLsizei primcount)
918 {
919     assert(m_state);
920 
921     GLuint currentVao = m_state->currentVertexArrayObject();
922     GLuint lastBoundVbo = m_state->currentArrayVbo();
923     for (int i = 0; i < m_state->nLocations(); i++) {
924         bool enableDirty;
925         const GLClientState::VertexAttribState& state = m_state->getStateAndEnableDirty(i, &enableDirty);
926 
927         if (!enableDirty && !state.enabled) {
928             continue;
929         }
930 
931         if (state.enabled) {
932             const GLClientState::BufferBinding& curr_binding = m_state->getCurrAttributeBindingInfo(i);
933             GLuint bufferObject = curr_binding.buffer;
934             if (hasClientArrays && lastBoundVbo != bufferObject) {
935                 this->m_glBindBuffer_enc(this, GL_ARRAY_BUFFER, bufferObject);
936                 lastBoundVbo = bufferObject;
937             }
938 
939             int divisor = curr_binding.divisor;
940             int stride = curr_binding.stride;
941             int effectiveStride = curr_binding.effectiveStride;
942             uintptr_t offset = curr_binding.offset;
943 
944             int firstIndex = effectiveStride * first;
945             if (firstIndex && divisor && !primcount) {
946                 // If firstIndex != 0 according to effectiveStride * first,
947                 // it needs to be adjusted if a divisor has been specified,
948                 // even if we are not in glDraw***Instanced.
949                 firstIndex = 0;
950             }
951 
952             if (bufferObject == 0) {
953                 unsigned int datalen = state.elementSize * count;
954                 if (divisor && primcount) {
955                     ALOGV("%s: divisor for att %d: %d, w/ stride %d (effective stride %d) size %d type 0x%x) datalen %u",
956                             __FUNCTION__, i, divisor, state.stride, effectiveStride, state.elementSize, state.type, datalen);
957                     int actual_count = std::max(1, (int)((primcount + divisor - 1) / divisor));
958                     datalen = state.elementSize * actual_count;
959                     ALOGV("%s: actual datalen %u", __FUNCTION__, datalen);
960                 }
961                 if (state.elementSize == 0) {
962                     // The vertex attribute array is uninitialized. Abandon it.
963                     ALOGE("a vertex attribute array is uninitialized. Skipping corresponding vertex attribute.");
964                     this->m_glDisableVertexAttribArray_enc(this, i);
965                     continue;
966                 }
967                 m_glEnableVertexAttribArray_enc(this, i);
968 
969                 if (datalen && (!offset || !((unsigned char*)offset + firstIndex))) {
970                     ALOGD("%s: bad offset / len!!!!!", __FUNCTION__);
971                     continue;
972                 }
973                 if (state.isInt) {
974                     this->glVertexAttribIPointerDataAEMU(this, i, state.size, state.type, stride, (unsigned char *)offset + firstIndex, datalen);
975                 } else {
976                     this->glVertexAttribPointerData(this, i, state.size, state.type, state.normalized, stride, (unsigned char *)offset + firstIndex, datalen);
977                 }
978             } else {
979                 const BufferData* buf = m_shared->getBufferData(bufferObject);
980                 // The following expression actually means bufLen = stride*count;
981                 // But the last element doesn't have to fill up the whole stride.
982                 // So it becomes the current form.
983                 unsigned int bufLen = effectiveStride * (count ? (count - 1) : 0) + state.elementSize;
984                 if (divisor && primcount) {
985                     int actual_count = std::max(1, (int)((primcount + divisor - 1) / divisor));
986                     bufLen = effectiveStride * (actual_count ? (actual_count - 1) : 0) + state.elementSize;
987                 }
988                 if (buf && firstIndex >= 0 && firstIndex + bufLen <= buf->m_size) {
989                     if (hasClientArrays) {
990                         m_glEnableVertexAttribArray_enc(this, i);
991                         if (state.isInt) {
992                             this->glVertexAttribIPointerOffsetAEMU(this, i, state.size, state.type, stride, offset + firstIndex);
993                         } else {
994                             this->glVertexAttribPointerOffset(this, i, state.size, state.type, state.normalized, stride, offset + firstIndex);
995                         }
996                     }
997                 } else {
998                     ALOGE("a vertex attribute index out of boundary is detected. Skipping corresponding vertex attribute. buf=%p", buf);
999                     if (buf) {
1000                         ALOGE("Out of bounds vertex attribute info: "
1001                                 "clientArray? %d attribute %d vbo %u allocedBufferSize %u bufferDataSpecified? %d wantedStart %u wantedEnd %u",
1002                                 hasClientArrays, i, bufferObject, buf->m_size, buf != NULL, firstIndex, firstIndex + bufLen);
1003                     }
1004                     m_glDisableVertexAttribArray_enc(this, i);
1005                 }
1006             }
1007         } else {
1008             if (hasClientArrays) {
1009                 this->m_glDisableVertexAttribArray_enc(this, i);
1010             }
1011         }
1012     }
1013 
1014     if (hasClientArrays && lastBoundVbo != m_state->currentArrayVbo()) {
1015         this->m_glBindBuffer_enc(this, GL_ARRAY_BUFFER, m_state->currentArrayVbo());
1016     }
1017 }
1018 
flushDrawCall()1019 void GL2Encoder::flushDrawCall() {
1020     // This used to be every other draw call, but
1021     // now that we are using real GPU buffers on host,
1022     // set this to every 200 draw calls
1023     // (tuned on z840 linux NVIDIA Quadro K2200)
1024     if (m_drawCallFlushCount % 200 == 0) {
1025         m_stream->flush();
1026     }
1027     m_drawCallFlushCount++;
1028 }
1029 
isValidDrawMode(GLenum mode)1030 static bool isValidDrawMode(GLenum mode)
1031 {
1032     bool retval = false;
1033     switch (mode) {
1034     case GL_POINTS:
1035     case GL_LINE_STRIP:
1036     case GL_LINE_LOOP:
1037     case GL_LINES:
1038     case GL_TRIANGLE_STRIP:
1039     case GL_TRIANGLE_FAN:
1040     case GL_TRIANGLES:
1041         retval = true;
1042     }
1043     return retval;
1044 }
1045 
s_glDrawArrays(void * self,GLenum mode,GLint first,GLsizei count)1046 void GL2Encoder::s_glDrawArrays(void *self, GLenum mode, GLint first, GLsizei count)
1047 {
1048     GL2Encoder *ctx = (GL2Encoder *)self;
1049     assert(ctx->m_state != NULL);
1050     SET_ERROR_IF(!isValidDrawMode(mode), GL_INVALID_ENUM);
1051     SET_ERROR_IF(count < 0, GL_INVALID_VALUE);
1052 
1053     bool has_client_vertex_arrays = false;
1054     bool has_indirect_arrays = false;
1055     ctx->getVBOUsage(&has_client_vertex_arrays,
1056                      &has_indirect_arrays);
1057 
1058     if (has_client_vertex_arrays ||
1059         (!has_client_vertex_arrays &&
1060          !has_indirect_arrays)) {
1061         ctx->sendVertexAttributes(first, count, true);
1062         ctx->m_glDrawArrays_enc(ctx, mode, 0, count);
1063     } else {
1064         ctx->sendVertexAttributes(0, count, false);
1065         ctx->m_glDrawArrays_enc(ctx, mode, first, count);
1066     }
1067 }
1068 
1069 
s_glDrawElements(void * self,GLenum mode,GLsizei count,GLenum type,const void * indices)1070 void GL2Encoder::s_glDrawElements(void *self, GLenum mode, GLsizei count, GLenum type, const void *indices)
1071 {
1072 
1073     GL2Encoder *ctx = (GL2Encoder *)self;
1074     assert(ctx->m_state != NULL);
1075     SET_ERROR_IF(!isValidDrawMode(mode), GL_INVALID_ENUM);
1076     SET_ERROR_IF(count < 0, GL_INVALID_VALUE);
1077     SET_ERROR_IF(!(type == GL_UNSIGNED_BYTE || type == GL_UNSIGNED_SHORT || type == GL_UNSIGNED_INT), GL_INVALID_ENUM);
1078     SET_ERROR_IF(ctx->m_state->getTransformFeedbackActiveUnpaused(), GL_INVALID_OPERATION);
1079 
1080     bool has_client_vertex_arrays = false;
1081     bool has_indirect_arrays = false;
1082     int nLocations = ctx->m_state->nLocations();
1083     GLintptr offset = 0;
1084 
1085     ctx->getVBOUsage(&has_client_vertex_arrays, &has_indirect_arrays);
1086 
1087     if (!has_client_vertex_arrays && !has_indirect_arrays) {
1088         // ALOGW("glDrawElements: no vertex arrays / buffers bound to the command\n");
1089         GLenum status = ctx->m_glCheckFramebufferStatus_enc(self, GL_FRAMEBUFFER);
1090         SET_ERROR_IF(status != GL_FRAMEBUFFER_COMPLETE, GL_INVALID_FRAMEBUFFER_OPERATION);
1091     }
1092 
1093     BufferData* buf = NULL;
1094     int minIndex = 0, maxIndex = 0;
1095 
1096     // For validation/immediate index array purposes,
1097     // we need the min/max vertex index of the index array.
1098     // If the VBO != 0, this may not be the first time we have
1099     // used this particular index buffer. getBufferIndexRange
1100     // can more quickly get min/max vertex index by
1101     // caching previous results.
1102     if (ctx->m_state->currentIndexVbo() != 0) {
1103         buf = ctx->m_shared->getBufferData(ctx->m_state->currentIndexVbo());
1104         offset = (GLintptr)indices;
1105         indices = (void*)((GLintptr)buf->m_fixedBuffer.ptr() + (GLintptr)indices);
1106         ctx->getBufferIndexRange(buf,
1107                                  indices,
1108                                  type,
1109                                  (size_t)count,
1110                                  (size_t)offset,
1111                                  &minIndex, &maxIndex);
1112     } else {
1113         // In this case, the |indices| field holds a real
1114         // array, so calculate the indices now. They will
1115         // also be needed to know how much data to
1116         // transfer to host.
1117         ctx->calcIndexRange(indices,
1118                             type,
1119                             count,
1120                             &minIndex,
1121                             &maxIndex);
1122     }
1123 
1124     bool adjustIndices = true;
1125     if (ctx->m_state->currentIndexVbo() != 0) {
1126         if (!has_client_vertex_arrays) {
1127             ctx->sendVertexAttributes(0, maxIndex + 1, false);
1128             ctx->m_glBindBuffer_enc(self, GL_ELEMENT_ARRAY_BUFFER, ctx->m_state->currentIndexVbo());
1129             ctx->glDrawElementsOffset(ctx, mode, count, type, offset);
1130             ctx->flushDrawCall();
1131             adjustIndices = false;
1132         } else {
1133             BufferData * buf = ctx->m_shared->getBufferData(ctx->m_state->currentIndexVbo());
1134             ctx->m_glBindBuffer_enc(self, GL_ELEMENT_ARRAY_BUFFER, 0);
1135         }
1136     }
1137     if (adjustIndices) {
1138         void *adjustedIndices =
1139             ctx->recenterIndices(indices,
1140                                  type,
1141                                  count,
1142                                  minIndex);
1143 
1144         if (has_indirect_arrays || 1) {
1145             ctx->sendVertexAttributes(minIndex, maxIndex - minIndex + 1, true);
1146             ctx->glDrawElementsData(ctx, mode, count, type, adjustedIndices,
1147                                     count * glSizeof(type));
1148             // XXX - OPTIMIZATION (see the other else branch) should be implemented
1149             if(!has_indirect_arrays) {
1150                 //ALOGD("unoptimized drawelements !!!\n");
1151             }
1152         } else {
1153             // we are all direct arrays and immidate mode index array -
1154             // rebuild the arrays and the index array;
1155             ALOGE("glDrawElements: direct index & direct buffer data - will be implemented in later versions;\n");
1156         }
1157     }
1158 }
1159 
1160 
getCompressedTextureFormats()1161 GLint * GL2Encoder::getCompressedTextureFormats()
1162 {
1163     if (m_compressedTextureFormats == NULL) {
1164         this->glGetIntegerv(this, GL_NUM_COMPRESSED_TEXTURE_FORMATS,
1165                             &m_num_compressedTextureFormats);
1166         if (m_num_compressedTextureFormats > 0) {
1167             // get number of texture formats;
1168             m_compressedTextureFormats = new GLint[m_num_compressedTextureFormats];
1169             this->glGetCompressedTextureFormats(this, m_num_compressedTextureFormats, m_compressedTextureFormats);
1170         }
1171     }
1172     return m_compressedTextureFormats;
1173 }
1174 
1175 // Replace uses of samplerExternalOES with sampler2D, recording the names of
1176 // modified shaders in data. Also remove
1177 //   #extension GL_OES_EGL_image_external : require
1178 // statements.
1179 //
1180 // This implementation assumes the input has already been pre-processed. If not,
1181 // a few cases will be mishandled:
1182 //
1183 // 1. "mySampler" will be incorrectly recorded as being a samplerExternalOES in
1184 //    the following code:
1185 //      #if 1
1186 //      uniform sampler2D mySampler;
1187 //      #else
1188 //      uniform samplerExternalOES mySampler;
1189 //      #endif
1190 //
1191 // 2. Comments that look like sampler declarations will be incorrectly modified
1192 //    and recorded:
1193 //      // samplerExternalOES hahaFooledYou
1194 //
1195 // 3. However, GLSL ES does not have a concatentation operator, so things like
1196 //    this (valid in C) are invalid and not a problem:
1197 //      #define SAMPLER(TYPE, NAME) uniform sampler#TYPE NAME
1198 //      SAMPLER(ExternalOES, mySampler);
1199 //
replaceSamplerExternalWith2D(char * const str,ShaderData * const data)1200 static bool replaceSamplerExternalWith2D(char* const str, ShaderData* const data)
1201 {
1202     static const char STR_HASH_EXTENSION[] = "#extension";
1203     static const char STR_GL_OES_EGL_IMAGE_EXTERNAL[] = "GL_OES_EGL_image_external";
1204     static const char STR_SAMPLER_EXTERNAL_OES[] = "samplerExternalOES";
1205     static const char STR_SAMPLER2D_SPACE[]      = "sampler2D         ";
1206 
1207     // -- overwrite all "#extension GL_OES_EGL_image_external : xxx" statements
1208     char* c = str;
1209     while ((c = strstr(c, STR_HASH_EXTENSION))) {
1210         char* start = c;
1211         c += sizeof(STR_HASH_EXTENSION)-1;
1212         while (isspace(*c) && *c != '\0') {
1213             c++;
1214         }
1215         if (strncmp(c, STR_GL_OES_EGL_IMAGE_EXTERNAL,
1216                 sizeof(STR_GL_OES_EGL_IMAGE_EXTERNAL)-1) == 0)
1217         {
1218             // #extension statements are terminated by end of line
1219             c = start;
1220             while (*c != '\0' && *c != '\r' && *c != '\n') {
1221                 *c++ = ' ';
1222             }
1223         }
1224     }
1225 
1226     // -- replace "samplerExternalOES" with "sampler2D" and record name
1227     c = str;
1228     while ((c = strstr(c, STR_SAMPLER_EXTERNAL_OES))) {
1229         // Make sure "samplerExternalOES" isn't a substring of a larger token
1230         if (c == str || !isspace(*(c-1))) {
1231             c++;
1232             continue;
1233         }
1234         char* sampler_start = c;
1235         c += sizeof(STR_SAMPLER_EXTERNAL_OES)-1;
1236         if (!isspace(*c) && *c != '\0') {
1237             continue;
1238         }
1239 
1240         // capture sampler name
1241         while (isspace(*c) && *c != '\0') {
1242             c++;
1243         }
1244         if (!isalpha(*c) && *c != '_') {
1245             // not an identifier
1246             return false;
1247         }
1248         char* name_start = c;
1249         do {
1250             c++;
1251         } while (isalnum(*c) || *c == '_');
1252         data->samplerExternalNames.push_back(
1253                 android::String8(name_start, c - name_start));
1254 
1255         // memcpy instead of strcpy since we don't want the NUL terminator
1256         memcpy(sampler_start, STR_SAMPLER2D_SPACE, sizeof(STR_SAMPLER2D_SPACE)-1);
1257     }
1258 
1259     return true;
1260 }
1261 
s_glShaderBinary(void * self,GLsizei n,const GLuint * shaders,GLenum binaryformat,const void * binary,GLsizei length)1262 void GL2Encoder::s_glShaderBinary(void *self, GLsizei n, const GLuint *shaders, GLenum binaryformat, const void* binary, GLsizei length)
1263 {
1264     GL2Encoder* ctx = (GL2Encoder*)self;
1265     // Although it is not supported, need to set proper error code.
1266     SET_ERROR_IF(1, GL_INVALID_ENUM);
1267 }
1268 
s_glShaderSource(void * self,GLuint shader,GLsizei count,const GLchar * const * string,const GLint * length)1269 void GL2Encoder::s_glShaderSource(void *self, GLuint shader, GLsizei count, const GLchar * const *string, const GLint *length)
1270 {
1271     GL2Encoder* ctx = (GL2Encoder*)self;
1272     ShaderData* shaderData = ctx->m_shared->getShaderData(shader);
1273     SET_ERROR_IF(!ctx->m_shared->isShaderOrProgramObject(shader), GL_INVALID_VALUE);
1274     SET_ERROR_IF(!shaderData, GL_INVALID_OPERATION);
1275     SET_ERROR_IF((count<0), GL_INVALID_VALUE);
1276 
1277     // Track original sources---they may be translated in the backend
1278     std::vector<std::string> orig_sources;
1279     for (int i = 0; i < count; i++) {
1280         orig_sources.push_back(std::string((const char*)(string[i])));
1281     }
1282     shaderData->sources = orig_sources;
1283 
1284     int len = glUtilsCalcShaderSourceLen((char**)string, (GLint*)length, count);
1285     char *str = new char[len + 1];
1286     glUtilsPackStrings(str, (char**)string, (GLint*)length, count);
1287 
1288     // TODO: pre-process str before calling replaceSamplerExternalWith2D().
1289     // Perhaps we can borrow Mesa's pre-processor?
1290 
1291     if (!replaceSamplerExternalWith2D(str, shaderData)) {
1292         delete[] str;
1293         ctx->setError(GL_OUT_OF_MEMORY);
1294         return;
1295     }
1296     ctx->glShaderString(ctx, shader, str, len + 1);
1297     delete[] str;
1298 }
1299 
s_glFinish(void * self)1300 void GL2Encoder::s_glFinish(void *self)
1301 {
1302     GL2Encoder *ctx = (GL2Encoder *)self;
1303     ctx->glFinishRoundTrip(self);
1304 }
1305 
s_glLinkProgram(void * self,GLuint program)1306 void GL2Encoder::s_glLinkProgram(void * self, GLuint program)
1307 {
1308     GL2Encoder *ctx = (GL2Encoder *)self;
1309     bool isProgram = ctx->m_shared->isProgram(program);
1310     SET_ERROR_IF(!isProgram && !ctx->m_shared->isShader(program), GL_INVALID_VALUE);
1311     SET_ERROR_IF(!isProgram, GL_INVALID_OPERATION);
1312 
1313     ctx->m_glLinkProgram_enc(self, program);
1314 
1315     GLint linkStatus = 0;
1316     ctx->glGetProgramiv(self,program,GL_LINK_STATUS,&linkStatus);
1317     if (!linkStatus) {
1318         return;
1319     }
1320 
1321     //get number of active uniforms in the program
1322     GLint numUniforms=0;
1323     ctx->glGetProgramiv(self, program, GL_ACTIVE_UNIFORMS, &numUniforms);
1324     ctx->m_shared->initProgramData(program,numUniforms);
1325 
1326     //get the length of the longest uniform name
1327     GLint maxLength=0;
1328     ctx->glGetProgramiv(self, program, GL_ACTIVE_UNIFORM_MAX_LENGTH, &maxLength);
1329 
1330     GLint size;
1331     GLenum type;
1332     GLchar *name = new GLchar[maxLength+1];
1333     GLint location;
1334     //for each active uniform, get its size and starting location.
1335     for (GLint i=0 ; i<numUniforms ; ++i)
1336     {
1337         ctx->glGetActiveUniform(self, program, i, maxLength, NULL, &size, &type, name);
1338         location = ctx->m_glGetUniformLocation_enc(self, program, name);
1339         ctx->m_shared->setProgramIndexInfo(program, i, location, size, type, name);
1340     }
1341     ctx->m_shared->setupLocationShiftWAR(program);
1342 
1343     delete[] name;
1344 }
1345 
s_glDeleteProgram(void * self,GLuint program)1346 void GL2Encoder::s_glDeleteProgram(void *self, GLuint program)
1347 {
1348     GL2Encoder *ctx = (GL2Encoder*)self;
1349     ctx->m_glDeleteProgram_enc(self, program);
1350 
1351     ctx->m_shared->deleteProgramData(program);
1352 }
1353 
s_glGetUniformiv(void * self,GLuint program,GLint location,GLint * params)1354 void GL2Encoder::s_glGetUniformiv(void *self, GLuint program, GLint location, GLint* params)
1355 {
1356     GL2Encoder *ctx = (GL2Encoder*)self;
1357     SET_ERROR_IF(!ctx->m_shared->isShaderOrProgramObject(program), GL_INVALID_VALUE);
1358     SET_ERROR_IF(!ctx->m_shared->isProgram(program), GL_INVALID_OPERATION);
1359     SET_ERROR_IF(!ctx->m_shared->isProgramInitialized(program), GL_INVALID_OPERATION);
1360     GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
1361     SET_ERROR_IF(ctx->m_shared->getProgramUniformType(program,hostLoc)==0, GL_INVALID_OPERATION);
1362     ctx->m_glGetUniformiv_enc(self, program, hostLoc, params);
1363 }
s_glGetUniformfv(void * self,GLuint program,GLint location,GLfloat * params)1364 void GL2Encoder::s_glGetUniformfv(void *self, GLuint program, GLint location, GLfloat* params)
1365 {
1366     GL2Encoder *ctx = (GL2Encoder*)self;
1367     SET_ERROR_IF(!ctx->m_shared->isShaderOrProgramObject(program), GL_INVALID_VALUE);
1368     SET_ERROR_IF(!ctx->m_shared->isProgram(program), GL_INVALID_OPERATION);
1369     SET_ERROR_IF(!ctx->m_shared->isProgramInitialized(program), GL_INVALID_OPERATION);
1370     GLint hostLoc = ctx->m_shared->locationWARAppToHost(program,location);
1371     SET_ERROR_IF(ctx->m_shared->getProgramUniformType(program,hostLoc)==0, GL_INVALID_OPERATION);
1372     ctx->m_glGetUniformfv_enc(self, program, hostLoc, params);
1373 }
1374 
s_glCreateProgram(void * self)1375 GLuint GL2Encoder::s_glCreateProgram(void * self)
1376 {
1377     GL2Encoder *ctx = (GL2Encoder*)self;
1378     GLuint program = ctx->m_glCreateProgram_enc(self);
1379     if (program!=0)
1380         ctx->m_shared->addProgramData(program);
1381     return program;
1382 }
1383 
s_glCreateShader(void * self,GLenum shaderType)1384 GLuint GL2Encoder::s_glCreateShader(void *self, GLenum shaderType)
1385 {
1386     GL2Encoder *ctx = (GL2Encoder*)self;
1387     RET_AND_SET_ERROR_IF(!GLESv2Validation::shaderType(ctx, shaderType), GL_INVALID_ENUM, 0);
1388     GLuint shader = ctx->m_glCreateShader_enc(self, shaderType);
1389     if (shader != 0) {
1390         if (!ctx->m_shared->addShaderData(shader)) {
1391             ctx->m_glDeleteShader_enc(self, shader);
1392             return 0;
1393         }
1394     }
1395     return shader;
1396 }
1397 
s_glGetAttachedShaders(void * self,GLuint program,GLsizei maxCount,GLsizei * count,GLuint * shaders)1398 void GL2Encoder::s_glGetAttachedShaders(void *self, GLuint program, GLsizei maxCount,
1399         GLsizei* count, GLuint* shaders)
1400 {
1401     GL2Encoder *ctx = (GL2Encoder*)self;
1402     SET_ERROR_IF(maxCount < 0, GL_INVALID_VALUE);
1403     ctx->m_glGetAttachedShaders_enc(self, program, maxCount, count, shaders);
1404 }
1405 
s_glGetShaderSource(void * self,GLuint shader,GLsizei bufsize,GLsizei * length,GLchar * source)1406 void GL2Encoder::s_glGetShaderSource(void *self, GLuint shader, GLsizei bufsize,
1407             GLsizei* length, GLchar* source)
1408 {
1409     GL2Encoder *ctx = (GL2Encoder*)self;
1410     SET_ERROR_IF(bufsize < 0, GL_INVALID_VALUE);
1411     ctx->m_glGetShaderSource_enc(self, shader, bufsize, length, source);
1412     ShaderData* shaderData = ctx->m_shared->getShaderData(shader);
1413     if (shaderData) {
1414         std::string returned;
1415         int curr_len = 0;
1416         for (int i = 0; i < shaderData->sources.size(); i++) {
1417             if (curr_len + shaderData->sources[i].size() < bufsize - 1) {
1418                 returned += shaderData->sources[i];
1419             } else {
1420                 returned += shaderData->sources[i].substr(0, bufsize - 1 - curr_len);
1421                 break;
1422             }
1423         }
1424         memcpy(source, returned.substr(0, bufsize - 1).c_str(), bufsize);
1425     }
1426 }
1427 
s_glGetShaderInfoLog(void * self,GLuint shader,GLsizei bufsize,GLsizei * length,GLchar * infolog)1428 void GL2Encoder::s_glGetShaderInfoLog(void *self, GLuint shader, GLsizei bufsize,
1429         GLsizei* length, GLchar* infolog)
1430 {
1431     GL2Encoder *ctx = (GL2Encoder*)self;
1432     SET_ERROR_IF(bufsize < 0, GL_INVALID_VALUE);
1433     ctx->m_glGetShaderInfoLog_enc(self, shader, bufsize, length, infolog);
1434 }
1435 
s_glGetProgramInfoLog(void * self,GLuint program,GLsizei bufsize,GLsizei * length,GLchar * infolog)1436 void GL2Encoder::s_glGetProgramInfoLog(void *self, GLuint program, GLsizei bufsize,
1437         GLsizei* length, GLchar* infolog)
1438 {
1439     GL2Encoder *ctx = (GL2Encoder*)self;
1440     SET_ERROR_IF(bufsize < 0, GL_INVALID_VALUE);
1441     ctx->m_glGetProgramInfoLog_enc(self, program, bufsize, length, infolog);
1442 }
1443 
s_glDeleteShader(void * self,GLenum shader)1444 void GL2Encoder::s_glDeleteShader(void *self, GLenum shader)
1445 {
1446     GL2Encoder *ctx = (GL2Encoder*)self;
1447     ctx->m_glDeleteShader_enc(self,shader);
1448     ctx->m_shared->unrefShaderData(shader);
1449 }
1450 
s_glAttachShader(void * self,GLuint program,GLuint shader)1451 void GL2Encoder::s_glAttachShader(void *self, GLuint program, GLuint shader)
1452 {
1453     GL2Encoder *ctx = (GL2Encoder*)self;
1454     ctx->m_glAttachShader_enc(self, program, shader);
1455     ctx->m_shared->attachShader(program, shader);
1456 }
1457 
s_glDetachShader(void * self,GLuint program,GLuint shader)1458 void GL2Encoder::s_glDetachShader(void *self, GLuint program, GLuint shader)
1459 {
1460     GL2Encoder *ctx = (GL2Encoder*)self;
1461     ctx->m_glDetachShader_enc(self, program, shader);
1462     ctx->m_shared->detachShader(program, shader);
1463 }
1464 
sArrIndexOfUniformExpr(const char * name,int * err)1465 int sArrIndexOfUniformExpr(const char* name, int* err) {
1466     *err = 0;
1467     int arrIndex = 0;
1468     int namelen = strlen(name);
1469     if (name[namelen-1] == ']') {
1470         const char *brace = strrchr(name,'[');
1471         if (!brace || sscanf(brace+1,"%d",&arrIndex) != 1) {
1472             *err = 1; return 0;
1473         }
1474     }
1475     return arrIndex;
1476 }
1477 
s_glGetUniformLocation(void * self,GLuint program,const GLchar * name)1478 int GL2Encoder::s_glGetUniformLocation(void *self, GLuint program, const GLchar *name)
1479 {
1480     if (!name) return -1;
1481 
1482     GL2Encoder *ctx = (GL2Encoder*)self;
1483 
1484     // if we need the uniform location WAR
1485     // parse array index from the end of the name string
1486     int arrIndex = 0;
1487     bool needLocationWAR = ctx->m_shared->needUniformLocationWAR(program);
1488     if (needLocationWAR) {
1489         int err;
1490         arrIndex = sArrIndexOfUniformExpr(name, &err);
1491         if (err) return -1;
1492     }
1493 
1494     int hostLoc = ctx->m_glGetUniformLocation_enc(self, program, name);
1495     if (hostLoc >= 0 && needLocationWAR) {
1496         return ctx->m_shared->locationWARHostToApp(program, hostLoc, arrIndex);
1497     }
1498     return hostLoc;
1499 }
1500 
updateHostTexture2DBinding(GLenum texUnit,GLenum newTarget)1501 bool GL2Encoder::updateHostTexture2DBinding(GLenum texUnit, GLenum newTarget)
1502 {
1503     if (newTarget != GL_TEXTURE_2D && newTarget != GL_TEXTURE_EXTERNAL_OES)
1504         return false;
1505 
1506     m_state->setActiveTextureUnit(texUnit);
1507 
1508     GLenum oldTarget = m_state->getPriorityEnabledTarget(GL_TEXTURE_2D);
1509     if (newTarget != oldTarget) {
1510         if (newTarget == GL_TEXTURE_EXTERNAL_OES) {
1511             m_state->disableTextureTarget(GL_TEXTURE_2D);
1512             m_state->enableTextureTarget(GL_TEXTURE_EXTERNAL_OES);
1513         } else {
1514             m_state->disableTextureTarget(GL_TEXTURE_EXTERNAL_OES);
1515             m_state->enableTextureTarget(GL_TEXTURE_2D);
1516         }
1517         m_glActiveTexture_enc(this, texUnit);
1518         m_glBindTexture_enc(this, GL_TEXTURE_2D,
1519                 m_state->getBoundTexture(newTarget));
1520         return true;
1521     }
1522 
1523     return false;
1524 }
1525 
updateHostTexture2DBindingsFromProgramData(GLuint program)1526 void GL2Encoder::updateHostTexture2DBindingsFromProgramData(GLuint program) {
1527     GL2Encoder *ctx = this;
1528     GLClientState* state = ctx->m_state;
1529     GLSharedGroupPtr shared = ctx->m_shared;
1530 
1531     GLenum origActiveTexture = state->getActiveTextureUnit();
1532     GLenum hostActiveTexture = origActiveTexture;
1533     GLint samplerIdx = -1;
1534     GLint samplerVal;
1535     GLenum samplerTarget;
1536     while ((samplerIdx = shared->getNextSamplerUniform(program, samplerIdx, &samplerVal, &samplerTarget)) != -1) {
1537         if (samplerVal < 0 || samplerVal >= GLClientState::MAX_TEXTURE_UNITS)
1538             continue;
1539         if (ctx->updateHostTexture2DBinding(GL_TEXTURE0 + samplerVal,
1540                     samplerTarget))
1541         {
1542             hostActiveTexture = GL_TEXTURE0 + samplerVal;
1543         }
1544     }
1545     state->setActiveTextureUnit(origActiveTexture);
1546     if (hostActiveTexture != origActiveTexture) {
1547         ctx->m_glActiveTexture_enc(ctx, origActiveTexture);
1548     }
1549 }
1550 
s_glUseProgram(void * self,GLuint program)1551 void GL2Encoder::s_glUseProgram(void *self, GLuint program)
1552 {
1553     GL2Encoder *ctx = (GL2Encoder*)self;
1554     GLSharedGroupPtr shared = ctx->m_shared;
1555 
1556     SET_ERROR_IF(program && !shared->isShaderOrProgramObject(program), GL_INVALID_VALUE);
1557     SET_ERROR_IF(program && !shared->isProgram(program), GL_INVALID_OPERATION);
1558 
1559     ctx->m_glUseProgram_enc(self, program);
1560     ctx->m_state->setCurrentProgram(program);
1561     ctx->m_state->setCurrentShaderProgram(program);
1562 
1563     ctx->updateHostTexture2DBindingsFromProgramData(program);
1564 }
1565 
s_glUniform1f(void * self,GLint location,GLfloat x)1566 void GL2Encoder::s_glUniform1f(void *self , GLint location, GLfloat x)
1567 {
1568     GL2Encoder *ctx = (GL2Encoder*)self;
1569     GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
1570     ctx->m_glUniform1f_enc(self, hostLoc, x);
1571 }
1572 
s_glUniform1fv(void * self,GLint location,GLsizei count,const GLfloat * v)1573 void GL2Encoder::s_glUniform1fv(void *self , GLint location, GLsizei count, const GLfloat* v)
1574 {
1575     GL2Encoder *ctx = (GL2Encoder*)self;
1576     GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
1577     ctx->m_glUniform1fv_enc(self, hostLoc, count, v);
1578 }
1579 
s_glUniform1i(void * self,GLint location,GLint x)1580 void GL2Encoder::s_glUniform1i(void *self , GLint location, GLint x)
1581 {
1582     GL2Encoder *ctx = (GL2Encoder*)self;
1583     GLClientState* state = ctx->m_state;
1584     GLSharedGroupPtr shared = ctx->m_shared;
1585 
1586     GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
1587     ctx->m_glUniform1i_enc(self, hostLoc, x);
1588 
1589     GLenum target;
1590     if (shared->setSamplerUniform(state->currentShaderProgram(), location, x, &target)) {
1591         GLenum origActiveTexture = state->getActiveTextureUnit();
1592         if (ctx->updateHostTexture2DBinding(GL_TEXTURE0 + x, target)) {
1593             ctx->m_glActiveTexture_enc(self, origActiveTexture);
1594         }
1595         state->setActiveTextureUnit(origActiveTexture);
1596     }
1597 }
1598 
s_glUniform1iv(void * self,GLint location,GLsizei count,const GLint * v)1599 void GL2Encoder::s_glUniform1iv(void *self , GLint location, GLsizei count, const GLint* v)
1600 {
1601     GL2Encoder *ctx = (GL2Encoder*)self;
1602     GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
1603     ctx->m_glUniform1iv_enc(self, hostLoc, count, v);
1604 }
1605 
s_glUniform2f(void * self,GLint location,GLfloat x,GLfloat y)1606 void GL2Encoder::s_glUniform2f(void *self , GLint location, GLfloat x, GLfloat y)
1607 {
1608     GL2Encoder *ctx = (GL2Encoder*)self;
1609     GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
1610     ctx->m_glUniform2f_enc(self, hostLoc, x, y);
1611 }
1612 
s_glUniform2fv(void * self,GLint location,GLsizei count,const GLfloat * v)1613 void GL2Encoder::s_glUniform2fv(void *self , GLint location, GLsizei count, const GLfloat* v)
1614 {
1615     GL2Encoder *ctx = (GL2Encoder*)self;
1616     GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
1617     ctx->m_glUniform2fv_enc(self, hostLoc, count, v);
1618 }
1619 
s_glUniform2i(void * self,GLint location,GLint x,GLint y)1620 void GL2Encoder::s_glUniform2i(void *self , GLint location, GLint x, GLint y)
1621 {
1622     GL2Encoder *ctx = (GL2Encoder*)self;
1623     GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
1624     ctx->m_glUniform2i_enc(self, hostLoc, x, y);
1625 }
1626 
s_glUniform2iv(void * self,GLint location,GLsizei count,const GLint * v)1627 void GL2Encoder::s_glUniform2iv(void *self , GLint location, GLsizei count, const GLint* v)
1628 {
1629     GL2Encoder *ctx = (GL2Encoder*)self;
1630     GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
1631     ctx->m_glUniform2iv_enc(self, hostLoc, count, v);
1632 }
1633 
s_glUniform3f(void * self,GLint location,GLfloat x,GLfloat y,GLfloat z)1634 void GL2Encoder::s_glUniform3f(void *self , GLint location, GLfloat x, GLfloat y, GLfloat z)
1635 {
1636     GL2Encoder *ctx = (GL2Encoder*)self;
1637     GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
1638     ctx->m_glUniform3f_enc(self, hostLoc, x, y, z);
1639 }
1640 
s_glUniform3fv(void * self,GLint location,GLsizei count,const GLfloat * v)1641 void GL2Encoder::s_glUniform3fv(void *self , GLint location, GLsizei count, const GLfloat* v)
1642 {
1643     GL2Encoder *ctx = (GL2Encoder*)self;
1644     GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
1645     ctx->m_glUniform3fv_enc(self, hostLoc, count, v);
1646 }
1647 
s_glUniform3i(void * self,GLint location,GLint x,GLint y,GLint z)1648 void GL2Encoder::s_glUniform3i(void *self , GLint location, GLint x, GLint y, GLint z)
1649 {
1650     GL2Encoder *ctx = (GL2Encoder*)self;
1651     GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
1652     ctx->m_glUniform3i_enc(self, hostLoc, x, y, z);
1653 }
1654 
s_glUniform3iv(void * self,GLint location,GLsizei count,const GLint * v)1655 void GL2Encoder::s_glUniform3iv(void *self , GLint location, GLsizei count, const GLint* v)
1656 {
1657     GL2Encoder *ctx = (GL2Encoder*)self;
1658     GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
1659     ctx->m_glUniform3iv_enc(self, hostLoc, count, v);
1660 }
1661 
s_glUniform4f(void * self,GLint location,GLfloat x,GLfloat y,GLfloat z,GLfloat w)1662 void GL2Encoder::s_glUniform4f(void *self , GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
1663 {
1664     GL2Encoder *ctx = (GL2Encoder*)self;
1665     GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
1666     ctx->m_glUniform4f_enc(self, hostLoc, x, y, z, w);
1667 }
1668 
s_glUniform4fv(void * self,GLint location,GLsizei count,const GLfloat * v)1669 void GL2Encoder::s_glUniform4fv(void *self , GLint location, GLsizei count, const GLfloat* v)
1670 {
1671     GL2Encoder *ctx = (GL2Encoder*)self;
1672     GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
1673     ctx->m_glUniform4fv_enc(self, hostLoc, count, v);
1674 }
1675 
s_glUniform4i(void * self,GLint location,GLint x,GLint y,GLint z,GLint w)1676 void GL2Encoder::s_glUniform4i(void *self , GLint location, GLint x, GLint y, GLint z, GLint w)
1677 {
1678     GL2Encoder *ctx = (GL2Encoder*)self;
1679     GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
1680     ctx->m_glUniform4i_enc(self, hostLoc, x, y, z, w);
1681 }
1682 
s_glUniform4iv(void * self,GLint location,GLsizei count,const GLint * v)1683 void GL2Encoder::s_glUniform4iv(void *self , GLint location, GLsizei count, const GLint* v)
1684 {
1685     GL2Encoder *ctx = (GL2Encoder*)self;
1686     GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
1687     ctx->m_glUniform4iv_enc(self, hostLoc, count, v);
1688 }
1689 
s_glUniformMatrix2fv(void * self,GLint location,GLsizei count,GLboolean transpose,const GLfloat * value)1690 void GL2Encoder::s_glUniformMatrix2fv(void *self , GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
1691 {
1692     GL2Encoder *ctx = (GL2Encoder*)self;
1693     GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
1694     ctx->m_glUniformMatrix2fv_enc(self, hostLoc, count, transpose, value);
1695 }
1696 
s_glUniformMatrix3fv(void * self,GLint location,GLsizei count,GLboolean transpose,const GLfloat * value)1697 void GL2Encoder::s_glUniformMatrix3fv(void *self , GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
1698 {
1699     GL2Encoder *ctx = (GL2Encoder*)self;
1700     GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
1701     ctx->m_glUniformMatrix3fv_enc(self, hostLoc, count, transpose, value);
1702 }
1703 
s_glUniformMatrix4fv(void * self,GLint location,GLsizei count,GLboolean transpose,const GLfloat * value)1704 void GL2Encoder::s_glUniformMatrix4fv(void *self , GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
1705 {
1706     GL2Encoder *ctx = (GL2Encoder*)self;
1707     GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
1708     ctx->m_glUniformMatrix4fv_enc(self, hostLoc, count, transpose, value);
1709 }
1710 
s_glActiveTexture(void * self,GLenum texture)1711 void GL2Encoder::s_glActiveTexture(void* self, GLenum texture)
1712 {
1713     GL2Encoder* ctx = (GL2Encoder*)self;
1714     GLClientState* state = ctx->m_state;
1715     GLenum err;
1716 
1717     SET_ERROR_IF((err = state->setActiveTextureUnit(texture)) != GL_NO_ERROR, err);
1718 
1719     ctx->m_glActiveTexture_enc(ctx, texture);
1720 }
1721 
s_glBindTexture(void * self,GLenum target,GLuint texture)1722 void GL2Encoder::s_glBindTexture(void* self, GLenum target, GLuint texture)
1723 {
1724     GL2Encoder* ctx = (GL2Encoder*)self;
1725     GLClientState* state = ctx->m_state;
1726     GLenum err;
1727     GLboolean firstUse;
1728 
1729     SET_ERROR_IF(!GLESv2Validation::textureTarget(ctx, target), GL_INVALID_ENUM);
1730     SET_ERROR_IF((err = state->bindTexture(target, texture, &firstUse)) != GL_NO_ERROR, err);
1731 
1732     if (target != GL_TEXTURE_2D && target != GL_TEXTURE_EXTERNAL_OES) {
1733         ctx->m_glBindTexture_enc(ctx, target, texture);
1734         return;
1735     }
1736 
1737     GLenum priorityTarget = state->getPriorityEnabledTarget(GL_TEXTURE_2D);
1738 
1739     if (target == GL_TEXTURE_EXTERNAL_OES && firstUse) {
1740         ctx->m_glBindTexture_enc(ctx, GL_TEXTURE_2D, texture);
1741         ctx->m_glTexParameteri_enc(ctx, GL_TEXTURE_2D,
1742                 GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1743         ctx->m_glTexParameteri_enc(ctx, GL_TEXTURE_2D,
1744                 GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1745         ctx->m_glTexParameteri_enc(ctx, GL_TEXTURE_2D,
1746                 GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1747 
1748         if (target != priorityTarget) {
1749             ctx->m_glBindTexture_enc(ctx, GL_TEXTURE_2D,
1750                     state->getBoundTexture(GL_TEXTURE_2D));
1751         }
1752     }
1753 
1754     if (target == priorityTarget) {
1755         ctx->m_glBindTexture_enc(ctx, GL_TEXTURE_2D, texture);
1756     }
1757 }
1758 
s_glDeleteTextures(void * self,GLsizei n,const GLuint * textures)1759 void GL2Encoder::s_glDeleteTextures(void* self, GLsizei n, const GLuint* textures)
1760 {
1761     GL2Encoder* ctx = (GL2Encoder*)self;
1762     GLClientState* state = ctx->m_state;
1763 
1764     state->deleteTextures(n, textures);
1765     ctx->m_glDeleteTextures_enc(ctx, n, textures);
1766 }
1767 
s_glGetTexParameterfv(void * self,GLenum target,GLenum pname,GLfloat * params)1768 void GL2Encoder::s_glGetTexParameterfv(void* self,
1769         GLenum target, GLenum pname, GLfloat* params)
1770 {
1771     GL2Encoder* ctx = (GL2Encoder*)self;
1772     const GLClientState* state = ctx->m_state;
1773 
1774     if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
1775         ctx->override2DTextureTarget(target);
1776         ctx->m_glGetTexParameterfv_enc(ctx, GL_TEXTURE_2D, pname, params);
1777         ctx->restore2DTextureTarget(target);
1778     } else {
1779         ctx->m_glGetTexParameterfv_enc(ctx, target, pname, params);
1780     }
1781 }
1782 
s_glGetTexParameteriv(void * self,GLenum target,GLenum pname,GLint * params)1783 void GL2Encoder::s_glGetTexParameteriv(void* self,
1784         GLenum target, GLenum pname, GLint* params)
1785 {
1786     GL2Encoder* ctx = (GL2Encoder*)self;
1787     const GLClientState* state = ctx->m_state;
1788 
1789     switch (pname) {
1790     case GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES:
1791         *params = 1;
1792         break;
1793 
1794     default:
1795         if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
1796             ctx->override2DTextureTarget(target);
1797             ctx->m_glGetTexParameteriv_enc(ctx, GL_TEXTURE_2D, pname, params);
1798             ctx->restore2DTextureTarget(target);
1799         } else {
1800             ctx->m_glGetTexParameteriv_enc(ctx, target, pname, params);
1801         }
1802         break;
1803     }
1804 }
1805 
isValidTextureExternalParam(GLenum pname,GLenum param)1806 static bool isValidTextureExternalParam(GLenum pname, GLenum param)
1807 {
1808     switch (pname) {
1809     case GL_TEXTURE_MIN_FILTER:
1810     case GL_TEXTURE_MAG_FILTER:
1811         return param == GL_NEAREST || param == GL_LINEAR;
1812 
1813     case GL_TEXTURE_WRAP_S:
1814     case GL_TEXTURE_WRAP_T:
1815         return param == GL_CLAMP_TO_EDGE;
1816 
1817     default:
1818         return true;
1819     }
1820 }
1821 
s_glTexParameterf(void * self,GLenum target,GLenum pname,GLfloat param)1822 void GL2Encoder::s_glTexParameterf(void* self,
1823         GLenum target, GLenum pname, GLfloat param)
1824 {
1825     GL2Encoder* ctx = (GL2Encoder*)self;
1826     const GLClientState* state = ctx->m_state;
1827 
1828     SET_ERROR_IF((target == GL_TEXTURE_EXTERNAL_OES &&
1829             !isValidTextureExternalParam(pname, (GLenum)param)),
1830             GL_INVALID_ENUM);
1831 
1832     if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
1833         ctx->override2DTextureTarget(target);
1834         ctx->m_glTexParameterf_enc(ctx, GL_TEXTURE_2D, pname, param);
1835         ctx->restore2DTextureTarget(target);
1836     } else {
1837         ctx->m_glTexParameterf_enc(ctx, target, pname, param);
1838     }
1839 }
1840 
s_glTexParameterfv(void * self,GLenum target,GLenum pname,const GLfloat * params)1841 void GL2Encoder::s_glTexParameterfv(void* self,
1842         GLenum target, GLenum pname, const GLfloat* params)
1843 {
1844     GL2Encoder* ctx = (GL2Encoder*)self;
1845     const GLClientState* state = ctx->m_state;
1846 
1847     SET_ERROR_IF((target == GL_TEXTURE_EXTERNAL_OES &&
1848             !isValidTextureExternalParam(pname, (GLenum)params[0])),
1849             GL_INVALID_ENUM);
1850 
1851     if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
1852         ctx->override2DTextureTarget(target);
1853         ctx->m_glTexParameterfv_enc(ctx, GL_TEXTURE_2D, pname, params);
1854         ctx->restore2DTextureTarget(target);
1855     } else {
1856         ctx->m_glTexParameterfv_enc(ctx, target, pname, params);
1857     }
1858 }
1859 
s_glTexParameteri(void * self,GLenum target,GLenum pname,GLint param)1860 void GL2Encoder::s_glTexParameteri(void* self,
1861         GLenum target, GLenum pname, GLint param)
1862 {
1863     GL2Encoder* ctx = (GL2Encoder*)self;
1864     const GLClientState* state = ctx->m_state;
1865 
1866     SET_ERROR_IF((target == GL_TEXTURE_EXTERNAL_OES &&
1867             !isValidTextureExternalParam(pname, (GLenum)param)),
1868             GL_INVALID_ENUM);
1869 
1870     if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
1871         ctx->override2DTextureTarget(target);
1872         ctx->m_glTexParameteri_enc(ctx, GL_TEXTURE_2D, pname, param);
1873         ctx->restore2DTextureTarget(target);
1874     } else {
1875         ctx->m_glTexParameteri_enc(ctx, target, pname, param);
1876     }
1877 }
1878 
ilog2(uint32_t x)1879 static int ilog2(uint32_t x) {
1880     int p = 0;
1881     while ((1 << p) < x)
1882         p++;
1883     return p;
1884 }
1885 
s_glTexImage2D(void * self,GLenum target,GLint level,GLint internalformat,GLsizei width,GLsizei height,GLint border,GLenum format,GLenum type,const GLvoid * pixels)1886 void GL2Encoder::s_glTexImage2D(void* self, GLenum target, GLint level,
1887         GLint internalformat, GLsizei width, GLsizei height, GLint border,
1888         GLenum format, GLenum type, const GLvoid* pixels)
1889 {
1890     GL2Encoder* ctx = (GL2Encoder*)self;
1891     GLClientState* state = ctx->m_state;
1892 
1893     SET_ERROR_IF(!GLESv2Validation::textureTarget(ctx, target), GL_INVALID_ENUM);
1894     SET_ERROR_IF(!GLESv2Validation::pixelType(ctx, type), GL_INVALID_ENUM);
1895     SET_ERROR_IF(!GLESv2Validation::pixelFormat(ctx, format), GL_INVALID_ENUM);
1896     // If unpack buffer is nonzero, verify unmapped state.
1897     SET_ERROR_IF(ctx->isBufferTargetMapped(GL_PIXEL_UNPACK_BUFFER), GL_INVALID_OPERATION);
1898 
1899     GLint max_texture_size;
1900     GLint max_cube_map_texture_size;
1901     ctx->glGetIntegerv(ctx, GL_MAX_TEXTURE_SIZE, &max_texture_size);
1902     ctx->glGetIntegerv(ctx, GL_MAX_CUBE_MAP_TEXTURE_SIZE, &max_cube_map_texture_size);
1903     SET_ERROR_IF(level < 0, GL_INVALID_VALUE);
1904     SET_ERROR_IF(level > ilog2(max_texture_size), GL_INVALID_VALUE);
1905     SET_ERROR_IF((target == GL_TEXTURE_CUBE_MAP) &&
1906                  (level > ilog2(max_cube_map_texture_size)), GL_INVALID_VALUE);
1907     SET_ERROR_IF(width < 0 || height < 0, GL_INVALID_VALUE);
1908     SET_ERROR_IF(width > max_texture_size, GL_INVALID_VALUE);
1909     SET_ERROR_IF(height > max_texture_size, GL_INVALID_VALUE);
1910     SET_ERROR_IF(GLESv2Validation::isCubeMapTarget(target) && width > max_cube_map_texture_size, GL_INVALID_VALUE);
1911     SET_ERROR_IF(GLESv2Validation::isCubeMapTarget(target) && height > max_cube_map_texture_size, GL_INVALID_VALUE);
1912     SET_ERROR_IF(border != 0, GL_INVALID_VALUE);
1913     // If unpack buffer is nonzero, verify buffer data fits and is evenly divisible by the type.
1914     SET_ERROR_IF(ctx->boundBuffer(GL_PIXEL_UNPACK_BUFFER) &&
1915                  ctx->getBufferData(GL_PIXEL_UNPACK_BUFFER) &&
1916                  (ctx->m_state->pboNeededDataSize(width, height, 1, format, type, 0) >
1917                   ctx->getBufferData(GL_PIXEL_UNPACK_BUFFER)->m_size),
1918                  GL_INVALID_OPERATION);
1919     SET_ERROR_IF(ctx->boundBuffer(GL_PIXEL_UNPACK_BUFFER) &&
1920                  ctx->getBufferData(GL_PIXEL_UNPACK_BUFFER) &&
1921                  (ctx->getBufferData(GL_PIXEL_UNPACK_BUFFER)->m_size %
1922                   glSizeof(type)),
1923                  GL_INVALID_OPERATION);
1924     SET_ERROR_IF(ctx->boundBuffer(GL_PIXEL_UNPACK_BUFFER) &&
1925                  ctx->getBufferData(GL_PIXEL_UNPACK_BUFFER) &&
1926                  ((uintptr_t)pixels % glSizeof(type)),
1927                  GL_INVALID_OPERATION);
1928     SET_ERROR_IF(state->isBoundTextureImmutableFormat(target), GL_INVALID_OPERATION);
1929 
1930     GLenum stateTarget = target;
1931     if (target == GL_TEXTURE_CUBE_MAP_POSITIVE_X ||
1932         target == GL_TEXTURE_CUBE_MAP_POSITIVE_Y ||
1933         target == GL_TEXTURE_CUBE_MAP_POSITIVE_Z ||
1934         target == GL_TEXTURE_CUBE_MAP_NEGATIVE_X ||
1935         target == GL_TEXTURE_CUBE_MAP_NEGATIVE_Y ||
1936         target == GL_TEXTURE_CUBE_MAP_NEGATIVE_Z)
1937         stateTarget = GL_TEXTURE_CUBE_MAP;
1938 
1939     state->setBoundTextureInternalFormat(stateTarget, internalformat);
1940     state->setBoundTextureFormat(stateTarget, format);
1941     state->setBoundTextureType(stateTarget, type);
1942     state->setBoundTextureDims(stateTarget, level, width, height, 1);
1943 
1944     if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
1945         ctx->override2DTextureTarget(target);
1946     }
1947 
1948     if (ctx->boundBuffer(GL_PIXEL_UNPACK_BUFFER)) {
1949         ctx->glTexImage2DOffsetAEMU(
1950                 ctx, target, level, internalformat,
1951                 width, height, border,
1952                 format, type, (uintptr_t)pixels);
1953     } else {
1954         ctx->m_glTexImage2D_enc(
1955                 ctx, target, level, internalformat,
1956                 width, height, border,
1957                 format, type, pixels);
1958     }
1959 
1960     if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
1961         ctx->restore2DTextureTarget(target);
1962     }
1963 }
1964 
s_glTexSubImage2D(void * self,GLenum target,GLint level,GLint xoffset,GLint yoffset,GLsizei width,GLsizei height,GLenum format,GLenum type,const GLvoid * pixels)1965 void GL2Encoder::s_glTexSubImage2D(void* self, GLenum target, GLint level,
1966         GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format,
1967         GLenum type, const GLvoid* pixels)
1968 {
1969     GL2Encoder* ctx = (GL2Encoder*)self;
1970     GLClientState* state = ctx->m_state;
1971 
1972     SET_ERROR_IF(!GLESv2Validation::textureTarget(ctx, target), GL_INVALID_ENUM);
1973     SET_ERROR_IF(!GLESv2Validation::pixelType(ctx, type), GL_INVALID_ENUM);
1974     SET_ERROR_IF(!GLESv2Validation::pixelFormat(ctx, format), GL_INVALID_ENUM);
1975     // If unpack buffer is nonzero, verify unmapped state.
1976     SET_ERROR_IF(ctx->isBufferTargetMapped(GL_PIXEL_UNPACK_BUFFER), GL_INVALID_OPERATION);
1977 
1978     GLint max_texture_size;
1979     GLint max_cube_map_texture_size;
1980     ctx->glGetIntegerv(ctx, GL_MAX_TEXTURE_SIZE, &max_texture_size);
1981     ctx->glGetIntegerv(ctx, GL_MAX_CUBE_MAP_TEXTURE_SIZE, &max_cube_map_texture_size);
1982     SET_ERROR_IF(level < 0, GL_INVALID_VALUE);
1983     SET_ERROR_IF(level > ilog2(max_texture_size), GL_INVALID_VALUE);
1984     SET_ERROR_IF(GLESv2Validation::isCubeMapTarget(target) &&
1985                  level > ilog2(max_cube_map_texture_size), GL_INVALID_VALUE);
1986     SET_ERROR_IF(width < 0 || height < 0, GL_INVALID_VALUE);
1987     SET_ERROR_IF(xoffset < 0 || yoffset < 0, GL_INVALID_VALUE);
1988 
1989     GLuint tex = state->getBoundTexture(target);
1990     GLsizei neededWidth = xoffset + width;
1991     GLsizei neededHeight = yoffset + height;
1992     GLsizei neededDepth = 1;
1993 
1994     if (tex && !state->queryTexEGLImageBacked(tex)) {
1995         SET_ERROR_IF(
1996                 (neededWidth > state->queryTexWidth(level, tex) ||
1997                  neededHeight > state->queryTexHeight(level, tex) ||
1998                  neededDepth > state->queryTexDepth(level, tex)),
1999                 GL_INVALID_VALUE);
2000     }
2001 
2002     // If unpack buffer is nonzero, verify buffer data fits and is evenly divisible by the type.
2003     SET_ERROR_IF(ctx->boundBuffer(GL_PIXEL_UNPACK_BUFFER) &&
2004                  ctx->getBufferData(GL_PIXEL_UNPACK_BUFFER) &&
2005                  (state->pboNeededDataSize(width, height, 1, format, type, 0) >
2006                   ctx->getBufferData(GL_PIXEL_UNPACK_BUFFER)->m_size),
2007                  GL_INVALID_OPERATION);
2008     SET_ERROR_IF(ctx->boundBuffer(GL_PIXEL_UNPACK_BUFFER) &&
2009                  ctx->getBufferData(GL_PIXEL_UNPACK_BUFFER) &&
2010                  (ctx->getBufferData(GL_PIXEL_UNPACK_BUFFER)->m_size %
2011                   glSizeof(type)),
2012                  GL_INVALID_OPERATION);
2013     SET_ERROR_IF(!ctx->boundBuffer(GL_PIXEL_UNPACK_BUFFER) && !pixels, GL_INVALID_OPERATION);
2014 
2015     if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
2016         ctx->override2DTextureTarget(target);
2017     }
2018 
2019     if (ctx->boundBuffer(GL_PIXEL_UNPACK_BUFFER)) {
2020         ctx->glTexSubImage2DOffsetAEMU(
2021                 ctx, target, level,
2022                 xoffset, yoffset, width, height,
2023                 format, type, (uintptr_t)pixels);
2024     } else {
2025         ctx->m_glTexSubImage2D_enc(ctx, target, level, xoffset, yoffset, width,
2026                 height, format, type, pixels);
2027     }
2028 
2029     if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
2030         ctx->restore2DTextureTarget(target);
2031     }
2032 }
2033 
s_glCopyTexImage2D(void * self,GLenum target,GLint level,GLenum internalformat,GLint x,GLint y,GLsizei width,GLsizei height,GLint border)2034 void GL2Encoder::s_glCopyTexImage2D(void* self, GLenum target, GLint level,
2035         GLenum internalformat, GLint x, GLint y,
2036         GLsizei width, GLsizei height, GLint border)
2037 {
2038     GL2Encoder* ctx = (GL2Encoder*)self;
2039     GLClientState* state = ctx->m_state;
2040 
2041     SET_ERROR_IF(ctx->glCheckFramebufferStatus(ctx, GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE,
2042                  GL_INVALID_FRAMEBUFFER_OPERATION);
2043     // This is needed to work around underlying OpenGL drivers
2044     // (such as those feeding some some AMD GPUs) that expect
2045     // positive components of cube maps to be defined _before_
2046     // the negative components (otherwise a segfault occurs).
2047     GLenum extraTarget =
2048         state->copyTexImageLuminanceCubeMapAMDWorkaround
2049             (target, level, internalformat);
2050 
2051     if (extraTarget) {
2052         ctx->m_glCopyTexImage2D_enc(ctx, extraTarget, level, internalformat,
2053                                     x, y, width, height, border);
2054     }
2055 
2056     ctx->m_glCopyTexImage2D_enc(ctx, target, level, internalformat,
2057                                 x, y, width, height, border);
2058 
2059     state->setBoundTextureInternalFormat(target, internalformat);
2060     state->setBoundTextureDims(target, level, width, height, 1);
2061 }
2062 
s_glTexParameteriv(void * self,GLenum target,GLenum pname,const GLint * params)2063 void GL2Encoder::s_glTexParameteriv(void* self,
2064         GLenum target, GLenum pname, const GLint* params)
2065 {
2066     GL2Encoder* ctx = (GL2Encoder*)self;
2067     const GLClientState* state = ctx->m_state;
2068 
2069     SET_ERROR_IF((target == GL_TEXTURE_EXTERNAL_OES &&
2070             !isValidTextureExternalParam(pname, (GLenum)params[0])),
2071             GL_INVALID_ENUM);
2072 
2073     if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
2074         ctx->override2DTextureTarget(target);
2075         ctx->m_glTexParameteriv_enc(ctx, GL_TEXTURE_2D, pname, params);
2076         ctx->restore2DTextureTarget(target);
2077     } else {
2078         ctx->m_glTexParameteriv_enc(ctx, target, pname, params);
2079     }
2080 }
2081 
texture2DNeedsOverride(GLenum target) const2082 bool GL2Encoder::texture2DNeedsOverride(GLenum target) const {
2083     return (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) &&
2084            target != m_state->getPriorityEnabledTarget(GL_TEXTURE_2D);
2085 }
2086 
override2DTextureTarget(GLenum target)2087 void GL2Encoder::override2DTextureTarget(GLenum target)
2088 {
2089     if (texture2DNeedsOverride(target)) {
2090         m_glBindTexture_enc(this, GL_TEXTURE_2D,
2091                 m_state->getBoundTexture(target));
2092     }
2093 }
2094 
restore2DTextureTarget(GLenum target)2095 void GL2Encoder::restore2DTextureTarget(GLenum target)
2096 {
2097     if (texture2DNeedsOverride(target)) {
2098         m_glBindTexture_enc(this, GL_TEXTURE_2D,
2099                 m_state->getBoundTexture(
2100                     m_state->getPriorityEnabledTarget(GL_TEXTURE_2D)));
2101     }
2102 }
2103 
associateEGLImage(GLenum target,GLeglImageOES eglImage)2104 void GL2Encoder::associateEGLImage(GLenum target, GLeglImageOES eglImage) {
2105     m_state->setBoundEGLImage(target, eglImage);
2106 }
2107 
2108 
boundBuffer(GLenum target) const2109 GLuint GL2Encoder::boundBuffer(GLenum target) const {
2110     return m_state->getBuffer(target);
2111 }
2112 
getBufferData(GLenum target) const2113 BufferData* GL2Encoder::getBufferData(GLenum target) const {
2114     GLuint bufferId = m_state->getBuffer(target);
2115     if (!bufferId) return NULL;
2116     return m_shared->getBufferData(bufferId);
2117 }
2118 
getBufferDataById(GLuint bufferId) const2119 BufferData* GL2Encoder::getBufferDataById(GLuint bufferId) const {
2120     if (!bufferId) return NULL;
2121     return m_shared->getBufferData(bufferId);
2122 }
2123 
isBufferMapped(GLuint buffer) const2124 bool GL2Encoder::isBufferMapped(GLuint buffer) const {
2125     return m_shared->getBufferData(buffer)->m_mapped;
2126 }
2127 
isBufferTargetMapped(GLenum target) const2128 bool GL2Encoder::isBufferTargetMapped(GLenum target) const {
2129     BufferData* buf = getBufferData(target);
2130     if (!buf) return false;
2131     return buf->m_mapped;
2132 }
2133 
s_glGenRenderbuffers(void * self,GLsizei n,GLuint * renderbuffers)2134 void GL2Encoder::s_glGenRenderbuffers(void* self,
2135         GLsizei n, GLuint* renderbuffers) {
2136     GL2Encoder* ctx = (GL2Encoder*)self;
2137     GLClientState* state = ctx->m_state;
2138 
2139     SET_ERROR_IF(n < 0, GL_INVALID_VALUE);
2140 
2141     ctx->m_glGenFramebuffers_enc(self, n, renderbuffers);
2142     state->addRenderbuffers(n, renderbuffers);
2143 }
2144 
s_glDeleteRenderbuffers(void * self,GLsizei n,const GLuint * renderbuffers)2145 void GL2Encoder::s_glDeleteRenderbuffers(void* self,
2146         GLsizei n, const GLuint* renderbuffers) {
2147     GL2Encoder* ctx = (GL2Encoder*)self;
2148     GLClientState* state = ctx->m_state;
2149 
2150     SET_ERROR_IF(n < 0, GL_INVALID_VALUE);
2151 
2152     ctx->m_glDeleteRenderbuffers_enc(self, n, renderbuffers);
2153 
2154     // Nope, lets just leak those for now.
2155     // The spec has an *amazingly* convoluted set of conditions for when
2156     // render buffers are actually deleted:
2157     // 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.
2158     //
2159     // 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***
2160     //
2161     // So, just detach this one from the bound FBO, and ignore the rest.
2162     for (int i = 0; i < n; i++) {
2163         state->detachRbo(renderbuffers[i]);
2164     }
2165     // state->removeRenderbuffers(n, renderbuffers);
2166 }
2167 
s_glBindRenderbuffer(void * self,GLenum target,GLuint renderbuffer)2168 void GL2Encoder::s_glBindRenderbuffer(void* self,
2169         GLenum target, GLuint renderbuffer) {
2170     GL2Encoder* ctx = (GL2Encoder*)self;
2171     GLClientState* state = ctx->m_state;
2172 
2173     SET_ERROR_IF((target != GL_RENDERBUFFER),
2174                  GL_INVALID_ENUM);
2175 
2176     ctx->m_glBindRenderbuffer_enc(self, target, renderbuffer);
2177     state->bindRenderbuffer(target, renderbuffer);
2178 }
2179 
s_glRenderbufferStorage(void * self,GLenum target,GLenum internalformat,GLsizei width,GLsizei height)2180 void GL2Encoder::s_glRenderbufferStorage(void* self,
2181         GLenum target, GLenum internalformat,
2182         GLsizei width, GLsizei height) {
2183     GL2Encoder* ctx = (GL2Encoder*) self;
2184     GLClientState* state = ctx->m_state;
2185 
2186     SET_ERROR_IF(target != GL_RENDERBUFFER, GL_INVALID_ENUM);
2187     SET_ERROR_IF(
2188         !GLESv2Validation::rboFormat(ctx, internalformat),
2189         GL_INVALID_ENUM);
2190 
2191     state->setBoundRenderbufferFormat(internalformat);
2192     state->setBoundRenderbufferSamples(0);
2193 
2194     ctx->m_glRenderbufferStorage_enc(self, target, internalformat,
2195                                      width, height);
2196 }
2197 
s_glFramebufferRenderbuffer(void * self,GLenum target,GLenum attachment,GLenum renderbuffertarget,GLuint renderbuffer)2198 void GL2Encoder::s_glFramebufferRenderbuffer(void* self,
2199         GLenum target, GLenum attachment,
2200         GLenum renderbuffertarget, GLuint renderbuffer) {
2201     GL2Encoder* ctx = (GL2Encoder*)self;
2202     GLClientState* state = ctx->m_state;
2203 
2204     SET_ERROR_IF(!GLESv2Validation::framebufferTarget(ctx, target), GL_INVALID_ENUM);
2205     SET_ERROR_IF(!GLESv2Validation::framebufferAttachment(ctx, attachment), GL_INVALID_ENUM);
2206     state->attachRbo(target, attachment, renderbuffer);
2207 
2208     ctx->m_glFramebufferRenderbuffer_enc(self, target, attachment, renderbuffertarget, renderbuffer);
2209 }
2210 
s_glGenFramebuffers(void * self,GLsizei n,GLuint * framebuffers)2211 void GL2Encoder::s_glGenFramebuffers(void* self,
2212         GLsizei n, GLuint* framebuffers) {
2213     GL2Encoder* ctx = (GL2Encoder*)self;
2214     GLClientState* state = ctx->m_state;
2215 
2216     SET_ERROR_IF(n < 0, GL_INVALID_VALUE);
2217 
2218     ctx->m_glGenFramebuffers_enc(self, n, framebuffers);
2219     state->addFramebuffers(n, framebuffers);
2220 }
2221 
s_glDeleteFramebuffers(void * self,GLsizei n,const GLuint * framebuffers)2222 void GL2Encoder::s_glDeleteFramebuffers(void* self,
2223         GLsizei n, const GLuint* framebuffers) {
2224     GL2Encoder* ctx = (GL2Encoder*)self;
2225     GLClientState* state = ctx->m_state;
2226 
2227     SET_ERROR_IF(n < 0, GL_INVALID_VALUE);
2228 
2229     ctx->m_glDeleteFramebuffers_enc(self, n, framebuffers);
2230     state->removeFramebuffers(n, framebuffers);
2231 }
2232 
s_glBindFramebuffer(void * self,GLenum target,GLuint framebuffer)2233 void GL2Encoder::s_glBindFramebuffer(void* self,
2234         GLenum target, GLuint framebuffer) {
2235     GL2Encoder* ctx = (GL2Encoder*)self;
2236     GLClientState* state = ctx->m_state;
2237 
2238     SET_ERROR_IF(!GLESv2Validation::framebufferTarget(ctx, target), GL_INVALID_ENUM);
2239 
2240     state->bindFramebuffer(target, framebuffer);
2241 
2242     ctx->m_glBindFramebuffer_enc(self, target, framebuffer);
2243 }
2244 
s_glFramebufferTexture2D(void * self,GLenum target,GLenum attachment,GLenum textarget,GLuint texture,GLint level)2245 void GL2Encoder::s_glFramebufferTexture2D(void* self,
2246         GLenum target, GLenum attachment,
2247         GLenum textarget, GLuint texture, GLint level) {
2248     GL2Encoder* ctx = (GL2Encoder*)self;
2249     GLClientState* state = ctx->m_state;
2250 
2251     SET_ERROR_IF(!GLESv2Validation::framebufferTarget(ctx, target), GL_INVALID_ENUM);
2252     SET_ERROR_IF(!GLESv2Validation::framebufferAttachment(ctx, attachment), GL_INVALID_ENUM);
2253     state->attachTextureObject(target, attachment, texture);
2254 
2255     ctx->m_glFramebufferTexture2D_enc(self, target, attachment, textarget, texture, level);
2256 }
2257 
s_glFramebufferTexture3DOES(void * self,GLenum target,GLenum attachment,GLenum textarget,GLuint texture,GLint level,GLint zoffset)2258 void GL2Encoder::s_glFramebufferTexture3DOES(void* self,
2259         GLenum target, GLenum attachment,
2260         GLenum textarget, GLuint texture, GLint level, GLint zoffset) {
2261     GL2Encoder* ctx = (GL2Encoder*)self;
2262     GLClientState* state = ctx->m_state;
2263 
2264     state->attachTextureObject(target, attachment, texture);
2265 
2266     ctx->m_glFramebufferTexture3DOES_enc(self, target, attachment, textarget, texture, level, zoffset);
2267 }
2268 
s_glGetFramebufferAttachmentParameteriv(void * self,GLenum target,GLenum attachment,GLenum pname,GLint * params)2269 void GL2Encoder::s_glGetFramebufferAttachmentParameteriv(void* self,
2270         GLenum target, GLenum attachment, GLenum pname, GLint* params) {
2271     GL2Encoder* ctx = (GL2Encoder*)self;
2272     const GLClientState* state = ctx->m_state;
2273     SET_ERROR_IF(!GLESv2Validation::framebufferTarget(ctx, target), GL_INVALID_ENUM);
2274     SET_ERROR_IF(pname != GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME &&
2275                  pname != GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE &&
2276                  !state->attachmentHasObject(target, attachment),
2277                  GL_INVALID_OPERATION);
2278     SET_ERROR_IF((pname == GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL ||
2279                   pname == GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE ||
2280                   pname == GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER) &&
2281                  (!state->attachmentHasObject(target, attachment) ||
2282                   state->getBoundFramebufferAttachmentType(target, attachment) !=
2283                   FBO_ATTACHMENT_TEXTURE),
2284                  !state->attachmentHasObject(target, attachment) ?
2285                  GL_INVALID_OPERATION : GL_INVALID_ENUM);
2286     SET_ERROR_IF(attachment == GL_DEPTH_STENCIL_ATTACHMENT &&
2287                  pname == GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME &&
2288                  (state->objectOfAttachment(target, GL_DEPTH_ATTACHMENT) !=
2289                   state->objectOfAttachment(target, GL_STENCIL_ATTACHMENT)),
2290                  GL_INVALID_OPERATION);
2291     SET_ERROR_IF(state->boundFramebuffer(target) &&
2292                  (attachment == GL_BACK ||
2293                   attachment == GL_FRONT),
2294                  GL_INVALID_OPERATION);
2295     ctx->m_glGetFramebufferAttachmentParameteriv_enc(self, target, attachment, pname, params);
2296 }
2297 
isCompleteFbo(GLenum target,const GLClientState * state,GLenum attachment) const2298 bool GL2Encoder::isCompleteFbo(GLenum target, const GLClientState* state,
2299                                GLenum attachment) const {
2300     FboFormatInfo fbo_format_info;
2301     state->getBoundFramebufferFormat(target, attachment, &fbo_format_info);
2302 
2303     bool res;
2304     switch (fbo_format_info.type) {
2305     case FBO_ATTACHMENT_RENDERBUFFER:
2306         switch (fbo_format_info.rb_format) {
2307         case GL_R16F:
2308         case GL_RG16F:
2309         case GL_RGBA16F:
2310         case GL_R32F:
2311         case GL_RG32F:
2312         case GL_RGBA32F:
2313         case GL_R11F_G11F_B10F:
2314             res = majorVersion() >= 3 && hasExtension("GL_EXT_color_buffer_float");
2315             break;
2316         case GL_RGB16F:
2317             res = majorVersion() >= 3 && hasExtension("GL_EXT_color_buffer_half_float");
2318             break;
2319         case GL_STENCIL_INDEX8:
2320             if (attachment == GL_STENCIL_ATTACHMENT) {
2321                 res = true;
2322             } else {
2323                 res = false;
2324             }
2325             break;
2326         default:
2327             res = true;
2328         }
2329         break;
2330     case FBO_ATTACHMENT_TEXTURE:
2331         switch (fbo_format_info.tex_internalformat) {
2332         case GL_R16F:
2333         case GL_RG16F:
2334         case GL_RGBA16F:
2335         case GL_R32F:
2336         case GL_RG32F:
2337         case GL_RGBA32F:
2338         case GL_R11F_G11F_B10F:
2339             res = majorVersion() >= 3 && hasExtension("GL_EXT_color_buffer_float");
2340             break;
2341         case GL_RGB16F:
2342             res = majorVersion() >= 3 && hasExtension("GL_EXT_color_buffer_half_float");
2343             break;
2344         case GL_RED:
2345         case GL_RG:
2346         case GL_SRGB8:
2347         case GL_RGB32UI:
2348         case GL_RGB16UI:
2349         case GL_RGB8UI:
2350         case GL_RGB32I:
2351         case GL_RGB16I:
2352         case GL_RGB8I:
2353         case GL_R8_SNORM:
2354         case GL_RG8_SNORM:
2355         case GL_RGB8_SNORM:
2356         case GL_RGBA8_SNORM:
2357             res = false;
2358             break;
2359         // No float/half-float formats allowed for RGB(A)
2360         case GL_RGB:
2361         case GL_RGBA:
2362             switch (fbo_format_info.tex_type) {
2363             case GL_FLOAT:
2364             case GL_HALF_FLOAT_OES:
2365             case GL_UNSIGNED_INT_10F_11F_11F_REV:
2366             case GL_UNSIGNED_INT_2_10_10_10_REV:
2367                 res = false;
2368                 break;
2369             default:
2370                 res = true;
2371             }
2372             break;
2373         default:
2374             res = true;
2375         }
2376         break;
2377     case FBO_ATTACHMENT_NONE:
2378         res = true;
2379         break;
2380     default:
2381         res = true;
2382     }
2383     return res;
2384 }
2385 
checkFramebufferCompleteness(GLenum target,const GLClientState * state) const2386 bool GL2Encoder::checkFramebufferCompleteness(GLenum target, const GLClientState* state) const {
2387     bool res = true;
2388 
2389     for (int i = 0; i < state->getMaxColorAttachments(); i++) {
2390         res = res && isCompleteFbo(target, state, glUtilsColorAttachmentName(i));
2391     }
2392 
2393     res = res && isCompleteFbo(target, state, GL_DEPTH_ATTACHMENT);
2394     res = res && isCompleteFbo(target, state, GL_STENCIL_ATTACHMENT);
2395 
2396     return res;
2397 }
2398 
s_glCheckFramebufferStatus(void * self,GLenum target)2399 GLenum GL2Encoder::s_glCheckFramebufferStatus(void* self, GLenum target) {
2400     GL2Encoder* ctx = (GL2Encoder*)self;
2401     GLClientState* state = ctx->m_state;
2402 
2403     bool fboCompleteByCodec =
2404         ctx->checkFramebufferCompleteness(target, state);
2405 
2406     if (!fboCompleteByCodec) {
2407         state->setCheckFramebufferStatus(target, GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT);
2408         return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
2409     } else {
2410         // double check with underlying opengl to avoid craziness.
2411         GLenum host_checkstatus = ctx->m_glCheckFramebufferStatus_enc(self, target);
2412         state->setCheckFramebufferStatus(target, host_checkstatus);
2413         if (host_checkstatus == GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS) return GL_FRAMEBUFFER_COMPLETE;
2414         return host_checkstatus;
2415     }
2416 }
2417 
s_glGenVertexArrays(void * self,GLsizei n,GLuint * arrays)2418 void GL2Encoder::s_glGenVertexArrays(void* self, GLsizei n, GLuint* arrays) {
2419     GL2Encoder* ctx = (GL2Encoder*)self;
2420     GLClientState* state = ctx->m_state;
2421     SET_ERROR_IF(n < 0, GL_INVALID_VALUE);
2422 
2423     ctx->m_glGenVertexArrays_enc(self, n, arrays);
2424     for (int i = 0; i < n; i++) {
2425         ALOGV("%s: gen vao %u", __FUNCTION__, arrays[i]);
2426     }
2427     state->addVertexArrayObjects(n, arrays);
2428 }
2429 
s_glDeleteVertexArrays(void * self,GLsizei n,const GLuint * arrays)2430 void GL2Encoder::s_glDeleteVertexArrays(void* self, GLsizei n, const GLuint* arrays) {
2431     GL2Encoder* ctx = (GL2Encoder*)self;
2432     GLClientState* state = ctx->m_state;
2433     SET_ERROR_IF(n < 0, GL_INVALID_VALUE);
2434 
2435     ctx->m_glDeleteVertexArrays_enc(self, n, arrays);
2436     for (int i = 0; i < n; i++) {
2437         ALOGV("%s: delete vao %u", __FUNCTION__, arrays[i]);
2438     }
2439     state->removeVertexArrayObjects(n, arrays);
2440 }
2441 
s_glBindVertexArray(void * self,GLuint array)2442 void GL2Encoder::s_glBindVertexArray(void* self, GLuint array) {
2443     ALOGV("%s: call. array=%u\n", __FUNCTION__, array);
2444     GL2Encoder* ctx = (GL2Encoder*)self;
2445     GLClientState* state = ctx->m_state;
2446     SET_ERROR_IF(!state->isVertexArrayObject(array), GL_INVALID_OPERATION);
2447     ctx->m_glBindVertexArray_enc(self, array);
2448     state->setVertexArrayObject(array);
2449 }
2450 
s_glMapBufferRange(void * self,GLenum target,GLintptr offset,GLsizeiptr length,GLbitfield access)2451 void* GL2Encoder::s_glMapBufferRange(void* self, GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access) {
2452     GL2Encoder* ctx = (GL2Encoder*)self;
2453     GLClientState* state = ctx->m_state;
2454 
2455     // begin validation (lots)
2456 
2457     RET_AND_SET_ERROR_IF(!GLESv2Validation::bufferTarget(ctx, target), GL_INVALID_ENUM, NULL);
2458 
2459     GLuint boundBuffer = ctx->m_state->getBuffer(target);
2460 
2461     RET_AND_SET_ERROR_IF(boundBuffer == 0, GL_INVALID_OPERATION, NULL);
2462 
2463     BufferData* buf = ctx->m_shared->getBufferData(boundBuffer);
2464     RET_AND_SET_ERROR_IF(!buf, GL_INVALID_VALUE, NULL);
2465 
2466     GLsizeiptr bufferDataSize = buf->m_size;
2467 
2468     RET_AND_SET_ERROR_IF(offset < 0, GL_INVALID_VALUE, NULL);
2469     RET_AND_SET_ERROR_IF(length < 0, GL_INVALID_VALUE, NULL);
2470     RET_AND_SET_ERROR_IF(offset + length > bufferDataSize, GL_INVALID_VALUE, NULL);
2471     RET_AND_SET_ERROR_IF(access & ~GLESv2Validation::allBufferMapAccessFlags, GL_INVALID_VALUE, NULL);
2472 
2473     RET_AND_SET_ERROR_IF(buf->m_mapped, GL_INVALID_OPERATION, NULL);
2474     RET_AND_SET_ERROR_IF(!(access & (GL_MAP_READ_BIT | GL_MAP_WRITE_BIT)), GL_INVALID_OPERATION, NULL);
2475     RET_AND_SET_ERROR_IF(
2476         (access & GL_MAP_READ_BIT) &&
2477              ((access & GL_MAP_INVALIDATE_RANGE_BIT) ||
2478               (access & GL_MAP_INVALIDATE_BUFFER_BIT) ||
2479               (access & GL_MAP_UNSYNCHRONIZED_BIT) ||
2480               (access & GL_MAP_FLUSH_EXPLICIT_BIT)), GL_INVALID_OPERATION, NULL);
2481 
2482     // end validation; actually do stuff now
2483 
2484     buf->m_mapped = true;
2485     buf->m_mappedAccess = access;
2486     buf->m_mappedOffset = offset;
2487     buf->m_mappedLength = length;
2488 
2489     char* todo = (char*)buf->m_fixedBuffer.ptr() + offset;
2490     ctx->glMapBufferRangeAEMU(
2491             ctx, target,
2492             offset, length,
2493             access,
2494             todo);
2495 
2496     return todo;
2497 }
2498 
s_glUnmapBuffer(void * self,GLenum target)2499 GLboolean GL2Encoder::s_glUnmapBuffer(void* self, GLenum target) {
2500     GL2Encoder* ctx = (GL2Encoder*)self;
2501     GLClientState* state = ctx->m_state;
2502 
2503     RET_AND_SET_ERROR_IF(!GLESv2Validation::bufferTarget(ctx, target), GL_INVALID_ENUM, GL_FALSE);
2504 
2505     GLuint boundBuffer = ctx->m_state->getBuffer(target);
2506 
2507     RET_AND_SET_ERROR_IF(boundBuffer == 0, GL_INVALID_OPERATION, GL_FALSE);
2508 
2509     BufferData* buf = ctx->m_shared->getBufferData(boundBuffer);
2510     RET_AND_SET_ERROR_IF(!buf, GL_INVALID_VALUE, GL_FALSE);
2511     RET_AND_SET_ERROR_IF(!buf->m_mapped, GL_INVALID_OPERATION, GL_FALSE);
2512 
2513     if (buf->m_mappedAccess & GL_MAP_WRITE_BIT) {
2514         // invalide index range cache here
2515         if (buf->m_mappedAccess & GL_MAP_INVALIDATE_BUFFER_BIT) {
2516             buf->m_indexRangeCache.invalidateRange(0, buf->m_size);
2517         } else {
2518             buf->m_indexRangeCache.invalidateRange(buf->m_mappedOffset, buf->m_mappedLength);
2519         }
2520     }
2521 
2522     GLboolean host_res = GL_TRUE;
2523 
2524     ctx->glUnmapBufferAEMU(
2525             ctx, target,
2526             buf->m_mappedOffset,
2527             buf->m_mappedLength,
2528             buf->m_mappedAccess,
2529             (void*)((char*)buf->m_fixedBuffer.ptr() + buf->m_mappedOffset),
2530             &host_res);
2531 
2532     buf->m_mapped = false;
2533     buf->m_mappedAccess = 0;
2534     buf->m_mappedOffset = 0;
2535     buf->m_mappedLength = 0;
2536 
2537     return host_res;
2538 }
2539 
s_glFlushMappedBufferRange(void * self,GLenum target,GLintptr offset,GLsizeiptr length)2540 void GL2Encoder::s_glFlushMappedBufferRange(void* self, GLenum target, GLintptr offset, GLsizeiptr length) {
2541     GL2Encoder* ctx = (GL2Encoder*)self;
2542     GLClientState* state = ctx->m_state;
2543 
2544     SET_ERROR_IF(!GLESv2Validation::bufferTarget(ctx, target), GL_INVALID_ENUM);
2545 
2546     GLuint boundBuffer = ctx->m_state->getBuffer(target);
2547     SET_ERROR_IF(!boundBuffer, GL_INVALID_OPERATION);
2548 
2549     BufferData* buf = ctx->m_shared->getBufferData(boundBuffer);
2550     SET_ERROR_IF(!buf, GL_INVALID_VALUE);
2551     SET_ERROR_IF(!buf->m_mapped, GL_INVALID_OPERATION);
2552     SET_ERROR_IF(!(buf->m_mappedAccess & GL_MAP_FLUSH_EXPLICIT_BIT), GL_INVALID_OPERATION);
2553 
2554     SET_ERROR_IF(offset < 0, GL_INVALID_VALUE);
2555     SET_ERROR_IF(length < 0, GL_INVALID_VALUE);
2556     SET_ERROR_IF(offset + length > buf->m_mappedLength, GL_INVALID_VALUE);
2557 
2558     GLintptr totalOffset = buf->m_mappedOffset + offset;
2559 
2560     buf->m_indexRangeCache.invalidateRange(totalOffset, length);
2561 
2562     ctx->glFlushMappedBufferRangeAEMU(
2563             ctx, target,
2564             totalOffset,
2565             length,
2566             buf->m_mappedAccess,
2567             (void*)((char*)buf->m_fixedBuffer.ptr() + totalOffset));
2568 }
2569 
s_glCompressedTexImage2D(void * self,GLenum target,GLint level,GLenum internalformat,GLsizei width,GLsizei height,GLint border,GLsizei imageSize,const GLvoid * data)2570 void GL2Encoder::s_glCompressedTexImage2D(void* self, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid* data) {
2571     GL2Encoder* ctx = (GL2Encoder*)self;
2572     GLClientState* state = ctx->m_state;
2573 
2574     SET_ERROR_IF(!GLESv2Validation::textureTarget(ctx, target), GL_INVALID_ENUM);
2575     // Filter compressed formats support.
2576     SET_ERROR_IF(!GLESv2Validation::supportedCompressedFormat(ctx, internalformat), GL_INVALID_ENUM);
2577     // Verify level <= log2(GL_MAX_TEXTURE_SIZE).
2578     GLint max_texture_size;
2579     GLint max_cube_map_texture_size;
2580     ctx->glGetIntegerv(ctx, GL_MAX_TEXTURE_SIZE, &max_texture_size);
2581     ctx->glGetIntegerv(ctx, GL_MAX_CUBE_MAP_TEXTURE_SIZE, &max_cube_map_texture_size);
2582     SET_ERROR_IF(level < 0, GL_INVALID_VALUE);
2583     SET_ERROR_IF(level > ilog2(max_texture_size), GL_INVALID_VALUE);
2584     SET_ERROR_IF(level > ilog2(max_cube_map_texture_size), GL_INVALID_VALUE);
2585     SET_ERROR_IF(width > max_texture_size, GL_INVALID_VALUE);
2586     SET_ERROR_IF(height > max_texture_size, GL_INVALID_VALUE);
2587     SET_ERROR_IF(border, GL_INVALID_VALUE);
2588     // If unpack buffer is nonzero, verify unmapped state.
2589     SET_ERROR_IF(ctx->isBufferTargetMapped(GL_PIXEL_UNPACK_BUFFER), GL_INVALID_OPERATION);
2590     SET_ERROR_IF(width < 0 || height < 0, GL_INVALID_VALUE);
2591     // If unpack buffer is nonzero, verify buffer data fits.
2592     SET_ERROR_IF(ctx->boundBuffer(GL_PIXEL_UNPACK_BUFFER) &&
2593                  ctx->getBufferData(GL_PIXEL_UNPACK_BUFFER) &&
2594                  (imageSize > ctx->getBufferData(GL_PIXEL_UNPACK_BUFFER)->m_size),
2595                  GL_INVALID_OPERATION);
2596     // TODO: Fix:
2597     // If |imageSize| is inconsistent with compressed dimensions.
2598     // SET_ERROR_IF(GLESv2Validation::compressedTexImageSize(internalformat, width, height, 1) != imageSize, GL_INVALID_VALUE);
2599 
2600     GLenum stateTarget = target;
2601     if (target == GL_TEXTURE_CUBE_MAP_POSITIVE_X ||
2602         target == GL_TEXTURE_CUBE_MAP_POSITIVE_Y ||
2603         target == GL_TEXTURE_CUBE_MAP_POSITIVE_Z ||
2604         target == GL_TEXTURE_CUBE_MAP_NEGATIVE_X ||
2605         target == GL_TEXTURE_CUBE_MAP_NEGATIVE_Y ||
2606         target == GL_TEXTURE_CUBE_MAP_NEGATIVE_Z)
2607         stateTarget = GL_TEXTURE_CUBE_MAP;
2608     state->setBoundTextureInternalFormat(stateTarget, (GLint)internalformat);
2609     state->setBoundTextureDims(stateTarget, level, width, height, 1);
2610 
2611     if (ctx->boundBuffer(GL_PIXEL_UNPACK_BUFFER)) {
2612         ctx->glCompressedTexImage2DOffsetAEMU(
2613                 ctx, target, level, internalformat,
2614                 width, height, border,
2615                 imageSize, (uintptr_t)data);
2616     } else {
2617         ctx->m_glCompressedTexImage2D_enc(
2618                 ctx, target, level, internalformat,
2619                 width, height, border,
2620                 imageSize, data);
2621     }
2622 }
2623 
s_glCompressedTexSubImage2D(void * self,GLenum target,GLint level,GLint xoffset,GLint yoffset,GLsizei width,GLsizei height,GLenum format,GLsizei imageSize,const GLvoid * data)2624 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) {
2625     GL2Encoder* ctx = (GL2Encoder*)self;
2626     GLClientState* state = ctx->m_state;
2627 
2628     SET_ERROR_IF(!GLESv2Validation::textureTarget(ctx, target), GL_INVALID_ENUM);
2629     // If unpack buffer is nonzero, verify unmapped state.
2630     SET_ERROR_IF(ctx->isBufferTargetMapped(GL_PIXEL_UNPACK_BUFFER), GL_INVALID_OPERATION);
2631     GLint max_texture_size;
2632     GLint max_cube_map_texture_size;
2633     ctx->glGetIntegerv(ctx, GL_MAX_TEXTURE_SIZE, &max_texture_size);
2634     ctx->glGetIntegerv(ctx, GL_MAX_CUBE_MAP_TEXTURE_SIZE, &max_cube_map_texture_size);
2635     SET_ERROR_IF(level < 0, GL_INVALID_VALUE);
2636     SET_ERROR_IF(level > ilog2(max_texture_size), GL_INVALID_VALUE);
2637     SET_ERROR_IF(level > ilog2(max_cube_map_texture_size), GL_INVALID_VALUE);
2638     SET_ERROR_IF(width < 0 || height < 0, GL_INVALID_VALUE);
2639     // If unpack buffer is nonzero, verify buffer data fits.
2640     SET_ERROR_IF(ctx->boundBuffer(GL_PIXEL_UNPACK_BUFFER) &&
2641                  ctx->getBufferData(GL_PIXEL_UNPACK_BUFFER) &&
2642                  (imageSize > ctx->getBufferData(GL_PIXEL_UNPACK_BUFFER)->m_size),
2643                  GL_INVALID_OPERATION);
2644     SET_ERROR_IF(xoffset < 0 || yoffset < 0, GL_INVALID_VALUE);
2645 
2646     if (ctx->boundBuffer(GL_PIXEL_UNPACK_BUFFER)) {
2647         ctx->glCompressedTexSubImage2DOffsetAEMU(
2648                 ctx, target, level,
2649                 xoffset, yoffset,
2650                 width, height, format,
2651                 imageSize, (uintptr_t)data);
2652     } else {
2653         ctx->m_glCompressedTexSubImage2D_enc(
2654                 ctx, target, level,
2655                 xoffset, yoffset,
2656                 width, height, format,
2657                 imageSize, data);
2658     }
2659 }
2660 
s_glBindBufferRange(void * self,GLenum target,GLuint index,GLuint buffer,GLintptr offset,GLsizeiptr size)2661 void GL2Encoder::s_glBindBufferRange(void* self, GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size) {
2662     GL2Encoder* ctx = (GL2Encoder*)self;
2663     GLClientState* state = ctx->m_state;
2664 
2665     SET_ERROR_IF(!GLESv2Validation::bufferTarget(ctx, target), GL_INVALID_ENUM);
2666 
2667     // Only works with certain targets
2668     SET_ERROR_IF(
2669         !(target == GL_ATOMIC_COUNTER_BUFFER ||
2670           target == GL_SHADER_STORAGE_BUFFER ||
2671           target == GL_TRANSFORM_FEEDBACK_BUFFER ||
2672           target == GL_UNIFORM_BUFFER),
2673         GL_INVALID_ENUM);
2674 
2675     // Can't exceed range
2676     SET_ERROR_IF(index < 0 ||
2677                  index >= state->getMaxIndexedBufferBindings(target),
2678                  GL_INVALID_VALUE);
2679     SET_ERROR_IF(buffer && size <= 0, GL_INVALID_VALUE);
2680     SET_ERROR_IF((target == GL_ATOMIC_COUNTER_BUFFER ||
2681                   target == GL_TRANSFORM_FEEDBACK_BUFFER) &&
2682                  (size % 4 || offset % 4),
2683                  GL_INVALID_VALUE);
2684 
2685     GLint ssbo_offset_align, ubo_offset_align;
2686     ctx->s_glGetIntegerv(ctx, GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT, &ssbo_offset_align);
2687     ctx->s_glGetIntegerv(ctx, GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT, &ubo_offset_align);
2688     SET_ERROR_IF(target == GL_SHADER_STORAGE_BUFFER &&
2689                  offset % ssbo_offset_align,
2690                  GL_INVALID_VALUE);
2691     SET_ERROR_IF(target == GL_UNIFORM_BUFFER &&
2692                  offset % ubo_offset_align,
2693                  GL_INVALID_VALUE);
2694 
2695     state->bindBuffer(target, buffer);
2696     ctx->m_state->addBuffer(buffer);
2697     state->bindIndexedBuffer(target, index, buffer, offset, size, 0, 0);
2698     ctx->m_glBindBufferRange_enc(self, target, index, buffer, offset, size);
2699 }
2700 
s_glBindBufferBase(void * self,GLenum target,GLuint index,GLuint buffer)2701 void GL2Encoder::s_glBindBufferBase(void* self, GLenum target, GLuint index, GLuint buffer) {
2702     GL2Encoder* ctx = (GL2Encoder*)self;
2703     GLClientState* state = ctx->m_state;
2704 
2705     SET_ERROR_IF(!GLESv2Validation::bufferTarget(ctx, target), GL_INVALID_ENUM);
2706 
2707     // Only works with certain targets
2708     SET_ERROR_IF(
2709         !(target == GL_ATOMIC_COUNTER_BUFFER ||
2710           target == GL_SHADER_STORAGE_BUFFER ||
2711           target == GL_TRANSFORM_FEEDBACK_BUFFER ||
2712           target == GL_UNIFORM_BUFFER),
2713         GL_INVALID_ENUM);
2714     // Can't exceed range
2715     SET_ERROR_IF(index < 0 ||
2716                  index >= state->getMaxIndexedBufferBindings(target),
2717                  GL_INVALID_VALUE);
2718 
2719     state->bindBuffer(target, buffer);
2720     ctx->m_state->addBuffer(buffer);
2721     BufferData* buf = ctx->getBufferDataById(buffer);
2722     state->bindIndexedBuffer(target, index, buffer, 0, buf ? buf->m_size : 0, 0, 0);
2723     ctx->m_glBindBufferBase_enc(self, target, index, buffer);
2724 }
2725 
s_glCopyBufferSubData(void * self,GLenum readtarget,GLenum writetarget,GLintptr readoffset,GLintptr writeoffset,GLsizeiptr size)2726 void GL2Encoder::s_glCopyBufferSubData(void *self , GLenum readtarget, GLenum writetarget, GLintptr readoffset, GLintptr writeoffset, GLsizeiptr size) {
2727     GL2Encoder* ctx = (GL2Encoder*)self;
2728     GLClientState* state = ctx->m_state;
2729 
2730     SET_ERROR_IF(!GLESv2Validation::bufferTarget(ctx, readtarget), GL_INVALID_ENUM);
2731     SET_ERROR_IF(!GLESv2Validation::bufferTarget(ctx, writetarget), GL_INVALID_ENUM);
2732     SET_ERROR_IF((readtarget == GL_ATOMIC_COUNTER_BUFFER ||
2733                   readtarget == GL_DISPATCH_INDIRECT_BUFFER ||
2734                   readtarget == GL_DRAW_INDIRECT_BUFFER ||
2735                   readtarget == GL_SHADER_STORAGE_BUFFER), GL_INVALID_ENUM);
2736     SET_ERROR_IF((writetarget == GL_ATOMIC_COUNTER_BUFFER ||
2737                   writetarget == GL_DISPATCH_INDIRECT_BUFFER ||
2738                   writetarget == GL_DRAW_INDIRECT_BUFFER ||
2739                   writetarget == GL_SHADER_STORAGE_BUFFER), GL_INVALID_ENUM);
2740     SET_ERROR_IF(!ctx->boundBuffer(readtarget), GL_INVALID_OPERATION);
2741     SET_ERROR_IF(!ctx->boundBuffer(writetarget), GL_INVALID_OPERATION);
2742     SET_ERROR_IF(ctx->isBufferTargetMapped(readtarget), GL_INVALID_OPERATION);
2743     SET_ERROR_IF(ctx->isBufferTargetMapped(writetarget), GL_INVALID_OPERATION);
2744     SET_ERROR_IF(readoffset < 0, GL_INVALID_VALUE);
2745     SET_ERROR_IF(writeoffset < 0, GL_INVALID_VALUE);
2746     SET_ERROR_IF(size < 0, GL_INVALID_VALUE);
2747     SET_ERROR_IF(
2748         ctx->getBufferData(readtarget) &&
2749         (readoffset + size > ctx->getBufferData(readtarget)->m_size),
2750         GL_INVALID_VALUE);
2751     SET_ERROR_IF(
2752         ctx->getBufferData(writetarget) &&
2753         (writeoffset + size > ctx->getBufferData(writetarget)->m_size),
2754         GL_INVALID_VALUE);
2755     SET_ERROR_IF(readtarget == writetarget &&
2756                  !((writeoffset >= readoffset + size) ||
2757                    (readoffset >= writeoffset + size)),
2758                  GL_INVALID_VALUE);
2759 
2760     ctx->m_glCopyBufferSubData_enc(self, readtarget, writetarget, readoffset, writeoffset, size);
2761 }
2762 
s_glGetBufferParameteriv(void * self,GLenum target,GLenum pname,GLint * params)2763 void GL2Encoder::s_glGetBufferParameteriv(void* self, GLenum target, GLenum pname, GLint* params) {
2764     GL2Encoder* ctx = (GL2Encoder*)self;
2765 
2766     SET_ERROR_IF(!GLESv2Validation::bufferTarget(ctx, target), GL_INVALID_ENUM);
2767     SET_ERROR_IF(
2768         target != GL_ARRAY_BUFFER &&
2769         target != GL_ELEMENT_ARRAY_BUFFER &&
2770         target != GL_COPY_READ_BUFFER &&
2771         target != GL_COPY_WRITE_BUFFER &&
2772         target != GL_PIXEL_PACK_BUFFER &&
2773         target != GL_PIXEL_UNPACK_BUFFER &&
2774         target != GL_TRANSFORM_FEEDBACK_BUFFER &&
2775         target != GL_UNIFORM_BUFFER,
2776         GL_INVALID_ENUM);
2777     SET_ERROR_IF(!GLESv2Validation::bufferParam(ctx, pname), GL_INVALID_ENUM);
2778     SET_ERROR_IF(!ctx->boundBuffer(target), GL_INVALID_OPERATION);
2779     SET_ERROR_IF(pname != GL_BUFFER_ACCESS_FLAGS &&
2780                  pname != GL_BUFFER_MAPPED &&
2781                  pname != GL_BUFFER_SIZE &&
2782                  pname != GL_BUFFER_USAGE &&
2783                  pname != GL_BUFFER_MAP_LENGTH &&
2784                  pname != GL_BUFFER_MAP_OFFSET,
2785                  GL_INVALID_ENUM);
2786 
2787     if (!params) return;
2788 
2789     BufferData* buf = ctx->getBufferData(target);
2790 
2791     switch (pname) {
2792         case GL_BUFFER_ACCESS_FLAGS:
2793             *params = buf ? buf->m_mappedAccess : 0;
2794             break;
2795         case GL_BUFFER_MAPPED:
2796             *params = buf ? (buf->m_mapped ? GL_TRUE : GL_FALSE) : GL_FALSE;
2797             break;
2798         case GL_BUFFER_SIZE:
2799             *params = buf ? buf->m_size : 0;
2800             break;
2801         case GL_BUFFER_USAGE:
2802             *params = buf ? buf->m_usage : GL_STATIC_DRAW;
2803             break;
2804         case GL_BUFFER_MAP_LENGTH:
2805             *params = buf ? buf->m_mappedLength : 0;
2806             break;
2807         case GL_BUFFER_MAP_OFFSET:
2808             *params = buf ? buf->m_mappedOffset : 0;
2809             break;
2810         default:
2811             break;
2812     }
2813 }
2814 
s_glGetBufferParameteri64v(void * self,GLenum target,GLenum pname,GLint64 * params)2815 void GL2Encoder::s_glGetBufferParameteri64v(void* self, GLenum target, GLenum pname, GLint64* params) {
2816     GL2Encoder* ctx = (GL2Encoder*)self;
2817 
2818     SET_ERROR_IF(!GLESv2Validation::bufferTarget(ctx, target), GL_INVALID_ENUM);
2819     SET_ERROR_IF(
2820         target != GL_ARRAY_BUFFER &&
2821         target != GL_ELEMENT_ARRAY_BUFFER &&
2822         target != GL_COPY_READ_BUFFER &&
2823         target != GL_COPY_WRITE_BUFFER &&
2824         target != GL_PIXEL_PACK_BUFFER &&
2825         target != GL_PIXEL_UNPACK_BUFFER &&
2826         target != GL_TRANSFORM_FEEDBACK_BUFFER &&
2827         target != GL_UNIFORM_BUFFER,
2828         GL_INVALID_ENUM);
2829     SET_ERROR_IF(!GLESv2Validation::bufferParam(ctx, pname), GL_INVALID_ENUM);
2830     SET_ERROR_IF(!ctx->boundBuffer(target), GL_INVALID_OPERATION);
2831     SET_ERROR_IF(pname != GL_BUFFER_ACCESS_FLAGS &&
2832                  pname != GL_BUFFER_MAPPED &&
2833                  pname != GL_BUFFER_SIZE &&
2834                  pname != GL_BUFFER_USAGE &&
2835                  pname != GL_BUFFER_MAP_LENGTH &&
2836                  pname != GL_BUFFER_MAP_OFFSET,
2837                  GL_INVALID_ENUM);
2838 
2839     if (!params) return;
2840 
2841     BufferData* buf = ctx->getBufferData(target);
2842 
2843     switch (pname) {
2844         case GL_BUFFER_ACCESS_FLAGS:
2845             *params = buf ? buf->m_mappedAccess : 0;
2846             break;
2847         case GL_BUFFER_MAPPED:
2848             *params = buf ? (buf->m_mapped ? GL_TRUE : GL_FALSE) : GL_FALSE;
2849             break;
2850         case GL_BUFFER_SIZE:
2851             *params = buf ? buf->m_size : 0;
2852             break;
2853         case GL_BUFFER_USAGE:
2854             *params = buf ? buf->m_usage : GL_STATIC_DRAW;
2855             break;
2856         case GL_BUFFER_MAP_LENGTH:
2857             *params = buf ? buf->m_mappedLength : 0;
2858             break;
2859         case GL_BUFFER_MAP_OFFSET:
2860             *params = buf ? buf->m_mappedOffset : 0;
2861             break;
2862         default:
2863             break;
2864     }
2865 }
2866 
s_glGetBufferPointerv(void * self,GLenum target,GLenum pname,GLvoid ** params)2867 void GL2Encoder::s_glGetBufferPointerv(void* self, GLenum target, GLenum pname, GLvoid** params) {
2868     GL2Encoder* ctx = (GL2Encoder*)self;
2869     SET_ERROR_IF(!GLESv2Validation::bufferTarget(ctx, target), GL_INVALID_ENUM);
2870     SET_ERROR_IF(
2871         target == GL_ATOMIC_COUNTER_BUFFER ||
2872         target == GL_DISPATCH_INDIRECT_BUFFER ||
2873         target == GL_DRAW_INDIRECT_BUFFER ||
2874         target == GL_SHADER_STORAGE_BUFFER,
2875         GL_INVALID_ENUM);
2876     SET_ERROR_IF(pname != GL_BUFFER_MAP_POINTER, GL_INVALID_ENUM);
2877     SET_ERROR_IF(!ctx->boundBuffer(target), GL_INVALID_OPERATION);
2878     if (!params) return;
2879 
2880     BufferData* buf = ctx->getBufferData(target);
2881 
2882     if (!buf || !buf->m_mapped) { *params = NULL; return; }
2883 
2884     *params = (GLvoid*)((char*)buf->m_fixedBuffer.ptr() + buf->m_mappedOffset);
2885 }
2886 
2887 static const char* const kNameDelimiter = ";";
2888 
packVarNames(GLsizei count,const char ** names,GLint * err_out)2889 static std::string packVarNames(GLsizei count, const char** names, GLint* err_out) {
2890 
2891 #define VALIDATE(cond, err) if (cond) { *err_out = err; return packed; } \
2892 
2893     std::string packed;
2894     // validate the array of char[]'s
2895     const char* currName;
2896     for (GLsizei i = 0; i < count; i++) {
2897         currName = names[i];
2898         VALIDATE(!currName, GL_INVALID_OPERATION);
2899         // check if has reasonable size
2900         size_t len = strlen(currName);
2901         VALIDATE(!len, GL_INVALID_OPERATION);
2902         // check for our delimiter, which if present
2903         // in the name, means an invalid name anyway.
2904         VALIDATE(strstr(currName, kNameDelimiter),
2905                  GL_INVALID_OPERATION);
2906         packed += currName;
2907         packed += ";";
2908     }
2909 
2910     *err_out = GL_NO_ERROR;
2911     return packed;
2912 }
2913 
s_glGetUniformIndices(void * self,GLuint program,GLsizei uniformCount,const GLchar ** uniformNames,GLuint * uniformIndices)2914 void GL2Encoder::s_glGetUniformIndices(void* self, GLuint program, GLsizei uniformCount, const GLchar ** uniformNames, GLuint* uniformIndices) {
2915     GL2Encoder* ctx = (GL2Encoder*)self;
2916 
2917     if (!uniformCount) return;
2918 
2919     GLint err = GL_NO_ERROR;
2920     std::string packed = packVarNames(uniformCount, (const char**)uniformNames, &err);
2921     SET_ERROR_IF(err != GL_NO_ERROR, GL_INVALID_OPERATION);
2922 
2923     bool needLocationWAR = ctx->m_shared->needUniformLocationWAR(program);
2924     std::vector<int> arrIndices;
2925     for (size_t i = 0; i < uniformCount; i++) {
2926         int err;
2927         arrIndices.push_back(sArrIndexOfUniformExpr(uniformNames[i], &err));
2928         if (err) {
2929             ALOGE("%s: invalid uniform name %s!", __FUNCTION__, uniformNames[i]);
2930             return;
2931         }
2932     }
2933 
2934     ctx->glGetUniformIndicesAEMU(ctx, program, uniformCount, (const GLchar*)&packed[0], packed.size() + 1, uniformIndices);
2935 
2936     for (int i = 0; i < uniformCount; i++) {
2937         if (uniformIndices[i] >= 0 && needLocationWAR) {
2938             uniformIndices[i] =
2939                 ctx->m_shared->locationWARHostToApp(program, uniformIndices[i], arrIndices[i]);
2940         }
2941     }
2942 }
2943 
s_glUniform1ui(void * self,GLint location,GLuint v0)2944 void GL2Encoder::s_glUniform1ui(void* self, GLint location, GLuint v0) {
2945     GL2Encoder *ctx = (GL2Encoder*)self;
2946     GLClientState* state = ctx->m_state;
2947     GLSharedGroupPtr shared = ctx->m_shared;
2948 
2949     GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
2950     ctx->m_glUniform1ui_enc(self, hostLoc, v0);
2951 
2952     GLenum target;
2953     if (shared->setSamplerUniform(state->currentShaderProgram(), location, v0, &target)) {
2954         GLenum origActiveTexture = state->getActiveTextureUnit();
2955         if (ctx->updateHostTexture2DBinding(GL_TEXTURE0 + v0, target)) {
2956             ctx->m_glActiveTexture_enc(self, origActiveTexture);
2957         }
2958         state->setActiveTextureUnit(origActiveTexture);
2959     }
2960 }
2961 
s_glUniform2ui(void * self,GLint location,GLuint v0,GLuint v1)2962 void GL2Encoder::s_glUniform2ui(void* self, GLint location, GLuint v0, GLuint v1) {
2963     GL2Encoder *ctx = (GL2Encoder*)self;
2964     GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
2965     ctx->m_glUniform2ui_enc(self, hostLoc, v0, v1);
2966 }
2967 
s_glUniform3ui(void * self,GLint location,GLuint v0,GLuint v1,GLuint v2)2968 void GL2Encoder::s_glUniform3ui(void* self, GLint location, GLuint v0, GLuint v1, GLuint v2) {
2969     GL2Encoder *ctx = (GL2Encoder*)self;
2970     GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
2971     ctx->m_glUniform3ui_enc(self, hostLoc, v0, v1, v2);
2972 }
2973 
s_glUniform4ui(void * self,GLint location,GLint v0,GLuint v1,GLuint v2,GLuint v3)2974 void GL2Encoder::s_glUniform4ui(void* self, GLint location, GLint v0, GLuint v1, GLuint v2, GLuint v3) {
2975     GL2Encoder *ctx = (GL2Encoder*)self;
2976     GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
2977     ctx->m_glUniform4ui_enc(self, hostLoc, v0, v1, v2, v3);
2978 }
2979 
s_glUniform1uiv(void * self,GLint location,GLsizei count,const GLuint * value)2980 void GL2Encoder::s_glUniform1uiv(void* self, GLint location, GLsizei count, const GLuint *value) {
2981     GL2Encoder *ctx = (GL2Encoder*)self;
2982     GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
2983     ctx->m_glUniform1uiv_enc(self, hostLoc, count, value);
2984 }
2985 
s_glUniform2uiv(void * self,GLint location,GLsizei count,const GLuint * value)2986 void GL2Encoder::s_glUniform2uiv(void* self, GLint location, GLsizei count, const GLuint *value) {
2987     GL2Encoder *ctx = (GL2Encoder*)self;
2988     GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
2989     ctx->m_glUniform2uiv_enc(self, hostLoc, count, value);
2990 }
2991 
s_glUniform3uiv(void * self,GLint location,GLsizei count,const GLuint * value)2992 void GL2Encoder::s_glUniform3uiv(void* self, GLint location, GLsizei count, const GLuint *value) {
2993     GL2Encoder *ctx = (GL2Encoder*)self;
2994     GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
2995     ctx->m_glUniform3uiv_enc(self, hostLoc, count, value);
2996 }
2997 
s_glUniform4uiv(void * self,GLint location,GLsizei count,const GLuint * value)2998 void GL2Encoder::s_glUniform4uiv(void* self, GLint location, GLsizei count, const GLuint *value) {
2999     GL2Encoder *ctx = (GL2Encoder*)self;
3000     GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
3001     ctx->m_glUniform4uiv_enc(self, hostLoc, count, value);
3002 }
3003 
s_glUniformMatrix2x3fv(void * self,GLint location,GLsizei count,GLboolean transpose,const GLfloat * value)3004 void GL2Encoder::s_glUniformMatrix2x3fv(void* self, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) {
3005     GL2Encoder *ctx = (GL2Encoder*)self;
3006     GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
3007     ctx->m_glUniformMatrix2x3fv_enc(self, hostLoc, count, transpose, value);
3008 }
3009 
s_glUniformMatrix3x2fv(void * self,GLint location,GLsizei count,GLboolean transpose,const GLfloat * value)3010 void GL2Encoder::s_glUniformMatrix3x2fv(void* self, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) {
3011     GL2Encoder *ctx = (GL2Encoder*)self;
3012     GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
3013     ctx->m_glUniformMatrix3x2fv_enc(self, hostLoc, count, transpose, value);
3014 }
3015 
s_glUniformMatrix2x4fv(void * self,GLint location,GLsizei count,GLboolean transpose,const GLfloat * value)3016 void GL2Encoder::s_glUniformMatrix2x4fv(void* self, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) {
3017     GL2Encoder *ctx = (GL2Encoder*)self;
3018     GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
3019     ctx->m_glUniformMatrix2x4fv_enc(self, hostLoc, count, transpose, value);
3020 }
3021 
s_glUniformMatrix4x2fv(void * self,GLint location,GLsizei count,GLboolean transpose,const GLfloat * value)3022 void GL2Encoder::s_glUniformMatrix4x2fv(void* self, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) {
3023     GL2Encoder *ctx = (GL2Encoder*)self;
3024     GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
3025     ctx->m_glUniformMatrix4x2fv_enc(self, hostLoc, count, transpose, value);
3026 }
3027 
s_glUniformMatrix3x4fv(void * self,GLint location,GLsizei count,GLboolean transpose,const GLfloat * value)3028 void GL2Encoder::s_glUniformMatrix3x4fv(void* self, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) {
3029     GL2Encoder *ctx = (GL2Encoder*)self;
3030     GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
3031     ctx->m_glUniformMatrix3x4fv_enc(self, hostLoc, count, transpose, value);
3032 }
3033 
s_glUniformMatrix4x3fv(void * self,GLint location,GLsizei count,GLboolean transpose,const GLfloat * value)3034 void GL2Encoder::s_glUniformMatrix4x3fv(void* self, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) {
3035     GL2Encoder *ctx = (GL2Encoder*)self;
3036     GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
3037     ctx->m_glUniformMatrix4x3fv_enc(self, hostLoc, count, transpose, value);
3038 }
3039 
s_glGetUniformuiv(void * self,GLuint program,GLint location,GLuint * params)3040 void GL2Encoder::s_glGetUniformuiv(void* self, GLuint program, GLint location, GLuint* params) {
3041     GL2Encoder *ctx = (GL2Encoder*)self;
3042     SET_ERROR_IF(!ctx->m_shared->isShaderOrProgramObject(program), GL_INVALID_VALUE);
3043     SET_ERROR_IF(!ctx->m_shared->isProgram(program), GL_INVALID_OPERATION);
3044     SET_ERROR_IF(!ctx->m_shared->isProgramInitialized(program), GL_INVALID_OPERATION);
3045     GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
3046     SET_ERROR_IF(ctx->m_shared->getProgramUniformType(program,hostLoc)==0, GL_INVALID_OPERATION);
3047     ctx->m_glGetUniformuiv_enc(self, program, hostLoc, params);
3048 }
3049 
s_glGetActiveUniformBlockiv(void * self,GLuint program,GLuint uniformBlockIndex,GLenum pname,GLint * params)3050 void GL2Encoder::s_glGetActiveUniformBlockiv(void* self, GLuint program, GLuint uniformBlockIndex, GLenum pname, GLint* params) {
3051     GL2Encoder* ctx = (GL2Encoder*)self;
3052     GLClientState* state = ctx->m_state;
3053 
3054     // refresh client state's # active uniforms in this block
3055     if (pname == GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES) {
3056         // TODO if worth it: cache uniform count and other params,
3057         // invalidate on program relinking.
3058         GLint numActiveUniforms;
3059         ctx->m_glGetActiveUniformBlockiv_enc(ctx,
3060                 program, uniformBlockIndex,
3061                 GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS,
3062                 &numActiveUniforms);
3063         ctx->m_state->setNumActiveUniformsInUniformBlock(
3064                 program, uniformBlockIndex, numActiveUniforms);
3065     }
3066 
3067     ctx->m_glGetActiveUniformBlockiv_enc(ctx,
3068             program, uniformBlockIndex,
3069             pname, params);
3070 }
3071 
s_glGetVertexAttribIiv(void * self,GLuint index,GLenum pname,GLint * params)3072 void GL2Encoder::s_glGetVertexAttribIiv(void* self, GLuint index, GLenum pname, GLint* params) {
3073     GL2Encoder *ctx = (GL2Encoder *)self;
3074     assert(ctx->m_state);
3075     GLint maxIndex;
3076     ctx->glGetIntegerv(self, GL_MAX_VERTEX_ATTRIBS, &maxIndex);
3077     SET_ERROR_IF(!(index < maxIndex), GL_INVALID_VALUE);
3078 
3079     if (!ctx->m_state->getVertexAttribParameter<GLint>(index, pname, params)) {
3080         ctx->m_glGetVertexAttribIiv_enc(self, index, pname, params);
3081     }
3082 }
3083 
s_glGetVertexAttribIuiv(void * self,GLuint index,GLenum pname,GLuint * params)3084 void GL2Encoder::s_glGetVertexAttribIuiv(void* self, GLuint index, GLenum pname, GLuint* params) {
3085     GL2Encoder *ctx = (GL2Encoder *)self;
3086     assert(ctx->m_state);
3087     GLint maxIndex;
3088     ctx->glGetIntegerv(self, GL_MAX_VERTEX_ATTRIBS, &maxIndex);
3089     SET_ERROR_IF(!(index < maxIndex), GL_INVALID_VALUE);
3090 
3091     if (!ctx->m_state->getVertexAttribParameter<GLuint>(index, pname, params)) {
3092         ctx->m_glGetVertexAttribIuiv_enc(self, index, pname, params);
3093     }
3094 }
3095 
s_glVertexAttribIPointer(void * self,GLuint index,GLint size,GLenum type,GLsizei stride,const GLvoid * pointer)3096 void GL2Encoder::s_glVertexAttribIPointer(void* self, GLuint index, GLint size, GLenum type, GLsizei stride, const GLvoid* pointer) {
3097     GL2Encoder *ctx = (GL2Encoder *)self;
3098     assert(ctx->m_state != NULL);
3099     VALIDATE_VERTEX_ATTRIB_INDEX(index);
3100     SET_ERROR_IF((size < 1 || size > 4), GL_INVALID_VALUE);
3101     SET_ERROR_IF(
3102         !(type == GL_BYTE ||
3103           type == GL_UNSIGNED_BYTE ||
3104           type == GL_SHORT ||
3105           type == GL_UNSIGNED_SHORT ||
3106           type == GL_INT ||
3107           type == GL_UNSIGNED_INT),
3108         GL_INVALID_ENUM);
3109     SET_ERROR_IF(stride < 0, GL_INVALID_VALUE);
3110 
3111     ctx->m_state->setVertexAttribBinding(index, index);
3112     ctx->m_state->setVertexAttribFormat(index, size, type, false, 0, true);
3113     GLsizei effectiveStride = stride;
3114     if (stride == 0) {
3115         effectiveStride = glSizeof(type) * size;
3116     }
3117     ctx->m_state->bindIndexedBuffer(0, index, ctx->m_state->currentArrayVbo(), (uintptr_t)pointer, 0, stride, effectiveStride);
3118 
3119     if (ctx->m_state->currentArrayVbo() != 0) {
3120         ctx->glVertexAttribIPointerOffsetAEMU(ctx, index, size, type, stride, (uintptr_t)pointer);
3121     } else {
3122         SET_ERROR_IF(ctx->m_state->currentVertexArrayObject() != 0 && pointer, GL_INVALID_OPERATION);
3123         // wait for client-array handler
3124     }
3125 }
3126 
s_glVertexAttribDivisor(void * self,GLuint index,GLuint divisor)3127 void GL2Encoder::s_glVertexAttribDivisor(void* self, GLuint index, GLuint divisor) {
3128     GL2Encoder *ctx = (GL2Encoder *)self;
3129     assert(ctx->m_state != NULL);
3130     VALIDATE_VERTEX_ATTRIB_INDEX(index);
3131     ctx->m_state->setVertexAttribBinding(index, index);
3132     ctx->m_state->setVertexBindingDivisor(index, divisor);
3133     ctx->m_glVertexAttribDivisor_enc(ctx, index, divisor);
3134 }
3135 
s_glRenderbufferStorageMultisample(void * self,GLenum target,GLsizei samples,GLenum internalformat,GLsizei width,GLsizei height)3136 void GL2Encoder::s_glRenderbufferStorageMultisample(void* self,
3137         GLenum target, GLsizei samples, GLenum internalformat,
3138         GLsizei width, GLsizei height) {
3139     GL2Encoder *ctx = (GL2Encoder *)self;
3140     GLClientState* state = ctx->m_state;
3141 
3142     SET_ERROR_IF(target != GL_RENDERBUFFER, GL_INVALID_ENUM);
3143     SET_ERROR_IF(!GLESv2Validation::rboFormat(ctx, internalformat), GL_INVALID_ENUM);
3144 
3145     GLint max_samples;
3146     ctx->s_glGetInternalformativ(ctx, target, internalformat, GL_SAMPLES, 1, &max_samples);
3147     SET_ERROR_IF(samples > max_samples, GL_INVALID_OPERATION);
3148 
3149     state->setBoundRenderbufferFormat(internalformat);
3150     state->setBoundRenderbufferSamples(samples);
3151     ctx->m_glRenderbufferStorageMultisample_enc(
3152             self, target, samples, internalformat, width, height);
3153 }
3154 
s_glDrawBuffers(void * self,GLsizei n,const GLenum * bufs)3155 void GL2Encoder::s_glDrawBuffers(void* self, GLsizei n, const GLenum* bufs) {
3156     GL2Encoder* ctx = (GL2Encoder*)self;
3157     SET_ERROR_IF(!ctx->m_state->boundFramebuffer(GL_DRAW_FRAMEBUFFER) && n > 1, GL_INVALID_OPERATION);
3158     SET_ERROR_IF(n < 0 || n > ctx->m_state->getMaxDrawBuffers(), GL_INVALID_VALUE);
3159     for (int i = 0; i < n; i++) {
3160         SET_ERROR_IF(
3161             bufs[i] != GL_NONE &&
3162             bufs[i] != GL_BACK &&
3163             glUtilsColorAttachmentIndex(bufs[i]) == -1,
3164             GL_INVALID_ENUM);
3165         SET_ERROR_IF(
3166             !ctx->m_state->boundFramebuffer(GL_DRAW_FRAMEBUFFER) &&
3167             glUtilsColorAttachmentIndex(bufs[i]) != -1,
3168             GL_INVALID_OPERATION);
3169         SET_ERROR_IF(
3170             ctx->m_state->boundFramebuffer(GL_DRAW_FRAMEBUFFER) &&
3171             ((glUtilsColorAttachmentIndex(bufs[i]) != -1 &&
3172               glUtilsColorAttachmentIndex(bufs[i]) != i) ||
3173              (glUtilsColorAttachmentIndex(bufs[i]) == -1 &&
3174               bufs[i] != GL_NONE)),
3175             GL_INVALID_OPERATION);
3176     }
3177 
3178     ctx->m_glDrawBuffers_enc(ctx, n, bufs);
3179 }
3180 
s_glReadBuffer(void * self,GLenum src)3181 void GL2Encoder::s_glReadBuffer(void* self, GLenum src) {
3182     GL2Encoder* ctx = (GL2Encoder*)self;
3183 
3184     SET_ERROR_IF(
3185         glUtilsColorAttachmentIndex(src) != -1 &&
3186          (glUtilsColorAttachmentIndex(src) >=
3187          ctx->m_state->getMaxColorAttachments()),
3188         GL_INVALID_OPERATION);
3189     SET_ERROR_IF(
3190         src != GL_NONE &&
3191         src != GL_BACK &&
3192         src > GL_COLOR_ATTACHMENT0 &&
3193         src < GL_DEPTH_ATTACHMENT &&
3194         (src - GL_COLOR_ATTACHMENT0) >
3195         ctx->m_state->getMaxColorAttachments(),
3196         GL_INVALID_OPERATION);
3197     SET_ERROR_IF(
3198         src != GL_NONE &&
3199         src != GL_BACK &&
3200         glUtilsColorAttachmentIndex(src) == -1,
3201         GL_INVALID_ENUM);
3202     SET_ERROR_IF(
3203         !ctx->m_state->boundFramebuffer(GL_READ_FRAMEBUFFER) &&
3204         src != GL_NONE &&
3205         src != GL_BACK,
3206         GL_INVALID_OPERATION);
3207     SET_ERROR_IF(
3208         ctx->m_state->boundFramebuffer(GL_READ_FRAMEBUFFER) &&
3209         src != GL_NONE &&
3210         glUtilsColorAttachmentIndex(src) == -1,
3211         GL_INVALID_OPERATION);
3212 
3213     ctx->m_glReadBuffer_enc(ctx, src);
3214 }
3215 
s_glFramebufferTextureLayer(void * self,GLenum target,GLenum attachment,GLuint texture,GLint level,GLint layer)3216 void GL2Encoder::s_glFramebufferTextureLayer(void* self, GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer) {
3217     GL2Encoder* ctx = (GL2Encoder*)self;
3218     GLClientState* state = ctx->m_state;
3219 
3220     SET_ERROR_IF(!GLESv2Validation::framebufferTarget(ctx, target), GL_INVALID_ENUM);
3221     SET_ERROR_IF(!GLESv2Validation::framebufferAttachment(ctx, attachment), GL_INVALID_ENUM);
3222     GLenum lastBoundTarget = state->queryTexLastBoundTarget(texture);
3223     SET_ERROR_IF(lastBoundTarget != GL_TEXTURE_2D_ARRAY &&
3224                  lastBoundTarget != GL_TEXTURE_3D,
3225                  GL_INVALID_OPERATION);
3226     state->attachTextureObject(target, attachment, texture);
3227 
3228     GLint max3DTextureSize;
3229     ctx->glGetIntegerv(ctx, GL_MAX_3D_TEXTURE_SIZE, &max3DTextureSize);
3230     SET_ERROR_IF(
3231             layer >= max3DTextureSize,
3232             GL_INVALID_VALUE);
3233 
3234     ctx->m_glFramebufferTextureLayer_enc(self, target, attachment, texture, level, layer);
3235 }
3236 
s_glTexStorage2D(void * self,GLenum target,GLsizei levels,GLenum internalformat,GLsizei width,GLsizei height)3237 void GL2Encoder::s_glTexStorage2D(void* self, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height) {
3238     GL2Encoder* ctx = (GL2Encoder*)self;
3239     GLClientState* state = ctx->m_state;
3240 
3241     SET_ERROR_IF(
3242         target != GL_TEXTURE_2D &&
3243         target != GL_TEXTURE_CUBE_MAP,
3244         GL_INVALID_ENUM);
3245     SET_ERROR_IF(!GLESv2Validation::pixelInternalFormat(internalformat), GL_INVALID_ENUM);
3246     SET_ERROR_IF(!state->getBoundTexture(target), GL_INVALID_OPERATION);
3247     SET_ERROR_IF(levels < 1 || width < 1 || height < 1, GL_INVALID_VALUE);
3248     SET_ERROR_IF(levels > ilog2((uint32_t)std::max(width, height)) + 1,
3249                  GL_INVALID_OPERATION);
3250     SET_ERROR_IF(state->isBoundTextureImmutableFormat(target), GL_INVALID_OPERATION);
3251 
3252     state->setBoundTextureInternalFormat(target, internalformat);
3253     state->setBoundTextureDims(target, -1, width, height, 1);
3254     state->setBoundTextureImmutableFormat(target);
3255     ctx->m_glTexStorage2D_enc(ctx, target, levels, internalformat, width, height);
3256 }
3257 
s_glTransformFeedbackVaryings(void * self,GLuint program,GLsizei count,const char ** varyings,GLenum bufferMode)3258 void GL2Encoder::s_glTransformFeedbackVaryings(void* self, GLuint program, GLsizei count, const char** varyings, GLenum bufferMode) {
3259     GL2Encoder* ctx = (GL2Encoder*)self;
3260 
3261     SET_ERROR_IF(!ctx->m_shared->isProgram(program), GL_INVALID_VALUE);
3262 
3263     GLint maxCount = 0;
3264     ctx->glGetIntegerv(ctx, GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS, &maxCount);
3265 
3266     SET_ERROR_IF(
3267         bufferMode == GL_SEPARATE_ATTRIBS &&
3268         maxCount < count,
3269         GL_INVALID_VALUE);
3270     SET_ERROR_IF(
3271         bufferMode != GL_INTERLEAVED_ATTRIBS &&
3272         bufferMode != GL_SEPARATE_ATTRIBS,
3273         GL_INVALID_ENUM);
3274 
3275     if (!count) return;
3276 
3277     GLint err = GL_NO_ERROR;
3278     std::string packed = packVarNames(count, varyings, &err);
3279     SET_ERROR_IF(err != GL_NO_ERROR, GL_INVALID_OPERATION);
3280 
3281     ctx->glTransformFeedbackVaryingsAEMU(ctx, program, count, (const char*)&packed[0], packed.size() + 1, bufferMode);
3282 }
3283 
s_glBeginTransformFeedback(void * self,GLenum primitiveMode)3284 void GL2Encoder::s_glBeginTransformFeedback(void* self, GLenum primitiveMode) {
3285     GL2Encoder* ctx = (GL2Encoder*)self;
3286     GLClientState* state = ctx->m_state;
3287     ctx->m_glBeginTransformFeedback_enc(ctx, primitiveMode);
3288     state->setTransformFeedbackActiveUnpaused(true);
3289 }
3290 
s_glEndTransformFeedback(void * self)3291 void GL2Encoder::s_glEndTransformFeedback(void* self) {
3292     GL2Encoder* ctx = (GL2Encoder*)self;
3293     GLClientState* state = ctx->m_state;
3294     ctx->m_glEndTransformFeedback_enc(ctx);
3295     state->setTransformFeedbackActiveUnpaused(false);
3296 }
3297 
s_glPauseTransformFeedback(void * self)3298 void GL2Encoder::s_glPauseTransformFeedback(void* self) {
3299     GL2Encoder* ctx = (GL2Encoder*)self;
3300     GLClientState* state = ctx->m_state;
3301     ctx->m_glPauseTransformFeedback_enc(ctx);
3302     state->setTransformFeedbackActiveUnpaused(false);
3303 }
3304 
s_glResumeTransformFeedback(void * self)3305 void GL2Encoder::s_glResumeTransformFeedback(void* self) {
3306     GL2Encoder* ctx = (GL2Encoder*)self;
3307     GLClientState* state = ctx->m_state;
3308     ctx->m_glResumeTransformFeedback_enc(ctx);
3309     state->setTransformFeedbackActiveUnpaused(true);
3310 }
3311 
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)3312 void GL2Encoder::s_glTexImage3D(void* self, GLenum target, GLint level, GLint internalFormat,
3313                                GLsizei width, GLsizei height, GLsizei depth,
3314                                GLint border, GLenum format, GLenum type, const GLvoid* data) {
3315     GL2Encoder* ctx = (GL2Encoder*)self;
3316     GLClientState* state = ctx->m_state;
3317 
3318     SET_ERROR_IF(target != GL_TEXTURE_3D &&
3319                  target != GL_TEXTURE_2D_ARRAY,
3320                  GL_INVALID_ENUM);
3321     SET_ERROR_IF(!GLESv2Validation::pixelType(ctx, type), GL_INVALID_ENUM);
3322     SET_ERROR_IF(!GLESv2Validation::pixelFormat(ctx, format), GL_INVALID_ENUM);
3323 
3324     // If unpack buffer is nonzero, verify unmapped state.
3325     SET_ERROR_IF(ctx->isBufferTargetMapped(GL_PIXEL_UNPACK_BUFFER), GL_INVALID_OPERATION);
3326 
3327     GLint max_texture_size;
3328     GLint max_3d_texture_size;
3329     ctx->glGetIntegerv(ctx, GL_MAX_TEXTURE_SIZE, &max_texture_size);
3330     ctx->glGetIntegerv(ctx, GL_MAX_3D_TEXTURE_SIZE, &max_3d_texture_size);
3331     SET_ERROR_IF(level < 0, GL_INVALID_VALUE);
3332     SET_ERROR_IF(level > ilog2(max_texture_size), GL_INVALID_VALUE);
3333     SET_ERROR_IF(level > ilog2(max_3d_texture_size), GL_INVALID_VALUE);
3334 
3335     SET_ERROR_IF(width < 0 || height < 0 || depth < 0, GL_INVALID_VALUE);
3336     SET_ERROR_IF(width > GL_MAX_TEXTURE_SIZE, GL_INVALID_VALUE);
3337     SET_ERROR_IF(height > GL_MAX_TEXTURE_SIZE, GL_INVALID_VALUE);
3338     SET_ERROR_IF(depth > GL_MAX_TEXTURE_SIZE, GL_INVALID_VALUE);
3339     SET_ERROR_IF(width > GL_MAX_3D_TEXTURE_SIZE, GL_INVALID_VALUE);
3340     SET_ERROR_IF(height > GL_MAX_3D_TEXTURE_SIZE, GL_INVALID_VALUE);
3341     SET_ERROR_IF(depth > GL_MAX_3D_TEXTURE_SIZE, GL_INVALID_VALUE);
3342     SET_ERROR_IF(border != 0, GL_INVALID_VALUE);
3343     // If unpack buffer is nonzero, verify buffer data fits and is evenly divisible by the type.
3344     SET_ERROR_IF(ctx->boundBuffer(GL_PIXEL_UNPACK_BUFFER) &&
3345                  ctx->getBufferData(GL_PIXEL_UNPACK_BUFFER) &&
3346                  (ctx->m_state->pboNeededDataSize(width, height, depth, format, type, 0) >
3347                   ctx->getBufferData(GL_PIXEL_UNPACK_BUFFER)->m_size),
3348                  GL_INVALID_OPERATION);
3349     SET_ERROR_IF(ctx->boundBuffer(GL_PIXEL_UNPACK_BUFFER) &&
3350                  ctx->getBufferData(GL_PIXEL_UNPACK_BUFFER) &&
3351                  (ctx->getBufferData(GL_PIXEL_UNPACK_BUFFER)->m_size %
3352                   glSizeof(type)),
3353                  GL_INVALID_OPERATION);
3354     SET_ERROR_IF(state->isBoundTextureImmutableFormat(target), GL_INVALID_OPERATION);
3355 
3356     state->setBoundTextureInternalFormat(target, internalFormat);
3357     state->setBoundTextureFormat(target, format);
3358     state->setBoundTextureType(target, type);
3359     state->setBoundTextureDims(target, level, width, height, depth);
3360 
3361     if (ctx->boundBuffer(GL_PIXEL_UNPACK_BUFFER)) {
3362         ctx->glTexImage3DOffsetAEMU(
3363                 ctx, target, level, internalFormat,
3364                 width, height, depth,
3365                 border, format, type, (uintptr_t)data);
3366     } else {
3367         ctx->m_glTexImage3D_enc(ctx,
3368                 target, level, internalFormat,
3369                 width, height, depth,
3370                 border, format, type, data);
3371     }
3372 }
3373 
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)3374 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) {
3375     GL2Encoder* ctx = (GL2Encoder*)self;
3376     GLClientState* state = ctx->m_state;
3377 
3378     SET_ERROR_IF(target != GL_TEXTURE_3D &&
3379                  target != GL_TEXTURE_2D_ARRAY,
3380                  GL_INVALID_ENUM);
3381     SET_ERROR_IF(!GLESv2Validation::pixelType(ctx, type), GL_INVALID_ENUM);
3382     SET_ERROR_IF(!GLESv2Validation::pixelFormat(ctx, format), GL_INVALID_ENUM);
3383     // If unpack buffer is nonzero, verify unmapped state.
3384     SET_ERROR_IF(ctx->isBufferTargetMapped(GL_PIXEL_UNPACK_BUFFER), GL_INVALID_OPERATION);
3385     GLint max_texture_size;
3386     GLint max_3d_texture_size;
3387     ctx->glGetIntegerv(ctx, GL_MAX_TEXTURE_SIZE, &max_texture_size);
3388     ctx->glGetIntegerv(ctx, GL_MAX_3D_TEXTURE_SIZE, &max_3d_texture_size);
3389     SET_ERROR_IF(level < 0, GL_INVALID_VALUE);
3390     SET_ERROR_IF(level > ilog2(max_texture_size), GL_INVALID_VALUE);
3391     SET_ERROR_IF(level > ilog2(max_3d_texture_size), GL_INVALID_VALUE);
3392     SET_ERROR_IF(width < 0 || height < 0 || depth < 0, GL_INVALID_VALUE);
3393     SET_ERROR_IF(xoffset < 0 || yoffset < 0 || zoffset < 0, GL_INVALID_VALUE);
3394     GLuint tex = state->getBoundTexture(target);
3395     GLsizei neededWidth = xoffset + width;
3396     GLsizei neededHeight = yoffset + height;
3397     GLsizei neededDepth = zoffset + depth;
3398 
3399     SET_ERROR_IF(tex &&
3400                  (neededWidth > state->queryTexWidth(level, tex) ||
3401                   neededHeight > state->queryTexHeight(level, tex) ||
3402                   neededDepth > state->queryTexDepth(level, tex)),
3403                  GL_INVALID_VALUE);
3404     // If unpack buffer is nonzero, verify buffer data fits and is evenly divisible by the type.
3405     SET_ERROR_IF(ctx->boundBuffer(GL_PIXEL_UNPACK_BUFFER) &&
3406                  ctx->getBufferData(GL_PIXEL_UNPACK_BUFFER) &&
3407                  (ctx->m_state->pboNeededDataSize(width, height, depth, format, type, 0) >
3408                   ctx->getBufferData(GL_PIXEL_UNPACK_BUFFER)->m_size),
3409                  GL_INVALID_OPERATION);
3410     SET_ERROR_IF(ctx->boundBuffer(GL_PIXEL_UNPACK_BUFFER) &&
3411                  ctx->getBufferData(GL_PIXEL_UNPACK_BUFFER) &&
3412                  (ctx->getBufferData(GL_PIXEL_UNPACK_BUFFER)->m_size %
3413                   glSizeof(type)),
3414                  GL_INVALID_OPERATION);
3415     SET_ERROR_IF(!ctx->boundBuffer(GL_PIXEL_UNPACK_BUFFER) && !data, GL_INVALID_OPERATION);
3416     SET_ERROR_IF(xoffset < 0 || yoffset < 0 || zoffset < 0, GL_INVALID_VALUE);
3417 
3418     if (ctx->boundBuffer(GL_PIXEL_UNPACK_BUFFER)) {
3419         ctx->glTexSubImage3DOffsetAEMU(ctx,
3420                 target, level,
3421                 xoffset, yoffset, zoffset,
3422                 width, height, depth,
3423                 format, type, (uintptr_t)data);
3424     } else {
3425         ctx->m_glTexSubImage3D_enc(ctx,
3426                 target, level,
3427                 xoffset, yoffset, zoffset,
3428                 width, height, depth,
3429                 format, type, data);
3430     }
3431 }
3432 
s_glCompressedTexImage3D(void * self,GLenum target,GLint level,GLenum internalformat,GLsizei width,GLsizei height,GLsizei depth,GLint border,GLsizei imageSize,const GLvoid * data)3433 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) {
3434     GL2Encoder* ctx = (GL2Encoder*)self;
3435     GLClientState* state = ctx->m_state;
3436 
3437     // Filter compressed formats support.
3438     SET_ERROR_IF(!GLESv2Validation::supportedCompressedFormat(ctx, internalformat), GL_INVALID_ENUM);
3439     // If unpack buffer is nonzero, verify unmapped state.
3440     SET_ERROR_IF(ctx->isBufferTargetMapped(GL_PIXEL_UNPACK_BUFFER), GL_INVALID_OPERATION);
3441     SET_ERROR_IF(width < 0 || height < 0 || depth < 0, GL_INVALID_VALUE);
3442     SET_ERROR_IF(border, GL_INVALID_VALUE);
3443     // If unpack buffer is nonzero, verify buffer data fits.
3444     SET_ERROR_IF(ctx->boundBuffer(GL_PIXEL_UNPACK_BUFFER) &&
3445                  ctx->getBufferData(GL_PIXEL_UNPACK_BUFFER) &&
3446                  (imageSize > ctx->getBufferData(GL_PIXEL_UNPACK_BUFFER)->m_size),
3447                  GL_INVALID_OPERATION);
3448     // TODO: Fix:
3449     // If |imageSize| is too small for compressed dimensions.
3450     // SET_ERROR_IF(GLESv2Validation::compressedTexImageSize(internalformat, width, height, depth) > imageSize, GL_INVALID_VALUE);
3451     state->setBoundTextureInternalFormat(target, (GLint)internalformat);
3452     state->setBoundTextureDims(target, level, width, height, depth);
3453 
3454     if (ctx->boundBuffer(GL_PIXEL_UNPACK_BUFFER)) {
3455         ctx->glCompressedTexImage3DOffsetAEMU(
3456                 ctx, target, level, internalformat,
3457                 width, height, depth, border,
3458                 imageSize, (uintptr_t)data);
3459     } else {
3460         ctx->m_glCompressedTexImage3D_enc(
3461                 ctx, target, level, internalformat,
3462                 width, height, depth, border,
3463                 imageSize, data);
3464     }
3465 }
3466 
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)3467 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) {
3468     GL2Encoder* ctx = (GL2Encoder*)self;
3469     GLClientState* state = ctx->m_state;
3470 
3471     SET_ERROR_IF(!GLESv2Validation::textureTarget(ctx, target), GL_INVALID_ENUM);
3472     // If unpack buffer is nonzero, verify unmapped state.
3473     SET_ERROR_IF(ctx->isBufferTargetMapped(GL_PIXEL_UNPACK_BUFFER), GL_INVALID_OPERATION);
3474     SET_ERROR_IF(width < 0 || height < 0 || depth < 0, GL_INVALID_VALUE);
3475     // If unpack buffer is nonzero, verify buffer data fits.
3476     SET_ERROR_IF(ctx->boundBuffer(GL_PIXEL_UNPACK_BUFFER) &&
3477                  ctx->getBufferData(GL_PIXEL_UNPACK_BUFFER) &&
3478                  (imageSize > ctx->getBufferData(GL_PIXEL_UNPACK_BUFFER)->m_size),
3479                  GL_INVALID_OPERATION);
3480     SET_ERROR_IF(xoffset < 0 || yoffset < 0 || zoffset < 0, GL_INVALID_VALUE);
3481 
3482     if (ctx->boundBuffer(GL_PIXEL_UNPACK_BUFFER)) {
3483         ctx->glCompressedTexSubImage3DOffsetAEMU(
3484                 ctx, target, level,
3485                 xoffset, yoffset, zoffset,
3486                 width, height, depth,
3487                 format, imageSize, (uintptr_t)data);
3488     } else {
3489         ctx->m_glCompressedTexSubImage3D_enc(
3490                 ctx, target, level,
3491                 xoffset, yoffset, zoffset,
3492                 width, height, depth,
3493                 format, imageSize, data);
3494 
3495     }
3496 }
3497 
s_glTexStorage3D(void * self,GLenum target,GLsizei levels,GLenum internalformat,GLsizei width,GLsizei height,GLsizei depth)3498 void GL2Encoder::s_glTexStorage3D(void* self, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth) {
3499     GL2Encoder* ctx = (GL2Encoder*)self;
3500     GLClientState* state = ctx->m_state;
3501     SET_ERROR_IF(target != GL_TEXTURE_3D &&
3502                  target != GL_TEXTURE_2D_ARRAY,
3503                  GL_INVALID_ENUM);
3504     SET_ERROR_IF(!GLESv2Validation::pixelInternalFormat(internalformat), GL_INVALID_ENUM);
3505     SET_ERROR_IF(!state->getBoundTexture(target), GL_INVALID_OPERATION);
3506     SET_ERROR_IF(levels < 1 || width < 1 || height < 1, GL_INVALID_VALUE);
3507     SET_ERROR_IF(target == GL_TEXTURE_3D && (levels > ilog2((uint32_t)std::max(width, std::max(height, depth))) + 1),
3508                  GL_INVALID_OPERATION);
3509     SET_ERROR_IF(target == GL_TEXTURE_2D_ARRAY && (levels > ilog2((uint32_t)std::max(width, height)) + 1),
3510                  GL_INVALID_OPERATION);
3511     SET_ERROR_IF(state->isBoundTextureImmutableFormat(target), GL_INVALID_OPERATION);
3512 
3513     state->setBoundTextureInternalFormat(target, internalformat);
3514     state->setBoundTextureDims(target, -1, width, height, depth);
3515     state->setBoundTextureImmutableFormat(target);
3516     ctx->m_glTexStorage3D_enc(ctx, target, levels, internalformat, width, height, depth);
3517     state->setBoundTextureImmutableFormat(target);
3518 }
3519 
s_glDrawArraysInstanced(void * self,GLenum mode,GLint first,GLsizei count,GLsizei primcount)3520 void GL2Encoder::s_glDrawArraysInstanced(void* self, GLenum mode, GLint first, GLsizei count, GLsizei primcount) {
3521     GL2Encoder *ctx = (GL2Encoder *)self;
3522     assert(ctx->m_state != NULL);
3523     SET_ERROR_IF(!isValidDrawMode(mode), GL_INVALID_ENUM);
3524     SET_ERROR_IF(count < 0, GL_INVALID_VALUE);
3525 
3526     bool has_client_vertex_arrays = false;
3527     bool has_indirect_arrays = false;
3528     ctx->getVBOUsage(&has_client_vertex_arrays,
3529                      &has_indirect_arrays);
3530 
3531     if (has_client_vertex_arrays ||
3532         (!has_client_vertex_arrays &&
3533          !has_indirect_arrays)) {
3534         ctx->sendVertexAttributes(first, count, true, primcount);
3535         ctx->m_glDrawArraysInstanced_enc(ctx, mode, 0, count, primcount);
3536     } else {
3537         ctx->sendVertexAttributes(0, count, false, primcount);
3538         ctx->m_glDrawArraysInstanced_enc(ctx, mode, first, count, primcount);
3539     }
3540     ctx->m_stream->flush();
3541 }
3542 
s_glDrawElementsInstanced(void * self,GLenum mode,GLsizei count,GLenum type,const void * indices,GLsizei primcount)3543 void GL2Encoder::s_glDrawElementsInstanced(void* self, GLenum mode, GLsizei count, GLenum type, const void* indices, GLsizei primcount)
3544 {
3545 
3546     GL2Encoder *ctx = (GL2Encoder *)self;
3547     assert(ctx->m_state != NULL);
3548     SET_ERROR_IF(!isValidDrawMode(mode), GL_INVALID_ENUM);
3549     SET_ERROR_IF(count < 0, GL_INVALID_VALUE);
3550     SET_ERROR_IF(!(type == GL_UNSIGNED_BYTE || type == GL_UNSIGNED_SHORT || type == GL_UNSIGNED_INT), GL_INVALID_ENUM);
3551     SET_ERROR_IF(ctx->m_state->getTransformFeedbackActiveUnpaused(), GL_INVALID_OPERATION);
3552 
3553     bool has_client_vertex_arrays = false;
3554     bool has_indirect_arrays = false;
3555     int nLocations = ctx->m_state->nLocations();
3556     GLintptr offset = 0;
3557 
3558     ctx->getVBOUsage(&has_client_vertex_arrays, &has_indirect_arrays);
3559 
3560     if (!has_client_vertex_arrays && !has_indirect_arrays) {
3561         // ALOGW("glDrawElements: no vertex arrays / buffers bound to the command\n");
3562         GLenum status = ctx->m_glCheckFramebufferStatus_enc(self, GL_FRAMEBUFFER);
3563         SET_ERROR_IF(status != GL_FRAMEBUFFER_COMPLETE, GL_INVALID_FRAMEBUFFER_OPERATION);
3564     }
3565 
3566     BufferData* buf = NULL;
3567     int minIndex = 0, maxIndex = 0;
3568 
3569     // For validation/immediate index array purposes,
3570     // we need the min/max vertex index of the index array.
3571     // If the VBO != 0, this may not be the first time we have
3572     // used this particular index buffer. getBufferIndexRange
3573     // can more quickly get min/max vertex index by
3574     // caching previous results.
3575     if (ctx->m_state->currentIndexVbo() != 0) {
3576         buf = ctx->m_shared->getBufferData(ctx->m_state->currentIndexVbo());
3577         offset = (GLintptr)indices;
3578         indices = (void*)((GLintptr)buf->m_fixedBuffer.ptr() + (GLintptr)indices);
3579         ctx->getBufferIndexRange(buf,
3580                                  indices,
3581                                  type,
3582                                  (size_t)count,
3583                                  (size_t)offset,
3584                                  &minIndex, &maxIndex);
3585     } else {
3586         // In this case, the |indices| field holds a real
3587         // array, so calculate the indices now. They will
3588         // also be needed to know how much data to
3589         // transfer to host.
3590         ctx->calcIndexRange(indices,
3591                             type,
3592                             count,
3593                             &minIndex,
3594                             &maxIndex);
3595     }
3596 
3597     bool adjustIndices = true;
3598     if (ctx->m_state->currentIndexVbo() != 0) {
3599         if (!has_client_vertex_arrays) {
3600             ctx->sendVertexAttributes(0, maxIndex + 1, false, primcount);
3601             ctx->m_glBindBuffer_enc(self, GL_ELEMENT_ARRAY_BUFFER, ctx->m_state->currentIndexVbo());
3602             ctx->glDrawElementsInstancedOffsetAEMU(ctx, mode, count, type, offset, primcount);
3603             ctx->flushDrawCall();
3604             adjustIndices = false;
3605         } else {
3606             BufferData * buf = ctx->m_shared->getBufferData(ctx->m_state->currentIndexVbo());
3607             ctx->m_glBindBuffer_enc(self, GL_ELEMENT_ARRAY_BUFFER, 0);
3608         }
3609     }
3610     if (adjustIndices) {
3611         void *adjustedIndices =
3612             ctx->recenterIndices(indices,
3613                                  type,
3614                                  count,
3615                                  minIndex);
3616 
3617         if (has_indirect_arrays || 1) {
3618             ctx->sendVertexAttributes(minIndex, maxIndex - minIndex + 1, true, primcount);
3619             ctx->glDrawElementsInstancedDataAEMU(ctx, mode, count, type, adjustedIndices, primcount, count * glSizeof(type));
3620             ctx->m_stream->flush();
3621             // XXX - OPTIMIZATION (see the other else branch) should be implemented
3622             if(!has_indirect_arrays) {
3623                 //ALOGD("unoptimized drawelements !!!\n");
3624             }
3625         } else {
3626             // we are all direct arrays and immidate mode index array -
3627             // rebuild the arrays and the index array;
3628             ALOGE("glDrawElements: direct index & direct buffer data - will be implemented in later versions;\n");
3629         }
3630     }
3631 }
3632 
s_glDrawRangeElements(void * self,GLenum mode,GLuint start,GLuint end,GLsizei count,GLenum type,const void * indices)3633 void GL2Encoder::s_glDrawRangeElements(void* self, GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void* indices)
3634 {
3635 
3636     GL2Encoder *ctx = (GL2Encoder *)self;
3637     assert(ctx->m_state != NULL);
3638     SET_ERROR_IF(!isValidDrawMode(mode), GL_INVALID_ENUM);
3639     SET_ERROR_IF(end < start, GL_INVALID_VALUE);
3640     SET_ERROR_IF(count < 0, GL_INVALID_VALUE);
3641     SET_ERROR_IF(!(type == GL_UNSIGNED_BYTE || type == GL_UNSIGNED_SHORT || type == GL_UNSIGNED_INT), GL_INVALID_ENUM);
3642     SET_ERROR_IF(ctx->m_state->getTransformFeedbackActiveUnpaused(), GL_INVALID_OPERATION);
3643 
3644     bool has_client_vertex_arrays = false;
3645     bool has_indirect_arrays = false;
3646     int nLocations = ctx->m_state->nLocations();
3647     GLintptr offset = 0;
3648 
3649     ctx->getVBOUsage(&has_client_vertex_arrays, &has_indirect_arrays);
3650 
3651     if (!has_client_vertex_arrays && !has_indirect_arrays) {
3652         // ALOGW("glDrawElements: no vertex arrays / buffers bound to the command\n");
3653         GLenum status = ctx->m_glCheckFramebufferStatus_enc(self, GL_FRAMEBUFFER);
3654         SET_ERROR_IF(status != GL_FRAMEBUFFER_COMPLETE, GL_INVALID_FRAMEBUFFER_OPERATION);
3655     }
3656 
3657     BufferData* buf = NULL;
3658     int minIndex = 0, maxIndex = 0;
3659 
3660     // For validation/immediate index array purposes,
3661     // we need the min/max vertex index of the index array.
3662     // If the VBO != 0, this may not be the first time we have
3663     // used this particular index buffer. getBufferIndexRange
3664     // can more quickly get min/max vertex index by
3665     // caching previous results.
3666     if (ctx->m_state->currentIndexVbo() != 0) {
3667         buf = ctx->m_shared->getBufferData(ctx->m_state->currentIndexVbo());
3668         offset = (GLintptr)indices;
3669         indices = (void*)((GLintptr)buf->m_fixedBuffer.ptr() + (GLintptr)indices);
3670         ctx->getBufferIndexRange(buf,
3671                                  indices,
3672                                  type,
3673                                  (size_t)count,
3674                                  (size_t)offset,
3675                                  &minIndex, &maxIndex);
3676     } else {
3677         // In this case, the |indices| field holds a real
3678         // array, so calculate the indices now. They will
3679         // also be needed to know how much data to
3680         // transfer to host.
3681         ctx->calcIndexRange(indices,
3682                             type,
3683                             count,
3684                             &minIndex,
3685                             &maxIndex);
3686     }
3687 
3688     bool adjustIndices = true;
3689     if (ctx->m_state->currentIndexVbo() != 0) {
3690         if (!has_client_vertex_arrays) {
3691             ctx->sendVertexAttributes(0, maxIndex + 1, false);
3692             ctx->m_glBindBuffer_enc(self, GL_ELEMENT_ARRAY_BUFFER, ctx->m_state->currentIndexVbo());
3693             ctx->glDrawElementsOffset(ctx, mode, count, type, offset);
3694             ctx->flushDrawCall();
3695             adjustIndices = false;
3696         } else {
3697             BufferData * buf = ctx->m_shared->getBufferData(ctx->m_state->currentIndexVbo());
3698             ctx->m_glBindBuffer_enc(self, GL_ELEMENT_ARRAY_BUFFER, 0);
3699         }
3700     }
3701     if (adjustIndices) {
3702         void *adjustedIndices =
3703             ctx->recenterIndices(indices,
3704                                  type,
3705                                  count,
3706                                  minIndex);
3707 
3708         if (has_indirect_arrays || 1) {
3709             ctx->sendVertexAttributes(minIndex, maxIndex - minIndex + 1, true);
3710             ctx->glDrawElementsData(ctx, mode, count, type, adjustedIndices, count * glSizeof(type));
3711             ctx->m_stream->flush();
3712             // XXX - OPTIMIZATION (see the other else branch) should be implemented
3713             if(!has_indirect_arrays) {
3714                 //ALOGD("unoptimized drawelements !!!\n");
3715             }
3716         } else {
3717             // we are all direct arrays and immidate mode index array -
3718             // rebuild the arrays and the index array;
3719             ALOGE("glDrawElements: direct index & direct buffer data - will be implemented in later versions;\n");
3720         }
3721     }
3722 }
3723 
3724 // struct GLStringKey {
3725 //     GLenum name;
3726 //     GLuint index;
3727 // };
3728 //
3729 // struct GLStringKeyCompare {
3730 //     bool operator() (const GLStringKey& a,
3731 //                      const GLStringKey& b) const {
3732 //         if (a.name != b.name) return a.name < b.name;
3733 //         if (a.index != b.index) return a.index < b.index;
3734 //         return false;
3735 //     }
3736 // };
3737 //
3738 // typedef std::map<GLStringKey, std::string, GLStringKeyCompare> GLStringStore;
3739 //
3740 // static GLStringStore sGLStringStore;
3741 // bool sGLStringStoreInitialized = false;
3742 
s_glGetStringi(void * self,GLenum name,GLuint index)3743 const GLubyte* GL2Encoder::s_glGetStringi(void* self, GLenum name, GLuint index) {
3744     GL2Encoder *ctx = (GL2Encoder *)self;
3745     GLubyte *retval =  (GLubyte *) "";
3746 
3747     RET_AND_SET_ERROR_IF(
3748         name != GL_VENDOR &&
3749         name != GL_RENDERER &&
3750         name != GL_VERSION &&
3751         name != GL_EXTENSIONS,
3752         GL_INVALID_ENUM,
3753         retval);
3754 
3755     RET_AND_SET_ERROR_IF(
3756         name == GL_VENDOR ||
3757         name == GL_RENDERER ||
3758         name == GL_VERSION ||
3759         name == GL_EXTENSIONS &&
3760         index != 0,
3761         GL_INVALID_VALUE,
3762         retval);
3763 
3764     switch (name) {
3765     case GL_VENDOR:
3766         retval = gVendorString;
3767         break;
3768     case GL_RENDERER:
3769         retval = gRendererString;
3770         break;
3771     case GL_VERSION:
3772         retval = gVersionString;
3773         break;
3774     case GL_EXTENSIONS:
3775         retval = gExtensionsString;
3776         break;
3777     }
3778 
3779     return retval;
3780 }
3781 
s_glGetProgramBinary(void * self,GLuint program,GLsizei bufSize,GLsizei * length,GLenum * binaryFormat,void * binary)3782 void GL2Encoder::s_glGetProgramBinary(void* self, GLuint program, GLsizei bufSize, GLsizei* length, GLenum* binaryFormat, void* binary) {
3783     GL2Encoder *ctx = (GL2Encoder *)self;
3784 
3785     SET_ERROR_IF(!ctx->m_shared->isProgram(program), GL_INVALID_OPERATION);
3786 
3787     GLint linkStatus = 0;
3788     ctx->glGetProgramiv(self, program, GL_LINK_STATUS, &linkStatus);
3789     GLint properLength = 0;
3790     ctx->glGetProgramiv(self, program, GL_PROGRAM_BINARY_LENGTH, &properLength);
3791 
3792     SET_ERROR_IF(!linkStatus, GL_INVALID_OPERATION);
3793     SET_ERROR_IF(bufSize < properLength, GL_INVALID_OPERATION);
3794 
3795     ctx->m_glGetProgramBinary_enc(ctx, program, bufSize, length, binaryFormat, binary);
3796 }
3797 
s_glReadPixels(void * self,GLint x,GLint y,GLsizei width,GLsizei height,GLenum format,GLenum type,GLvoid * pixels)3798 void GL2Encoder::s_glReadPixels(void* self, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels) {
3799     GL2Encoder *ctx = (GL2Encoder *)self;
3800 
3801     SET_ERROR_IF(!GLESv2Validation::readPixelsFormat(format), GL_INVALID_ENUM);
3802     SET_ERROR_IF(!GLESv2Validation::readPixelsType(type), GL_INVALID_ENUM);
3803     SET_ERROR_IF(width < 0 || height < 0, GL_INVALID_VALUE);
3804     SET_ERROR_IF(ctx->isBufferTargetMapped(GL_PIXEL_PACK_BUFFER), GL_INVALID_OPERATION);
3805     SET_ERROR_IF(ctx->boundBuffer(GL_PIXEL_PACK_BUFFER) &&
3806                  ctx->getBufferData(GL_PIXEL_PACK_BUFFER) &&
3807                  (ctx->m_state->pboNeededDataSize(width, height, 1, format, type, 1) >
3808                   ctx->getBufferData(GL_PIXEL_PACK_BUFFER)->m_size),
3809                  GL_INVALID_OPERATION);
3810     /*
3811 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.
3812 
3813 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.
3814 
3815 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.
3816 
3817 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.
3818 */
3819 
3820     FboFormatInfo fbo_format_info;
3821     ctx->m_state->getBoundFramebufferFormat(
3822             GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, &fbo_format_info);
3823     SET_ERROR_IF(
3824         fbo_format_info.type == FBO_ATTACHMENT_TEXTURE &&
3825         !GLESv2Validation::readPixelsFboFormatMatch(
3826             format, type, fbo_format_info.tex_type),
3827         GL_INVALID_OPERATION);
3828 
3829     if (ctx->boundBuffer(GL_PIXEL_PACK_BUFFER)) {
3830         ctx->glReadPixelsOffsetAEMU(
3831                 ctx, x, y, width, height,
3832                 format, type, (uintptr_t)pixels);
3833     } else {
3834         ctx->m_glReadPixels_enc(
3835                 ctx, x, y, width, height,
3836                 format, type, pixels);
3837     }
3838 }
3839 
3840 // Track enabled state for some things like:
3841 // - Primitive restart
s_glEnable(void * self,GLenum what)3842 void GL2Encoder::s_glEnable(void* self, GLenum what) {
3843     GL2Encoder *ctx = (GL2Encoder *)self;
3844 
3845     switch (what) {
3846     case GL_PRIMITIVE_RESTART_FIXED_INDEX:
3847         ctx->m_primitiveRestartEnabled = true;
3848         break;
3849     }
3850 
3851     ctx->m_glEnable_enc(ctx, what);
3852 }
3853 
s_glDisable(void * self,GLenum what)3854 void GL2Encoder::s_glDisable(void* self, GLenum what) {
3855     GL2Encoder *ctx = (GL2Encoder *)self;
3856 
3857     switch (what) {
3858     case GL_PRIMITIVE_RESTART_FIXED_INDEX:
3859         ctx->m_primitiveRestartEnabled = false;
3860         break;
3861     }
3862 
3863     ctx->m_glDisable_enc(ctx, what);
3864 }
3865 
s_glClearBufferiv(void * self,GLenum buffer,GLint drawBuffer,const GLint * value)3866 void GL2Encoder::s_glClearBufferiv(void* self, GLenum buffer, GLint drawBuffer, const GLint * value) {
3867     GL2Encoder *ctx = (GL2Encoder *)self;
3868 
3869     SET_ERROR_IF(buffer == GL_DEPTH || buffer == GL_DEPTH_STENCIL, GL_INVALID_ENUM);
3870 
3871     ctx->m_glClearBufferiv_enc(ctx, buffer, drawBuffer, value);
3872 }
3873 
s_glClearBufferuiv(void * self,GLenum buffer,GLint drawBuffer,const GLuint * value)3874 void GL2Encoder::s_glClearBufferuiv(void* self, GLenum buffer, GLint drawBuffer, const GLuint * value) {
3875     GL2Encoder *ctx = (GL2Encoder *)self;
3876 
3877     SET_ERROR_IF(buffer == GL_DEPTH || buffer == GL_STENCIL || buffer == GL_DEPTH_STENCIL, GL_INVALID_ENUM);
3878 
3879     ctx->m_glClearBufferuiv_enc(ctx, buffer, drawBuffer, value);
3880 }
3881 
s_glClearBufferfv(void * self,GLenum buffer,GLint drawBuffer,const GLfloat * value)3882 void GL2Encoder::s_glClearBufferfv(void* self, GLenum buffer, GLint drawBuffer, const GLfloat * value) {
3883     GL2Encoder *ctx = (GL2Encoder *)self;
3884 
3885     SET_ERROR_IF(buffer == GL_STENCIL || buffer == GL_DEPTH_STENCIL, GL_INVALID_ENUM);
3886 
3887     ctx->m_glClearBufferfv_enc(ctx, buffer, drawBuffer, value);
3888 }
3889 
s_glBlitFramebuffer(void * self,GLint srcX0,GLint srcY0,GLint srcX1,GLint srcY1,GLint dstX0,GLint dstY0,GLint dstX1,GLint dstY1,GLbitfield mask,GLenum filter)3890 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) {
3891     GL2Encoder *ctx = (GL2Encoder *)self;
3892     GLClientState* state = ctx->m_state;
3893 
3894     bool validateColor = mask | GL_COLOR_BUFFER_BIT;
3895     bool validateDepth = mask | GL_DEPTH_BUFFER_BIT;
3896     bool validateStencil = mask | GL_STENCIL_BUFFER_BIT;
3897 
3898     FboFormatInfo read_fbo_format_info;
3899     FboFormatInfo draw_fbo_format_info;
3900     if (validateColor) {
3901         state->getBoundFramebufferFormat(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, &read_fbo_format_info);
3902         state->getBoundFramebufferFormat(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, &draw_fbo_format_info);
3903 
3904         if (read_fbo_format_info.type == FBO_ATTACHMENT_TEXTURE &&
3905             draw_fbo_format_info.type == FBO_ATTACHMENT_TEXTURE) {
3906             SET_ERROR_IF(
3907                     state->boundFramebuffer(GL_READ_FRAMEBUFFER) &&
3908                     state->boundFramebuffer(GL_DRAW_FRAMEBUFFER) &&
3909                     !GLESv2Validation::blitFramebufferFormat(
3910                         read_fbo_format_info.tex_type,
3911                         draw_fbo_format_info.tex_type),
3912                     GL_INVALID_OPERATION);
3913         }
3914     }
3915 
3916     if (validateDepth) {
3917         state->getBoundFramebufferFormat(GL_READ_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, &read_fbo_format_info);
3918         state->getBoundFramebufferFormat(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, &draw_fbo_format_info);
3919 
3920         if (read_fbo_format_info.type == FBO_ATTACHMENT_RENDERBUFFER &&
3921             draw_fbo_format_info.type == FBO_ATTACHMENT_RENDERBUFFER) {
3922             SET_ERROR_IF(
3923                     state->boundFramebuffer(GL_READ_FRAMEBUFFER) &&
3924                     state->boundFramebuffer(GL_DRAW_FRAMEBUFFER) &&
3925                     !GLESv2Validation::blitFramebufferFormat(
3926                         read_fbo_format_info.rb_format,
3927                         draw_fbo_format_info.rb_format),
3928                     GL_INVALID_OPERATION);
3929         }
3930     }
3931 
3932     if (validateStencil) {
3933         state->getBoundFramebufferFormat(GL_READ_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, &read_fbo_format_info);
3934         state->getBoundFramebufferFormat(GL_DRAW_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, &draw_fbo_format_info);
3935 
3936         if (read_fbo_format_info.type == FBO_ATTACHMENT_RENDERBUFFER &&
3937             draw_fbo_format_info.type == FBO_ATTACHMENT_RENDERBUFFER) {
3938             SET_ERROR_IF(
3939                     state->boundFramebuffer(GL_READ_FRAMEBUFFER) &&
3940                     state->boundFramebuffer(GL_DRAW_FRAMEBUFFER) &&
3941                     !GLESv2Validation::blitFramebufferFormat(
3942                         read_fbo_format_info.rb_format,
3943                         draw_fbo_format_info.rb_format),
3944                     GL_INVALID_OPERATION);
3945         }
3946     }
3947 
3948     state->getBoundFramebufferFormat(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, &draw_fbo_format_info);
3949     SET_ERROR_IF(
3950             draw_fbo_format_info.type == FBO_ATTACHMENT_RENDERBUFFER &&
3951             draw_fbo_format_info.rb_multisamples > 0,
3952             GL_INVALID_OPERATION);
3953     SET_ERROR_IF(
3954             draw_fbo_format_info.type == FBO_ATTACHMENT_TEXTURE &&
3955             draw_fbo_format_info.tex_multisamples > 0,
3956             GL_INVALID_OPERATION);
3957 
3958     state->getBoundFramebufferFormat(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, &read_fbo_format_info);
3959     SET_ERROR_IF(
3960             read_fbo_format_info.type == FBO_ATTACHMENT_RENDERBUFFER &&
3961             read_fbo_format_info.rb_multisamples > 0 &&
3962             draw_fbo_format_info.type == FBO_ATTACHMENT_RENDERBUFFER &&
3963             state->boundFramebuffer(GL_READ_FRAMEBUFFER) &&
3964             state->boundFramebuffer(GL_DRAW_FRAMEBUFFER) &&
3965             (read_fbo_format_info.rb_format !=
3966              draw_fbo_format_info.rb_format),
3967             GL_INVALID_OPERATION);
3968     SET_ERROR_IF(
3969             read_fbo_format_info.type == FBO_ATTACHMENT_RENDERBUFFER &&
3970             read_fbo_format_info.rb_multisamples > 0 &&
3971             draw_fbo_format_info.type == FBO_ATTACHMENT_RENDERBUFFER &&
3972             (srcX0 != dstX0 || srcY0 != dstY0 ||
3973              srcX1 != dstX1 || srcY1 != dstY1),
3974             GL_INVALID_OPERATION);
3975 
3976 	ctx->m_glBlitFramebuffer_enc(ctx,
3977             srcX0, srcY0, srcX1, srcY1,
3978             dstX0, dstY0, dstX1, dstY1,
3979             mask, filter);
3980 }
3981 
s_glGetInternalformativ(void * self,GLenum target,GLenum internalformat,GLenum pname,GLsizei bufSize,GLint * params)3982 void GL2Encoder::s_glGetInternalformativ(void* self, GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint *params) {
3983     GL2Encoder *ctx = (GL2Encoder *)self;
3984 
3985     SET_ERROR_IF(pname != GL_NUM_SAMPLE_COUNTS &&
3986                  pname != GL_SAMPLES,
3987                  GL_INVALID_ENUM);
3988     SET_ERROR_IF(!GLESv2Validation::internalFormatTarget(ctx, target), GL_INVALID_ENUM);
3989     SET_ERROR_IF(!GLESv2Validation::unsizedFormat(internalformat) &&
3990                  !GLESv2Validation::colorRenderableFormat(ctx, internalformat) &&
3991                  !GLESv2Validation::depthRenderableFormat(ctx, internalformat) &&
3992                  !GLESv2Validation::stencilRenderableFormat(ctx, internalformat),
3993                  GL_INVALID_ENUM);
3994     SET_ERROR_IF(bufSize < 0, GL_INVALID_VALUE);
3995 
3996     if (bufSize < 1) return;
3997 
3998     // Desktop OpenGL can allow a mindboggling # samples per pixel (such as 64).
3999     // Limit to 4 (spec minimum) to keep dEQP tests from timing out.
4000     switch (pname) {
4001         case GL_NUM_SAMPLE_COUNTS:
4002             *params = 3;
4003             break;
4004         case GL_SAMPLES:
4005             params[0] = 4;
4006             if (bufSize > 1) params[1] = 2;
4007             if (bufSize > 2) params[2] = 1;
4008             break;
4009         default:
4010             break;
4011     }
4012 }
4013 
s_glGenerateMipmap(void * self,GLenum target)4014 void GL2Encoder::s_glGenerateMipmap(void* self, GLenum target) {
4015     GL2Encoder *ctx = (GL2Encoder *)self;
4016     GLClientState* state = ctx->m_state;
4017 
4018     SET_ERROR_IF(target != GL_TEXTURE_2D &&
4019                  target != GL_TEXTURE_3D &&
4020                  target != GL_TEXTURE_CUBE_MAP,
4021                  GL_INVALID_ENUM);
4022 
4023     GLuint tex = state->getBoundTexture(target);
4024     GLenum internalformat = state->queryTexInternalFormat(tex);
4025     GLenum format = state->queryTexFormat(tex);
4026 
4027     SET_ERROR_IF(tex && GLESv2Validation::isCompressedFormat(internalformat),
4028                  GL_INVALID_OPERATION);
4029     SET_ERROR_IF(tex &&
4030                  !GLESv2Validation::unsizedFormat(internalformat) &&
4031                  !(GLESv2Validation::colorRenderableFormat(ctx, internalformat) &&
4032                    GLESv2Validation::filterableTexFormat(ctx, internalformat)),
4033                  GL_INVALID_OPERATION);
4034 
4035     ctx->m_glGenerateMipmap_enc(ctx, target);
4036 }
4037 
s_glBindSampler(void * self,GLuint unit,GLuint sampler)4038 void GL2Encoder::s_glBindSampler(void* self, GLuint unit, GLuint sampler) {
4039     GL2Encoder *ctx = (GL2Encoder *)self;
4040     GLint maxCombinedUnits;
4041     ctx->glGetIntegerv(ctx, GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &maxCombinedUnits);
4042     SET_ERROR_IF(unit >= maxCombinedUnits, GL_INVALID_VALUE);
4043 
4044     ctx->m_glBindSampler_enc(ctx, unit, sampler);
4045 }
4046 
s_glFenceSync(void * self,GLenum condition,GLbitfield flags)4047 GLsync GL2Encoder::s_glFenceSync(void* self, GLenum condition, GLbitfield flags) {
4048     GL2Encoder *ctx = (GL2Encoder *)self;
4049     uint64_t syncHandle = ctx->glFenceSyncAEMU(ctx, condition, flags);
4050     return (GLsync)(uintptr_t)syncHandle;
4051 }
4052 
s_glClientWaitSync(void * self,GLsync wait_on,GLbitfield flags,GLuint64 timeout)4053 GLenum GL2Encoder::s_glClientWaitSync(void* self, GLsync wait_on, GLbitfield flags, GLuint64 timeout) {
4054     GL2Encoder *ctx = (GL2Encoder *)self;
4055     return ctx->glClientWaitSyncAEMU(ctx, (uint64_t)(uintptr_t)wait_on, flags, timeout);
4056 }
4057 
s_glWaitSync(void * self,GLsync wait_on,GLbitfield flags,GLuint64 timeout)4058 void GL2Encoder::s_glWaitSync(void* self, GLsync wait_on, GLbitfield flags, GLuint64 timeout) {
4059     GL2Encoder *ctx = (GL2Encoder *)self;
4060     ctx->glWaitSyncAEMU(ctx, (uint64_t)(uintptr_t)wait_on, flags, timeout);
4061 }
4062 
s_glDeleteSync(void * self,GLsync sync)4063 void GL2Encoder::s_glDeleteSync(void* self, GLsync sync) {
4064     GL2Encoder *ctx = (GL2Encoder *)self;
4065 
4066     if (!sync) return;
4067 
4068     ctx->glDeleteSyncAEMU(ctx, (uint64_t)(uintptr_t)sync);
4069 }
4070 
s_glIsSync(void * self,GLsync sync)4071 GLboolean GL2Encoder::s_glIsSync(void* self, GLsync sync) {
4072     GL2Encoder *ctx = (GL2Encoder *)self;
4073     return ctx->glIsSyncAEMU(ctx, (uint64_t)(uintptr_t)sync);
4074 }
4075 
s_glGetSynciv(void * self,GLsync sync,GLenum pname,GLsizei bufSize,GLsizei * length,GLint * values)4076 void GL2Encoder::s_glGetSynciv(void* self, GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values) {
4077     GL2Encoder *ctx = (GL2Encoder *)self;
4078 
4079     SET_ERROR_IF(bufSize < 0, GL_INVALID_VALUE);
4080 
4081     return ctx->glGetSyncivAEMU(ctx, (uint64_t)(uintptr_t)sync, pname, bufSize, length, values);
4082 }
4083 
4084 #define LIMIT_CASE(target, lim) \
4085     case target: \
4086         ctx->glGetIntegerv(ctx, lim, &limit); \
4087         SET_ERROR_IF(index < 0 || index >= limit, GL_INVALID_VALUE); \
4088         break; \
4089 
s_glGetIntegeri_v(void * self,GLenum target,GLuint index,GLint * params)4090 void GL2Encoder::s_glGetIntegeri_v(void* self, GLenum target, GLuint index, GLint* params) {
4091     GL2Encoder *ctx = (GL2Encoder *)self;
4092     GLClientState* state = ctx->m_state;
4093 
4094     GLint limit;
4095 
4096     switch (target) {
4097     LIMIT_CASE(GL_TRANSFORM_FEEDBACK_BUFFER_BINDING, GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS)
4098     LIMIT_CASE(GL_UNIFORM_BUFFER_BINDING, GL_MAX_UNIFORM_BUFFER_BINDINGS)
4099     LIMIT_CASE(GL_ATOMIC_COUNTER_BUFFER_BINDING, GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS)
4100     LIMIT_CASE(GL_SHADER_STORAGE_BUFFER_BINDING, GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS)
4101     default:
4102         break;
4103     }
4104 
4105     const GLClientState::VertexAttribBindingVector& currBindings =
4106         state->currentVertexBufferBindings();
4107 
4108     switch (target) {
4109     case GL_VERTEX_BINDING_DIVISOR:
4110     case GL_VERTEX_BINDING_OFFSET:
4111     case GL_VERTEX_BINDING_STRIDE:
4112     case GL_VERTEX_BINDING_BUFFER:
4113         SET_ERROR_IF(index < 0 || index > currBindings.size(), GL_INVALID_VALUE);
4114         break;
4115     default:
4116         break;
4117     }
4118 
4119     switch (target) {
4120     case GL_VERTEX_BINDING_DIVISOR:
4121         *params = currBindings[index].divisor;
4122         return;
4123     case GL_VERTEX_BINDING_OFFSET:
4124         *params = currBindings[index].offset;
4125         return;
4126     case GL_VERTEX_BINDING_STRIDE:
4127         *params = currBindings[index].effectiveStride;
4128         return;
4129     case GL_VERTEX_BINDING_BUFFER:
4130         *params = currBindings[index].buffer;
4131         return;
4132     default:
4133         break;
4134     }
4135 
4136     ctx->m_glGetIntegeri_v_enc(self, target, index, params);
4137 }
4138 
s_glGetInteger64i_v(void * self,GLenum target,GLuint index,GLint64 * params)4139 void GL2Encoder::s_glGetInteger64i_v(void* self, GLenum target, GLuint index, GLint64* params) {
4140     GL2Encoder *ctx = (GL2Encoder *)self;
4141     GLClientState* state = ctx->m_state;
4142 
4143     GLint limit;
4144 
4145     switch (target) {
4146     LIMIT_CASE(GL_TRANSFORM_FEEDBACK_BUFFER_BINDING, GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS)
4147     LIMIT_CASE(GL_UNIFORM_BUFFER_BINDING, GL_MAX_UNIFORM_BUFFER_BINDINGS)
4148     LIMIT_CASE(GL_ATOMIC_COUNTER_BUFFER_BINDING, GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS)
4149     LIMIT_CASE(GL_SHADER_STORAGE_BUFFER_BINDING, GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS)
4150     default:
4151         break;
4152     }
4153 
4154     const GLClientState::VertexAttribBindingVector& currBindings =
4155         state->currentVertexBufferBindings();
4156 
4157     switch (target) {
4158     case GL_VERTEX_BINDING_DIVISOR:
4159     case GL_VERTEX_BINDING_OFFSET:
4160     case GL_VERTEX_BINDING_STRIDE:
4161     case GL_VERTEX_BINDING_BUFFER:
4162         SET_ERROR_IF(index < 0 || index > currBindings.size(), GL_INVALID_VALUE);
4163         break;
4164     default:
4165         break;
4166     }
4167 
4168     switch (target) {
4169     case GL_VERTEX_BINDING_DIVISOR:
4170         *params = currBindings[index].divisor;
4171         return;
4172     case GL_VERTEX_BINDING_OFFSET:
4173         *params = currBindings[index].offset;
4174         return;
4175     case GL_VERTEX_BINDING_STRIDE:
4176         *params = currBindings[index].effectiveStride;
4177         return;
4178     case GL_VERTEX_BINDING_BUFFER:
4179         *params = currBindings[index].buffer;
4180         return;
4181     default:
4182         break;
4183     }
4184 
4185     ctx->m_glGetInteger64i_v_enc(self, target, index, params);
4186 }
4187 
s_glGetShaderiv(void * self,GLuint shader,GLenum pname,GLint * params)4188 void GL2Encoder::s_glGetShaderiv(void* self, GLuint shader, GLenum pname, GLint* params) {
4189     GL2Encoder *ctx = (GL2Encoder *)self;
4190     ctx->m_glGetShaderiv_enc(self, shader, pname, params);
4191     if (pname == GL_SHADER_SOURCE_LENGTH) {
4192         ShaderData* shaderData = ctx->m_shared->getShaderData(shader);
4193         if (shaderData) {
4194             int totalLen = 0;
4195             for (int i = 0; i < shaderData->sources.size(); i++) {
4196                 totalLen += shaderData->sources[i].size();
4197             }
4198             if (totalLen != 0) {
4199                 *params = totalLen + 1; // account for null terminator
4200             }
4201         }
4202     }
4203 }
4204 
s_glActiveShaderProgram(void * self,GLuint pipeline,GLuint program)4205 void GL2Encoder::s_glActiveShaderProgram(void* self, GLuint pipeline, GLuint program) {
4206     GL2Encoder *ctx = (GL2Encoder*)self;
4207     GLClientState* state = ctx->m_state;
4208     GLSharedGroupPtr shared = ctx->m_shared;
4209 
4210     SET_ERROR_IF(!pipeline, GL_INVALID_OPERATION);
4211     SET_ERROR_IF(program && !shared->isShaderOrProgramObject(program), GL_INVALID_VALUE);
4212     SET_ERROR_IF(program && !shared->isProgram(program), GL_INVALID_OPERATION);
4213 
4214     ctx->m_glActiveShaderProgram_enc(ctx, pipeline, program);
4215     if (!state->currentProgram()) {
4216         state->setCurrentShaderProgram(program);
4217     }
4218 }
4219 
s_glCreateShaderProgramv(void * self,GLenum type,GLsizei count,const char ** strings)4220 GLuint GL2Encoder::s_glCreateShaderProgramv(void* self, GLenum type, GLsizei count, const char** strings) {
4221 
4222     GLint* length = NULL;
4223     GL2Encoder* ctx = (GL2Encoder*)self;
4224 
4225     int len = glUtilsCalcShaderSourceLen((char**)strings, length, count);
4226     char *str = new char[len + 1];
4227     glUtilsPackStrings(str, (char**)strings, (GLint*)length, count);
4228 
4229     // Do GLSharedGroup and location WorkARound-specific initialization
4230     // Phase 1: create a ShaderData and initialize with replaceSamplerExternalWith2D()
4231     uint32_t spDataId = ctx->m_shared->addNewShaderProgramData();
4232     ShaderProgramData* spData = ctx->m_shared->getShaderProgramDataById(spDataId);
4233     ShaderData* sData = spData->shaderData;
4234 
4235     if (!replaceSamplerExternalWith2D(str, sData)) {
4236         delete [] str;
4237         ctx->setError(GL_OUT_OF_MEMORY);
4238         ctx->m_shared->deleteShaderProgramDataById(spDataId);
4239         return -1;
4240     }
4241 
4242     GLuint res = ctx->glCreateShaderProgramvAEMU(ctx, type, count, str, len + 1);
4243     delete [] str;
4244 
4245     // Phase 2: do glLinkProgram-related initialization for locationWorkARound
4246     GLint linkStatus = 0;
4247     ctx->glGetProgramiv(self, res, GL_LINK_STATUS ,&linkStatus);
4248     if (!linkStatus) {
4249         ctx->m_shared->deleteShaderProgramDataById(spDataId);
4250         return -1;
4251     }
4252 
4253     ctx->m_shared->associateGLShaderProgram(res, spDataId);
4254 
4255     GLint numUniforms = 0;
4256     ctx->glGetProgramiv(ctx, res, GL_ACTIVE_UNIFORMS, &numUniforms);
4257     ctx->m_shared->initShaderProgramData(res, numUniforms);
4258 
4259     GLint maxLength=0;
4260     ctx->glGetProgramiv(self, res, GL_ACTIVE_UNIFORM_MAX_LENGTH, &maxLength);
4261 
4262     GLint size; GLenum uniformType; GLchar* name = new GLchar[maxLength + 1];
4263 
4264     for (GLint i = 0; i < numUniforms; ++i) {
4265         ctx->glGetActiveUniform(self, res, i, maxLength, NULL, &size, &uniformType, name);
4266         GLint location = ctx->m_glGetUniformLocation_enc(self, res, name);
4267         ctx->m_shared->setShaderProgramIndexInfo(res, i, location, size, uniformType, name);
4268     }
4269 
4270     ctx->m_shared->setupShaderProgramLocationShiftWAR(res);
4271 
4272     delete [] name;
4273 
4274     return res;
4275 }
4276 
s_glProgramUniform1f(void * self,GLuint program,GLint location,GLfloat v0)4277 void GL2Encoder::s_glProgramUniform1f(void* self, GLuint program, GLint location, GLfloat v0)
4278 {
4279     GL2Encoder *ctx = (GL2Encoder*)self;
4280     GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
4281     ctx->m_glProgramUniform1f_enc(self, program, hostLoc, v0);
4282 }
4283 
s_glProgramUniform1fv(void * self,GLuint program,GLint location,GLsizei count,const GLfloat * value)4284 void GL2Encoder::s_glProgramUniform1fv(void* self, GLuint program, GLint location, GLsizei count, const GLfloat *value)
4285 {
4286     GL2Encoder *ctx = (GL2Encoder*)self;
4287     GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
4288     ctx->m_glProgramUniform1fv_enc(self, program, hostLoc, count, value);
4289 }
4290 
s_glProgramUniform1i(void * self,GLuint program,GLint location,GLint v0)4291 void GL2Encoder::s_glProgramUniform1i(void* self, GLuint program, GLint location, GLint v0)
4292 {
4293     GL2Encoder *ctx = (GL2Encoder*)self;
4294     GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
4295     ctx->m_glProgramUniform1i_enc(self, program, hostLoc, v0);
4296 
4297     GLClientState* state = ctx->m_state;
4298     GLSharedGroupPtr shared = ctx->m_shared;
4299     GLenum target;
4300 
4301     if (shared->setSamplerUniform(program, location, v0, &target)) {
4302         GLenum origActiveTexture = state->getActiveTextureUnit();
4303         if (ctx->updateHostTexture2DBinding(GL_TEXTURE0 + v0, target)) {
4304             ctx->m_glActiveTexture_enc(self, origActiveTexture);
4305         }
4306         state->setActiveTextureUnit(origActiveTexture);
4307     }
4308 }
4309 
s_glProgramUniform1iv(void * self,GLuint program,GLint location,GLsizei count,const GLint * value)4310 void GL2Encoder::s_glProgramUniform1iv(void* self, GLuint program, GLint location, GLsizei count, const GLint *value)
4311 {
4312     GL2Encoder *ctx = (GL2Encoder*)self;
4313     GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
4314     ctx->m_glProgramUniform1iv_enc(self, program, hostLoc, count, value);
4315 }
4316 
s_glProgramUniform1ui(void * self,GLuint program,GLint location,GLuint v0)4317 void GL2Encoder::s_glProgramUniform1ui(void* self, GLuint program, GLint location, GLuint v0)
4318 {
4319     GL2Encoder *ctx = (GL2Encoder*)self;
4320     GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
4321     ctx->m_glProgramUniform1ui_enc(self, program, hostLoc, v0);
4322 
4323     GLClientState* state = ctx->m_state;
4324     GLSharedGroupPtr shared = ctx->m_shared;
4325     GLenum target;
4326 
4327     if (shared->setSamplerUniform(program, location, v0, &target)) {
4328         GLenum origActiveTexture = state->getActiveTextureUnit();
4329         if (ctx->updateHostTexture2DBinding(GL_TEXTURE0 + v0, target)) {
4330             ctx->m_glActiveTexture_enc(self, origActiveTexture);
4331         }
4332         state->setActiveTextureUnit(origActiveTexture);
4333     }
4334 }
4335 
s_glProgramUniform1uiv(void * self,GLuint program,GLint location,GLsizei count,const GLuint * value)4336 void GL2Encoder::s_glProgramUniform1uiv(void* self, GLuint program, GLint location, GLsizei count, const GLuint *value)
4337 {
4338     GL2Encoder *ctx = (GL2Encoder*)self;
4339     GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
4340     ctx->m_glProgramUniform1uiv_enc(self, program, hostLoc, count, value);
4341 }
4342 
s_glProgramUniform2f(void * self,GLuint program,GLint location,GLfloat v0,GLfloat v1)4343 void GL2Encoder::s_glProgramUniform2f(void* self, GLuint program, GLint location, GLfloat v0, GLfloat v1)
4344 {
4345     GL2Encoder *ctx = (GL2Encoder*)self;
4346     GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
4347     ctx->m_glProgramUniform2f_enc(self, program, hostLoc, v0, v1);
4348 }
4349 
s_glProgramUniform2fv(void * self,GLuint program,GLint location,GLsizei count,const GLfloat * value)4350 void GL2Encoder::s_glProgramUniform2fv(void* self, GLuint program, GLint location, GLsizei count, const GLfloat *value)
4351 {
4352     GL2Encoder *ctx = (GL2Encoder*)self;
4353     GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
4354     ctx->m_glProgramUniform2fv_enc(self, program, hostLoc, count, value);
4355 }
4356 
s_glProgramUniform2i(void * self,GLuint program,GLint location,GLint v0,GLint v1)4357 void GL2Encoder::s_glProgramUniform2i(void* self, GLuint program, GLint location, GLint v0, GLint v1)
4358 {
4359     GL2Encoder *ctx = (GL2Encoder*)self;
4360     GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
4361     ctx->m_glProgramUniform2i_enc(self, program, hostLoc, v0, v1);
4362 }
4363 
s_glProgramUniform2iv(void * self,GLuint program,GLint location,GLsizei count,const GLint * value)4364 void GL2Encoder::s_glProgramUniform2iv(void* self, GLuint program, GLint location, GLsizei count, const GLint *value)
4365 {
4366     GL2Encoder *ctx = (GL2Encoder*)self;
4367     GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
4368     ctx->m_glProgramUniform2iv_enc(self, program, hostLoc, count, value);
4369 }
4370 
s_glProgramUniform2ui(void * self,GLuint program,GLint location,GLint v0,GLuint v1)4371 void GL2Encoder::s_glProgramUniform2ui(void* self, GLuint program, GLint location, GLint v0, GLuint v1)
4372 {
4373     GL2Encoder *ctx = (GL2Encoder*)self;
4374     GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
4375     ctx->m_glProgramUniform2ui_enc(self, program, hostLoc, v0, v1);
4376 }
4377 
s_glProgramUniform2uiv(void * self,GLuint program,GLint location,GLsizei count,const GLuint * value)4378 void GL2Encoder::s_glProgramUniform2uiv(void* self, GLuint program, GLint location, GLsizei count, const GLuint *value)
4379 {
4380     GL2Encoder *ctx = (GL2Encoder*)self;
4381     GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
4382     ctx->m_glProgramUniform2uiv_enc(self, program, hostLoc, count, value);
4383 }
4384 
s_glProgramUniform3f(void * self,GLuint program,GLint location,GLfloat v0,GLfloat v1,GLfloat v2)4385 void GL2Encoder::s_glProgramUniform3f(void* self, GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2)
4386 {
4387     GL2Encoder *ctx = (GL2Encoder*)self;
4388     GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
4389     ctx->m_glProgramUniform3f_enc(self, program, hostLoc, v0, v1, v2);
4390 }
4391 
s_glProgramUniform3fv(void * self,GLuint program,GLint location,GLsizei count,const GLfloat * value)4392 void GL2Encoder::s_glProgramUniform3fv(void* self, GLuint program, GLint location, GLsizei count, const GLfloat *value)
4393 {
4394     GL2Encoder *ctx = (GL2Encoder*)self;
4395     GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
4396     ctx->m_glProgramUniform3fv_enc(self, program, hostLoc, count, value);
4397 }
4398 
s_glProgramUniform3i(void * self,GLuint program,GLint location,GLint v0,GLint v1,GLint v2)4399 void GL2Encoder::s_glProgramUniform3i(void* self, GLuint program, GLint location, GLint v0, GLint v1, GLint v2)
4400 {
4401     GL2Encoder *ctx = (GL2Encoder*)self;
4402     GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
4403     ctx->m_glProgramUniform3i_enc(self, program, hostLoc, v0, v1, v2);
4404 }
4405 
s_glProgramUniform3iv(void * self,GLuint program,GLint location,GLsizei count,const GLint * value)4406 void GL2Encoder::s_glProgramUniform3iv(void* self, GLuint program, GLint location, GLsizei count, const GLint *value)
4407 {
4408     GL2Encoder *ctx = (GL2Encoder*)self;
4409     GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
4410     ctx->m_glProgramUniform3iv_enc(self, program, hostLoc, count, value);
4411 }
4412 
s_glProgramUniform3ui(void * self,GLuint program,GLint location,GLint v0,GLint v1,GLuint v2)4413 void GL2Encoder::s_glProgramUniform3ui(void* self, GLuint program, GLint location, GLint v0, GLint v1, GLuint v2)
4414 {
4415     GL2Encoder *ctx = (GL2Encoder*)self;
4416     GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
4417     ctx->m_glProgramUniform3ui_enc(self, program, hostLoc, v0, v1, v2);
4418 }
4419 
s_glProgramUniform3uiv(void * self,GLuint program,GLint location,GLsizei count,const GLuint * value)4420 void GL2Encoder::s_glProgramUniform3uiv(void* self, GLuint program, GLint location, GLsizei count, const GLuint *value)
4421 {
4422     GL2Encoder *ctx = (GL2Encoder*)self;
4423     GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
4424     ctx->m_glProgramUniform3uiv_enc(self, program, hostLoc, count, value);
4425 }
4426 
s_glProgramUniform4f(void * self,GLuint program,GLint location,GLfloat v0,GLfloat v1,GLfloat v2,GLfloat v3)4427 void GL2Encoder::s_glProgramUniform4f(void* self, GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3)
4428 {
4429     GL2Encoder *ctx = (GL2Encoder*)self;
4430     GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
4431     ctx->m_glProgramUniform4f_enc(self, program, hostLoc, v0, v1, v2, v3);
4432 }
4433 
s_glProgramUniform4fv(void * self,GLuint program,GLint location,GLsizei count,const GLfloat * value)4434 void GL2Encoder::s_glProgramUniform4fv(void* self, GLuint program, GLint location, GLsizei count, const GLfloat *value)
4435 {
4436     GL2Encoder *ctx = (GL2Encoder*)self;
4437     GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
4438     ctx->m_glProgramUniform4fv_enc(self, program, hostLoc, count, value);
4439 }
4440 
s_glProgramUniform4i(void * self,GLuint program,GLint location,GLint v0,GLint v1,GLint v2,GLint v3)4441 void GL2Encoder::s_glProgramUniform4i(void* self, GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLint v3)
4442 {
4443     GL2Encoder *ctx = (GL2Encoder*)self;
4444     GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
4445     ctx->m_glProgramUniform4i_enc(self, program, hostLoc, v0, v1, v2, v3);
4446 }
4447 
s_glProgramUniform4iv(void * self,GLuint program,GLint location,GLsizei count,const GLint * value)4448 void GL2Encoder::s_glProgramUniform4iv(void* self, GLuint program, GLint location, GLsizei count, const GLint *value)
4449 {
4450     GL2Encoder *ctx = (GL2Encoder*)self;
4451     GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
4452     ctx->m_glProgramUniform4iv_enc(self, program, hostLoc, count, value);
4453 }
4454 
s_glProgramUniform4ui(void * self,GLuint program,GLint location,GLint v0,GLint v1,GLint v2,GLuint v3)4455 void GL2Encoder::s_glProgramUniform4ui(void* self, GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLuint v3)
4456 {
4457     GL2Encoder *ctx = (GL2Encoder*)self;
4458     GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
4459     ctx->m_glProgramUniform4ui_enc(self, program, hostLoc, v0, v1, v2, v3);
4460 }
4461 
s_glProgramUniform4uiv(void * self,GLuint program,GLint location,GLsizei count,const GLuint * value)4462 void GL2Encoder::s_glProgramUniform4uiv(void* self, GLuint program, GLint location, GLsizei count, const GLuint *value)
4463 {
4464     GL2Encoder *ctx = (GL2Encoder*)self;
4465     GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
4466     ctx->m_glProgramUniform4uiv_enc(self, program, hostLoc, count, value);
4467 }
4468 
s_glProgramUniformMatrix2fv(void * self,GLuint program,GLint location,GLsizei count,GLboolean transpose,const GLfloat * value)4469 void GL2Encoder::s_glProgramUniformMatrix2fv(void* self, GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
4470 {
4471     GL2Encoder *ctx = (GL2Encoder*)self;
4472     GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
4473     ctx->m_glProgramUniformMatrix2fv_enc(self, program, hostLoc, count, transpose, value);
4474 }
4475 
s_glProgramUniformMatrix2x3fv(void * self,GLuint program,GLint location,GLsizei count,GLboolean transpose,const GLfloat * value)4476 void GL2Encoder::s_glProgramUniformMatrix2x3fv(void* self, GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
4477 {
4478     GL2Encoder *ctx = (GL2Encoder*)self;
4479     GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
4480     ctx->m_glProgramUniformMatrix2x3fv_enc(self, program, hostLoc, count, transpose, value);
4481 }
4482 
s_glProgramUniformMatrix2x4fv(void * self,GLuint program,GLint location,GLsizei count,GLboolean transpose,const GLfloat * value)4483 void GL2Encoder::s_glProgramUniformMatrix2x4fv(void* self, GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
4484 {
4485     GL2Encoder *ctx = (GL2Encoder*)self;
4486     GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
4487     ctx->m_glProgramUniformMatrix2x4fv_enc(self, program, hostLoc, count, transpose, value);
4488 }
4489 
s_glProgramUniformMatrix3fv(void * self,GLuint program,GLint location,GLsizei count,GLboolean transpose,const GLfloat * value)4490 void GL2Encoder::s_glProgramUniformMatrix3fv(void* self, GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
4491 {
4492     GL2Encoder *ctx = (GL2Encoder*)self;
4493     GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
4494     ctx->m_glProgramUniformMatrix3fv_enc(self, program, hostLoc, count, transpose, value);
4495 }
4496 
s_glProgramUniformMatrix3x2fv(void * self,GLuint program,GLint location,GLsizei count,GLboolean transpose,const GLfloat * value)4497 void GL2Encoder::s_glProgramUniformMatrix3x2fv(void* self, GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
4498 {
4499     GL2Encoder *ctx = (GL2Encoder*)self;
4500     GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
4501     ctx->m_glProgramUniformMatrix3x2fv_enc(self, program, hostLoc, count, transpose, value);
4502 }
4503 
s_glProgramUniformMatrix3x4fv(void * self,GLuint program,GLint location,GLsizei count,GLboolean transpose,const GLfloat * value)4504 void GL2Encoder::s_glProgramUniformMatrix3x4fv(void* self, GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
4505 {
4506     GL2Encoder *ctx = (GL2Encoder*)self;
4507     GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
4508     ctx->m_glProgramUniformMatrix3x4fv_enc(self, program, hostLoc, count, transpose, value);
4509 }
4510 
s_glProgramUniformMatrix4fv(void * self,GLuint program,GLint location,GLsizei count,GLboolean transpose,const GLfloat * value)4511 void GL2Encoder::s_glProgramUniformMatrix4fv(void* self, GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
4512 {
4513     GL2Encoder *ctx = (GL2Encoder*)self;
4514     GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
4515     ctx->m_glProgramUniformMatrix4fv_enc(self, program, hostLoc, count, transpose, value);
4516 }
4517 
s_glProgramUniformMatrix4x2fv(void * self,GLuint program,GLint location,GLsizei count,GLboolean transpose,const GLfloat * value)4518 void GL2Encoder::s_glProgramUniformMatrix4x2fv(void* self, GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
4519 {
4520     GL2Encoder *ctx = (GL2Encoder*)self;
4521     GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
4522     ctx->m_glProgramUniformMatrix4x2fv_enc(self, program, hostLoc, count, transpose, value);
4523 }
4524 
s_glProgramUniformMatrix4x3fv(void * self,GLuint program,GLint location,GLsizei count,GLboolean transpose,const GLfloat * value)4525 void GL2Encoder::s_glProgramUniformMatrix4x3fv(void* self, GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
4526 {
4527     GL2Encoder *ctx = (GL2Encoder*)self;
4528     GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
4529     ctx->m_glProgramUniformMatrix4x3fv_enc(self, program, hostLoc, count, transpose, value);
4530 }
4531 
s_glProgramParameteri(void * self,GLuint program,GLenum pname,GLint value)4532 void GL2Encoder::s_glProgramParameteri(void* self, GLuint program, GLenum pname, GLint value) {
4533     GL2Encoder* ctx = (GL2Encoder*)self;
4534     ctx->m_glProgramParameteri_enc(self, program, pname, value);
4535 }
4536 
s_glUseProgramStages(void * self,GLuint pipeline,GLbitfield stages,GLuint program)4537 void GL2Encoder::s_glUseProgramStages(void *self, GLuint pipeline, GLbitfield stages, GLuint program)
4538 {
4539     GL2Encoder *ctx = (GL2Encoder*)self;
4540     GLClientState* state = ctx->m_state;
4541     GLSharedGroupPtr shared = ctx->m_shared;
4542 
4543     SET_ERROR_IF(!pipeline, GL_INVALID_OPERATION);
4544     SET_ERROR_IF(program && !shared->isShaderOrProgramObject(program), GL_INVALID_VALUE);
4545     SET_ERROR_IF(program && !shared->isProgram(program), GL_INVALID_OPERATION);
4546 
4547     ctx->m_glUseProgramStages_enc(self, pipeline, stages, program);
4548     state->associateProgramWithPipeline(program, pipeline);
4549 
4550     // There is an active non-separable shader program in effect; no need to update external/2D bindings.
4551     if (state->currentProgram()) {
4552         return;
4553     }
4554 
4555     // Otherwise, update host texture 2D bindings.
4556     ctx->updateHostTexture2DBindingsFromProgramData(program);
4557 }
4558 
s_glBindProgramPipeline(void * self,GLuint pipeline)4559 void GL2Encoder::s_glBindProgramPipeline(void* self, GLuint pipeline)
4560 {
4561     GL2Encoder *ctx = (GL2Encoder*)self;
4562     GLClientState* state = ctx->m_state;
4563 
4564     ctx->m_glBindProgramPipeline_enc(self, pipeline);
4565 
4566     // There is an active non-separable shader program in effect; no need to update external/2D bindings.
4567     if (!pipeline || state->currentProgram()) {
4568         return;
4569     }
4570 
4571     GLClientState::ProgramPipelineIterator it = state->programPipelineBegin();
4572     for (; it != state->programPipelineEnd(); ++it) {
4573         if (it->second == pipeline) {
4574             ctx->updateHostTexture2DBindingsFromProgramData(it->first);
4575         }
4576     }
4577 }
4578 
s_glGetProgramResourceiv(void * self,GLuint program,GLenum programInterface,GLuint index,GLsizei propCount,const GLenum * props,GLsizei bufSize,GLsizei * length,GLint * params)4579 void GL2Encoder::s_glGetProgramResourceiv(void* self, GLuint program, GLenum programInterface, GLuint index, GLsizei propCount, const GLenum * props, GLsizei bufSize, GLsizei * length, GLint * params) {
4580     GL2Encoder *ctx = (GL2Encoder*)self;
4581     SET_ERROR_IF(bufSize < 0, GL_INVALID_VALUE);
4582     if (bufSize == 0) {
4583         if (length) *length = 0;
4584         return;
4585     }
4586 
4587     // Avoid modifying |name| if |*length| < bufSize.
4588     GLint* intermediate = new GLint[bufSize];
4589     GLsizei* myLength = length ? length : new GLsizei;
4590     bool needFreeLength = length == NULL;
4591 
4592     ctx->m_glGetProgramResourceiv_enc(self, program, programInterface, index, propCount, props, bufSize, myLength, intermediate);
4593     GLsizei writtenInts = *myLength;
4594     memcpy(params, intermediate, writtenInts * sizeof(GLint));
4595 
4596     delete [] intermediate;
4597     if (needFreeLength)
4598         delete myLength;
4599 }
4600 
s_glGetProgramResourceIndex(void * self,GLuint program,GLenum programInterface,const char * name)4601 GLuint GL2Encoder::s_glGetProgramResourceIndex(void* self, GLuint program, GLenum programInterface, const char* name) {
4602     GL2Encoder *ctx = (GL2Encoder*)self;
4603     return ctx->m_glGetProgramResourceIndex_enc(self, program, programInterface, name);
4604 }
4605 
s_glGetProgramResourceLocation(void * self,GLuint program,GLenum programInterface,const char * name)4606 GLint GL2Encoder::s_glGetProgramResourceLocation(void* self, GLuint program, GLenum programInterface, const char* name) {
4607     GL2Encoder *ctx = (GL2Encoder*)self;
4608     return ctx->m_glGetProgramResourceLocation_enc(self, program, programInterface, name);
4609 }
4610 
s_glGetProgramResourceName(void * self,GLuint program,GLenum programInterface,GLuint index,GLsizei bufSize,GLsizei * length,char * name)4611 void GL2Encoder::s_glGetProgramResourceName(void* self, GLuint program, GLenum programInterface, GLuint index, GLsizei bufSize, GLsizei* length, char* name) {
4612     GL2Encoder *ctx = (GL2Encoder*)self;
4613     SET_ERROR_IF(bufSize < 0, GL_INVALID_VALUE);
4614     if (bufSize == 0) {
4615         if (length) *length = 0;
4616         return;
4617     }
4618 
4619     // Avoid modifying |name| if |*length| < bufSize.
4620     char* intermediate = new char[bufSize];
4621     GLsizei* myLength = length ? length : new GLsizei;
4622     bool needFreeLength = length == NULL;
4623 
4624     ctx->m_glGetProgramResourceName_enc(self, program, programInterface, index, bufSize, myLength, intermediate);
4625     GLsizei writtenStrLen = *myLength;
4626     memcpy(name, intermediate, writtenStrLen + 1);
4627 
4628     delete [] intermediate;
4629     if (needFreeLength)
4630         delete myLength;
4631 }
4632 
s_glGetProgramPipelineInfoLog(void * self,GLuint pipeline,GLsizei bufSize,GLsizei * length,GLchar * infoLog)4633 void GL2Encoder::s_glGetProgramPipelineInfoLog(void* self, GLuint pipeline, GLsizei bufSize, GLsizei* length, GLchar* infoLog) {
4634     GL2Encoder *ctx = (GL2Encoder*)self;
4635     SET_ERROR_IF(bufSize < 0, GL_INVALID_VALUE);
4636     if (bufSize == 0) {
4637         if (length) *length = 0;
4638         return;
4639     }
4640 
4641     // Avoid modifying |infoLog| if |*length| < bufSize.
4642     GLchar* intermediate = new GLchar[bufSize];
4643     GLsizei* myLength = length ? length : new GLsizei;
4644     bool needFreeLength = length == NULL;
4645 
4646     ctx->m_glGetProgramPipelineInfoLog_enc(self, pipeline, bufSize, myLength, intermediate);
4647     GLsizei writtenStrLen = *myLength;
4648     memcpy(infoLog, intermediate, writtenStrLen + 1);
4649 
4650     delete [] intermediate;
4651     if (needFreeLength)
4652         delete myLength;
4653 }
4654 
s_glVertexAttribFormat(void * self,GLuint attribindex,GLint size,GLenum type,GLboolean normalized,GLuint relativeoffset)4655 void GL2Encoder::s_glVertexAttribFormat(void* self, GLuint attribindex, GLint size, GLenum type, GLboolean normalized, GLuint relativeoffset) {
4656     GL2Encoder *ctx = (GL2Encoder*)self;
4657     GLClientState* state = ctx->m_state;
4658 
4659     VALIDATE_VERTEX_ATTRIB_INDEX(attribindex);
4660     SET_ERROR_IF(!state->currentVertexArrayObject(), GL_INVALID_OPERATION);
4661 
4662     state->setVertexAttribFormat(attribindex, size, type, normalized, relativeoffset, false);
4663     ctx->m_glVertexAttribFormat_enc(ctx, attribindex, size, type, normalized, relativeoffset);
4664 }
4665 
s_glVertexAttribIFormat(void * self,GLuint attribindex,GLint size,GLenum type,GLuint relativeoffset)4666 void GL2Encoder::s_glVertexAttribIFormat(void* self, GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset) {
4667     GL2Encoder *ctx = (GL2Encoder*)self;
4668     GLClientState* state = ctx->m_state;
4669 
4670     VALIDATE_VERTEX_ATTRIB_INDEX(attribindex);
4671     SET_ERROR_IF(!state->currentVertexArrayObject(), GL_INVALID_OPERATION);
4672 
4673     state->setVertexAttribFormat(attribindex, size, type, GL_FALSE, relativeoffset, true);
4674     ctx->m_glVertexAttribIFormat_enc(ctx, attribindex, size, type, relativeoffset);
4675 }
4676 
s_glVertexBindingDivisor(void * self,GLuint bindingindex,GLuint divisor)4677 void GL2Encoder::s_glVertexBindingDivisor(void* self, GLuint bindingindex, GLuint divisor) {
4678     GL2Encoder *ctx = (GL2Encoder*)self;
4679     GLClientState* state = ctx->m_state;
4680 
4681     SET_ERROR_IF(!state->currentVertexArrayObject(), GL_INVALID_OPERATION);
4682 
4683     state->setVertexBindingDivisor(bindingindex, divisor);
4684     ctx->m_glVertexBindingDivisor_enc(ctx, bindingindex, divisor);
4685 }
4686 
s_glVertexAttribBinding(void * self,GLuint attribindex,GLuint bindingindex)4687 void GL2Encoder::s_glVertexAttribBinding(void* self, GLuint attribindex, GLuint bindingindex) {
4688     GL2Encoder *ctx = (GL2Encoder*)self;
4689     GLClientState* state = ctx->m_state;
4690     VALIDATE_VERTEX_ATTRIB_INDEX(attribindex);
4691     SET_ERROR_IF(!state->currentVertexArrayObject(), GL_INVALID_OPERATION);
4692 
4693     state->setVertexAttribBinding(attribindex, bindingindex);
4694     ctx->m_glVertexAttribBinding_enc(ctx, attribindex, bindingindex);
4695 }
4696 
s_glBindVertexBuffer(void * self,GLuint bindingindex,GLuint buffer,GLintptr offset,GLintptr stride)4697 void GL2Encoder::s_glBindVertexBuffer(void* self, GLuint bindingindex, GLuint buffer, GLintptr offset, GLintptr stride) {
4698     GL2Encoder *ctx = (GL2Encoder*)self;
4699     GLClientState* state = ctx->m_state;
4700 
4701     SET_ERROR_IF(offset < 0, GL_INVALID_VALUE);
4702 
4703     GLint maxStride;
4704     ctx->glGetIntegerv(ctx, GL_MAX_VERTEX_ATTRIB_STRIDE, &maxStride);
4705     SET_ERROR_IF(stride < 0 || stride > maxStride, GL_INVALID_VALUE);
4706 
4707     SET_ERROR_IF(!state->currentVertexArrayObject(), GL_INVALID_OPERATION);
4708 
4709     state->bindIndexedBuffer(0, bindingindex, buffer, offset, 0, stride, stride);
4710     ctx->m_glBindVertexBuffer_enc(ctx, bindingindex, buffer, offset, stride);
4711 }
4712 
s_glDrawArraysIndirect(void * self,GLenum mode,const void * indirect)4713 void GL2Encoder::s_glDrawArraysIndirect(void* self, GLenum mode, const void* indirect) {
4714     GL2Encoder *ctx = (GL2Encoder*)self;
4715     GLClientState* state = ctx->m_state;
4716 
4717     bool hasClientArrays = false;
4718     ctx->getVBOUsage(&hasClientArrays, NULL);
4719 
4720     SET_ERROR_IF(hasClientArrays, GL_INVALID_OPERATION);
4721     SET_ERROR_IF(!state->currentVertexArrayObject(), GL_INVALID_OPERATION);
4722     SET_ERROR_IF(!ctx->boundBuffer(GL_DRAW_INDIRECT_BUFFER), GL_INVALID_OPERATION);
4723 
4724     GLuint indirectStructSize = glUtilsIndirectStructSize(INDIRECT_COMMAND_DRAWARRAYS);
4725     if (ctx->boundBuffer(GL_DRAW_INDIRECT_BUFFER)) {
4726         // BufferData* buf = ctx->getBufferData(target);
4727         // if (buf) {
4728         //     SET_ERROR_IF((GLuint)(uintptr_t)indirect + indirectStructSize > buf->m_size, GL_INVALID_VALUE);
4729         // }
4730         ctx->glDrawArraysIndirectOffsetAEMU(ctx, mode, (uintptr_t)indirect);
4731     } else {
4732         // Client command structs are technically allowed in desktop OpenGL, but not in ES.
4733         // This is purely for debug/dev purposes.
4734         ctx->glDrawArraysIndirectDataAEMU(ctx, mode, indirect, indirectStructSize);
4735     }
4736 }
4737 
s_glDrawElementsIndirect(void * self,GLenum mode,GLenum type,const void * indirect)4738 void GL2Encoder::s_glDrawElementsIndirect(void* self, GLenum mode, GLenum type, const void* indirect) {
4739     GL2Encoder *ctx = (GL2Encoder*)self;
4740 
4741     GLClientState* state = ctx->m_state;
4742 
4743     bool hasClientArrays = false;
4744     ctx->getVBOUsage(&hasClientArrays, NULL);
4745 
4746     SET_ERROR_IF(hasClientArrays, GL_INVALID_OPERATION);
4747     SET_ERROR_IF(!state->currentVertexArrayObject(), GL_INVALID_OPERATION);
4748     SET_ERROR_IF(!ctx->boundBuffer(GL_DRAW_INDIRECT_BUFFER), GL_INVALID_OPERATION);
4749 
4750     SET_ERROR_IF(ctx->m_state->getTransformFeedbackActiveUnpaused(), GL_INVALID_OPERATION);
4751 
4752     GLuint indirectStructSize = glUtilsIndirectStructSize(INDIRECT_COMMAND_DRAWELEMENTS);
4753     if (ctx->boundBuffer(GL_DRAW_INDIRECT_BUFFER)) {
4754         // BufferData* buf = ctx->getBufferData(target);
4755         // if (buf) {
4756         //     SET_ERROR_IF((GLuint)(uintptr_t)indirect + indirectStructSize > buf->m_size, GL_INVALID_VALUE);
4757         // }
4758         ctx->glDrawElementsIndirectOffsetAEMU(ctx, mode, type, (uintptr_t)indirect);
4759     } else {
4760         // Client command structs are technically allowed in desktop OpenGL, but not in ES.
4761         // This is purely for debug/dev purposes.
4762         ctx->glDrawElementsIndirectDataAEMU(ctx, mode, type, indirect, indirectStructSize);
4763     }
4764 
4765 }
4766 
s_glTexStorage2DMultisample(void * self,GLenum target,GLsizei samples,GLenum internalformat,GLsizei width,GLsizei height,GLboolean fixedsamplelocations)4767 void GL2Encoder::s_glTexStorage2DMultisample(void* self, GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations) {
4768     GL2Encoder *ctx = (GL2Encoder*)self;
4769     GLClientState* state = ctx->m_state;
4770 
4771     SET_ERROR_IF(target != GL_TEXTURE_2D_MULTISAMPLE, GL_INVALID_ENUM);
4772     SET_ERROR_IF(!GLESv2Validation::pixelInternalFormat(internalformat), GL_INVALID_ENUM);
4773     SET_ERROR_IF(!state->getBoundTexture(target), GL_INVALID_OPERATION);
4774     SET_ERROR_IF(width < 1 || height < 1, GL_INVALID_VALUE);
4775     SET_ERROR_IF(state->isBoundTextureImmutableFormat(target), GL_INVALID_OPERATION);
4776     GLint max_samples;
4777     ctx->s_glGetInternalformativ(ctx, target, internalformat, GL_SAMPLES, 1, &max_samples);
4778     SET_ERROR_IF(samples > max_samples, GL_INVALID_OPERATION);
4779 
4780     state->setBoundTextureInternalFormat(target, internalformat);
4781     state->setBoundTextureDims(target, 0, width, height, 1);
4782     state->setBoundTextureImmutableFormat(target);
4783     state->setBoundTextureSamples(target, samples);
4784 
4785     ctx->m_glTexStorage2DMultisample_enc(ctx, target, samples, internalformat, width, height, fixedsamplelocations);
4786 }
4787 
4788