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 static GLubyte *gVendorString= (GLubyte *) "Android"; 23 static GLubyte *gRendererString= (GLubyte *) "Android HW-GLES 1.0"; 24 static GLubyte *gVersionString= (GLubyte *) "OpenGL ES-CM 1.0"; 25 static GLubyte *gExtensionsString= (GLubyte *) ""; // no extensions at this point; 26 27 #define DEFINE_AND_VALIDATE_HOST_CONNECTION(ret) \ 28 HostConnection *hostCon = HostConnection::get(); \ 29 if (!hostCon) { \ 30 LOGE("egl: Failed to get host connection\n"); \ 31 return ret; \ 32 } \ 33 renderControl_encoder_context_t *rcEnc = hostCon->rcEncoder(); \ 34 if (!rcEnc) { \ 35 LOGE("egl: Failed to get renderControl encoder context\n"); \ 36 return ret; \ 37 } 38 39 #define SET_ERROR_IF(condition,err) if((condition)) { \ 40 LOGE("%s:%s:%d GL error 0x%x\n", __FILE__, __FUNCTION__, __LINE__, err); \ 41 ctx->setError(err); \ 42 return; \ 43 } 44 45 46 #define RET_AND_SET_ERROR_IF(condition,err,ret) if((condition)) { \ 47 LOGE("%s:%s:%d GL error 0x%x\n", __FILE__, __FUNCTION__, __LINE__, err); \ 48 ctx->setError(err); \ 49 return ret; \ 50 } 51 52 GLenum GLEncoder::s_glGetError(void * self) 53 { 54 GLEncoder *ctx = (GLEncoder *)self; 55 GLenum err = ctx->getError(); 56 if(err != GL_NO_ERROR) { 57 ctx->setError(GL_NO_ERROR); 58 return err; 59 } 60 61 return ctx->m_glGetError_enc(self); 62 63 } 64 65 GLint * GLEncoder::getCompressedTextureFormats() 66 { 67 if (m_compressedTextureFormats == NULL) { 68 this->glGetIntegerv(this, GL_NUM_COMPRESSED_TEXTURE_FORMATS, 69 &m_num_compressedTextureFormats); 70 if (m_num_compressedTextureFormats > 0) { 71 // get number of texture formats; 72 m_compressedTextureFormats = new GLint[m_num_compressedTextureFormats]; 73 this->glGetCompressedTextureFormats(this, m_num_compressedTextureFormats, m_compressedTextureFormats); 74 } 75 } 76 return m_compressedTextureFormats; 77 } 78 79 void GLEncoder::s_glGetIntegerv(void *self, GLenum param, GLint *ptr) 80 { 81 GLEncoder *ctx = (GLEncoder *)self; 82 assert(ctx->m_state != NULL); 83 if (param == GL_COMPRESSED_TEXTURE_FORMATS) { 84 GLint * compressedTextureFormats = ctx->getCompressedTextureFormats(); 85 if (ctx->m_num_compressedTextureFormats > 0 && compressedTextureFormats != NULL) { 86 memcpy(ptr, compressedTextureFormats, ctx->m_num_compressedTextureFormats * sizeof(GLint)); 87 } 88 } 89 else if (!ctx->m_state->getClientStateParameter<GLint>(param,ptr)) { 90 ctx->m_glGetIntegerv_enc(self, param, ptr); 91 } 92 } 93 94 void GLEncoder::s_glGetFloatv(void *self, GLenum param, GLfloat *ptr) 95 { 96 GLEncoder *ctx = (GLEncoder *)self; 97 assert(ctx->m_state != NULL); 98 if (param == GL_COMPRESSED_TEXTURE_FORMATS) { 99 GLint * compressedTextureFormats = ctx->getCompressedTextureFormats(); 100 if (ctx->m_num_compressedTextureFormats > 0 && compressedTextureFormats != NULL) { 101 for (int i = 0; i < ctx->m_num_compressedTextureFormats; i++) { 102 ptr[i] = (GLfloat) compressedTextureFormats[i]; 103 } 104 } 105 } 106 else if (!ctx->m_state->getClientStateParameter<GLfloat>(param,ptr)) { 107 ctx->m_glGetFloatv_enc(self, param, ptr); 108 } 109 } 110 111 void GLEncoder::s_glGetFixedv(void *self, GLenum param, GLfixed *ptr) 112 { 113 GLEncoder *ctx = (GLEncoder *)self; 114 assert(ctx->m_state != NULL); 115 if (param == GL_COMPRESSED_TEXTURE_FORMATS) { 116 GLint * compressedTextureFormats = ctx->getCompressedTextureFormats(); 117 if (ctx->m_num_compressedTextureFormats > 0 && compressedTextureFormats != NULL) { 118 for (int i = 0; i < ctx->m_num_compressedTextureFormats; i++) { 119 ptr[i] = compressedTextureFormats[i] << 16; 120 } 121 } 122 } 123 else if (!ctx->m_state->getClientStateParameter<GLfixed>(param,ptr)) { 124 ctx->m_glGetFixedv_enc(self, param, ptr); 125 } 126 } 127 128 void GLEncoder::s_glGetBooleanv(void *self, GLenum param, GLboolean *ptr) 129 { 130 GLEncoder *ctx = (GLEncoder *)self; 131 assert(ctx->m_state != NULL); 132 if (param == GL_COMPRESSED_TEXTURE_FORMATS) { 133 // ignore the command, although we should have generated a GLerror; 134 } 135 else if (!ctx->m_state->getClientStateParameter<GLboolean>(param,ptr)) { 136 ctx->m_glGetBooleanv_enc(self, param, ptr); 137 } 138 } 139 140 void GLEncoder::s_glGetPointerv(void * self, GLenum param, GLvoid **params) 141 { 142 GLEncoder * ctx = (GLEncoder *) self; 143 assert(ctx->m_state != NULL); 144 ctx->m_state->getClientStatePointer(param,params); 145 } 146 147 void GLEncoder::s_glFlush(void *self) 148 { 149 GLEncoder *ctx = (GLEncoder *)self; 150 ctx->m_glFlush_enc(self); 151 ctx->m_stream->flush(); 152 } 153 154 const GLubyte *GLEncoder::s_glGetString(void *self, GLenum name) 155 { 156 GLubyte *retval = (GLubyte *) ""; 157 switch(name) { 158 case GL_VENDOR: 159 retval = gVendorString; 160 break; 161 case GL_RENDERER: 162 retval = gRendererString; 163 break; 164 case GL_VERSION: 165 retval = gVersionString; 166 break; 167 case GL_EXTENSIONS: 168 retval = gExtensionsString; 169 break; 170 } 171 return retval; 172 } 173 174 void GLEncoder::s_glPixelStorei(void *self, GLenum param, GLint value) 175 { 176 GLEncoder *ctx = (GLEncoder *)self; 177 ctx->m_glPixelStorei_enc(ctx, param, value); 178 LOG_ASSERT(ctx->m_state, "GLEncoder::s_glPixelStorei"); 179 ctx->m_state->setPixelStore(param, value); 180 } 181 182 void GLEncoder::s_glVertexPointer(void *self, int size, GLenum type, GLsizei stride, const void *data) 183 { 184 GLEncoder *ctx = (GLEncoder *)self; 185 assert(ctx->m_state != NULL); 186 ctx->m_state->setState(GLClientState::VERTEX_LOCATION, size, type, false, stride, data); 187 } 188 189 void GLEncoder::s_glNormalPointer(void *self, GLenum type, GLsizei stride, const void *data) 190 { 191 GLEncoder *ctx = (GLEncoder *)self; 192 assert(ctx->m_state != NULL); 193 ctx->m_state->setState(GLClientState::NORMAL_LOCATION, 3, type, false, stride, data); 194 } 195 196 void GLEncoder::s_glColorPointer(void *self, int size, GLenum type, GLsizei stride, const void *data) 197 { 198 GLEncoder *ctx = (GLEncoder *)self; 199 assert(ctx->m_state != NULL); 200 ctx->m_state->setState(GLClientState::COLOR_LOCATION, size, type, false, stride, data); 201 } 202 203 void GLEncoder::s_glPointsizePointer(void *self, GLenum type, GLsizei stride, const void *data) 204 { 205 GLEncoder *ctx = (GLEncoder *)self; 206 assert(ctx->m_state != NULL); 207 ctx->m_state->setState(GLClientState::POINTSIZE_LOCATION, 1, type, false, stride, data); 208 } 209 210 void GLEncoder::s_glClientActiveTexture(void *self, GLenum texture) 211 { 212 GLEncoder *ctx = (GLEncoder *)self; 213 assert(ctx->m_state != NULL); 214 ctx->m_state->setActiveTexture(texture - GL_TEXTURE0); 215 } 216 217 void GLEncoder::s_glTexcoordPointer(void *self, int size, GLenum type, GLsizei stride, const void *data) 218 { 219 GLEncoder *ctx = (GLEncoder *)self; 220 assert(ctx->m_state != NULL); 221 int loc = ctx->m_state->getLocation(GL_TEXTURE_COORD_ARRAY); 222 ctx->m_state->setState(loc, size, type, false, stride, data); 223 } 224 225 void GLEncoder::s_glMatrixIndexPointerOES(void *self, int size, GLenum type, GLsizei stride, const void * data) 226 { 227 GLEncoder *ctx = (GLEncoder *)self; 228 assert(ctx->m_state != NULL); 229 int loc = ctx->m_state->getLocation(GL_MATRIX_INDEX_ARRAY_OES); 230 ctx->m_state->setState(loc, size, type, false, stride, data); 231 } 232 233 void GLEncoder::s_glWeightPointerOES(void * self, int size, GLenum type, GLsizei stride, const void * data) 234 { 235 GLEncoder *ctx = (GLEncoder *)self; 236 assert(ctx->m_state != NULL); 237 int loc = ctx->m_state->getLocation(GL_WEIGHT_ARRAY_OES); 238 ctx->m_state->setState(loc, size, type, false, stride, data); 239 } 240 241 void GLEncoder::s_glEnableClientState(void *self, GLenum state) 242 { 243 GLEncoder *ctx = (GLEncoder *) self; 244 assert(ctx->m_state != NULL); 245 int loc = ctx->m_state->getLocation(state); 246 ctx->m_state->enable(loc, 1); 247 } 248 249 void GLEncoder::s_glDisableClientState(void *self, GLenum state) 250 { 251 GLEncoder *ctx = (GLEncoder *) self; 252 assert(ctx->m_state != NULL); 253 int loc = ctx->m_state->getLocation(state); 254 ctx->m_state->enable(loc, 0); 255 } 256 257 GLboolean GLEncoder::s_glIsEnabled(void *self, GLenum cap) 258 { 259 GLEncoder *ctx = (GLEncoder *) self; 260 assert(ctx->m_state != NULL); 261 int loc = ctx->m_state->getLocation(cap); 262 const GLClientState::VertexAttribState *state = ctx->m_state->getState(loc); 263 264 if (state!=NULL) 265 return state->enabled; 266 267 return ctx->m_glIsEnabled_enc(self,cap); 268 } 269 270 void GLEncoder::s_glBindBuffer(void *self, GLenum target, GLuint id) 271 { 272 GLEncoder *ctx = (GLEncoder *) self; 273 assert(ctx->m_state != NULL); 274 ctx->m_state->bindBuffer(target, id); 275 // TODO set error state if needed; 276 ctx->m_glBindBuffer_enc(self, target, id); 277 } 278 279 void GLEncoder::s_glBufferData(void * self, GLenum target, GLsizeiptr size, const GLvoid * data, GLenum usage) 280 { 281 GLEncoder *ctx = (GLEncoder *) self; 282 GLuint bufferId = ctx->m_state->getBuffer(target); 283 SET_ERROR_IF(bufferId==0, GL_INVALID_OPERATION); 284 SET_ERROR_IF(size<0, GL_INVALID_VALUE); 285 286 ctx->m_shared->updateBufferData(bufferId, size, (void*)data); 287 ctx->m_glBufferData_enc(self, target, size, data, usage); 288 } 289 290 void GLEncoder::s_glBufferSubData(void * self, GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid * data) 291 { 292 GLEncoder *ctx = (GLEncoder *) self; 293 GLuint bufferId = ctx->m_state->getBuffer(target); 294 SET_ERROR_IF(bufferId==0, GL_INVALID_OPERATION); 295 296 GLenum res = ctx->m_shared->subUpdateBufferData(bufferId, offset, size, (void*)data); 297 SET_ERROR_IF(res, res); 298 299 ctx->m_glBufferSubData_enc(self, target, offset, size, data); 300 } 301 302 void GLEncoder::s_glDeleteBuffers(void * self, GLsizei n, const GLuint * buffers) 303 { 304 GLEncoder *ctx = (GLEncoder *) self; 305 SET_ERROR_IF(n<0, GL_INVALID_VALUE); 306 for (int i=0; i<n; i++) { 307 ctx->m_shared->deleteBufferData(buffers[i]); 308 ctx->m_glDeleteBuffers_enc(self,1,&buffers[i]); 309 } 310 } 311 312 void GLEncoder::sendVertexData(unsigned int first, unsigned int count) 313 { 314 assert(m_state != NULL); 315 for (int i = 0; i < GLClientState::LAST_LOCATION; i++) { 316 bool enableDirty; 317 const GLClientState::VertexAttribState *state = m_state->getStateAndEnableDirty(i, &enableDirty); 318 319 // do not process if state not valid 320 if (!state) continue; 321 322 // do not send disable state if state was already disabled 323 if (!enableDirty && !state->enabled) continue; 324 325 if ( i >= GLClientState::TEXCOORD0_LOCATION && 326 i <= GLClientState::TEXCOORD7_LOCATION ) { 327 m_glClientActiveTexture_enc(this, GL_TEXTURE0 + i - GLClientState::TEXCOORD0_LOCATION); 328 } 329 330 if (state->enabled) { 331 332 if (enableDirty) 333 m_glEnableClientState_enc(this, state->glConst); 334 335 unsigned int datalen = state->elementSize * count; 336 int stride = state->stride; 337 if (stride == 0) stride = state->elementSize; 338 int firstIndex = stride * first; 339 340 if (state->bufferObject == 0) { 341 342 switch(i) { 343 case GLClientState::VERTEX_LOCATION: 344 this->glVertexPointerData(this, state->size, state->type, state->stride, 345 (unsigned char *)state->data + firstIndex, datalen); 346 break; 347 case GLClientState::NORMAL_LOCATION: 348 this->glNormalPointerData(this, state->type, state->stride, 349 (unsigned char *)state->data + firstIndex, datalen); 350 break; 351 case GLClientState::COLOR_LOCATION: 352 this->glColorPointerData(this, state->size, state->type, state->stride, 353 (unsigned char *)state->data + firstIndex, datalen); 354 break; 355 case GLClientState::TEXCOORD0_LOCATION: 356 case GLClientState::TEXCOORD1_LOCATION: 357 case GLClientState::TEXCOORD2_LOCATION: 358 case GLClientState::TEXCOORD3_LOCATION: 359 case GLClientState::TEXCOORD4_LOCATION: 360 case GLClientState::TEXCOORD5_LOCATION: 361 case GLClientState::TEXCOORD6_LOCATION: 362 case GLClientState::TEXCOORD7_LOCATION: 363 this->glTexCoordPointerData(this, i - GLClientState::TEXCOORD0_LOCATION, state->size, state->type, state->stride, 364 (unsigned char *)state->data + firstIndex, datalen); 365 break; 366 case GLClientState::POINTSIZE_LOCATION: 367 this->glPointSizePointerData(this, state->type, state->stride, 368 (unsigned char *) state->data + firstIndex, datalen); 369 break; 370 case GLClientState::WEIGHT_LOCATION: 371 this->glWeightPointerData(this, state->size, state->type, state->stride, 372 (unsigned char * ) state->data + firstIndex, datalen); 373 break; 374 case GLClientState::MATRIXINDEX_LOCATION: 375 this->glMatrixIndexPointerData(this, state->size, state->type, state->stride, 376 (unsigned char *)state->data + firstIndex, datalen); 377 break; 378 } 379 } else { 380 this->m_glBindBuffer_enc(this, GL_ARRAY_BUFFER, state->bufferObject); 381 382 switch(i) { 383 case GLClientState::VERTEX_LOCATION: 384 this->glVertexPointerOffset(this, state->size, state->type, state->stride, 385 (GLuint)state->data + firstIndex); 386 break; 387 case GLClientState::NORMAL_LOCATION: 388 this->glNormalPointerOffset(this, state->type, state->stride, 389 (GLuint) state->data + firstIndex); 390 break; 391 case GLClientState::POINTSIZE_LOCATION: 392 this->glPointSizePointerOffset(this, state->type, state->stride, 393 (GLuint) state->data + firstIndex); 394 break; 395 case GLClientState::COLOR_LOCATION: 396 this->glColorPointerOffset(this, state->size, state->type, state->stride, 397 (GLuint) state->data + firstIndex); 398 break; 399 case GLClientState::TEXCOORD0_LOCATION: 400 case GLClientState::TEXCOORD1_LOCATION: 401 case GLClientState::TEXCOORD2_LOCATION: 402 case GLClientState::TEXCOORD3_LOCATION: 403 case GLClientState::TEXCOORD4_LOCATION: 404 case GLClientState::TEXCOORD5_LOCATION: 405 case GLClientState::TEXCOORD6_LOCATION: 406 case GLClientState::TEXCOORD7_LOCATION: 407 this->glTexCoordPointerOffset(this, state->size, state->type, state->stride, 408 (GLuint) state->data + firstIndex); 409 break; 410 case GLClientState::WEIGHT_LOCATION: 411 this->glWeightPointerOffset(this,state->size,state->type,state->stride, 412 (GLuint)state->data+firstIndex); 413 break; 414 case GLClientState::MATRIXINDEX_LOCATION: 415 this->glMatrixIndexPointerOffset(this,state->size,state->type,state->stride, 416 (GLuint)state->data+firstIndex); 417 break; 418 } 419 this->m_glBindBuffer_enc(this, GL_ARRAY_BUFFER, m_state->currentArrayVbo()); 420 } 421 } else { 422 this->m_glDisableClientState_enc(this, state->glConst); 423 } 424 } 425 } 426 427 void GLEncoder::s_glDrawArrays(void *self, GLenum mode, GLint first, GLsizei count) 428 { 429 GLEncoder *ctx = (GLEncoder *)self; 430 431 ctx->sendVertexData(first, count); 432 ctx->m_glDrawArrays_enc(ctx, mode, /*first*/ 0, count); 433 } 434 435 void GLEncoder::s_glDrawElements(void *self, GLenum mode, GLsizei count, GLenum type, const void *indices) 436 { 437 438 GLEncoder *ctx = (GLEncoder *)self; 439 assert(ctx->m_state != NULL); 440 SET_ERROR_IF(count<0, GL_INVALID_VALUE); 441 442 bool has_immediate_arrays = false; 443 bool has_indirect_arrays = false; 444 445 for (int i = 0; i < GLClientState::LAST_LOCATION; i++) { 446 const GLClientState::VertexAttribState *state = ctx->m_state->getState(i); 447 if (state->enabled) { 448 if (state->bufferObject != 0) { 449 has_indirect_arrays = true; 450 } else { 451 has_immediate_arrays = true; 452 } 453 } 454 } 455 456 if (!has_immediate_arrays && !has_indirect_arrays) { 457 LOGE("glDrawElements: no data bound to the command - ignoring\n"); 458 return; 459 } 460 461 bool adjustIndices = true; 462 if (ctx->m_state->currentIndexVbo() != 0) { 463 if (!has_immediate_arrays) { 464 ctx->sendVertexData(0, count); 465 ctx->m_glBindBuffer_enc(self, GL_ELEMENT_ARRAY_BUFFER, ctx->m_state->currentIndexVbo()); 466 ctx->glDrawElementsOffset(ctx, mode, count, type, (GLuint)indices); 467 adjustIndices = false; 468 } else { 469 BufferData * buf = ctx->m_shared->getBufferData(ctx->m_state->currentIndexVbo()); 470 ctx->m_glBindBuffer_enc(self, GL_ELEMENT_ARRAY_BUFFER, 0); 471 indices = (void*)((GLintptr)buf->m_fixedBuffer.ptr() + (GLintptr)indices); 472 } 473 } 474 if (adjustIndices) { 475 void *adjustedIndices = (void*)indices; 476 int minIndex = 0, maxIndex = 0; 477 478 switch(type) { 479 case GL_BYTE: 480 case GL_UNSIGNED_BYTE: 481 GLUtils::minmax<unsigned char>((unsigned char *)indices, count, &minIndex, &maxIndex); 482 if (minIndex != 0) { 483 adjustedIndices = ctx->m_fixedBuffer.alloc(glSizeof(type) * count); 484 GLUtils::shiftIndices<unsigned char>((unsigned char *)indices, 485 (unsigned char *)adjustedIndices, 486 count, -minIndex); 487 } 488 break; 489 case GL_SHORT: 490 case GL_UNSIGNED_SHORT: 491 GLUtils::minmax<unsigned short>((unsigned short *)indices, count, &minIndex, &maxIndex); 492 if (minIndex != 0) { 493 adjustedIndices = ctx->m_fixedBuffer.alloc(glSizeof(type) * count); 494 GLUtils::shiftIndices<unsigned short>((unsigned short *)indices, 495 (unsigned short *)adjustedIndices, 496 count, -minIndex); 497 } 498 break; 499 default: 500 LOGE("unsupported index buffer type %d\n", type); 501 } 502 if (has_indirect_arrays || 1) { 503 ctx->sendVertexData(minIndex, maxIndex - minIndex + 1); 504 ctx->glDrawElementsData(ctx, mode, count, type, adjustedIndices, 505 count * glSizeof(type)); 506 // XXX - OPTIMIZATION (see the other else branch) should be implemented 507 if(!has_indirect_arrays) { 508 //LOGD("unoptimized drawelements !!!\n"); 509 } 510 } else { 511 // we are all direct arrays and immidate mode index array - 512 // rebuild the arrays and the index array; 513 LOGE("glDrawElements: direct index & direct buffer data - will be implemented in later versions;\n"); 514 } 515 } 516 } 517 518 GLEncoder::GLEncoder(IOStream *stream) : gl_encoder_context_t(stream) 519 { 520 m_initialized = false; 521 m_state = NULL; 522 m_error = GL_NO_ERROR; 523 m_num_compressedTextureFormats = 0; 524 m_compressedTextureFormats = NULL; 525 // overrides; 526 m_glFlush_enc = set_glFlush(s_glFlush); 527 m_glPixelStorei_enc = set_glPixelStorei(s_glPixelStorei); 528 m_glVertexPointer_enc = set_glVertexPointer(s_glVertexPointer); 529 m_glNormalPointer_enc = set_glNormalPointer(s_glNormalPointer); 530 m_glColorPointer_enc = set_glColorPointer(s_glColorPointer); 531 m_glPointSizePointerOES_enc = set_glPointSizePointerOES(s_glPointsizePointer); 532 m_glClientActiveTexture_enc = set_glClientActiveTexture(s_glClientActiveTexture); 533 m_glTexCoordPointer_enc = set_glTexCoordPointer(s_glTexcoordPointer); 534 m_glMatrixIndexPointerOES_enc = set_glMatrixIndexPointerOES(s_glMatrixIndexPointerOES); 535 m_glWeightPointerOES_enc = set_glWeightPointerOES(s_glWeightPointerOES); 536 537 m_glGetIntegerv_enc = set_glGetIntegerv(s_glGetIntegerv); 538 m_glGetFloatv_enc = set_glGetFloatv(s_glGetFloatv); 539 m_glGetBooleanv_enc = set_glGetBooleanv(s_glGetBooleanv); 540 m_glGetFixedv_enc = set_glGetFixedv(s_glGetFixedv); 541 m_glGetPointerv_enc = set_glGetPointerv(s_glGetPointerv); 542 543 m_glBindBuffer_enc = set_glBindBuffer(s_glBindBuffer); 544 m_glBufferData_enc = set_glBufferData(s_glBufferData); 545 m_glBufferSubData_enc = set_glBufferSubData(s_glBufferSubData); 546 m_glDeleteBuffers_enc = set_glDeleteBuffers(s_glDeleteBuffers); 547 548 m_glEnableClientState_enc = set_glEnableClientState(s_glEnableClientState); 549 m_glDisableClientState_enc = set_glDisableClientState(s_glDisableClientState); 550 m_glIsEnabled_enc = set_glIsEnabled(s_glIsEnabled); 551 m_glDrawArrays_enc = set_glDrawArrays(s_glDrawArrays); 552 m_glDrawElements_enc = set_glDrawElements(s_glDrawElements); 553 set_glGetString(s_glGetString); 554 set_glFinish(s_glFinish); 555 m_glGetError_enc = set_glGetError(s_glGetError); 556 557 } 558 559 GLEncoder::~GLEncoder() 560 { 561 delete [] m_compressedTextureFormats; 562 } 563 564 size_t GLEncoder::pixelDataSize(GLsizei width, GLsizei height, GLenum format, GLenum type, int pack) 565 { 566 assert(m_state != NULL); 567 return m_state->pixelDataSize(width, height, format, type, pack); 568 } 569 570 void GLEncoder::s_glFinish(void *self) 571 { 572 GLEncoder *ctx = (GLEncoder *)self; 573 ctx->glFinishRoundTrip(self); 574 } 575 576