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