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