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