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