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