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 26static GLubyte *gVendorString= (GLubyte *) "Android"; 27static GLubyte *gRendererString= (GLubyte *) "Android HW-GLES 1.0"; 28static GLubyte *gVersionString= (GLubyte *) "OpenGL ES-CM 1.0"; 29static 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 44GLenum 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 57GLint * 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 71void 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 109void 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 148void 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 187void 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 222void 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 229void GLEncoder::s_glFlush(void *self) 230{ 231 GLEncoder *ctx = (GLEncoder *)self; 232 ctx->m_glFlush_enc(self); 233 ctx->m_stream->flush(); 234} 235 236const 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 256void 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 264void 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 271void 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 278void 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 285void 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 292void 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 299void 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 307void 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 315void 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 323void 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 331void 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 339GLboolean 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 352void 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 361void 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 372void 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 384void 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 394void 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 (GLuint)state->data + firstIndex); 468 break; 469 case GLClientState::NORMAL_LOCATION: 470 this->glNormalPointerOffset(this, state->type, state->stride, 471 (GLuint) state->data + firstIndex); 472 break; 473 case GLClientState::POINTSIZE_LOCATION: 474 this->glPointSizePointerOffset(this, state->type, state->stride, 475 (GLuint) state->data + firstIndex); 476 break; 477 case GLClientState::COLOR_LOCATION: 478 this->glColorPointerOffset(this, state->size, state->type, state->stride, 479 (GLuint) 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 (GLuint) state->data + firstIndex); 491 break; 492 case GLClientState::WEIGHT_LOCATION: 493 this->glWeightPointerOffset(this,state->size,state->type,state->stride, 494 (GLuint)state->data+firstIndex); 495 break; 496 case GLClientState::MATRIXINDEX_LOCATION: 497 this->glMatrixIndexPointerOffset(this,state->size,state->type,state->stride, 498 (GLuint)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 509void 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 517void 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, (GLuint)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 600void 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 615void 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 656void 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 665void 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 692void 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 717void 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 732void 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 755void 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 770static 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 789void 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 808void 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 827void 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 846void 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 865void 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 884void 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 903void 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 912void 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 919GLEncoder::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 974GLEncoder::~GLEncoder() 975{ 976 delete [] m_compressedTextureFormats; 977} 978 979size_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 985void GLEncoder::s_glFinish(void *self) 986{ 987 GLEncoder *ctx = (GLEncoder *)self; 988 ctx->glFinishRoundTrip(self); 989} 990