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