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