state.cpp revision 18b915a1026dfe9d273ee3fd2139b7feed22008c
1/* libs/opengles/state.cpp 2** 3** Copyright 2006, The Android Open Source Project 4** 5** Licensed under the Apache License, Version 2.0 (the "License"); 6** you may not use this file except in compliance with the License. 7** You may obtain a copy of the License at 8** 9** http://www.apache.org/licenses/LICENSE-2.0 10** 11** Unless required by applicable law or agreed to in writing, software 12** distributed under the License is distributed on an "AS IS" BASIS, 13** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14** See the License for the specific language governing permissions and 15** limitations under the License. 16*/ 17 18#include <stdlib.h> 19 20#include "context.h" 21#include "fp.h" 22#include "state.h" 23#include "array.h" 24#include "matrix.h" 25#include "vertex.h" 26#include "light.h" 27#include "texture.h" 28#include "BufferObjectManager.h" 29#include "TextureObjectManager.h" 30 31#ifdef LIBAGL_USE_GRALLOC_COPYBITS 32#include <hardware/copybit.h> 33#endif // LIBAGL_USE_GRALLOC_COPYBITS 34 35namespace android { 36 37// ---------------------------------------------------------------------------- 38 39static char const * const gVendorString = "Android"; 40static char const * const gRendererString = "Android PixelFlinger 1.2"; 41static char const * const gVersionString = "OpenGL ES-CM 1.0"; 42static char const * const gExtensionsString = 43 "GL_OES_byte_coordinates " // OK 44 "GL_OES_fixed_point " // OK 45 "GL_OES_single_precision " // OK 46 "GL_OES_read_format " // OK 47 "GL_OES_compressed_paletted_texture " // OK 48 "GL_OES_draw_texture " // OK 49 "GL_OES_matrix_get " // OK 50 "GL_OES_query_matrix " // OK 51 // "GL_OES_point_size_array " // TODO 52 // "GL_OES_point_sprite " // TODO 53 "GL_OES_EGL_image " // OK 54#ifdef GL_OES_compressed_ETC1_RGB8_texture 55 "GL_OES_compressed_ETC1_RGB8_texture " // OK 56#endif 57 "GL_ARB_texture_compression " // OK 58 "GL_ARB_texture_non_power_of_two " // OK 59 "GL_ANDROID_user_clip_plane " // OK 60 "GL_ANDROID_vertex_buffer_object " // OK 61 "GL_ANDROID_generate_mipmap " // OK 62 ; 63 64// ---------------------------------------------------------------------------- 65#if 0 66#pragma mark - 67#endif 68 69ogles_context_t *ogles_init(size_t extra) 70{ 71 void* const base = malloc(extra + sizeof(ogles_context_t) + 32); 72 if (!base) return 0; 73 74 ogles_context_t *c = 75 (ogles_context_t *)((ptrdiff_t(base) + extra + 31) & ~0x1FL); 76 memset(c, 0, sizeof(ogles_context_t)); 77 ggl_init_context(&(c->rasterizer)); 78 79 // XXX: this should be passed as an argument 80 sp<EGLSurfaceManager> smgr(new EGLSurfaceManager()); 81 c->surfaceManager = smgr.get(); 82 c->surfaceManager->incStrong(c); 83 84 sp<EGLBufferObjectManager> bomgr(new EGLBufferObjectManager()); 85 c->bufferObjectManager = bomgr.get(); 86 c->bufferObjectManager->incStrong(c); 87 88 ogles_init_array(c); 89 ogles_init_matrix(c); 90 ogles_init_vertex(c); 91 ogles_init_light(c); 92 ogles_init_texture(c); 93 94 c->rasterizer.base = base; 95 c->point.size = TRI_ONE; 96 c->line.width = TRI_ONE; 97 98 // in OpenGL, writing to the depth buffer is enabled by default. 99 c->rasterizer.procs.depthMask(c, 1); 100 101 // OpenGL enables dithering by default 102 c->rasterizer.procs.enable(c, GL_DITHER); 103 104 c->copybits.blitEngine = NULL; 105 c->copybits.minScale = 0; 106 c->copybits.maxScale = 0; 107 c->copybits.drawSurfaceBuffer = 0; 108 109#ifdef LIBAGL_USE_GRALLOC_COPYBITS 110 hw_module_t const* module; 111 if (hw_get_module(COPYBIT_HARDWARE_MODULE_ID, &module) == 0) { 112 struct copybit_device_t* copyBits; 113 if (copybit_open(module, ©Bits) == 0) { 114 c->copybits.blitEngine = copyBits; 115 { 116 int minLim = copyBits->get(copyBits, 117 COPYBIT_MINIFICATION_LIMIT); 118 if (minLim != -EINVAL && minLim > 0) { 119 c->copybits.minScale = (1 << 16) / minLim; 120 } 121 } 122 { 123 int magLim = copyBits->get(copyBits, 124 COPYBIT_MAGNIFICATION_LIMIT); 125 if (magLim != -EINVAL && magLim > 0) { 126 c->copybits.maxScale = min(32*1024-1, magLim) << 16; 127 } 128 } 129 } 130 } 131#endif // LIBAGL_USE_GRALLOC_COPYBITS 132 133 return c; 134} 135 136void ogles_uninit(ogles_context_t* c) 137{ 138 ogles_uninit_array(c); 139 ogles_uninit_matrix(c); 140 ogles_uninit_vertex(c); 141 ogles_uninit_light(c); 142 ogles_uninit_texture(c); 143 c->surfaceManager->decStrong(c); 144 c->bufferObjectManager->decStrong(c); 145 ggl_uninit_context(&(c->rasterizer)); 146 free(c->rasterizer.base); 147#ifdef LIBAGL_USE_GRALLOC_COPYBITS 148 if (c->copybits.blitEngine != NULL) { 149 copybit_close((struct copybit_device_t*) c->copybits.blitEngine); 150 } 151#endif // LIBAGL_USE_GRALLOC_COPYBITS 152} 153 154void _ogles_error(ogles_context_t* c, GLenum error) 155{ 156 if (c->error == GL_NO_ERROR) 157 c->error = error; 158} 159 160static bool stencilop_valid(GLenum op) { 161 switch (op) { 162 case GL_KEEP: 163 case GL_ZERO: 164 case GL_REPLACE: 165 case GL_INCR: 166 case GL_DECR: 167 case GL_INVERT: 168 return true; 169 } 170 return false; 171} 172 173static void enable_disable(ogles_context_t* c, GLenum cap, int enabled) 174{ 175 if ((cap >= GL_LIGHT0) && (cap<GL_LIGHT0+OGLES_MAX_LIGHTS)) { 176 c->lighting.lights[cap-GL_LIGHT0].enable = enabled; 177 c->lighting.enabledLights &= ~(1<<(cap-GL_LIGHT0)); 178 c->lighting.enabledLights |= (enabled<<(cap-GL_LIGHT0)); 179 return; 180 } 181 182 switch (cap) { 183 case GL_POINT_SMOOTH: 184 c->point.smooth = enabled; 185 break; 186 case GL_LINE_SMOOTH: 187 c->line.smooth = enabled; 188 break; 189 case GL_POLYGON_OFFSET_FILL: 190 c->polygonOffset.enable = enabled; 191 break; 192 case GL_CULL_FACE: 193 c->cull.enable = enabled; 194 break; 195 case GL_LIGHTING: 196 c->lighting.enable = enabled; 197 break; 198 case GL_COLOR_MATERIAL: 199 c->lighting.colorMaterial.enable = enabled; 200 break; 201 case GL_NORMALIZE: 202 case GL_RESCALE_NORMAL: 203 c->transforms.rescaleNormals = enabled ? cap : 0; 204 // XXX: invalidate mvit 205 break; 206 207 case GL_CLIP_PLANE0: 208 case GL_CLIP_PLANE1: 209 case GL_CLIP_PLANE2: 210 case GL_CLIP_PLANE3: 211 case GL_CLIP_PLANE4: 212 case GL_CLIP_PLANE5: 213 c->clipPlanes.enable &= ~(1<<(cap-GL_CLIP_PLANE0)); 214 c->clipPlanes.enable |= (enabled<<(cap-GL_CLIP_PLANE0)); 215 ogles_invalidate_perspective(c); 216 break; 217 218 case GL_FOG: 219 case GL_DEPTH_TEST: 220 ogles_invalidate_perspective(c); 221 // fall-through... 222 case GL_BLEND: 223 case GL_SCISSOR_TEST: 224 case GL_ALPHA_TEST: 225 case GL_COLOR_LOGIC_OP: 226 case GL_DITHER: 227 case GL_STENCIL_TEST: 228 case GL_TEXTURE_2D: 229 // these need to fall through into the rasterizer 230 c->rasterizer.procs.enableDisable(c, cap, enabled); 231 break; 232 233 case GL_MULTISAMPLE: 234 case GL_SAMPLE_ALPHA_TO_COVERAGE: 235 case GL_SAMPLE_ALPHA_TO_ONE: 236 case GL_SAMPLE_COVERAGE: 237 // not supported in this implementation 238 break; 239 240 default: 241 ogles_error(c, GL_INVALID_ENUM); 242 return; 243 } 244} 245 246// ---------------------------------------------------------------------------- 247}; // namespace android 248// ---------------------------------------------------------------------------- 249using namespace android; 250 251#if 0 252#pragma mark - 253#endif 254 255// These ones are super-easy, we're not supporting those features! 256void glSampleCoverage(GLclampf value, GLboolean invert) { 257} 258void glSampleCoveragex(GLclampx value, GLboolean invert) { 259} 260void glStencilFunc(GLenum func, GLint ref, GLuint mask) { 261 ogles_context_t* c = ogles_context_t::get(); 262 if (func < GL_NEVER || func > GL_ALWAYS) { 263 ogles_error(c, GL_INVALID_ENUM); 264 return; 265 } 266 // from OpenGL|ES 1.0 sepcification: 267 // If there is no stencil buffer, no stencil modification can occur 268 // and it is as if the stencil test always passes. 269} 270 271void glStencilOp(GLenum fail, GLenum zfail, GLenum zpass) { 272 ogles_context_t* c = ogles_context_t::get(); 273 if ((stencilop_valid(fail) & 274 stencilop_valid(zfail) & 275 stencilop_valid(zpass)) == 0) { 276 ogles_error(c, GL_INVALID_ENUM); 277 return; 278 } 279} 280 281// ---------------------------------------------------------------------------- 282 283void glAlphaFunc(GLenum func, GLclampf ref) 284{ 285 glAlphaFuncx(func, gglFloatToFixed(ref)); 286} 287 288void glCullFace(GLenum mode) 289{ 290 ogles_context_t* c = ogles_context_t::get(); 291 switch (mode) { 292 case GL_FRONT: 293 case GL_BACK: 294 case GL_FRONT_AND_BACK: 295 break; 296 default: 297 ogles_error(c, GL_INVALID_ENUM); 298 } 299 c->cull.cullFace = mode; 300} 301 302void glFrontFace(GLenum mode) 303{ 304 ogles_context_t* c = ogles_context_t::get(); 305 switch (mode) { 306 case GL_CW: 307 case GL_CCW: 308 break; 309 default: 310 ogles_error(c, GL_INVALID_ENUM); 311 return; 312 } 313 c->cull.frontFace = mode; 314} 315 316void glHint(GLenum target, GLenum mode) 317{ 318 ogles_context_t* c = ogles_context_t::get(); 319 switch (target) { 320 case GL_FOG_HINT: 321 case GL_GENERATE_MIPMAP_HINT: 322 case GL_LINE_SMOOTH_HINT: 323 break; 324 case GL_POINT_SMOOTH_HINT: 325 c->rasterizer.procs.enableDisable(c, 326 GGL_POINT_SMOOTH_NICE, mode==GL_NICEST); 327 break; 328 case GL_PERSPECTIVE_CORRECTION_HINT: 329 c->perspective = (mode == GL_NICEST) ? 1 : 0; 330 break; 331 default: 332 ogles_error(c, GL_INVALID_ENUM); 333 } 334} 335 336void glEnable(GLenum cap) { 337 ogles_context_t* c = ogles_context_t::get(); 338 enable_disable(c, cap, 1); 339} 340void glDisable(GLenum cap) { 341 ogles_context_t* c = ogles_context_t::get(); 342 enable_disable(c, cap, 0); 343} 344 345void glFinish() 346{ // nothing to do for our software implementation 347} 348 349void glFlush() 350{ // nothing to do for our software implementation 351} 352 353GLenum glGetError() 354{ 355 // From OpenGL|ES 1.0 specification: 356 // If more than one flag has recorded an error, glGetError returns 357 // and clears an arbitrary error flag value. Thus, glGetError should 358 // always be called in a loop, until it returns GL_NO_ERROR, 359 // if all error flags are to be reset. 360 361 ogles_context_t* c = ogles_context_t::get(); 362 if (c->error) { 363 const GLenum ret(c->error); 364 c->error = 0; 365 return ret; 366 } 367 368 if (c->rasterizer.error) { 369 const GLenum ret(c->rasterizer.error); 370 c->rasterizer.error = 0; 371 return ret; 372 } 373 374 return GL_NO_ERROR; 375} 376 377const GLubyte* glGetString(GLenum string) 378{ 379 switch (string) { 380 case GL_VENDOR: return (const GLubyte*)gVendorString; 381 case GL_RENDERER: return (const GLubyte*)gRendererString; 382 case GL_VERSION: return (const GLubyte*)gVersionString; 383 case GL_EXTENSIONS: return (const GLubyte*)gExtensionsString; 384 } 385 ogles_context_t* c = ogles_context_t::get(); 386 ogles_error(c, GL_INVALID_ENUM); 387 return 0; 388} 389 390void glGetIntegerv(GLenum pname, GLint *params) 391{ 392 int i; 393 ogles_context_t* c = ogles_context_t::get(); 394 switch (pname) { 395 case GL_ALIASED_POINT_SIZE_RANGE: 396 params[0] = 0; 397 params[1] = GGL_MAX_ALIASED_POINT_SIZE; 398 break; 399 case GL_ALIASED_LINE_WIDTH_RANGE: 400 params[0] = 0; 401 params[1] = GGL_MAX_ALIASED_POINT_SIZE; 402 break; 403 case GL_ALPHA_BITS: { 404 int index = c->rasterizer.state.buffers.color.format; 405 GGLFormat const * formats = gglGetPixelFormatTable(); 406 params[0] = formats[index].ah - formats[index].al; 407 break; 408 } 409 case GL_RED_BITS: { 410 int index = c->rasterizer.state.buffers.color.format; 411 GGLFormat const * formats = gglGetPixelFormatTable(); 412 params[0] = formats[index].rh - formats[index].rl; 413 break; 414 } 415 case GL_GREEN_BITS: { 416 int index = c->rasterizer.state.buffers.color.format; 417 GGLFormat const * formats = gglGetPixelFormatTable(); 418 params[0] = formats[index].gh - formats[index].gl; 419 break; 420 } 421 case GL_BLUE_BITS: { 422 int index = c->rasterizer.state.buffers.color.format; 423 GGLFormat const * formats = gglGetPixelFormatTable(); 424 params[0] = formats[index].bh - formats[index].bl; 425 break; 426 } 427 case GL_COMPRESSED_TEXTURE_FORMATS: 428 params[ 0] = GL_PALETTE4_RGB8_OES; 429 params[ 1] = GL_PALETTE4_RGBA8_OES; 430 params[ 2] = GL_PALETTE4_R5_G6_B5_OES; 431 params[ 3] = GL_PALETTE4_RGBA4_OES; 432 params[ 4] = GL_PALETTE4_RGB5_A1_OES; 433 params[ 5] = GL_PALETTE8_RGB8_OES; 434 params[ 6] = GL_PALETTE8_RGBA8_OES; 435 params[ 7] = GL_PALETTE8_R5_G6_B5_OES; 436 params[ 8] = GL_PALETTE8_RGBA4_OES; 437 params[ 9] = GL_PALETTE8_RGB5_A1_OES; 438 i = 10; 439#ifdef GL_OES_compressed_ETC1_RGB8_texture 440 params[i++] = GL_ETC1_RGB8_OES; 441#endif 442 break; 443 case GL_DEPTH_BITS: 444 params[0] = c->rasterizer.state.buffers.depth.format ? 0 : 16; 445 break; 446 case GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES: 447 params[0] = GL_RGB; 448 break; 449 case GL_IMPLEMENTATION_COLOR_READ_TYPE_OES: 450 params[0] = GL_UNSIGNED_SHORT_5_6_5; 451 break; 452 case GL_MAX_LIGHTS: 453 params[0] = OGLES_MAX_LIGHTS; 454 break; 455 case GL_MAX_CLIP_PLANES: 456 params[0] = OGLES_MAX_CLIP_PLANES; 457 break; 458 case GL_MAX_MODELVIEW_STACK_DEPTH: 459 params[0] = OGLES_MODELVIEW_STACK_DEPTH; 460 break; 461 case GL_MAX_PROJECTION_STACK_DEPTH: 462 params[0] = OGLES_PROJECTION_STACK_DEPTH; 463 break; 464 case GL_MAX_TEXTURE_STACK_DEPTH: 465 params[0] = OGLES_TEXTURE_STACK_DEPTH; 466 break; 467 case GL_MAX_TEXTURE_SIZE: 468 params[0] = GGL_MAX_TEXTURE_SIZE; 469 break; 470 case GL_MAX_TEXTURE_UNITS: 471 params[0] = GGL_TEXTURE_UNIT_COUNT; 472 break; 473 case GL_MAX_VIEWPORT_DIMS: 474 params[0] = GGL_MAX_VIEWPORT_DIMS; 475 params[1] = GGL_MAX_VIEWPORT_DIMS; 476 break; 477 case GL_NUM_COMPRESSED_TEXTURE_FORMATS: 478 params[0] = OGLES_NUM_COMPRESSED_TEXTURE_FORMATS; 479 break; 480 case GL_SMOOTH_LINE_WIDTH_RANGE: 481 params[0] = 0; 482 params[1] = GGL_MAX_SMOOTH_LINE_WIDTH; 483 break; 484 case GL_SMOOTH_POINT_SIZE_RANGE: 485 params[0] = 0; 486 params[1] = GGL_MAX_SMOOTH_POINT_SIZE; 487 break; 488 case GL_STENCIL_BITS: 489 params[0] = 0; 490 break; 491 case GL_SUBPIXEL_BITS: 492 params[0] = GGL_SUBPIXEL_BITS; 493 break; 494 495 case GL_MODELVIEW_MATRIX_FLOAT_AS_INT_BITS_OES: 496 memcpy( params, 497 c->transforms.modelview.top().elements(), 498 16*sizeof(GLint)); 499 break; 500 case GL_PROJECTION_MATRIX_FLOAT_AS_INT_BITS_OES: 501 memcpy( params, 502 c->transforms.projection.top().elements(), 503 16*sizeof(GLint)); 504 break; 505 case GL_TEXTURE_MATRIX_FLOAT_AS_INT_BITS_OES: 506 memcpy( params, 507 c->transforms.texture[c->textures.active].top().elements(), 508 16*sizeof(GLint)); 509 break; 510 511 default: 512 ogles_error(c, GL_INVALID_ENUM); 513 break; 514 } 515} 516 517// ---------------------------------------------------------------------------- 518 519void glPointSize(GLfloat size) 520{ 521 ogles_context_t* c = ogles_context_t::get(); 522 if (size <= 0) { 523 ogles_error(c, GL_INVALID_ENUM); 524 return; 525 } 526 c->point.size = TRI_FROM_FIXED(gglFloatToFixed(size)); 527} 528 529void glPointSizex(GLfixed size) 530{ 531 ogles_context_t* c = ogles_context_t::get(); 532 if (size <= 0) { 533 ogles_error(c, GL_INVALID_ENUM); 534 return; 535 } 536 c->point.size = TRI_FROM_FIXED(size); 537} 538 539// ---------------------------------------------------------------------------- 540 541void glLineWidth(GLfloat width) 542{ 543 ogles_context_t* c = ogles_context_t::get(); 544 if (width <= 0) { 545 ogles_error(c, GL_INVALID_ENUM); 546 return; 547 } 548 c->line.width = TRI_FROM_FIXED(gglFloatToFixed(width)); 549} 550 551void glLineWidthx(GLfixed width) 552{ 553 ogles_context_t* c = ogles_context_t::get(); 554 if (width <= 0) { 555 ogles_error(c, GL_INVALID_ENUM); 556 return; 557 } 558 c->line.width = TRI_FROM_FIXED(width); 559} 560 561// ---------------------------------------------------------------------------- 562 563void glColorMask(GLboolean r, GLboolean g, GLboolean b, GLboolean a) { 564 ogles_context_t* c = ogles_context_t::get(); 565 c->rasterizer.procs.colorMask(c, r, g, b, a); 566} 567 568void glDepthMask(GLboolean flag) { 569 ogles_context_t* c = ogles_context_t::get(); 570 c->rasterizer.procs.depthMask(c, flag); 571} 572 573void glStencilMask(GLuint mask) { 574 ogles_context_t* c = ogles_context_t::get(); 575 c->rasterizer.procs.stencilMask(c, mask); 576} 577 578void glDepthFunc(GLenum func) { 579 ogles_context_t* c = ogles_context_t::get(); 580 c->rasterizer.procs.depthFunc(c, func); 581} 582 583void glLogicOp(GLenum opcode) { 584 ogles_context_t* c = ogles_context_t::get(); 585 c->rasterizer.procs.logicOp(c, opcode); 586} 587 588void glAlphaFuncx(GLenum func, GLclampx ref) { 589 ogles_context_t* c = ogles_context_t::get(); 590 c->rasterizer.procs.alphaFuncx(c, func, ref); 591} 592 593void glBlendFunc(GLenum sfactor, GLenum dfactor) { 594 ogles_context_t* c = ogles_context_t::get(); 595 c->rasterizer.procs.blendFunc(c, sfactor, dfactor); 596} 597 598void glClear(GLbitfield mask) { 599 ogles_context_t* c = ogles_context_t::get(); 600 c->rasterizer.procs.clear(c, mask); 601} 602 603void glClearColorx(GLclampx red, GLclampx green, GLclampx blue, GLclampx alpha) { 604 ogles_context_t* c = ogles_context_t::get(); 605 c->rasterizer.procs.clearColorx(c, red, green, blue, alpha); 606} 607 608void glClearColor(GLclampf r, GLclampf g, GLclampf b, GLclampf a) 609{ 610 ogles_context_t* c = ogles_context_t::get(); 611 c->rasterizer.procs.clearColorx(c, 612 gglFloatToFixed(r), 613 gglFloatToFixed(g), 614 gglFloatToFixed(b), 615 gglFloatToFixed(a)); 616} 617 618void glClearDepthx(GLclampx depth) { 619 ogles_context_t* c = ogles_context_t::get(); 620 c->rasterizer.procs.clearDepthx(c, depth); 621} 622 623void glClearDepthf(GLclampf depth) 624{ 625 ogles_context_t* c = ogles_context_t::get(); 626 c->rasterizer.procs.clearDepthx(c, gglFloatToFixed(depth)); 627} 628 629void glClearStencil(GLint s) { 630 ogles_context_t* c = ogles_context_t::get(); 631 c->rasterizer.procs.clearStencil(c, s); 632} 633