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 <assert.h> 19 #include <ctype.h> 20 21 #ifndef MIN 22 #define MIN(a, b) ((a) < (b) ? (a) : (b)) 23 #endif 24 25 static GLubyte *gVendorString= (GLubyte *) "Android"; 26 static GLubyte *gRendererString= (GLubyte *) "Android HW-GLES 2.0"; 27 static GLubyte *gVersionString= (GLubyte *) "OpenGL ES 2.0"; 28 static GLubyte *gExtensionsString= (GLubyte *) ""; // no extensions at this point; 29 30 #define SET_ERROR_IF(condition,err) if((condition)) { \ 31 ALOGE("%s:%s:%d GL error 0x%x\n", __FILE__, __FUNCTION__, __LINE__, err); \ 32 ctx->setError(err); \ 33 return; \ 34 } 35 36 37 #define RET_AND_SET_ERROR_IF(condition,err,ret) if((condition)) { \ 38 ALOGE("%s:%s:%d GL error 0x%x\n", __FILE__, __FUNCTION__, __LINE__, err); \ 39 ctx->setError(err); \ 40 return ret; \ 41 } 42 43 44 GL2Encoder::GL2Encoder(IOStream *stream) : gl2_encoder_context_t(stream) 45 { 46 m_initialized = false; 47 m_state = NULL; 48 m_error = GL_NO_ERROR; 49 m_num_compressedTextureFormats = 0; 50 m_compressedTextureFormats = NULL; 51 52 //overrides 53 #define OVERRIDE(name) m_##name##_enc = this-> name ; this-> name = &s_##name 54 55 OVERRIDE(glFlush); 56 OVERRIDE(glPixelStorei); 57 OVERRIDE(glGetString); 58 OVERRIDE(glBindBuffer); 59 OVERRIDE(glBufferData); 60 OVERRIDE(glBufferSubData); 61 OVERRIDE(glDeleteBuffers); 62 OVERRIDE(glDrawArrays); 63 OVERRIDE(glDrawElements); 64 OVERRIDE(glGetIntegerv); 65 OVERRIDE(glGetFloatv); 66 OVERRIDE(glGetBooleanv); 67 OVERRIDE(glVertexAttribPointer); 68 OVERRIDE(glEnableVertexAttribArray); 69 OVERRIDE(glDisableVertexAttribArray); 70 OVERRIDE(glGetVertexAttribiv); 71 OVERRIDE(glGetVertexAttribfv); 72 OVERRIDE(glGetVertexAttribPointerv); 73 74 this->glShaderSource = &s_glShaderSource; 75 this->glFinish = &s_glFinish; 76 77 OVERRIDE(glGetError); 78 OVERRIDE(glLinkProgram); 79 OVERRIDE(glDeleteProgram); 80 OVERRIDE(glGetUniformiv); 81 OVERRIDE(glGetUniformfv); 82 OVERRIDE(glCreateProgram); 83 OVERRIDE(glCreateShader); 84 OVERRIDE(glDeleteShader); 85 OVERRIDE(glAttachShader); 86 OVERRIDE(glDetachShader); 87 OVERRIDE(glGetAttachedShaders); 88 OVERRIDE(glGetShaderSource); 89 OVERRIDE(glGetShaderInfoLog); 90 OVERRIDE(glGetProgramInfoLog); 91 92 OVERRIDE(glGetUniformLocation); 93 OVERRIDE(glUseProgram); 94 95 OVERRIDE(glUniform1f); 96 OVERRIDE(glUniform1fv); 97 OVERRIDE(glUniform1i); 98 OVERRIDE(glUniform1iv); 99 OVERRIDE(glUniform2f); 100 OVERRIDE(glUniform2fv); 101 OVERRIDE(glUniform2i); 102 OVERRIDE(glUniform2iv); 103 OVERRIDE(glUniform3f); 104 OVERRIDE(glUniform3fv); 105 OVERRIDE(glUniform3i); 106 OVERRIDE(glUniform3iv); 107 OVERRIDE(glUniform4f); 108 OVERRIDE(glUniform4fv); 109 OVERRIDE(glUniform4i); 110 OVERRIDE(glUniform4iv); 111 OVERRIDE(glUniformMatrix2fv); 112 OVERRIDE(glUniformMatrix3fv); 113 OVERRIDE(glUniformMatrix4fv); 114 115 OVERRIDE(glActiveTexture); 116 OVERRIDE(glBindTexture); 117 OVERRIDE(glDeleteTextures); 118 OVERRIDE(glGetTexParameterfv); 119 OVERRIDE(glGetTexParameteriv); 120 OVERRIDE(glTexParameterf); 121 OVERRIDE(glTexParameterfv); 122 OVERRIDE(glTexParameteri); 123 OVERRIDE(glTexParameteriv); 124 OVERRIDE(glTexImage2D); 125 } 126 127 GL2Encoder::~GL2Encoder() 128 { 129 delete m_compressedTextureFormats; 130 } 131 132 GLenum GL2Encoder::s_glGetError(void * self) 133 { 134 GL2Encoder *ctx = (GL2Encoder *)self; 135 GLenum err = ctx->getError(); 136 if(err != GL_NO_ERROR) { 137 ctx->setError(GL_NO_ERROR); 138 return err; 139 } 140 141 return ctx->m_glGetError_enc(self); 142 143 } 144 145 void GL2Encoder::s_glFlush(void *self) 146 { 147 GL2Encoder *ctx = (GL2Encoder *) self; 148 ctx->m_glFlush_enc(self); 149 ctx->m_stream->flush(); 150 } 151 152 const GLubyte *GL2Encoder::s_glGetString(void *self, GLenum name) 153 { 154 (void)self; 155 156 GLubyte *retval = (GLubyte *) ""; 157 switch(name) { 158 case GL_VENDOR: 159 retval = gVendorString; 160 break; 161 case GL_RENDERER: 162 retval = gRendererString; 163 break; 164 case GL_VERSION: 165 retval = gVersionString; 166 break; 167 case GL_EXTENSIONS: 168 retval = gExtensionsString; 169 break; 170 } 171 return retval; 172 } 173 174 void GL2Encoder::s_glPixelStorei(void *self, GLenum param, GLint value) 175 { 176 GL2Encoder *ctx = (GL2Encoder *)self; 177 ctx->m_glPixelStorei_enc(ctx, param, value); 178 assert(ctx->m_state != NULL); 179 ctx->m_state->setPixelStore(param, value); 180 } 181 182 183 void GL2Encoder::s_glBindBuffer(void *self, GLenum target, GLuint id) 184 { 185 GL2Encoder *ctx = (GL2Encoder *) self; 186 assert(ctx->m_state != NULL); 187 ctx->m_state->bindBuffer(target, id); 188 // TODO set error state if needed; 189 ctx->m_glBindBuffer_enc(self, target, id); 190 } 191 192 void GL2Encoder::s_glBufferData(void * self, GLenum target, GLsizeiptr size, const GLvoid * data, GLenum usage) 193 { 194 GL2Encoder *ctx = (GL2Encoder *) self; 195 SET_ERROR_IF(!(target == GL_ARRAY_BUFFER || target == GL_ELEMENT_ARRAY_BUFFER), GL_INVALID_ENUM); 196 GLuint bufferId = ctx->m_state->getBuffer(target); 197 SET_ERROR_IF(bufferId==0, GL_INVALID_OPERATION); 198 SET_ERROR_IF(size<0, GL_INVALID_VALUE); 199 200 ctx->m_shared->updateBufferData(bufferId, size, (void*)data); 201 ctx->m_glBufferData_enc(self, target, size, data, usage); 202 } 203 204 void GL2Encoder::s_glBufferSubData(void * self, GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid * data) 205 { 206 GL2Encoder *ctx = (GL2Encoder *) self; 207 SET_ERROR_IF(!(target == GL_ARRAY_BUFFER || target == GL_ELEMENT_ARRAY_BUFFER), GL_INVALID_ENUM); 208 GLuint bufferId = ctx->m_state->getBuffer(target); 209 SET_ERROR_IF(bufferId==0, GL_INVALID_OPERATION); 210 211 GLenum res = ctx->m_shared->subUpdateBufferData(bufferId, offset, size, (void*)data); 212 SET_ERROR_IF(res, res); 213 214 ctx->m_glBufferSubData_enc(self, target, offset, size, data); 215 } 216 217 void GL2Encoder::s_glDeleteBuffers(void * self, GLsizei n, const GLuint * buffers) 218 { 219 GL2Encoder *ctx = (GL2Encoder *) self; 220 SET_ERROR_IF(n<0, GL_INVALID_VALUE); 221 for (int i=0; i<n; i++) { 222 ctx->m_shared->deleteBufferData(buffers[i]); 223 ctx->m_state->unBindBuffer(buffers[i]); 224 ctx->m_glDeleteBuffers_enc(self,1,&buffers[i]); 225 } 226 } 227 228 void GL2Encoder::s_glVertexAttribPointer(void *self, GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid * ptr) 229 { 230 GL2Encoder *ctx = (GL2Encoder *)self; 231 assert(ctx->m_state != NULL); 232 ctx->m_state->setState(indx, size, type, normalized, stride, ptr); 233 } 234 235 void GL2Encoder::s_glGetIntegerv(void *self, GLenum param, GLint *ptr) 236 { 237 GL2Encoder *ctx = (GL2Encoder *) self; 238 assert(ctx->m_state != NULL); 239 GLClientState* state = ctx->m_state; 240 241 switch (param) { 242 case GL_NUM_SHADER_BINARY_FORMATS: 243 *ptr = 0; 244 break; 245 case GL_SHADER_BINARY_FORMATS: 246 // do nothing 247 break; 248 249 case GL_COMPRESSED_TEXTURE_FORMATS: { 250 GLint *compressedTextureFormats = ctx->getCompressedTextureFormats(); 251 if (ctx->m_num_compressedTextureFormats > 0 && 252 compressedTextureFormats != NULL) { 253 memcpy(ptr, compressedTextureFormats, 254 ctx->m_num_compressedTextureFormats * sizeof(GLint)); 255 } 256 break; 257 } 258 259 case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: 260 case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS: 261 case GL_MAX_TEXTURE_IMAGE_UNITS: 262 ctx->m_glGetIntegerv_enc(self, param, ptr); 263 *ptr = MIN(*ptr, GLClientState::MAX_TEXTURE_UNITS); 264 break; 265 266 case GL_TEXTURE_BINDING_2D: 267 *ptr = state->getBoundTexture(GL_TEXTURE_2D); 268 break; 269 case GL_TEXTURE_BINDING_EXTERNAL_OES: 270 *ptr = state->getBoundTexture(GL_TEXTURE_EXTERNAL_OES); 271 break; 272 273 default: 274 if (!ctx->m_state->getClientStateParameter<GLint>(param, ptr)) { 275 ctx->m_glGetIntegerv_enc(self, param, ptr); 276 } 277 break; 278 } 279 } 280 281 282 void GL2Encoder::s_glGetFloatv(void *self, GLenum param, GLfloat *ptr) 283 { 284 GL2Encoder *ctx = (GL2Encoder *)self; 285 assert(ctx->m_state != NULL); 286 GLClientState* state = ctx->m_state; 287 288 switch (param) { 289 case GL_NUM_SHADER_BINARY_FORMATS: 290 *ptr = 0; 291 break; 292 case GL_SHADER_BINARY_FORMATS: 293 // do nothing 294 break; 295 296 case GL_COMPRESSED_TEXTURE_FORMATS: { 297 GLint *compressedTextureFormats = ctx->getCompressedTextureFormats(); 298 if (ctx->m_num_compressedTextureFormats > 0 && 299 compressedTextureFormats != NULL) { 300 for (int i = 0; i < ctx->m_num_compressedTextureFormats; i++) { 301 ptr[i] = (GLfloat) compressedTextureFormats[i]; 302 } 303 } 304 break; 305 } 306 307 case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: 308 case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS: 309 case GL_MAX_TEXTURE_IMAGE_UNITS: 310 ctx->m_glGetFloatv_enc(self, param, ptr); 311 *ptr = MIN(*ptr, (GLfloat)GLClientState::MAX_TEXTURE_UNITS); 312 break; 313 314 case GL_TEXTURE_BINDING_2D: 315 *ptr = (GLfloat)state->getBoundTexture(GL_TEXTURE_2D); 316 break; 317 case GL_TEXTURE_BINDING_EXTERNAL_OES: 318 *ptr = (GLfloat)state->getBoundTexture(GL_TEXTURE_EXTERNAL_OES); 319 break; 320 321 default: 322 if (!ctx->m_state->getClientStateParameter<GLfloat>(param, ptr)) { 323 ctx->m_glGetFloatv_enc(self, param, ptr); 324 } 325 break; 326 } 327 } 328 329 330 void GL2Encoder::s_glGetBooleanv(void *self, GLenum param, GLboolean *ptr) 331 { 332 GL2Encoder *ctx = (GL2Encoder *)self; 333 assert(ctx->m_state != NULL); 334 GLClientState* state = ctx->m_state; 335 336 switch (param) { 337 case GL_NUM_SHADER_BINARY_FORMATS: 338 *ptr = GL_FALSE; 339 break; 340 case GL_SHADER_BINARY_FORMATS: 341 // do nothing 342 break; 343 344 case GL_COMPRESSED_TEXTURE_FORMATS: { 345 GLint *compressedTextureFormats = ctx->getCompressedTextureFormats(); 346 if (ctx->m_num_compressedTextureFormats > 0 && 347 compressedTextureFormats != NULL) { 348 for (int i = 0; i < ctx->m_num_compressedTextureFormats; i++) { 349 ptr[i] = compressedTextureFormats[i] != 0 ? GL_TRUE : GL_FALSE; 350 } 351 } 352 break; 353 } 354 355 case GL_TEXTURE_BINDING_2D: 356 *ptr = state->getBoundTexture(GL_TEXTURE_2D) != 0 ? GL_TRUE : GL_FALSE; 357 break; 358 case GL_TEXTURE_BINDING_EXTERNAL_OES: 359 *ptr = state->getBoundTexture(GL_TEXTURE_EXTERNAL_OES) != 0 360 ? GL_TRUE : GL_FALSE; 361 break; 362 363 default: 364 if (!ctx->m_state->getClientStateParameter<GLboolean>(param, ptr)) { 365 ctx->m_glGetBooleanv_enc(self, param, ptr); 366 } 367 *ptr = (*ptr != 0) ? GL_TRUE : GL_FALSE; 368 break; 369 } 370 } 371 372 373 void GL2Encoder::s_glEnableVertexAttribArray(void *self, GLuint index) 374 { 375 GL2Encoder *ctx = (GL2Encoder *)self; 376 assert(ctx->m_state); 377 ctx->m_state->enable(index, 1); 378 } 379 380 void GL2Encoder::s_glDisableVertexAttribArray(void *self, GLuint index) 381 { 382 GL2Encoder *ctx = (GL2Encoder *)self; 383 assert(ctx->m_state); 384 ctx->m_state->enable(index, 0); 385 } 386 387 388 void GL2Encoder::s_glGetVertexAttribiv(void *self, GLuint index, GLenum pname, GLint *params) 389 { 390 GL2Encoder *ctx = (GL2Encoder *)self; 391 assert(ctx->m_state); 392 393 if (!ctx->m_state->getVertexAttribParameter<GLint>(index, pname, params)) { 394 ctx->m_glGetVertexAttribiv_enc(self, index, pname, params); 395 } 396 } 397 398 void GL2Encoder::s_glGetVertexAttribfv(void *self, GLuint index, GLenum pname, GLfloat *params) 399 { 400 GL2Encoder *ctx = (GL2Encoder *)self; 401 assert(ctx->m_state); 402 403 if (!ctx->m_state->getVertexAttribParameter<GLfloat>(index, pname, params)) { 404 ctx->m_glGetVertexAttribfv_enc(self, index, pname, params); 405 } 406 } 407 408 void GL2Encoder::s_glGetVertexAttribPointerv(void *self, GLuint index, GLenum pname, GLvoid **pointer) 409 { 410 GL2Encoder *ctx = (GL2Encoder *)self; 411 if (ctx->m_state == NULL) return; 412 413 (void)pname; 414 415 const GLClientState::VertexAttribState *va_state = ctx->m_state->getState(index); 416 if (va_state != NULL) { 417 *pointer = va_state->data; 418 } 419 } 420 421 422 void GL2Encoder::sendVertexAttributes(GLint first, GLsizei count) 423 { 424 assert(m_state); 425 426 for (int i = 0; i < m_state->nLocations(); i++) { 427 bool enableDirty; 428 const GLClientState::VertexAttribState *state = m_state->getStateAndEnableDirty(i, &enableDirty); 429 430 if (!state) { 431 continue; 432 } 433 434 if (!enableDirty && !state->enabled) { 435 continue; 436 } 437 438 439 if (state->enabled) { 440 m_glEnableVertexAttribArray_enc(this, i); 441 442 unsigned int datalen = state->elementSize * count; 443 int stride = state->stride == 0 ? state->elementSize : state->stride; 444 int firstIndex = stride * first; 445 446 this->m_glBindBuffer_enc(this, GL_ARRAY_BUFFER, state->bufferObject); 447 if (state->bufferObject == 0) { 448 this->glVertexAttribPointerData(this, i, state->size, state->type, state->normalized, state->stride, 449 (unsigned char *)state->data + firstIndex, datalen); 450 } else { 451 this->glVertexAttribPointerOffset(this, i, state->size, state->type, state->normalized, state->stride, 452 (uintptr_t) state->data + firstIndex); 453 } 454 this->m_glBindBuffer_enc(this, GL_ARRAY_BUFFER, m_state->currentArrayVbo()); 455 } else { 456 this->m_glDisableVertexAttribArray_enc(this, i); 457 } 458 } 459 } 460 461 void GL2Encoder::s_glDrawArrays(void *self, GLenum mode, GLint first, GLsizei count) 462 { 463 GL2Encoder *ctx = (GL2Encoder *)self; 464 ctx->sendVertexAttributes(first, count); 465 ctx->m_glDrawArrays_enc(ctx, mode, 0, count); 466 } 467 468 469 void GL2Encoder::s_glDrawElements(void *self, GLenum mode, GLsizei count, GLenum type, const void *indices) 470 { 471 472 GL2Encoder *ctx = (GL2Encoder *)self; 473 assert(ctx->m_state != NULL); 474 SET_ERROR_IF(count<0, GL_INVALID_VALUE); 475 476 bool has_immediate_arrays = false; 477 bool has_indirect_arrays = false; 478 int nLocations = ctx->m_state->nLocations(); 479 480 for (int i = 0; i < nLocations; i++) { 481 const GLClientState::VertexAttribState *state = ctx->m_state->getState(i); 482 if (state->enabled) { 483 if (state->bufferObject != 0) { 484 has_indirect_arrays = true; 485 } else { 486 has_immediate_arrays = true; 487 } 488 } 489 } 490 491 if (!has_immediate_arrays && !has_indirect_arrays) { 492 ALOGE("glDrawElements: no data bound to the command - ignoring\n"); 493 return; 494 } 495 496 bool adjustIndices = true; 497 if (ctx->m_state->currentIndexVbo() != 0) { 498 if (!has_immediate_arrays) { 499 ctx->sendVertexAttributes(0, count); 500 ctx->m_glBindBuffer_enc(self, GL_ELEMENT_ARRAY_BUFFER, ctx->m_state->currentIndexVbo()); 501 ctx->glDrawElementsOffset(ctx, mode, count, type, (uintptr_t)indices); 502 adjustIndices = false; 503 } else { 504 BufferData * buf = ctx->m_shared->getBufferData(ctx->m_state->currentIndexVbo()); 505 ctx->m_glBindBuffer_enc(self, GL_ELEMENT_ARRAY_BUFFER, 0); 506 indices = (void*)((GLintptr)buf->m_fixedBuffer.ptr() + (GLintptr)indices); 507 } 508 } 509 if (adjustIndices) { 510 void *adjustedIndices = (void*)indices; 511 int minIndex = 0, maxIndex = 0; 512 513 switch(type) { 514 case GL_BYTE: 515 case GL_UNSIGNED_BYTE: 516 GLUtils::minmax<unsigned char>((unsigned char *)indices, count, &minIndex, &maxIndex); 517 if (minIndex != 0) { 518 adjustedIndices = ctx->m_fixedBuffer.alloc(glSizeof(type) * count); 519 GLUtils::shiftIndices<unsigned char>((unsigned char *)indices, 520 (unsigned char *)adjustedIndices, 521 count, -minIndex); 522 } 523 break; 524 case GL_SHORT: 525 case GL_UNSIGNED_SHORT: 526 GLUtils::minmax<unsigned short>((unsigned short *)indices, count, &minIndex, &maxIndex); 527 if (minIndex != 0) { 528 adjustedIndices = ctx->m_fixedBuffer.alloc(glSizeof(type) * count); 529 GLUtils::shiftIndices<unsigned short>((unsigned short *)indices, 530 (unsigned short *)adjustedIndices, 531 count, -minIndex); 532 } 533 break; 534 default: 535 ALOGE("unsupported index buffer type %d\n", type); 536 } 537 if (has_indirect_arrays || 1) { 538 ctx->sendVertexAttributes(minIndex, maxIndex - minIndex + 1); 539 ctx->glDrawElementsData(ctx, mode, count, type, adjustedIndices, 540 count * glSizeof(type)); 541 // XXX - OPTIMIZATION (see the other else branch) should be implemented 542 if(!has_indirect_arrays) { 543 //ALOGD("unoptimized drawelements !!!\n"); 544 } 545 } else { 546 // we are all direct arrays and immidate mode index array - 547 // rebuild the arrays and the index array; 548 ALOGE("glDrawElements: direct index & direct buffer data - will be implemented in later versions;\n"); 549 } 550 } 551 } 552 553 554 GLint * GL2Encoder::getCompressedTextureFormats() 555 { 556 if (m_compressedTextureFormats == NULL) { 557 this->glGetIntegerv(this, GL_NUM_COMPRESSED_TEXTURE_FORMATS, 558 &m_num_compressedTextureFormats); 559 if (m_num_compressedTextureFormats > 0) { 560 // get number of texture formats; 561 m_compressedTextureFormats = new GLint[m_num_compressedTextureFormats]; 562 this->glGetCompressedTextureFormats(this, m_num_compressedTextureFormats, m_compressedTextureFormats); 563 } 564 } 565 return m_compressedTextureFormats; 566 } 567 568 // Replace uses of samplerExternalOES with sampler2D, recording the names of 569 // modified shaders in data. Also remove 570 // #extension GL_OES_EGL_image_external : require 571 // statements. 572 // 573 // This implementation assumes the input has already been pre-processed. If not, 574 // a few cases will be mishandled: 575 // 576 // 1. "mySampler" will be incorrectly recorded as being a samplerExternalOES in 577 // the following code: 578 // #if 1 579 // uniform sampler2D mySampler; 580 // #else 581 // uniform samplerExternalOES mySampler; 582 // #endif 583 // 584 // 2. Comments that look like sampler declarations will be incorrectly modified 585 // and recorded: 586 // // samplerExternalOES hahaFooledYou 587 // 588 // 3. However, GLSL ES does not have a concatentation operator, so things like 589 // this (valid in C) are invalid and not a problem: 590 // #define SAMPLER(TYPE, NAME) uniform sampler#TYPE NAME 591 // SAMPLER(ExternalOES, mySampler); 592 // 593 static bool replaceSamplerExternalWith2D(char* const str, ShaderData* const data) 594 { 595 static const char STR_HASH_EXTENSION[] = "#extension"; 596 static const char STR_GL_OES_EGL_IMAGE_EXTERNAL[] = "GL_OES_EGL_image_external"; 597 static const char STR_SAMPLER_EXTERNAL_OES[] = "samplerExternalOES"; 598 static const char STR_SAMPLER2D_SPACE[] = "sampler2D "; 599 600 // -- overwrite all "#extension GL_OES_EGL_image_external : xxx" statements 601 char* c = str; 602 while ((c = strstr(c, STR_HASH_EXTENSION))) { 603 char* start = c; 604 c += sizeof(STR_HASH_EXTENSION)-1; 605 while (isspace(*c) && *c != '\0') { 606 c++; 607 } 608 if (strncmp(c, STR_GL_OES_EGL_IMAGE_EXTERNAL, 609 sizeof(STR_GL_OES_EGL_IMAGE_EXTERNAL)-1) == 0) 610 { 611 // #extension statements are terminated by end of line 612 c = start; 613 while (*c != '\0' && *c != '\r' && *c != '\n') { 614 *c++ = ' '; 615 } 616 } 617 } 618 619 // -- replace "samplerExternalOES" with "sampler2D" and record name 620 c = str; 621 while ((c = strstr(c, STR_SAMPLER_EXTERNAL_OES))) { 622 // Make sure "samplerExternalOES" isn't a substring of a larger token 623 if (c == str || !isspace(*(c-1))) { 624 c++; 625 continue; 626 } 627 char* sampler_start = c; 628 c += sizeof(STR_SAMPLER_EXTERNAL_OES)-1; 629 if (!isspace(*c) && *c != '\0') { 630 continue; 631 } 632 633 // capture sampler name 634 while (isspace(*c) && *c != '\0') { 635 c++; 636 } 637 if (!isalpha(*c) && *c != '_') { 638 // not an identifier 639 return false; 640 } 641 char* name_start = c; 642 do { 643 c++; 644 } while (isalnum(*c) || *c == '_'); 645 data->samplerExternalNames.push_back( 646 android::String8(name_start, c - name_start)); 647 648 // memcpy instead of strcpy since we don't want the NUL terminator 649 memcpy(sampler_start, STR_SAMPLER2D_SPACE, sizeof(STR_SAMPLER2D_SPACE)-1); 650 } 651 652 return true; 653 } 654 655 void GL2Encoder::s_glShaderSource(void *self, GLuint shader, GLsizei count, const GLchar * const *string, const GLint *length) 656 { 657 GL2Encoder* ctx = (GL2Encoder*)self; 658 ShaderData* shaderData = ctx->m_shared->getShaderData(shader); 659 SET_ERROR_IF(!shaderData, GL_INVALID_VALUE); 660 661 int len = glUtilsCalcShaderSourceLen((char**)string, (GLint*)length, count); 662 char *str = new char[len + 1]; 663 glUtilsPackStrings(str, (char**)string, (GLint*)length, count); 664 665 // TODO: pre-process str before calling replaceSamplerExternalWith2D(). 666 // Perhaps we can borrow Mesa's pre-processor? 667 668 if (!replaceSamplerExternalWith2D(str, shaderData)) { 669 delete str; 670 ctx->setError(GL_OUT_OF_MEMORY); 671 return; 672 } 673 674 ctx->glShaderString(ctx, shader, str, len + 1); 675 delete str; 676 } 677 678 void GL2Encoder::s_glFinish(void *self) 679 { 680 GL2Encoder *ctx = (GL2Encoder *)self; 681 ctx->glFinishRoundTrip(self); 682 } 683 684 void GL2Encoder::s_glLinkProgram(void * self, GLuint program) 685 { 686 GL2Encoder *ctx = (GL2Encoder *)self; 687 ctx->m_glLinkProgram_enc(self, program); 688 689 GLint linkStatus = 0; 690 ctx->glGetProgramiv(self,program,GL_LINK_STATUS,&linkStatus); 691 if (!linkStatus) 692 return; 693 694 //get number of active uniforms in the program 695 GLint numUniforms=0; 696 ctx->glGetProgramiv(self, program, GL_ACTIVE_UNIFORMS, &numUniforms); 697 ctx->m_shared->initProgramData(program,numUniforms); 698 699 //get the length of the longest uniform name 700 GLint maxLength=0; 701 ctx->glGetProgramiv(self, program, GL_ACTIVE_UNIFORM_MAX_LENGTH, &maxLength); 702 703 GLint size; 704 GLenum type; 705 GLchar *name = new GLchar[maxLength+1]; 706 GLint location; 707 //for each active uniform, get its size and starting location. 708 for (GLint i=0 ; i<numUniforms ; ++i) 709 { 710 ctx->glGetActiveUniform(self, program, i, maxLength, NULL, &size, &type, name); 711 location = ctx->m_glGetUniformLocation_enc(self, program, name); 712 ctx->m_shared->setProgramIndexInfo(program, i, location, size, type, name); 713 } 714 ctx->m_shared->setupLocationShiftWAR(program); 715 716 delete[] name; 717 } 718 719 void GL2Encoder::s_glDeleteProgram(void *self, GLuint program) 720 { 721 GL2Encoder *ctx = (GL2Encoder*)self; 722 ctx->m_glDeleteProgram_enc(self, program); 723 724 ctx->m_shared->deleteProgramData(program); 725 } 726 727 void GL2Encoder::s_glGetUniformiv(void *self, GLuint program, GLint location, GLint* params) 728 { 729 GL2Encoder *ctx = (GL2Encoder*)self; 730 SET_ERROR_IF(!ctx->m_shared->isProgram(program), GL_INVALID_VALUE); 731 SET_ERROR_IF(!ctx->m_shared->isProgramInitialized(program), GL_INVALID_OPERATION); 732 GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location); 733 SET_ERROR_IF(ctx->m_shared->getProgramUniformType(program,hostLoc)==0, GL_INVALID_OPERATION); 734 ctx->m_glGetUniformiv_enc(self, program, hostLoc, params); 735 } 736 void GL2Encoder::s_glGetUniformfv(void *self, GLuint program, GLint location, GLfloat* params) 737 { 738 GL2Encoder *ctx = (GL2Encoder*)self; 739 SET_ERROR_IF(!ctx->m_shared->isProgram(program), GL_INVALID_VALUE); 740 SET_ERROR_IF(!ctx->m_shared->isProgramInitialized(program), GL_INVALID_OPERATION); 741 GLint hostLoc = ctx->m_shared->locationWARAppToHost(program,location); 742 SET_ERROR_IF(ctx->m_shared->getProgramUniformType(program,hostLoc)==0, GL_INVALID_OPERATION); 743 ctx->m_glGetUniformfv_enc(self, program, hostLoc, params); 744 } 745 746 GLuint GL2Encoder::s_glCreateProgram(void * self) 747 { 748 GL2Encoder *ctx = (GL2Encoder*)self; 749 GLuint program = ctx->m_glCreateProgram_enc(self); 750 if (program!=0) 751 ctx->m_shared->addProgramData(program); 752 return program; 753 } 754 755 GLuint GL2Encoder::s_glCreateShader(void *self, GLenum shaderType) 756 { 757 GL2Encoder *ctx = (GL2Encoder*)self; 758 GLuint shader = ctx->m_glCreateShader_enc(self, shaderType); 759 if (shader != 0) { 760 if (!ctx->m_shared->addShaderData(shader)) { 761 ctx->m_glDeleteShader_enc(self, shader); 762 return 0; 763 } 764 } 765 return shader; 766 } 767 768 void GL2Encoder::s_glGetAttachedShaders(void *self, GLuint program, GLsizei maxCount, 769 GLsizei* count, GLuint* shaders) 770 { 771 GL2Encoder *ctx = (GL2Encoder*)self; 772 SET_ERROR_IF(maxCount < 0, GL_INVALID_VALUE); 773 ctx->m_glGetAttachedShaders_enc(self, program, maxCount, count, shaders); 774 } 775 776 void GL2Encoder::s_glGetShaderSource(void *self, GLuint shader, GLsizei bufsize, 777 GLsizei* length, GLchar* source) 778 { 779 GL2Encoder *ctx = (GL2Encoder*)self; 780 SET_ERROR_IF(bufsize < 0, GL_INVALID_VALUE); 781 ctx->m_glGetShaderSource_enc(self, shader, bufsize, length, source); 782 } 783 784 void GL2Encoder::s_glGetShaderInfoLog(void *self, GLuint shader, GLsizei bufsize, 785 GLsizei* length, GLchar* infolog) 786 { 787 GL2Encoder *ctx = (GL2Encoder*)self; 788 SET_ERROR_IF(bufsize < 0, GL_INVALID_VALUE); 789 ctx->m_glGetShaderInfoLog_enc(self, shader, bufsize, length, infolog); 790 } 791 792 void GL2Encoder::s_glGetProgramInfoLog(void *self, GLuint program, GLsizei bufsize, 793 GLsizei* length, GLchar* infolog) 794 { 795 GL2Encoder *ctx = (GL2Encoder*)self; 796 SET_ERROR_IF(bufsize < 0, GL_INVALID_VALUE); 797 ctx->m_glGetProgramInfoLog_enc(self, program, bufsize, length, infolog); 798 } 799 800 void GL2Encoder::s_glDeleteShader(void *self, GLenum shader) 801 { 802 GL2Encoder *ctx = (GL2Encoder*)self; 803 ctx->m_glDeleteShader_enc(self,shader); 804 ctx->m_shared->unrefShaderData(shader); 805 } 806 807 void GL2Encoder::s_glAttachShader(void *self, GLuint program, GLuint shader) 808 { 809 GL2Encoder *ctx = (GL2Encoder*)self; 810 ctx->m_glAttachShader_enc(self, program, shader); 811 ctx->m_shared->attachShader(program, shader); 812 } 813 814 void GL2Encoder::s_glDetachShader(void *self, GLuint program, GLuint shader) 815 { 816 GL2Encoder *ctx = (GL2Encoder*)self; 817 ctx->m_glDetachShader_enc(self, program, shader); 818 ctx->m_shared->detachShader(program, shader); 819 } 820 821 int GL2Encoder::s_glGetUniformLocation(void *self, GLuint program, const GLchar *name) 822 { 823 if (!name) return -1; 824 825 GL2Encoder *ctx = (GL2Encoder*)self; 826 827 // if we need the uniform location WAR 828 // parse array index from the end of the name string 829 int arrIndex = 0; 830 bool needLocationWAR = ctx->m_shared->needUniformLocationWAR(program); 831 if (needLocationWAR) { 832 int namelen = strlen(name); 833 if (name[namelen-1] == ']') { 834 char *brace = strrchr(name,'['); 835 if (!brace || sscanf(brace+1,"%d",&arrIndex) != 1) { 836 return -1; 837 } 838 839 } 840 } 841 842 int hostLoc = ctx->m_glGetUniformLocation_enc(self, program, name); 843 if (hostLoc >= 0 && needLocationWAR) { 844 return ctx->m_shared->locationWARHostToApp(program, hostLoc, arrIndex); 845 } 846 return hostLoc; 847 } 848 849 bool GL2Encoder::updateHostTexture2DBinding(GLenum texUnit, GLenum newTarget) 850 { 851 if (newTarget != GL_TEXTURE_2D && newTarget != GL_TEXTURE_EXTERNAL_OES) 852 return false; 853 854 m_state->setActiveTextureUnit(texUnit); 855 856 GLenum oldTarget = m_state->getPriorityEnabledTarget(GL_TEXTURE_2D); 857 if (newTarget != oldTarget) { 858 if (newTarget == GL_TEXTURE_EXTERNAL_OES) { 859 m_state->disableTextureTarget(GL_TEXTURE_2D); 860 m_state->enableTextureTarget(GL_TEXTURE_EXTERNAL_OES); 861 } else { 862 m_state->disableTextureTarget(GL_TEXTURE_EXTERNAL_OES); 863 m_state->enableTextureTarget(GL_TEXTURE_2D); 864 } 865 m_glActiveTexture_enc(this, texUnit); 866 m_glBindTexture_enc(this, GL_TEXTURE_2D, 867 m_state->getBoundTexture(newTarget)); 868 return true; 869 } 870 871 return false; 872 } 873 874 void GL2Encoder::s_glUseProgram(void *self, GLuint program) 875 { 876 GL2Encoder *ctx = (GL2Encoder*)self; 877 GLClientState* state = ctx->m_state; 878 GLSharedGroupPtr shared = ctx->m_shared; 879 880 ctx->m_glUseProgram_enc(self, program); 881 ctx->m_state->setCurrentProgram(program); 882 883 GLenum origActiveTexture = state->getActiveTextureUnit(); 884 GLenum hostActiveTexture = origActiveTexture; 885 GLint samplerIdx = -1; 886 GLint samplerVal; 887 GLenum samplerTarget; 888 while ((samplerIdx = shared->getNextSamplerUniform(program, samplerIdx, &samplerVal, &samplerTarget)) != -1) { 889 if (samplerVal < 0 || samplerVal >= GLClientState::MAX_TEXTURE_UNITS) 890 continue; 891 if (ctx->updateHostTexture2DBinding(GL_TEXTURE0 + samplerVal, 892 samplerTarget)) 893 { 894 hostActiveTexture = GL_TEXTURE0 + samplerVal; 895 } 896 } 897 state->setActiveTextureUnit(origActiveTexture); 898 if (hostActiveTexture != origActiveTexture) { 899 ctx->m_glActiveTexture_enc(self, origActiveTexture); 900 } 901 } 902 903 void GL2Encoder::s_glUniform1f(void *self , GLint location, GLfloat x) 904 { 905 GL2Encoder *ctx = (GL2Encoder*)self; 906 GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentProgram(),location); 907 ctx->m_glUniform1f_enc(self, hostLoc, x); 908 } 909 910 void GL2Encoder::s_glUniform1fv(void *self , GLint location, GLsizei count, const GLfloat* v) 911 { 912 GL2Encoder *ctx = (GL2Encoder*)self; 913 GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentProgram(),location); 914 ctx->m_glUniform1fv_enc(self, hostLoc, count, v); 915 } 916 917 void GL2Encoder::s_glUniform1i(void *self , GLint location, GLint x) 918 { 919 GL2Encoder *ctx = (GL2Encoder*)self; 920 GLClientState* state = ctx->m_state; 921 GLSharedGroupPtr shared = ctx->m_shared; 922 923 GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentProgram(),location); 924 ctx->m_glUniform1i_enc(self, hostLoc, x); 925 926 GLenum target; 927 if (shared->setSamplerUniform(state->currentProgram(), location, x, &target)) { 928 GLenum origActiveTexture = state->getActiveTextureUnit(); 929 if (ctx->updateHostTexture2DBinding(GL_TEXTURE0 + x, target)) { 930 ctx->m_glActiveTexture_enc(self, origActiveTexture); 931 } 932 state->setActiveTextureUnit(origActiveTexture); 933 } 934 } 935 936 void GL2Encoder::s_glUniform1iv(void *self , GLint location, GLsizei count, const GLint* v) 937 { 938 GL2Encoder *ctx = (GL2Encoder*)self; 939 GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentProgram(),location); 940 ctx->m_glUniform1iv_enc(self, hostLoc, count, v); 941 } 942 943 void GL2Encoder::s_glUniform2f(void *self , GLint location, GLfloat x, GLfloat y) 944 { 945 GL2Encoder *ctx = (GL2Encoder*)self; 946 GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentProgram(),location); 947 ctx->m_glUniform2f_enc(self, hostLoc, x, y); 948 } 949 950 void GL2Encoder::s_glUniform2fv(void *self , GLint location, GLsizei count, const GLfloat* v) 951 { 952 GL2Encoder *ctx = (GL2Encoder*)self; 953 GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentProgram(),location); 954 ctx->m_glUniform2fv_enc(self, hostLoc, count, v); 955 } 956 957 void GL2Encoder::s_glUniform2i(void *self , GLint location, GLint x, GLint y) 958 { 959 GL2Encoder *ctx = (GL2Encoder*)self; 960 GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentProgram(),location); 961 ctx->m_glUniform2i_enc(self, hostLoc, x, y); 962 } 963 964 void GL2Encoder::s_glUniform2iv(void *self , GLint location, GLsizei count, const GLint* v) 965 { 966 GL2Encoder *ctx = (GL2Encoder*)self; 967 GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentProgram(),location); 968 ctx->m_glUniform2iv_enc(self, hostLoc, count, v); 969 } 970 971 void GL2Encoder::s_glUniform3f(void *self , GLint location, GLfloat x, GLfloat y, GLfloat z) 972 { 973 GL2Encoder *ctx = (GL2Encoder*)self; 974 GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentProgram(),location); 975 ctx->m_glUniform3f_enc(self, hostLoc, x, y, z); 976 } 977 978 void GL2Encoder::s_glUniform3fv(void *self , GLint location, GLsizei count, const GLfloat* v) 979 { 980 GL2Encoder *ctx = (GL2Encoder*)self; 981 GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentProgram(),location); 982 ctx->m_glUniform3fv_enc(self, hostLoc, count, v); 983 } 984 985 void GL2Encoder::s_glUniform3i(void *self , GLint location, GLint x, GLint y, GLint z) 986 { 987 GL2Encoder *ctx = (GL2Encoder*)self; 988 GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentProgram(),location); 989 ctx->m_glUniform3i_enc(self, hostLoc, x, y, z); 990 } 991 992 void GL2Encoder::s_glUniform3iv(void *self , GLint location, GLsizei count, const GLint* v) 993 { 994 GL2Encoder *ctx = (GL2Encoder*)self; 995 GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentProgram(),location); 996 ctx->m_glUniform3iv_enc(self, hostLoc, count, v); 997 } 998 999 void GL2Encoder::s_glUniform4f(void *self , GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w) 1000 { 1001 GL2Encoder *ctx = (GL2Encoder*)self; 1002 GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentProgram(),location); 1003 ctx->m_glUniform4f_enc(self, hostLoc, x, y, z, w); 1004 } 1005 1006 void GL2Encoder::s_glUniform4fv(void *self , GLint location, GLsizei count, const GLfloat* v) 1007 { 1008 GL2Encoder *ctx = (GL2Encoder*)self; 1009 GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentProgram(),location); 1010 ctx->m_glUniform4fv_enc(self, hostLoc, count, v); 1011 } 1012 1013 void GL2Encoder::s_glUniform4i(void *self , GLint location, GLint x, GLint y, GLint z, GLint w) 1014 { 1015 GL2Encoder *ctx = (GL2Encoder*)self; 1016 GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentProgram(),location); 1017 ctx->m_glUniform4i_enc(self, hostLoc, x, y, z, w); 1018 } 1019 1020 void GL2Encoder::s_glUniform4iv(void *self , GLint location, GLsizei count, const GLint* v) 1021 { 1022 GL2Encoder *ctx = (GL2Encoder*)self; 1023 GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentProgram(),location); 1024 ctx->m_glUniform4iv_enc(self, hostLoc, count, v); 1025 } 1026 1027 void GL2Encoder::s_glUniformMatrix2fv(void *self , GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) 1028 { 1029 GL2Encoder *ctx = (GL2Encoder*)self; 1030 GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentProgram(),location); 1031 ctx->m_glUniformMatrix2fv_enc(self, hostLoc, count, transpose, value); 1032 } 1033 1034 void GL2Encoder::s_glUniformMatrix3fv(void *self , GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) 1035 { 1036 GL2Encoder *ctx = (GL2Encoder*)self; 1037 GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentProgram(),location); 1038 ctx->m_glUniformMatrix3fv_enc(self, hostLoc, count, transpose, value); 1039 } 1040 1041 void GL2Encoder::s_glUniformMatrix4fv(void *self , GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) 1042 { 1043 GL2Encoder *ctx = (GL2Encoder*)self; 1044 GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentProgram(),location); 1045 ctx->m_glUniformMatrix4fv_enc(self, hostLoc, count, transpose, value); 1046 } 1047 1048 void GL2Encoder::s_glActiveTexture(void* self, GLenum texture) 1049 { 1050 GL2Encoder* ctx = (GL2Encoder*)self; 1051 GLClientState* state = ctx->m_state; 1052 GLenum err; 1053 1054 SET_ERROR_IF((err = state->setActiveTextureUnit(texture)) != GL_NO_ERROR, err); 1055 1056 ctx->m_glActiveTexture_enc(ctx, texture); 1057 } 1058 1059 void GL2Encoder::s_glBindTexture(void* self, GLenum target, GLuint texture) 1060 { 1061 GL2Encoder* ctx = (GL2Encoder*)self; 1062 GLClientState* state = ctx->m_state; 1063 GLenum err; 1064 GLboolean firstUse; 1065 1066 SET_ERROR_IF((err = state->bindTexture(target, texture, &firstUse)) != GL_NO_ERROR, err); 1067 1068 if (target != GL_TEXTURE_2D && target != GL_TEXTURE_EXTERNAL_OES) { 1069 ctx->m_glBindTexture_enc(ctx, target, texture); 1070 return; 1071 } 1072 1073 GLenum priorityTarget = state->getPriorityEnabledTarget(GL_TEXTURE_2D); 1074 1075 if (target == GL_TEXTURE_EXTERNAL_OES && firstUse) { 1076 ctx->m_glBindTexture_enc(ctx, GL_TEXTURE_2D, texture); 1077 ctx->m_glTexParameteri_enc(ctx, GL_TEXTURE_2D, 1078 GL_TEXTURE_MIN_FILTER, GL_LINEAR); 1079 ctx->m_glTexParameteri_enc(ctx, GL_TEXTURE_2D, 1080 GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 1081 ctx->m_glTexParameteri_enc(ctx, GL_TEXTURE_2D, 1082 GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 1083 1084 if (target != priorityTarget) { 1085 ctx->m_glBindTexture_enc(ctx, GL_TEXTURE_2D, 1086 state->getBoundTexture(GL_TEXTURE_2D)); 1087 } 1088 } 1089 1090 if (target == priorityTarget) { 1091 ctx->m_glBindTexture_enc(ctx, GL_TEXTURE_2D, texture); 1092 } 1093 } 1094 1095 void GL2Encoder::s_glDeleteTextures(void* self, GLsizei n, const GLuint* textures) 1096 { 1097 GL2Encoder* ctx = (GL2Encoder*)self; 1098 GLClientState* state = ctx->m_state; 1099 1100 state->deleteTextures(n, textures); 1101 ctx->m_glDeleteTextures_enc(ctx, n, textures); 1102 } 1103 1104 void GL2Encoder::s_glGetTexParameterfv(void* self, 1105 GLenum target, GLenum pname, GLfloat* params) 1106 { 1107 GL2Encoder* ctx = (GL2Encoder*)self; 1108 const GLClientState* state = ctx->m_state; 1109 1110 if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) { 1111 ctx->override2DTextureTarget(target); 1112 ctx->m_glGetTexParameterfv_enc(ctx, GL_TEXTURE_2D, pname, params); 1113 ctx->restore2DTextureTarget(); 1114 } else { 1115 ctx->m_glGetTexParameterfv_enc(ctx, target, pname, params); 1116 } 1117 } 1118 1119 void GL2Encoder::s_glGetTexParameteriv(void* self, 1120 GLenum target, GLenum pname, GLint* params) 1121 { 1122 GL2Encoder* ctx = (GL2Encoder*)self; 1123 const GLClientState* state = ctx->m_state; 1124 1125 switch (pname) { 1126 case GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES: 1127 *params = 1; 1128 break; 1129 1130 default: 1131 if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) { 1132 ctx->override2DTextureTarget(target); 1133 ctx->m_glGetTexParameteriv_enc(ctx, GL_TEXTURE_2D, pname, params); 1134 ctx->restore2DTextureTarget(); 1135 } else { 1136 ctx->m_glGetTexParameteriv_enc(ctx, target, pname, params); 1137 } 1138 break; 1139 } 1140 } 1141 1142 static bool isValidTextureExternalParam(GLenum pname, GLenum param) 1143 { 1144 switch (pname) { 1145 case GL_TEXTURE_MIN_FILTER: 1146 case GL_TEXTURE_MAG_FILTER: 1147 return param == GL_NEAREST || param == GL_LINEAR; 1148 1149 case GL_TEXTURE_WRAP_S: 1150 case GL_TEXTURE_WRAP_T: 1151 return param == GL_CLAMP_TO_EDGE; 1152 1153 default: 1154 return true; 1155 } 1156 } 1157 1158 void GL2Encoder::s_glTexParameterf(void* self, 1159 GLenum target, GLenum pname, GLfloat param) 1160 { 1161 GL2Encoder* ctx = (GL2Encoder*)self; 1162 const GLClientState* state = ctx->m_state; 1163 1164 SET_ERROR_IF((target == GL_TEXTURE_EXTERNAL_OES && 1165 !isValidTextureExternalParam(pname, (GLenum)param)), 1166 GL_INVALID_ENUM); 1167 1168 if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) { 1169 ctx->override2DTextureTarget(target); 1170 ctx->m_glTexParameterf_enc(ctx, GL_TEXTURE_2D, pname, param); 1171 ctx->restore2DTextureTarget(); 1172 } else { 1173 ctx->m_glTexParameterf_enc(ctx, target, pname, param); 1174 } 1175 } 1176 1177 void GL2Encoder::s_glTexParameterfv(void* self, 1178 GLenum target, GLenum pname, const GLfloat* params) 1179 { 1180 GL2Encoder* ctx = (GL2Encoder*)self; 1181 const GLClientState* state = ctx->m_state; 1182 1183 SET_ERROR_IF((target == GL_TEXTURE_EXTERNAL_OES && 1184 !isValidTextureExternalParam(pname, (GLenum)params[0])), 1185 GL_INVALID_ENUM); 1186 1187 if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) { 1188 ctx->override2DTextureTarget(target); 1189 ctx->m_glTexParameterfv_enc(ctx, GL_TEXTURE_2D, pname, params); 1190 ctx->restore2DTextureTarget(); 1191 } else { 1192 ctx->m_glTexParameterfv_enc(ctx, target, pname, params); 1193 } 1194 } 1195 1196 void GL2Encoder::s_glTexParameteri(void* self, 1197 GLenum target, GLenum pname, GLint param) 1198 { 1199 GL2Encoder* ctx = (GL2Encoder*)self; 1200 const GLClientState* state = ctx->m_state; 1201 1202 SET_ERROR_IF((target == GL_TEXTURE_EXTERNAL_OES && 1203 !isValidTextureExternalParam(pname, (GLenum)param)), 1204 GL_INVALID_ENUM); 1205 1206 if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) { 1207 ctx->override2DTextureTarget(target); 1208 ctx->m_glTexParameteri_enc(ctx, GL_TEXTURE_2D, pname, param); 1209 ctx->restore2DTextureTarget(); 1210 } else { 1211 ctx->m_glTexParameteri_enc(ctx, target, pname, param); 1212 } 1213 } 1214 1215 void GL2Encoder::s_glTexImage2D(void* self, GLenum target, GLint level, 1216 GLint internalformat, GLsizei width, GLsizei height, GLint border, 1217 GLenum format, GLenum type, const GLvoid* pixels) 1218 { 1219 GL2Encoder* ctx = (GL2Encoder*)self; 1220 if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) { 1221 ctx->override2DTextureTarget(target); 1222 ctx->m_glTexImage2D_enc(ctx, target, level, internalformat, width, 1223 height, border, format, type, pixels); 1224 ctx->restore2DTextureTarget(); 1225 } else { 1226 ctx->m_glTexImage2D_enc(ctx, target, level, internalformat, width, 1227 height, border, format, type, pixels); 1228 } 1229 } 1230 1231 1232 void GL2Encoder::s_glTexParameteriv(void* self, 1233 GLenum target, GLenum pname, const GLint* params) 1234 { 1235 GL2Encoder* ctx = (GL2Encoder*)self; 1236 const GLClientState* state = ctx->m_state; 1237 1238 SET_ERROR_IF((target == GL_TEXTURE_EXTERNAL_OES && 1239 !isValidTextureExternalParam(pname, (GLenum)params[0])), 1240 GL_INVALID_ENUM); 1241 1242 if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) { 1243 ctx->override2DTextureTarget(target); 1244 ctx->m_glTexParameteriv_enc(ctx, GL_TEXTURE_2D, pname, params); 1245 ctx->restore2DTextureTarget(); 1246 } else { 1247 ctx->m_glTexParameteriv_enc(ctx, target, pname, params); 1248 } 1249 } 1250 1251 void GL2Encoder::override2DTextureTarget(GLenum target) 1252 { 1253 if ((target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) && 1254 target != m_state->getPriorityEnabledTarget(GL_TEXTURE_2D)) { 1255 m_glBindTexture_enc(this, GL_TEXTURE_2D, 1256 m_state->getBoundTexture(target)); 1257 } 1258 } 1259 1260 void GL2Encoder::restore2DTextureTarget() 1261 { 1262 GLenum priorityTarget = m_state->getPriorityEnabledTarget(GL_TEXTURE_2D); 1263 m_glBindTexture_enc(this, GL_TEXTURE_2D, 1264 m_state->getBoundTexture(priorityTarget)); 1265 } 1266