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