1 /* libs/pixelflinger/pixelflinger.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 19 #include <stdlib.h> 20 #include <string.h> 21 #include <assert.h> 22 23 #include <sys/time.h> 24 25 #include <pixelflinger/pixelflinger.h> 26 #include <private/pixelflinger/ggl_context.h> 27 28 #include "buffer.h" 29 #include "clear.h" 30 #include "picker.h" 31 #include "raster.h" 32 #include "scanline.h" 33 #include "trap.h" 34 35 #include "codeflinger/GGLAssembler.h" 36 #include "codeflinger/CodeCache.h" 37 38 #include <stdio.h> 39 40 41 namespace android { 42 43 // ---------------------------------------------------------------------------- 44 45 // 8x8 Bayer dither matrix 46 static const uint8_t gDitherMatrix[GGL_DITHER_SIZE] = { 47 0, 32, 8, 40, 2, 34, 10, 42, 48 48, 16, 56, 24, 50, 18, 58, 26, 49 12, 44, 4, 36, 14, 46, 6, 38, 50 60, 28, 52, 20, 62, 30, 54, 22, 51 3, 35, 11, 43, 1, 33, 9, 41, 52 51, 19, 59, 27, 49, 17, 57, 25, 53 15, 47, 7, 39, 13, 45, 5, 37, 54 63, 31, 55, 23, 61, 29, 53, 21 55 }; 56 57 static void ggl_init_procs(context_t* c); 58 static void ggl_set_scissor(context_t* c); 59 60 static void ggl_enable_blending(context_t* c, int enable); 61 static void ggl_enable_scissor_test(context_t* c, int enable); 62 static void ggl_enable_alpha_test(context_t* c, int enable); 63 static void ggl_enable_logic_op(context_t* c, int enable); 64 static void ggl_enable_dither(context_t* c, int enable); 65 static void ggl_enable_stencil_test(context_t* c, int enable); 66 static void ggl_enable_depth_test(context_t* c, int enable); 67 static void ggl_enable_aa(context_t* c, int enable); 68 static void ggl_enable_point_aa_nice(context_t* c, int enable); 69 static void ggl_enable_texture2d(context_t* c, int enable); 70 static void ggl_enable_w_lerp(context_t* c, int enable); 71 static void ggl_enable_fog(context_t* c, int enable); 72 73 static inline int min(int a, int b) CONST; 74 static inline int min(int a, int b) { 75 return a < b ? a : b; 76 } 77 78 static inline int max(int a, int b) CONST; 79 static inline int max(int a, int b) { 80 return a < b ? b : a; 81 } 82 83 // ---------------------------------------------------------------------------- 84 85 void ggl_error(context_t* c, GGLenum error) 86 { 87 if (c->error == GGL_NO_ERROR) 88 c->error = error; 89 } 90 91 // ---------------------------------------------------------------------------- 92 93 static void ggl_bindTexture(void* con, const GGLSurface* surface) 94 { 95 GGL_CONTEXT(c, con); 96 if (surface->format != c->activeTMU->surface.format) 97 ggl_state_changed(c, GGL_TMU_STATE); 98 ggl_set_surface(c, &(c->activeTMU->surface), surface); 99 } 100 101 102 static void ggl_bindTextureLod(void* con, GGLuint tmu,const GGLSurface* surface) 103 { 104 GGL_CONTEXT(c, con); 105 // All LODs must have the same format 106 ggl_set_surface(c, &c->state.texture[tmu].surface, surface); 107 } 108 109 static void ggl_colorBuffer(void* con, const GGLSurface* surface) 110 { 111 GGL_CONTEXT(c, con); 112 if (surface->format != c->state.buffers.color.format) 113 ggl_state_changed(c, GGL_CB_STATE); 114 115 if (surface->width > c->state.buffers.coverageBufferSize) { 116 // allocate the coverage factor buffer 117 free(c->state.buffers.coverage); 118 c->state.buffers.coverage = (int16_t*)malloc(surface->width * 2); 119 c->state.buffers.coverageBufferSize = 120 c->state.buffers.coverage ? surface->width : 0; 121 } 122 ggl_set_surface(c, &(c->state.buffers.color), surface); 123 if (c->state.buffers.read.format == 0) { 124 ggl_set_surface(c, &(c->state.buffers.read), surface); 125 } 126 ggl_set_scissor(c); 127 } 128 129 static void ggl_readBuffer(void* con, const GGLSurface* surface) 130 { 131 GGL_CONTEXT(c, con); 132 ggl_set_surface(c, &(c->state.buffers.read), surface); 133 } 134 135 static void ggl_depthBuffer(void* con, const GGLSurface* surface) 136 { 137 GGL_CONTEXT(c, con); 138 if (surface->format == GGL_PIXEL_FORMAT_Z_16) { 139 ggl_set_surface(c, &(c->state.buffers.depth), surface); 140 } else { 141 c->state.buffers.depth.format = GGL_PIXEL_FORMAT_NONE; 142 ggl_enable_depth_test(c, 0); 143 } 144 } 145 146 static void ggl_scissor(void* con, GGLint x, GGLint y, 147 GGLsizei width, GGLsizei height) 148 { 149 GGL_CONTEXT(c, con); 150 c->state.scissor.user_left = x; 151 c->state.scissor.user_top = y; 152 c->state.scissor.user_right = x + width; 153 c->state.scissor.user_bottom = y + height; 154 ggl_set_scissor(c); 155 } 156 157 // ---------------------------------------------------------------------------- 158 159 static void enable_disable(context_t* c, GGLenum name, int en) 160 { 161 switch (name) { 162 case GGL_BLEND: ggl_enable_blending(c, en); break; 163 case GGL_SCISSOR_TEST: ggl_enable_scissor_test(c, en); break; 164 case GGL_ALPHA_TEST: ggl_enable_alpha_test(c, en); break; 165 case GGL_COLOR_LOGIC_OP: ggl_enable_logic_op(c, en); break; 166 case GGL_DITHER: ggl_enable_dither(c, en); break; 167 case GGL_STENCIL_TEST: ggl_enable_stencil_test(c, en); break; 168 case GGL_DEPTH_TEST: ggl_enable_depth_test(c, en); break; 169 case GGL_AA: ggl_enable_aa(c, en); break; 170 case GGL_TEXTURE_2D: ggl_enable_texture2d(c, en); break; 171 case GGL_W_LERP: ggl_enable_w_lerp(c, en); break; 172 case GGL_FOG: ggl_enable_fog(c, en); break; 173 case GGL_POINT_SMOOTH_NICE: ggl_enable_point_aa_nice(c, en); break; 174 } 175 } 176 177 static void ggl_enable(void* con, GGLenum name) 178 { 179 GGL_CONTEXT(c, con); 180 enable_disable(c, name, 1); 181 } 182 183 static void ggl_disable(void* con, GGLenum name) 184 { 185 GGL_CONTEXT(c, con); 186 enable_disable(c, name, 0); 187 } 188 189 static void ggl_enableDisable(void* con, GGLenum name, GGLboolean en) 190 { 191 GGL_CONTEXT(c, con); 192 enable_disable(c, name, en ? 1 : 0); 193 } 194 195 // ---------------------------------------------------------------------------- 196 197 static void ggl_shadeModel(void* con, GGLenum mode) 198 { 199 GGL_CONTEXT(c, con); 200 switch (mode) { 201 case GGL_FLAT: 202 if (c->state.enables & GGL_ENABLE_SMOOTH) { 203 c->state.enables &= ~GGL_ENABLE_SMOOTH; 204 ggl_state_changed(c, GGL_PIXEL_PIPELINE_STATE); 205 } 206 break; 207 case GGL_SMOOTH: 208 if (!(c->state.enables & GGL_ENABLE_SMOOTH)) { 209 c->state.enables |= GGL_ENABLE_SMOOTH; 210 ggl_state_changed(c, GGL_PIXEL_PIPELINE_STATE); 211 } 212 break; 213 default: 214 ggl_error(c, GGL_INVALID_ENUM); 215 } 216 } 217 218 static void ggl_color4xv(void* con, const GGLclampx* color) 219 { 220 GGL_CONTEXT(c, con); 221 c->shade.r0 = gglFixedToIteratedColor(color[0]); 222 c->shade.g0 = gglFixedToIteratedColor(color[1]); 223 c->shade.b0 = gglFixedToIteratedColor(color[2]); 224 c->shade.a0 = gglFixedToIteratedColor(color[3]); 225 } 226 227 static void ggl_colorGrad12xv(void* con, const GGLcolor* grad) 228 { 229 GGL_CONTEXT(c, con); 230 // it is very important to round the iterated value here because 231 // the rasterizer doesn't clamp them, therefore the iterated value 232 //must absolutely be correct. 233 // GGLColor is encoded as 8.16 value 234 const int32_t round = 0x8000; 235 c->shade.r0 = grad[ 0] + round; 236 c->shade.drdx = grad[ 1]; 237 c->shade.drdy = grad[ 2]; 238 c->shade.g0 = grad[ 3] + round; 239 c->shade.dgdx = grad[ 4]; 240 c->shade.dgdy = grad[ 5]; 241 c->shade.b0 = grad[ 6] + round; 242 c->shade.dbdx = grad[ 7]; 243 c->shade.dbdy = grad[ 8]; 244 c->shade.a0 = grad[ 9] + round; 245 c->shade.dadx = grad[10]; 246 c->shade.dady = grad[11]; 247 } 248 249 static void ggl_zGrad3xv(void* con, const GGLfixed32* grad) 250 { 251 GGL_CONTEXT(c, con); 252 // z iterators are encoded as 0.32 fixed point and the z-buffer 253 // holds 16 bits, the rounding value is 0x8000. 254 const uint32_t round = 0x8000; 255 c->shade.z0 = grad[0] + round; 256 c->shade.dzdx = grad[1]; 257 c->shade.dzdy = grad[2]; 258 } 259 260 static void ggl_wGrad3xv(void* con, const GGLfixed* grad) 261 { 262 GGL_CONTEXT(c, con); 263 c->shade.w0 = grad[0]; 264 c->shade.dwdx = grad[1]; 265 c->shade.dwdy = grad[2]; 266 } 267 268 // ---------------------------------------------------------------------------- 269 270 static void ggl_fogGrad3xv(void* con, const GGLfixed* grad) 271 { 272 GGL_CONTEXT(c, con); 273 c->shade.f0 = grad[0]; 274 c->shade.dfdx = grad[1]; 275 c->shade.dfdy = grad[2]; 276 } 277 278 static void ggl_fogColor3xv(void* con, const GGLclampx* color) 279 { 280 GGL_CONTEXT(c, con); 281 const int32_t r = gglClampx(color[0]); 282 const int32_t g = gglClampx(color[1]); 283 const int32_t b = gglClampx(color[2]); 284 c->state.fog.color[GGLFormat::ALPHA]= 0xFF; // unused 285 c->state.fog.color[GGLFormat::RED] = (r - (r>>8))>>8; 286 c->state.fog.color[GGLFormat::GREEN]= (g - (g>>8))>>8; 287 c->state.fog.color[GGLFormat::BLUE] = (b - (b>>8))>>8; 288 } 289 290 static void ggl_enable_fog(context_t* c, int enable) 291 { 292 const int e = (c->state.enables & GGL_ENABLE_FOG)?1:0; 293 if (e != enable) { 294 if (enable) c->state.enables |= GGL_ENABLE_FOG; 295 else c->state.enables &= ~GGL_ENABLE_FOG; 296 ggl_state_changed(c, GGL_PIXEL_PIPELINE_STATE); 297 } 298 } 299 300 // ---------------------------------------------------------------------------- 301 302 static void ggl_blendFunc(void* con, GGLenum src, GGLenum dst) 303 { 304 GGL_CONTEXT(c, con); 305 c->state.blend.src = src; 306 c->state.blend.src_alpha = src; 307 c->state.blend.dst = dst; 308 c->state.blend.dst_alpha = dst; 309 c->state.blend.alpha_separate = 0; 310 if (c->state.enables & GGL_ENABLE_BLENDING) { 311 ggl_state_changed(c, GGL_PIXEL_PIPELINE_STATE); 312 } 313 } 314 315 static void ggl_blendFuncSeparate(void* con, 316 GGLenum src, GGLenum dst, 317 GGLenum srcAlpha, GGLenum dstAplha) 318 { 319 GGL_CONTEXT(c, con); 320 c->state.blend.src = src; 321 c->state.blend.src_alpha = srcAlpha; 322 c->state.blend.dst = dst; 323 c->state.blend.dst_alpha = dstAplha; 324 c->state.blend.alpha_separate = 1; 325 if (c->state.enables & GGL_ENABLE_BLENDING) { 326 ggl_state_changed(c, GGL_PIXEL_PIPELINE_STATE); 327 } 328 } 329 330 // ---------------------------------------------------------------------------- 331 332 static void ggl_texEnvi(void* con, GGLenum target, 333 GGLenum pname, 334 GGLint param) 335 { 336 GGL_CONTEXT(c, con); 337 if (target != GGL_TEXTURE_ENV || pname != GGL_TEXTURE_ENV_MODE) { 338 ggl_error(c, GGL_INVALID_ENUM); 339 return; 340 } 341 switch (param) { 342 case GGL_REPLACE: 343 case GGL_MODULATE: 344 case GGL_DECAL: 345 case GGL_BLEND: 346 case GGL_ADD: 347 if (c->activeTMU->env != param) { 348 c->activeTMU->env = param; 349 ggl_state_changed(c, GGL_TMU_STATE); 350 } 351 break; 352 default: 353 ggl_error(c, GGL_INVALID_ENUM); 354 } 355 } 356 357 static void ggl_texEnvxv(void* con, GGLenum target, 358 GGLenum pname, const GGLfixed* params) 359 { 360 GGL_CONTEXT(c, con); 361 if (target != GGL_TEXTURE_ENV) { 362 ggl_error(c, GGL_INVALID_ENUM); 363 return; 364 } 365 switch (pname) { 366 case GGL_TEXTURE_ENV_MODE: 367 ggl_texEnvi(con, target, pname, params[0]); 368 break; 369 case GGL_TEXTURE_ENV_COLOR: { 370 uint8_t* const color = c->activeTMU->env_color; 371 const GGLclampx r = gglClampx(params[0]); 372 const GGLclampx g = gglClampx(params[1]); 373 const GGLclampx b = gglClampx(params[2]); 374 const GGLclampx a = gglClampx(params[3]); 375 color[0] = (a-(a>>8))>>8; 376 color[1] = (r-(r>>8))>>8; 377 color[2] = (g-(g>>8))>>8; 378 color[3] = (b-(b>>8))>>8; 379 break; 380 } 381 default: 382 ggl_error(c, GGL_INVALID_ENUM); 383 return; 384 } 385 } 386 387 388 static void ggl_texParameteri(void* con, 389 GGLenum target, 390 GGLenum pname, 391 GGLint param) 392 { 393 GGL_CONTEXT(c, con); 394 if (target != GGL_TEXTURE_2D) { 395 ggl_error(c, GGL_INVALID_ENUM); 396 return; 397 } 398 399 if (param == GGL_CLAMP_TO_EDGE) 400 param = GGL_CLAMP; 401 402 uint16_t* what = 0; 403 switch (pname) { 404 case GGL_TEXTURE_WRAP_S: 405 if ((param == GGL_CLAMP) || 406 (param == GGL_REPEAT)) { 407 what = &c->activeTMU->s_wrap; 408 } 409 break; 410 case GGL_TEXTURE_WRAP_T: 411 if ((param == GGL_CLAMP) || 412 (param == GGL_REPEAT)) { 413 what = &c->activeTMU->t_wrap; 414 } 415 break; 416 case GGL_TEXTURE_MIN_FILTER: 417 if ((param == GGL_NEAREST) || 418 (param == GGL_NEAREST_MIPMAP_NEAREST) || 419 (param == GGL_NEAREST_MIPMAP_LINEAR)) { 420 what = &c->activeTMU->min_filter; 421 param = GGL_NEAREST; 422 } 423 if ((param == GGL_LINEAR) || 424 (param == GGL_LINEAR_MIPMAP_NEAREST) || 425 (param == GGL_LINEAR_MIPMAP_LINEAR)) { 426 what = &c->activeTMU->min_filter; 427 param = GGL_LINEAR; 428 } 429 break; 430 case GGL_TEXTURE_MAG_FILTER: 431 if ((param == GGL_NEAREST) || 432 (param == GGL_LINEAR)) { 433 what = &c->activeTMU->mag_filter; 434 } 435 break; 436 } 437 438 if (!what) { 439 ggl_error(c, GGL_INVALID_ENUM); 440 return; 441 } 442 443 if (*what != param) { 444 *what = param; 445 ggl_state_changed(c, GGL_TMU_STATE); 446 } 447 } 448 449 static void ggl_texCoordGradScale8xv(void* con, GGLint tmu, const int32_t* grad) 450 { 451 GGL_CONTEXT(c, con); 452 texture_t& u = c->state.texture[tmu]; 453 u.shade.is0 = grad[0]; 454 u.shade.idsdx = grad[1]; 455 u.shade.idsdy = grad[2]; 456 u.shade.it0 = grad[3]; 457 u.shade.idtdx = grad[4]; 458 u.shade.idtdy = grad[5]; 459 u.shade.sscale= grad[6]; 460 u.shade.tscale= grad[7]; 461 } 462 463 static void ggl_texCoord2x(void* con, GGLfixed s, GGLfixed t) 464 { 465 GGL_CONTEXT(c, con); 466 c->activeTMU->shade.is0 = s; 467 c->activeTMU->shade.it0 = t; 468 c->activeTMU->shade.sscale= 0; 469 c->activeTMU->shade.tscale= 0; 470 } 471 472 static void ggl_texCoord2i(void* con, GGLint s, GGLint t) 473 { 474 ggl_texCoord2x(con, s<<16, t<<16); 475 } 476 477 static void ggl_texGeni(void* con, GGLenum coord, GGLenum pname, GGLint param) 478 { 479 GGL_CONTEXT(c, con); 480 if (pname != GGL_TEXTURE_GEN_MODE) { 481 ggl_error(c, GGL_INVALID_ENUM); 482 return; 483 } 484 485 uint32_t* coord_ptr = 0; 486 if (coord == GGL_S) coord_ptr = &(c->activeTMU->s_coord); 487 else if (coord == GGL_T) coord_ptr = &(c->activeTMU->t_coord); 488 489 if (coord_ptr) { 490 if (*coord_ptr != uint32_t(param)) { 491 *coord_ptr = uint32_t(param); 492 ggl_state_changed(c, GGL_TMU_STATE); 493 } 494 } else { 495 ggl_error(c, GGL_INVALID_ENUM); 496 } 497 } 498 499 static void ggl_activeTexture(void* con, GGLuint tmu) 500 { 501 GGL_CONTEXT(c, con); 502 if (tmu >= GGLuint(GGL_TEXTURE_UNIT_COUNT)) { 503 ggl_error(c, GGL_INVALID_ENUM); 504 return; 505 } 506 c->activeTMUIndex = tmu; 507 c->activeTMU = &(c->state.texture[tmu]); 508 } 509 510 // ---------------------------------------------------------------------------- 511 512 static void ggl_colorMask(void* con, GGLboolean r, 513 GGLboolean g, 514 GGLboolean b, 515 GGLboolean a) 516 { 517 GGL_CONTEXT(c, con); 518 int mask = 0; 519 if (a) mask |= 1 << GGLFormat::ALPHA; 520 if (r) mask |= 1 << GGLFormat::RED; 521 if (g) mask |= 1 << GGLFormat::GREEN; 522 if (b) mask |= 1 << GGLFormat::BLUE; 523 if (c->state.mask.color != mask) { 524 c->state.mask.color = mask; 525 ggl_state_changed(c, GGL_PIXEL_PIPELINE_STATE); 526 } 527 } 528 529 static void ggl_depthMask(void* con, GGLboolean flag) 530 { 531 GGL_CONTEXT(c, con); 532 if (c->state.mask.depth != flag?1:0) { 533 c->state.mask.depth = flag?1:0; 534 ggl_state_changed(c, GGL_PIXEL_PIPELINE_STATE); 535 } 536 } 537 538 static void ggl_stencilMask(void* con, GGLuint mask) 539 { 540 GGL_CONTEXT(c, con); 541 if (c->state.mask.stencil != mask) { 542 c->state.mask.stencil = mask; 543 ggl_state_changed(c, GGL_PIXEL_PIPELINE_STATE); 544 } 545 } 546 547 // ---------------------------------------------------------------------------- 548 549 static void ggl_alphaFuncx(void* con, GGLenum func, GGLclampx ref) 550 { 551 GGL_CONTEXT(c, con); 552 if ((func < GGL_NEVER) || (func > GGL_ALWAYS)) { 553 ggl_error(c, GGL_INVALID_ENUM); 554 return; 555 } 556 c->state.alpha_test.ref = gglFixedToIteratedColor(gglClampx(ref)); 557 if (c->state.alpha_test.func != func) { 558 c->state.alpha_test.func = func; 559 ggl_state_changed(c, GGL_PIXEL_PIPELINE_STATE); 560 } 561 } 562 563 // ---------------------------------------------------------------------------- 564 565 static void ggl_depthFunc(void* con, GGLenum func) 566 { 567 GGL_CONTEXT(c, con); 568 if ((func < GGL_NEVER) || (func > GGL_ALWAYS)) { 569 ggl_error(c, GGL_INVALID_ENUM); 570 return; 571 } 572 if (c->state.depth_test.func != func) { 573 c->state.depth_test.func = func; 574 ggl_state_changed(c, GGL_PIXEL_PIPELINE_STATE); 575 } 576 } 577 578 // ---------------------------------------------------------------------------- 579 580 static void ggl_logicOp(void* con, GGLenum opcode) 581 { 582 GGL_CONTEXT(c, con); 583 if ((opcode < GGL_CLEAR) || (opcode > GGL_SET)) { 584 ggl_error(c, GGL_INVALID_ENUM); 585 return; 586 } 587 if (c->state.logic_op.opcode != opcode) { 588 c->state.logic_op.opcode = opcode; 589 ggl_state_changed(c, GGL_PIXEL_PIPELINE_STATE); 590 } 591 } 592 593 594 // ---------------------------------------------------------------------------- 595 596 void ggl_set_scissor(context_t* c) 597 { 598 if (c->state.enables & GGL_ENABLE_SCISSOR_TEST) { 599 const int32_t l = c->state.scissor.user_left; 600 const int32_t t = c->state.scissor.user_top; 601 const int32_t r = c->state.scissor.user_right; 602 const int32_t b = c->state.scissor.user_bottom; 603 c->state.scissor.left = max(0, l); 604 c->state.scissor.right = min(c->state.buffers.color.width, r); 605 c->state.scissor.top = max(0, t); 606 c->state.scissor.bottom = min(c->state.buffers.color.height, b); 607 } else { 608 c->state.scissor.left = 0; 609 c->state.scissor.top = 0; 610 c->state.scissor.right = c->state.buffers.color.width; 611 c->state.scissor.bottom = c->state.buffers.color.height; 612 } 613 } 614 615 void ggl_enable_blending(context_t* c, int enable) 616 { 617 const int e = (c->state.enables & GGL_ENABLE_BLENDING)?1:0; 618 if (e != enable) { 619 if (enable) c->state.enables |= GGL_ENABLE_BLENDING; 620 else c->state.enables &= ~GGL_ENABLE_BLENDING; 621 ggl_state_changed(c, GGL_PIXEL_PIPELINE_STATE); 622 } 623 } 624 625 void ggl_enable_scissor_test(context_t* c, int enable) 626 { 627 const int e = (c->state.enables & GGL_ENABLE_SCISSOR_TEST)?1:0; 628 if (e != enable) { 629 if (enable) c->state.enables |= GGL_ENABLE_SCISSOR_TEST; 630 else c->state.enables &= ~GGL_ENABLE_SCISSOR_TEST; 631 ggl_set_scissor(c); 632 } 633 } 634 635 void ggl_enable_alpha_test(context_t* c, int enable) 636 { 637 const int e = (c->state.enables & GGL_ENABLE_ALPHA_TEST)?1:0; 638 if (e != enable) { 639 if (enable) c->state.enables |= GGL_ENABLE_ALPHA_TEST; 640 else c->state.enables &= ~GGL_ENABLE_ALPHA_TEST; 641 ggl_state_changed(c, GGL_PIXEL_PIPELINE_STATE); 642 } 643 } 644 645 void ggl_enable_logic_op(context_t* c, int enable) 646 { 647 const int e = (c->state.enables & GGL_ENABLE_LOGIC_OP)?1:0; 648 if (e != enable) { 649 if (enable) c->state.enables |= GGL_ENABLE_LOGIC_OP; 650 else c->state.enables &= ~GGL_ENABLE_LOGIC_OP; 651 ggl_state_changed(c, GGL_PIXEL_PIPELINE_STATE); 652 } 653 } 654 655 void ggl_enable_dither(context_t* c, int enable) 656 { 657 const int e = (c->state.enables & GGL_ENABLE_DITHER)?1:0; 658 if (e != enable) { 659 if (enable) c->state.enables |= GGL_ENABLE_DITHER; 660 else c->state.enables &= ~GGL_ENABLE_DITHER; 661 ggl_state_changed(c, GGL_PIXEL_PIPELINE_STATE); 662 } 663 } 664 665 void ggl_enable_stencil_test(context_t* /*c*/, int /*enable*/) 666 { 667 } 668 669 void ggl_enable_depth_test(context_t* c, int enable) 670 { 671 if (c->state.buffers.depth.format == 0) 672 enable = 0; 673 const int e = (c->state.enables & GGL_ENABLE_DEPTH_TEST)?1:0; 674 if (e != enable) { 675 if (enable) c->state.enables |= GGL_ENABLE_DEPTH_TEST; 676 else c->state.enables &= ~GGL_ENABLE_DEPTH_TEST; 677 ggl_state_changed(c, GGL_PIXEL_PIPELINE_STATE); 678 } 679 } 680 681 void ggl_enable_aa(context_t* c, int enable) 682 { 683 const int e = (c->state.enables & GGL_ENABLE_AA)?1:0; 684 if (e != enable) { 685 if (enable) c->state.enables |= GGL_ENABLE_AA; 686 else c->state.enables &= ~GGL_ENABLE_AA; 687 ggl_state_changed(c, GGL_PIXEL_PIPELINE_STATE); 688 } 689 } 690 691 void ggl_enable_point_aa_nice(context_t* c, int enable) 692 { 693 const int e = (c->state.enables & GGL_ENABLE_POINT_AA_NICE)?1:0; 694 if (e != enable) { 695 if (enable) c->state.enables |= GGL_ENABLE_POINT_AA_NICE; 696 else c->state.enables &= ~GGL_ENABLE_POINT_AA_NICE; 697 ggl_state_changed(c, GGL_PIXEL_PIPELINE_STATE); 698 } 699 } 700 701 void ggl_enable_w_lerp(context_t* c, int enable) 702 { 703 const int e = (c->state.enables & GGL_ENABLE_W)?1:0; 704 if (e != enable) { 705 if (enable) c->state.enables |= GGL_ENABLE_W; 706 else c->state.enables &= ~GGL_ENABLE_W; 707 ggl_state_changed(c, GGL_PIXEL_PIPELINE_STATE); 708 } 709 } 710 711 void ggl_enable_texture2d(context_t* c, int enable) 712 { 713 if (c->activeTMU->enable != enable) { 714 const uint32_t tmu = c->activeTMUIndex; 715 c->activeTMU->enable = enable; 716 const uint32_t mask = 1UL << tmu; 717 if (enable) c->state.enabled_tmu |= mask; 718 else c->state.enabled_tmu &= ~mask; 719 if (c->state.enabled_tmu) c->state.enables |= GGL_ENABLE_TMUS; 720 else c->state.enables &= ~GGL_ENABLE_TMUS; 721 ggl_state_changed(c, GGL_TMU_STATE); 722 } 723 } 724 725 726 // ---------------------------------------------------------------------------- 727 728 int64_t ggl_system_time() 729 { 730 struct timespec t; 731 t.tv_sec = t.tv_nsec = 0; 732 clock_gettime(CLOCK_THREAD_CPUTIME_ID, &t); 733 return int64_t(t.tv_sec)*1000000000LL + t.tv_nsec; 734 } 735 736 // ---------------------------------------------------------------------------- 737 738 void ggl_init_procs(context_t* c) 739 { 740 GGLContext& procs = *(GGLContext*)c; 741 GGL_INIT_PROC(procs, scissor); 742 GGL_INIT_PROC(procs, activeTexture); 743 GGL_INIT_PROC(procs, bindTexture); 744 GGL_INIT_PROC(procs, bindTextureLod); 745 GGL_INIT_PROC(procs, colorBuffer); 746 GGL_INIT_PROC(procs, readBuffer); 747 GGL_INIT_PROC(procs, depthBuffer); 748 GGL_INIT_PROC(procs, enable); 749 GGL_INIT_PROC(procs, disable); 750 GGL_INIT_PROC(procs, enableDisable); 751 GGL_INIT_PROC(procs, shadeModel); 752 GGL_INIT_PROC(procs, color4xv); 753 GGL_INIT_PROC(procs, colorGrad12xv); 754 GGL_INIT_PROC(procs, zGrad3xv); 755 GGL_INIT_PROC(procs, wGrad3xv); 756 GGL_INIT_PROC(procs, fogGrad3xv); 757 GGL_INIT_PROC(procs, fogColor3xv); 758 GGL_INIT_PROC(procs, blendFunc); 759 GGL_INIT_PROC(procs, blendFuncSeparate); 760 GGL_INIT_PROC(procs, texEnvi); 761 GGL_INIT_PROC(procs, texEnvxv); 762 GGL_INIT_PROC(procs, texParameteri); 763 GGL_INIT_PROC(procs, texCoord2i); 764 GGL_INIT_PROC(procs, texCoord2x); 765 GGL_INIT_PROC(procs, texCoordGradScale8xv); 766 GGL_INIT_PROC(procs, texGeni); 767 GGL_INIT_PROC(procs, colorMask); 768 GGL_INIT_PROC(procs, depthMask); 769 GGL_INIT_PROC(procs, stencilMask); 770 GGL_INIT_PROC(procs, alphaFuncx); 771 GGL_INIT_PROC(procs, depthFunc); 772 GGL_INIT_PROC(procs, logicOp); 773 ggl_init_clear(c); 774 } 775 776 void ggl_init_context(context_t* c) 777 { 778 memset(c, 0, sizeof(context_t)); 779 ggl_init_procs(c); 780 ggl_init_trap(c); 781 ggl_init_scanline(c); 782 ggl_init_texture(c); 783 ggl_init_picker(c); 784 ggl_init_raster(c); 785 c->formats = gglGetPixelFormatTable(); 786 c->state.blend.src = GGL_ONE; 787 c->state.blend.dst = GGL_ZERO; 788 c->state.blend.src_alpha = GGL_ONE; 789 c->state.blend.dst_alpha = GGL_ZERO; 790 c->state.mask.color = 0xF; 791 c->state.mask.depth = 0; 792 c->state.mask.stencil = 0xFFFFFFFF; 793 c->state.logic_op.opcode = GGL_COPY; 794 c->state.alpha_test.func = GGL_ALWAYS; 795 c->state.depth_test.func = GGL_LESS; 796 c->state.depth_test.clearValue = FIXED_ONE; 797 c->shade.w0 = FIXED_ONE; 798 memcpy(c->ditherMatrix, gDitherMatrix, sizeof(gDitherMatrix)); 799 } 800 801 void ggl_uninit_context(context_t* c) 802 { 803 ggl_uninit_scanline(c); 804 } 805 806 // ---------------------------------------------------------------------------- 807 }; // namespace android 808 // ---------------------------------------------------------------------------- 809 810 811 812 using namespace android; 813 814 ssize_t gglInit(GGLContext** context) 815 { 816 void* const base = malloc(sizeof(context_t) + 32); 817 if (base) { 818 // always align the context on cache lines 819 context_t *c = (context_t *)((ptrdiff_t(base)+31) & ~0x1FL); 820 ggl_init_context(c); 821 c->base = base; 822 *context = (GGLContext*)c; 823 } else { 824 return -1; 825 } 826 return 0; 827 } 828 829 ssize_t gglUninit(GGLContext* con) 830 { 831 GGL_CONTEXT(c, (void*)con); 832 ggl_uninit_context(c); 833 free(c->base); 834 return 0; 835 } 836 837