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 #include "GLEncoder.h" 17 #include "glUtils.h" 18 #include "FixedBuffer.h" 19 #include <cutils/log.h> 20 #include <assert.h> 21 22 #ifndef MIN 23 #define MIN(a, b) ((a) < (b) ? (a) : (b)) 24 #endif 25 26 static GLubyte *gVendorString= (GLubyte *) "Android"; 27 static GLubyte *gRendererString= (GLubyte *) "Android HW-GLES 1.0"; 28 static GLubyte *gVersionString= (GLubyte *) "OpenGL ES-CM 1.0"; 29 static GLubyte *gExtensionsString= (GLubyte *) ""; // no extensions at this point; 30 31 #define SET_ERROR_IF(condition,err) if((condition)) { \ 32 ALOGE("%s:%s:%d GL error 0x%x\n", __FILE__, __FUNCTION__, __LINE__, err); \ 33 ctx->setError(err); \ 34 return; \ 35 } 36 37 38 #define RET_AND_SET_ERROR_IF(condition,err,ret) if((condition)) { \ 39 ALOGE("%s:%s:%d GL error 0x%x\n", __FILE__, __FUNCTION__, __LINE__, err); \ 40 ctx->setError(err); \ 41 return ret; \ 42 } 43 44 GLenum GLEncoder::s_glGetError(void * self) 45 { 46 GLEncoder *ctx = (GLEncoder *)self; 47 GLenum err = ctx->getError(); 48 if(err != GL_NO_ERROR) { 49 ctx->setError(GL_NO_ERROR); 50 return err; 51 } 52 53 return ctx->m_glGetError_enc(self); 54 55 } 56 57 GLint * GLEncoder::getCompressedTextureFormats() 58 { 59 if (m_compressedTextureFormats == NULL) { 60 this->glGetIntegerv(this, GL_NUM_COMPRESSED_TEXTURE_FORMATS, 61 &m_num_compressedTextureFormats); 62 if (m_num_compressedTextureFormats > 0) { 63 // get number of texture formats; 64 m_compressedTextureFormats = new GLint[m_num_compressedTextureFormats]; 65 this->glGetCompressedTextureFormats(this, m_num_compressedTextureFormats, m_compressedTextureFormats); 66 } 67 } 68 return m_compressedTextureFormats; 69 } 70 71 void GLEncoder::s_glGetIntegerv(void *self, GLenum param, GLint *ptr) 72 { 73 GLEncoder *ctx = (GLEncoder *)self; 74 assert(ctx->m_state != NULL); 75 GLClientState* state = ctx->m_state; 76 77 switch (param) { 78 case GL_COMPRESSED_TEXTURE_FORMATS: { 79 GLint * compressedTextureFormats = ctx->getCompressedTextureFormats(); 80 if (ctx->m_num_compressedTextureFormats > 0 && 81 compressedTextureFormats != NULL) { 82 memcpy(ptr, compressedTextureFormats, 83 ctx->m_num_compressedTextureFormats * sizeof(GLint)); 84 } 85 break; 86 } 87 88 case GL_MAX_TEXTURE_UNITS: 89 ctx->m_glGetIntegerv_enc(self, param, ptr); 90 *ptr = MIN(*ptr, GLClientState::MAX_TEXTURE_UNITS); 91 break; 92 93 case GL_TEXTURE_BINDING_2D: 94 *ptr = state->getBoundTexture(GL_TEXTURE_2D); 95 break; 96 97 case GL_TEXTURE_BINDING_EXTERNAL_OES: 98 *ptr = state->getBoundTexture(GL_TEXTURE_EXTERNAL_OES); 99 break; 100 101 default: 102 if (!state->getClientStateParameter<GLint>(param,ptr)) { 103 ctx->m_glGetIntegerv_enc(self, param, ptr); 104 } 105 break; 106 } 107 } 108 109 void GLEncoder::s_glGetFloatv(void *self, GLenum param, GLfloat *ptr) 110 { 111 GLEncoder *ctx = (GLEncoder *)self; 112 assert(ctx->m_state != NULL); 113 GLClientState* state = ctx->m_state; 114 115 switch (param) { 116 case GL_COMPRESSED_TEXTURE_FORMATS: { 117 GLint * compressedTextureFormats = ctx->getCompressedTextureFormats(); 118 if (ctx->m_num_compressedTextureFormats > 0 && 119 compressedTextureFormats != NULL) { 120 for (int i = 0; i < ctx->m_num_compressedTextureFormats; i++) { 121 ptr[i] = (GLfloat) compressedTextureFormats[i]; 122 } 123 } 124 break; 125 } 126 127 case GL_MAX_TEXTURE_UNITS: 128 ctx->m_glGetFloatv_enc(self, param, ptr); 129 *ptr = MIN(*ptr, (GLfloat)GLClientState::MAX_TEXTURE_UNITS); 130 break; 131 132 case GL_TEXTURE_BINDING_2D: 133 *ptr = (GLfloat)state->getBoundTexture(GL_TEXTURE_2D); 134 break; 135 136 case GL_TEXTURE_BINDING_EXTERNAL_OES: 137 *ptr = (GLfloat)state->getBoundTexture(GL_TEXTURE_EXTERNAL_OES); 138 break; 139 140 default: 141 if (!state->getClientStateParameter<GLfloat>(param,ptr)) { 142 ctx->m_glGetFloatv_enc(self, param, ptr); 143 } 144 break; 145 } 146 } 147 148 void GLEncoder::s_glGetFixedv(void *self, GLenum param, GLfixed *ptr) 149 { 150 GLEncoder *ctx = (GLEncoder *)self; 151 assert(ctx->m_state != NULL); 152 GLClientState* state = ctx->m_state; 153 154 switch (param) { 155 case GL_COMPRESSED_TEXTURE_FORMATS: { 156 GLint * compressedTextureFormats = ctx->getCompressedTextureFormats(); 157 if (ctx->m_num_compressedTextureFormats > 0 && 158 compressedTextureFormats != NULL) { 159 for (int i = 0; i < ctx->m_num_compressedTextureFormats; i++) { 160 ptr[i] = compressedTextureFormats[i] << 16; 161 } 162 } 163 break; 164 } 165 166 case GL_MAX_TEXTURE_UNITS: 167 ctx->m_glGetFixedv_enc(self, param, ptr); 168 *ptr = MIN(*ptr, GLClientState::MAX_TEXTURE_UNITS << 16); 169 break; 170 171 case GL_TEXTURE_BINDING_2D: 172 *ptr = state->getBoundTexture(GL_TEXTURE_2D) << 16; 173 break; 174 175 case GL_TEXTURE_BINDING_EXTERNAL_OES: 176 *ptr = state->getBoundTexture(GL_TEXTURE_EXTERNAL_OES) << 16; 177 break; 178 179 default: 180 if (!state->getClientStateParameter<GLfixed>(param,ptr)) { 181 ctx->m_glGetFixedv_enc(self, param, ptr); 182 } 183 break; 184 } 185 } 186 187 void GLEncoder::s_glGetBooleanv(void *self, GLenum param, GLboolean *ptr) 188 { 189 GLEncoder *ctx = (GLEncoder *)self; 190 assert(ctx->m_state != NULL); 191 GLClientState* state = ctx->m_state; 192 193 switch (param) { 194 case GL_COMPRESSED_TEXTURE_FORMATS: { 195 GLint* compressedTextureFormats = ctx->getCompressedTextureFormats(); 196 if (ctx->m_num_compressedTextureFormats > 0 && 197 compressedTextureFormats != NULL) { 198 for (int i = 0; i < ctx->m_num_compressedTextureFormats; i++) { 199 ptr[i] = compressedTextureFormats[i] != 0 ? GL_TRUE : GL_FALSE; 200 } 201 } 202 break; 203 } 204 205 case GL_TEXTURE_BINDING_2D: 206 *ptr = state->getBoundTexture(GL_TEXTURE_2D) != 0 ? GL_TRUE : GL_FALSE; 207 break; 208 209 case GL_TEXTURE_BINDING_EXTERNAL_OES: 210 *ptr = state->getBoundTexture(GL_TEXTURE_EXTERNAL_OES) != 0 211 ? GL_TRUE : GL_FALSE; 212 break; 213 214 default: 215 if (!state->getClientStateParameter<GLboolean>(param,ptr)) { 216 ctx->m_glGetBooleanv_enc(self, param, ptr); 217 } 218 break; 219 } 220 } 221 222 void GLEncoder::s_glGetPointerv(void * self, GLenum param, GLvoid **params) 223 { 224 GLEncoder * ctx = (GLEncoder *) self; 225 assert(ctx->m_state != NULL); 226 ctx->m_state->getClientStatePointer(param,params); 227 } 228 229 void GLEncoder::s_glFlush(void *self) 230 { 231 GLEncoder *ctx = (GLEncoder *)self; 232 ctx->m_glFlush_enc(self); 233 ctx->m_stream->flush(); 234 } 235 236 const GLubyte *GLEncoder::s_glGetString(void *self, GLenum name) 237 { 238 GLubyte *retval = (GLubyte *) ""; 239 switch(name) { 240 case GL_VENDOR: 241 retval = gVendorString; 242 break; 243 case GL_RENDERER: 244 retval = gRendererString; 245 break; 246 case GL_VERSION: 247 retval = gVersionString; 248 break; 249 case GL_EXTENSIONS: 250 retval = gExtensionsString; 251 break; 252 } 253 return retval; 254 } 255 256 void GLEncoder::s_glPixelStorei(void *self, GLenum param, GLint value) 257 { 258 GLEncoder *ctx = (GLEncoder *)self; 259 ctx->m_glPixelStorei_enc(ctx, param, value); 260 ALOG_ASSERT(ctx->m_state, "GLEncoder::s_glPixelStorei"); 261 ctx->m_state->setPixelStore(param, value); 262 } 263 264 void GLEncoder::s_glVertexPointer(void *self, int size, GLenum type, GLsizei stride, const void *data) 265 { 266 GLEncoder *ctx = (GLEncoder *)self; 267 assert(ctx->m_state != NULL); 268 ctx->m_state->setState(GLClientState::VERTEX_LOCATION, size, type, false, stride, data); 269 } 270 271 void GLEncoder::s_glNormalPointer(void *self, GLenum type, GLsizei stride, const void *data) 272 { 273 GLEncoder *ctx = (GLEncoder *)self; 274 assert(ctx->m_state != NULL); 275 ctx->m_state->setState(GLClientState::NORMAL_LOCATION, 3, type, false, stride, data); 276 } 277 278 void GLEncoder::s_glColorPointer(void *self, int size, GLenum type, GLsizei stride, const void *data) 279 { 280 GLEncoder *ctx = (GLEncoder *)self; 281 assert(ctx->m_state != NULL); 282 ctx->m_state->setState(GLClientState::COLOR_LOCATION, size, type, false, stride, data); 283 } 284 285 void GLEncoder::s_glPointsizePointer(void *self, GLenum type, GLsizei stride, const void *data) 286 { 287 GLEncoder *ctx = (GLEncoder *)self; 288 assert(ctx->m_state != NULL); 289 ctx->m_state->setState(GLClientState::POINTSIZE_LOCATION, 1, type, false, stride, data); 290 } 291 292 void GLEncoder::s_glClientActiveTexture(void *self, GLenum texture) 293 { 294 GLEncoder *ctx = (GLEncoder *)self; 295 assert(ctx->m_state != NULL); 296 ctx->m_state->setActiveTexture(texture - GL_TEXTURE0); 297 } 298 299 void GLEncoder::s_glTexcoordPointer(void *self, int size, GLenum type, GLsizei stride, const void *data) 300 { 301 GLEncoder *ctx = (GLEncoder *)self; 302 assert(ctx->m_state != NULL); 303 int loc = ctx->m_state->getLocation(GL_TEXTURE_COORD_ARRAY); 304 ctx->m_state->setState(loc, size, type, false, stride, data); 305 } 306 307 void GLEncoder::s_glMatrixIndexPointerOES(void *self, int size, GLenum type, GLsizei stride, const void * data) 308 { 309 GLEncoder *ctx = (GLEncoder *)self; 310 assert(ctx->m_state != NULL); 311 int loc = ctx->m_state->getLocation(GL_MATRIX_INDEX_ARRAY_OES); 312 ctx->m_state->setState(loc, size, type, false, stride, data); 313 } 314 315 void GLEncoder::s_glWeightPointerOES(void * self, int size, GLenum type, GLsizei stride, const void * data) 316 { 317 GLEncoder *ctx = (GLEncoder *)self; 318 assert(ctx->m_state != NULL); 319 int loc = ctx->m_state->getLocation(GL_WEIGHT_ARRAY_OES); 320 ctx->m_state->setState(loc, size, type, false, stride, data); 321 } 322 323 void GLEncoder::s_glEnableClientState(void *self, GLenum state) 324 { 325 GLEncoder *ctx = (GLEncoder *) self; 326 assert(ctx->m_state != NULL); 327 int loc = ctx->m_state->getLocation(state); 328 ctx->m_state->enable(loc, 1); 329 } 330 331 void GLEncoder::s_glDisableClientState(void *self, GLenum state) 332 { 333 GLEncoder *ctx = (GLEncoder *) self; 334 assert(ctx->m_state != NULL); 335 int loc = ctx->m_state->getLocation(state); 336 ctx->m_state->enable(loc, 0); 337 } 338 339 GLboolean GLEncoder::s_glIsEnabled(void *self, GLenum cap) 340 { 341 GLEncoder *ctx = (GLEncoder *) self; 342 assert(ctx->m_state != NULL); 343 int loc = ctx->m_state->getLocation(cap); 344 const GLClientState::VertexAttribState *state = ctx->m_state->getState(loc); 345 346 if (state!=NULL) 347 return state->enabled; 348 349 return ctx->m_glIsEnabled_enc(self,cap); 350 } 351 352 void GLEncoder::s_glBindBuffer(void *self, GLenum target, GLuint id) 353 { 354 GLEncoder *ctx = (GLEncoder *) self; 355 assert(ctx->m_state != NULL); 356 ctx->m_state->bindBuffer(target, id); 357 // TODO set error state if needed; 358 ctx->m_glBindBuffer_enc(self, target, id); 359 } 360 361 void GLEncoder::s_glBufferData(void * self, GLenum target, GLsizeiptr size, const GLvoid * data, GLenum usage) 362 { 363 GLEncoder *ctx = (GLEncoder *) self; 364 GLuint bufferId = ctx->m_state->getBuffer(target); 365 SET_ERROR_IF(bufferId==0, GL_INVALID_OPERATION); 366 SET_ERROR_IF(size<0, GL_INVALID_VALUE); 367 368 ctx->m_shared->updateBufferData(bufferId, size, (void*)data); 369 ctx->m_glBufferData_enc(self, target, size, data, usage); 370 } 371 372 void GLEncoder::s_glBufferSubData(void * self, GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid * data) 373 { 374 GLEncoder *ctx = (GLEncoder *) self; 375 GLuint bufferId = ctx->m_state->getBuffer(target); 376 SET_ERROR_IF(bufferId==0, GL_INVALID_OPERATION); 377 378 GLenum res = ctx->m_shared->subUpdateBufferData(bufferId, offset, size, (void*)data); 379 SET_ERROR_IF(res, res); 380 381 ctx->m_glBufferSubData_enc(self, target, offset, size, data); 382 } 383 384 void GLEncoder::s_glDeleteBuffers(void * self, GLsizei n, const GLuint * buffers) 385 { 386 GLEncoder *ctx = (GLEncoder *) self; 387 SET_ERROR_IF(n<0, GL_INVALID_VALUE); 388 for (int i=0; i<n; i++) { 389 ctx->m_shared->deleteBufferData(buffers[i]); 390 ctx->m_glDeleteBuffers_enc(self,1,&buffers[i]); 391 } 392 } 393 394 void GLEncoder::sendVertexData(unsigned int first, unsigned int count) 395 { 396 assert(m_state != NULL); 397 for (int i = 0; i < GLClientState::LAST_LOCATION; i++) { 398 bool enableDirty; 399 const GLClientState::VertexAttribState *state = m_state->getStateAndEnableDirty(i, &enableDirty); 400 401 // do not process if state not valid 402 if (!state) continue; 403 404 // do not send disable state if state was already disabled 405 if (!enableDirty && !state->enabled) continue; 406 407 if ( i >= GLClientState::TEXCOORD0_LOCATION && 408 i <= GLClientState::TEXCOORD7_LOCATION ) { 409 m_glClientActiveTexture_enc(this, GL_TEXTURE0 + i - GLClientState::TEXCOORD0_LOCATION); 410 } 411 412 if (state->enabled) { 413 414 if (enableDirty) 415 m_glEnableClientState_enc(this, state->glConst); 416 417 unsigned int datalen = state->elementSize * count; 418 int stride = state->stride; 419 if (stride == 0) stride = state->elementSize; 420 int firstIndex = stride * first; 421 422 if (state->bufferObject == 0) { 423 424 switch(i) { 425 case GLClientState::VERTEX_LOCATION: 426 this->glVertexPointerData(this, state->size, state->type, state->stride, 427 (unsigned char *)state->data + firstIndex, datalen); 428 break; 429 case GLClientState::NORMAL_LOCATION: 430 this->glNormalPointerData(this, state->type, state->stride, 431 (unsigned char *)state->data + firstIndex, datalen); 432 break; 433 case GLClientState::COLOR_LOCATION: 434 this->glColorPointerData(this, state->size, state->type, state->stride, 435 (unsigned char *)state->data + firstIndex, datalen); 436 break; 437 case GLClientState::TEXCOORD0_LOCATION: 438 case GLClientState::TEXCOORD1_LOCATION: 439 case GLClientState::TEXCOORD2_LOCATION: 440 case GLClientState::TEXCOORD3_LOCATION: 441 case GLClientState::TEXCOORD4_LOCATION: 442 case GLClientState::TEXCOORD5_LOCATION: 443 case GLClientState::TEXCOORD6_LOCATION: 444 case GLClientState::TEXCOORD7_LOCATION: 445 this->glTexCoordPointerData(this, i - GLClientState::TEXCOORD0_LOCATION, state->size, state->type, state->stride, 446 (unsigned char *)state->data + firstIndex, datalen); 447 break; 448 case GLClientState::POINTSIZE_LOCATION: 449 this->glPointSizePointerData(this, state->type, state->stride, 450 (unsigned char *) state->data + firstIndex, datalen); 451 break; 452 case GLClientState::WEIGHT_LOCATION: 453 this->glWeightPointerData(this, state->size, state->type, state->stride, 454 (unsigned char * ) state->data + firstIndex, datalen); 455 break; 456 case GLClientState::MATRIXINDEX_LOCATION: 457 this->glMatrixIndexPointerData(this, state->size, state->type, state->stride, 458 (unsigned char *)state->data + firstIndex, datalen); 459 break; 460 } 461 } else { 462 this->m_glBindBuffer_enc(this, GL_ARRAY_BUFFER, state->bufferObject); 463 464 switch(i) { 465 case GLClientState::VERTEX_LOCATION: 466 this->glVertexPointerOffset(this, state->size, state->type, state->stride, 467 (uintptr_t)state->data + firstIndex); 468 break; 469 case GLClientState::NORMAL_LOCATION: 470 this->glNormalPointerOffset(this, state->type, state->stride, 471 (uintptr_t)state->data + firstIndex); 472 break; 473 case GLClientState::POINTSIZE_LOCATION: 474 this->glPointSizePointerOffset(this, state->type, state->stride, 475 (uintptr_t)state->data + firstIndex); 476 break; 477 case GLClientState::COLOR_LOCATION: 478 this->glColorPointerOffset(this, state->size, state->type, state->stride, 479 (uintptr_t)state->data + firstIndex); 480 break; 481 case GLClientState::TEXCOORD0_LOCATION: 482 case GLClientState::TEXCOORD1_LOCATION: 483 case GLClientState::TEXCOORD2_LOCATION: 484 case GLClientState::TEXCOORD3_LOCATION: 485 case GLClientState::TEXCOORD4_LOCATION: 486 case GLClientState::TEXCOORD5_LOCATION: 487 case GLClientState::TEXCOORD6_LOCATION: 488 case GLClientState::TEXCOORD7_LOCATION: 489 this->glTexCoordPointerOffset(this, state->size, state->type, state->stride, 490 (uintptr_t)state->data + firstIndex); 491 break; 492 case GLClientState::WEIGHT_LOCATION: 493 this->glWeightPointerOffset(this,state->size,state->type,state->stride, 494 (uintptr_t)state->data+firstIndex); 495 break; 496 case GLClientState::MATRIXINDEX_LOCATION: 497 this->glMatrixIndexPointerOffset(this,state->size,state->type,state->stride, 498 (uintptr_t)state->data+firstIndex); 499 break; 500 } 501 this->m_glBindBuffer_enc(this, GL_ARRAY_BUFFER, m_state->currentArrayVbo()); 502 } 503 } else { 504 this->m_glDisableClientState_enc(this, state->glConst); 505 } 506 } 507 } 508 509 void GLEncoder::s_glDrawArrays(void *self, GLenum mode, GLint first, GLsizei count) 510 { 511 GLEncoder *ctx = (GLEncoder *)self; 512 513 ctx->sendVertexData(first, count); 514 ctx->m_glDrawArrays_enc(ctx, mode, /*first*/ 0, count); 515 } 516 517 void GLEncoder::s_glDrawElements(void *self, GLenum mode, GLsizei count, GLenum type, const void *indices) 518 { 519 520 GLEncoder *ctx = (GLEncoder *)self; 521 assert(ctx->m_state != NULL); 522 SET_ERROR_IF(count<0, GL_INVALID_VALUE); 523 524 bool has_immediate_arrays = false; 525 bool has_indirect_arrays = false; 526 527 for (int i = 0; i < GLClientState::LAST_LOCATION; i++) { 528 const GLClientState::VertexAttribState *state = ctx->m_state->getState(i); 529 if (state->enabled) { 530 if (state->bufferObject != 0) { 531 has_indirect_arrays = true; 532 } else { 533 has_immediate_arrays = true; 534 } 535 } 536 } 537 538 if (!has_immediate_arrays && !has_indirect_arrays) { 539 ALOGE("glDrawElements: no data bound to the command - ignoring\n"); 540 return; 541 } 542 543 bool adjustIndices = true; 544 if (ctx->m_state->currentIndexVbo() != 0) { 545 if (!has_immediate_arrays) { 546 ctx->sendVertexData(0, count); 547 ctx->m_glBindBuffer_enc(self, GL_ELEMENT_ARRAY_BUFFER, ctx->m_state->currentIndexVbo()); 548 ctx->glDrawElementsOffset(ctx, mode, count, type, (uintptr_t)indices); 549 adjustIndices = false; 550 } else { 551 BufferData * buf = ctx->m_shared->getBufferData(ctx->m_state->currentIndexVbo()); 552 ctx->m_glBindBuffer_enc(self, GL_ELEMENT_ARRAY_BUFFER, 0); 553 indices = (void*)((GLintptr)buf->m_fixedBuffer.ptr() + (GLintptr)indices); 554 } 555 } 556 if (adjustIndices) { 557 void *adjustedIndices = (void*)indices; 558 int minIndex = 0, maxIndex = 0; 559 560 switch(type) { 561 case GL_BYTE: 562 case GL_UNSIGNED_BYTE: 563 GLUtils::minmax<unsigned char>((unsigned char *)indices, count, &minIndex, &maxIndex); 564 if (minIndex != 0) { 565 adjustedIndices = ctx->m_fixedBuffer.alloc(glSizeof(type) * count); 566 GLUtils::shiftIndices<unsigned char>((unsigned char *)indices, 567 (unsigned char *)adjustedIndices, 568 count, -minIndex); 569 } 570 break; 571 case GL_SHORT: 572 case GL_UNSIGNED_SHORT: 573 GLUtils::minmax<unsigned short>((unsigned short *)indices, count, &minIndex, &maxIndex); 574 if (minIndex != 0) { 575 adjustedIndices = ctx->m_fixedBuffer.alloc(glSizeof(type) * count); 576 GLUtils::shiftIndices<unsigned short>((unsigned short *)indices, 577 (unsigned short *)adjustedIndices, 578 count, -minIndex); 579 } 580 break; 581 default: 582 ALOGE("unsupported index buffer type %d\n", type); 583 } 584 if (has_indirect_arrays || 1) { 585 ctx->sendVertexData(minIndex, maxIndex - minIndex + 1); 586 ctx->glDrawElementsData(ctx, mode, count, type, adjustedIndices, 587 count * glSizeof(type)); 588 // XXX - OPTIMIZATION (see the other else branch) should be implemented 589 if(!has_indirect_arrays) { 590 //ALOGD("unoptimized drawelements !!!\n"); 591 } 592 } else { 593 // we are all direct arrays and immidate mode index array - 594 // rebuild the arrays and the index array; 595 ALOGE("glDrawElements: direct index & direct buffer data - will be implemented in later versions;\n"); 596 } 597 } 598 } 599 600 void GLEncoder::s_glActiveTexture(void* self, GLenum texture) 601 { 602 GLEncoder* ctx = (GLEncoder*)self; 603 GLClientState* state = ctx->m_state; 604 GLenum err; 605 606 if ((err = state->setActiveTextureUnit(texture)) != GL_NO_ERROR) { 607 ALOGE("%s:%s:%d GL error %#x\n", __FILE__, __FUNCTION__, __LINE__, err); 608 ctx->setError(err); 609 return; 610 } 611 612 ctx->m_glActiveTexture_enc(ctx, texture); 613 } 614 615 void GLEncoder::s_glBindTexture(void* self, GLenum target, GLuint texture) 616 { 617 GLEncoder* ctx = (GLEncoder*)self; 618 GLClientState* state = ctx->m_state; 619 GLenum err; 620 621 GLboolean firstUse; 622 if ((err = state->bindTexture(target, texture, &firstUse)) != GL_NO_ERROR) { 623 ALOGE("%s:%s:%d GL error %#x\n", __FILE__, __FUNCTION__, __LINE__, err); 624 ctx->setError(err); 625 return; 626 } 627 628 if (target != GL_TEXTURE_2D && target != GL_TEXTURE_EXTERNAL_OES) { 629 ctx->m_glBindTexture_enc(ctx, target, texture); 630 return; 631 } 632 633 GLenum priorityTarget = state->getPriorityEnabledTarget(GL_TEXTURE_2D); 634 635 if (target == GL_TEXTURE_EXTERNAL_OES && firstUse) { 636 // set TEXTURE_EXTERNAL_OES default states which differ from TEXTURE_2D 637 ctx->m_glBindTexture_enc(ctx, GL_TEXTURE_2D, texture); 638 ctx->m_glTexParameteri_enc(ctx, GL_TEXTURE_2D, 639 GL_TEXTURE_MIN_FILTER, GL_LINEAR); 640 ctx->m_glTexParameteri_enc(ctx, GL_TEXTURE_2D, 641 GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 642 ctx->m_glTexParameteri_enc(ctx, GL_TEXTURE_2D, 643 GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 644 645 if (target != priorityTarget) { 646 ctx->m_glBindTexture_enc(ctx, GL_TEXTURE_2D, 647 state->getBoundTexture(GL_TEXTURE_2D)); 648 } 649 } 650 651 if (target == priorityTarget) { 652 ctx->m_glBindTexture_enc(ctx, GL_TEXTURE_2D, texture); 653 } 654 } 655 656 void GLEncoder::s_glDeleteTextures(void* self, GLsizei n, const GLuint* textures) 657 { 658 GLEncoder* ctx = (GLEncoder*)self; 659 GLClientState* state = ctx->m_state; 660 661 state->deleteTextures(n, textures); 662 ctx->m_glDeleteTextures_enc(ctx, n, textures); 663 } 664 665 void GLEncoder::s_glDisable(void* self, GLenum cap) 666 { 667 GLEncoder* ctx = (GLEncoder*)self; 668 GLClientState* state = ctx->m_state; 669 670 if (cap == GL_TEXTURE_2D || cap == GL_TEXTURE_EXTERNAL_OES) { 671 GLenum prevTarget = state->getPriorityEnabledTarget(GL_INVALID_ENUM); 672 state->disableTextureTarget(cap); 673 GLenum currTarget = state->getPriorityEnabledTarget(GL_INVALID_ENUM); 674 675 if (prevTarget != currTarget) { 676 if (currTarget == GL_INVALID_ENUM) { 677 ctx->m_glDisable_enc(ctx, GL_TEXTURE_2D); 678 currTarget = GL_TEXTURE_2D; 679 } 680 // maintain the invariant that when TEXTURE_EXTERNAL_OES is 681 // disabled, the TEXTURE_2D binding is active, even if 682 // TEXTURE_2D is also disabled. 683 ctx->m_glBindTexture_enc(ctx, GL_TEXTURE_2D, 684 state->getBoundTexture(currTarget)); 685 } 686 687 } else { 688 ctx->m_glDisable_enc(ctx, cap); 689 } 690 } 691 692 void GLEncoder::s_glEnable(void* self, GLenum cap) 693 { 694 GLEncoder* ctx = (GLEncoder*)self; 695 GLClientState* state = ctx->m_state; 696 697 if (cap == GL_TEXTURE_2D || cap == GL_TEXTURE_EXTERNAL_OES) { 698 GLenum prevTarget = state->getPriorityEnabledTarget(GL_INVALID_ENUM); 699 state->enableTextureTarget(cap); 700 GLenum currTarget = state->getPriorityEnabledTarget(GL_INVALID_ENUM); 701 702 if (prevTarget != currTarget) { 703 if (prevTarget == GL_INVALID_ENUM) { 704 ctx->m_glEnable_enc(ctx, GL_TEXTURE_2D); 705 } 706 if (currTarget == GL_TEXTURE_EXTERNAL_OES) { 707 ctx->m_glBindTexture_enc(ctx, GL_TEXTURE_2D, 708 state->getBoundTexture(currTarget)); 709 } 710 } 711 712 } else { 713 ctx->m_glEnable_enc(ctx, cap); 714 } 715 } 716 717 void GLEncoder::s_glGetTexParameterfv(void* self, 718 GLenum target, GLenum pname, GLfloat* params) 719 { 720 GLEncoder* ctx = (GLEncoder*)self; 721 const GLClientState* state = ctx->m_state; 722 723 if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) { 724 ctx->override2DTextureTarget(target); 725 ctx->m_glGetTexParameterfv_enc(ctx, GL_TEXTURE_2D, pname, params); 726 ctx->restore2DTextureTarget(); 727 } else { 728 ctx->m_glGetTexParameterfv_enc(ctx, target, pname, params); 729 } 730 } 731 732 void GLEncoder::s_glGetTexParameteriv(void* self, 733 GLenum target, GLenum pname, GLint* params) 734 { 735 GLEncoder* ctx = (GLEncoder*)self; 736 const GLClientState* state = ctx->m_state; 737 738 switch (pname) { 739 case GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES: 740 *params = 1; 741 break; 742 743 default: 744 if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) { 745 ctx->override2DTextureTarget(target); 746 ctx->m_glGetTexParameteriv_enc(ctx, GL_TEXTURE_2D, pname, params); 747 ctx->restore2DTextureTarget(); 748 } else { 749 ctx->m_glGetTexParameteriv_enc(ctx, target, pname, params); 750 } 751 break; 752 } 753 } 754 755 void GLEncoder::s_glGetTexParameterxv(void* self, 756 GLenum target, GLenum pname, GLfixed* params) 757 { 758 GLEncoder* ctx = (GLEncoder*)self; 759 const GLClientState* state = ctx->m_state; 760 761 if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) { 762 ctx->override2DTextureTarget(target); 763 ctx->m_glGetTexParameterxv_enc(ctx, GL_TEXTURE_2D, pname, params); 764 ctx->restore2DTextureTarget(); 765 } else { 766 ctx->m_glGetTexParameterxv_enc(ctx, target, pname, params); 767 } 768 } 769 770 static bool isValidTextureExternalParam(GLenum pname, GLenum param) 771 { 772 switch (pname) { 773 case GL_TEXTURE_MIN_FILTER: 774 case GL_TEXTURE_MAG_FILTER: 775 return param == GL_NEAREST || param == GL_LINEAR; 776 777 case GL_TEXTURE_WRAP_S: 778 case GL_TEXTURE_WRAP_T: 779 return param == GL_CLAMP_TO_EDGE; 780 781 case GL_GENERATE_MIPMAP: 782 return param == GL_FALSE; 783 784 default: 785 return true; 786 } 787 } 788 789 void GLEncoder::s_glTexParameterf(void* self, 790 GLenum target, GLenum pname, GLfloat param) 791 { 792 GLEncoder* ctx = (GLEncoder*)self; 793 const GLClientState* state = ctx->m_state; 794 795 SET_ERROR_IF((target == GL_TEXTURE_EXTERNAL_OES && 796 !isValidTextureExternalParam(pname, (GLenum)param)), 797 GL_INVALID_ENUM); 798 799 if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) { 800 ctx->override2DTextureTarget(target); 801 ctx->m_glTexParameterf_enc(ctx, GL_TEXTURE_2D, pname, param); 802 ctx->restore2DTextureTarget(); 803 } else { 804 ctx->m_glTexParameterf_enc(ctx, target, pname, param); 805 } 806 } 807 808 void GLEncoder::s_glTexParameterfv(void* self, 809 GLenum target, GLenum pname, const GLfloat* params) 810 { 811 GLEncoder* ctx = (GLEncoder*)self; 812 const GLClientState* state = ctx->m_state; 813 814 SET_ERROR_IF((target == GL_TEXTURE_EXTERNAL_OES && 815 !isValidTextureExternalParam(pname, (GLenum)params[0])), 816 GL_INVALID_ENUM); 817 818 if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) { 819 ctx->override2DTextureTarget(target); 820 ctx->m_glTexParameterfv_enc(ctx, GL_TEXTURE_2D, pname, params); 821 ctx->restore2DTextureTarget(); 822 } else { 823 ctx->m_glTexParameterfv_enc(ctx, target, pname, params); 824 } 825 } 826 827 void GLEncoder::s_glTexParameteri(void* self, 828 GLenum target, GLenum pname, GLint param) 829 { 830 GLEncoder* ctx = (GLEncoder*)self; 831 const GLClientState* state = ctx->m_state; 832 833 SET_ERROR_IF((target == GL_TEXTURE_EXTERNAL_OES && 834 !isValidTextureExternalParam(pname, (GLenum)param)), 835 GL_INVALID_ENUM); 836 837 if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) { 838 ctx->override2DTextureTarget(target); 839 ctx->m_glTexParameteri_enc(ctx, GL_TEXTURE_2D, pname, param); 840 ctx->restore2DTextureTarget(); 841 } else { 842 ctx->m_glTexParameteri_enc(ctx, target, pname, param); 843 } 844 } 845 846 void GLEncoder::s_glTexParameterx(void* self, 847 GLenum target, GLenum pname, GLfixed param) 848 { 849 GLEncoder* ctx = (GLEncoder*)self; 850 const GLClientState* state = ctx->m_state; 851 852 SET_ERROR_IF((target == GL_TEXTURE_EXTERNAL_OES && 853 !isValidTextureExternalParam(pname, (GLenum)param)), 854 GL_INVALID_ENUM); 855 856 if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) { 857 ctx->override2DTextureTarget(target); 858 ctx->m_glTexParameterx_enc(ctx, GL_TEXTURE_2D, pname, param); 859 ctx->restore2DTextureTarget(); 860 } else { 861 ctx->m_glTexParameterx_enc(ctx, target, pname, param); 862 } 863 } 864 865 void GLEncoder::s_glTexParameteriv(void* self, 866 GLenum target, GLenum pname, const GLint* params) 867 { 868 GLEncoder* ctx = (GLEncoder*)self; 869 const GLClientState* state = ctx->m_state; 870 871 SET_ERROR_IF((target == GL_TEXTURE_EXTERNAL_OES && 872 !isValidTextureExternalParam(pname, (GLenum)params[0])), 873 GL_INVALID_ENUM); 874 875 if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) { 876 ctx->override2DTextureTarget(target); 877 ctx->m_glTexParameteriv_enc(ctx, GL_TEXTURE_2D, pname, params); 878 ctx->restore2DTextureTarget(); 879 } else { 880 ctx->m_glTexParameteriv_enc(ctx, target, pname, params); 881 } 882 } 883 884 void GLEncoder::s_glTexParameterxv(void* self, 885 GLenum target, GLenum pname, const GLfixed* params) 886 { 887 GLEncoder* ctx = (GLEncoder*)self; 888 const GLClientState* state = ctx->m_state; 889 890 SET_ERROR_IF((target == GL_TEXTURE_EXTERNAL_OES && 891 !isValidTextureExternalParam(pname, (GLenum)params[0])), 892 GL_INVALID_ENUM); 893 894 if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) { 895 ctx->override2DTextureTarget(target); 896 ctx->m_glTexParameterxv_enc(ctx, GL_TEXTURE_2D, pname, params); 897 ctx->restore2DTextureTarget(); 898 } else { 899 ctx->m_glTexParameterxv_enc(ctx, target, pname, params); 900 } 901 } 902 903 void GLEncoder::override2DTextureTarget(GLenum target) 904 { 905 if ((target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) && 906 target != m_state->getPriorityEnabledTarget(GL_TEXTURE_2D)) { 907 m_glBindTexture_enc(this, GL_TEXTURE_2D, 908 m_state->getBoundTexture(target)); 909 } 910 } 911 912 void GLEncoder::restore2DTextureTarget() 913 { 914 GLenum priorityTarget = m_state->getPriorityEnabledTarget(GL_TEXTURE_2D); 915 m_glBindTexture_enc(this, GL_TEXTURE_2D, 916 m_state->getBoundTexture(priorityTarget)); 917 } 918 919 GLEncoder::GLEncoder(IOStream *stream) : gl_encoder_context_t(stream) 920 { 921 m_initialized = false; 922 m_state = NULL; 923 m_error = GL_NO_ERROR; 924 m_num_compressedTextureFormats = 0; 925 m_compressedTextureFormats = NULL; 926 // overrides; 927 m_glFlush_enc = set_glFlush(s_glFlush); 928 m_glPixelStorei_enc = set_glPixelStorei(s_glPixelStorei); 929 m_glVertexPointer_enc = set_glVertexPointer(s_glVertexPointer); 930 m_glNormalPointer_enc = set_glNormalPointer(s_glNormalPointer); 931 m_glColorPointer_enc = set_glColorPointer(s_glColorPointer); 932 m_glPointSizePointerOES_enc = set_glPointSizePointerOES(s_glPointsizePointer); 933 m_glClientActiveTexture_enc = set_glClientActiveTexture(s_glClientActiveTexture); 934 m_glTexCoordPointer_enc = set_glTexCoordPointer(s_glTexcoordPointer); 935 m_glMatrixIndexPointerOES_enc = set_glMatrixIndexPointerOES(s_glMatrixIndexPointerOES); 936 m_glWeightPointerOES_enc = set_glWeightPointerOES(s_glWeightPointerOES); 937 938 m_glGetIntegerv_enc = set_glGetIntegerv(s_glGetIntegerv); 939 m_glGetFloatv_enc = set_glGetFloatv(s_glGetFloatv); 940 m_glGetBooleanv_enc = set_glGetBooleanv(s_glGetBooleanv); 941 m_glGetFixedv_enc = set_glGetFixedv(s_glGetFixedv); 942 m_glGetPointerv_enc = set_glGetPointerv(s_glGetPointerv); 943 944 m_glBindBuffer_enc = set_glBindBuffer(s_glBindBuffer); 945 m_glBufferData_enc = set_glBufferData(s_glBufferData); 946 m_glBufferSubData_enc = set_glBufferSubData(s_glBufferSubData); 947 m_glDeleteBuffers_enc = set_glDeleteBuffers(s_glDeleteBuffers); 948 949 m_glEnableClientState_enc = set_glEnableClientState(s_glEnableClientState); 950 m_glDisableClientState_enc = set_glDisableClientState(s_glDisableClientState); 951 m_glIsEnabled_enc = set_glIsEnabled(s_glIsEnabled); 952 m_glDrawArrays_enc = set_glDrawArrays(s_glDrawArrays); 953 m_glDrawElements_enc = set_glDrawElements(s_glDrawElements); 954 set_glGetString(s_glGetString); 955 set_glFinish(s_glFinish); 956 m_glGetError_enc = set_glGetError(s_glGetError); 957 958 m_glActiveTexture_enc = set_glActiveTexture(s_glActiveTexture); 959 m_glBindTexture_enc = set_glBindTexture(s_glBindTexture); 960 m_glDeleteTextures_enc = set_glDeleteTextures(s_glDeleteTextures); 961 m_glDisable_enc = set_glDisable(s_glDisable); 962 m_glEnable_enc = set_glEnable(s_glEnable); 963 m_glGetTexParameterfv_enc = set_glGetTexParameterfv(s_glGetTexParameterfv); 964 m_glGetTexParameteriv_enc = set_glGetTexParameteriv(s_glGetTexParameteriv); 965 m_glGetTexParameterxv_enc = set_glGetTexParameterxv(s_glGetTexParameterxv); 966 m_glTexParameterf_enc = set_glTexParameterf(s_glTexParameterf); 967 m_glTexParameterfv_enc = set_glTexParameterfv(s_glTexParameterfv); 968 m_glTexParameteri_enc = set_glTexParameteri(s_glTexParameteri); 969 m_glTexParameterx_enc = set_glTexParameterx(s_glTexParameterx); 970 m_glTexParameteriv_enc = set_glTexParameteriv(s_glTexParameteriv); 971 m_glTexParameterxv_enc = set_glTexParameterxv(s_glTexParameterxv); 972 } 973 974 GLEncoder::~GLEncoder() 975 { 976 delete [] m_compressedTextureFormats; 977 } 978 979 size_t GLEncoder::pixelDataSize(GLsizei width, GLsizei height, GLenum format, GLenum type, int pack) 980 { 981 assert(m_state != NULL); 982 return m_state->pixelDataSize(width, height, format, type, pack); 983 } 984 985 void GLEncoder::s_glFinish(void *self) 986 { 987 GLEncoder *ctx = (GLEncoder *)self; 988 ctx->glFinishRoundTrip(self); 989 } 990