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