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