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