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