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