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