pixelflinger.cpp revision dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0
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 41namespace android { 42 43// ---------------------------------------------------------------------------- 44 45// 8x8 Bayer dither matrix 46static 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 57static void ggl_init_procs(context_t* c); 58static void ggl_set_scissor(context_t* c); 59 60static void ggl_enable_blending(context_t* c, int enable); 61static void ggl_enable_scissor_test(context_t* c, int enable); 62static void ggl_enable_alpha_test(context_t* c, int enable); 63static void ggl_enable_logic_op(context_t* c, int enable); 64static void ggl_enable_dither(context_t* c, int enable); 65static void ggl_enable_stencil_test(context_t* c, int enable); 66static void ggl_enable_depth_test(context_t* c, int enable); 67static void ggl_enable_aa(context_t* c, int enable); 68static void ggl_enable_point_aa_nice(context_t* c, int enable); 69static void ggl_enable_texture2d(context_t* c, int enable); 70static void ggl_enable_w_lerp(context_t* c, int enable); 71static void ggl_enable_fog(context_t* c, int enable); 72 73static inline int min(int a, int b) CONST; 74static inline int min(int a, int b) { 75 return a < b ? a : b; 76} 77 78static inline int max(int a, int b) CONST; 79static inline int max(int a, int b) { 80 return a < b ? b : a; 81} 82 83// ---------------------------------------------------------------------------- 84 85void ggl_error(context_t* c, GGLenum error) 86{ 87 if (c->error == GGL_NO_ERROR) 88 c->error = error; 89} 90 91// ---------------------------------------------------------------------------- 92 93static 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 102static 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 109static 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 129static 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 135static 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 146static 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 159static 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 177static void ggl_enable(void* con, GGLenum name) 178{ 179 GGL_CONTEXT(c, con); 180 enable_disable(c, name, 1); 181} 182 183static void ggl_disable(void* con, GGLenum name) 184{ 185 GGL_CONTEXT(c, con); 186 enable_disable(c, name, 0); 187} 188 189static 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 197static 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 218static 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 227static 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 249static 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 260static 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 270static 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 278static 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::RED] = (r - (r>>8))>>8; 285 c->state.fog.color[GGLFormat::GREEN]= (g - (g>>8))>>8; 286 c->state.fog.color[GGLFormat::BLUE] = (b - (b>>8))>>8; 287} 288 289static void ggl_enable_fog(context_t* c, int enable) 290{ 291 const int e = (c->state.enables & GGL_ENABLE_FOG)?1:0; 292 if (e != enable) { 293 if (enable) c->state.enables |= GGL_ENABLE_FOG; 294 else c->state.enables &= ~GGL_ENABLE_FOG; 295 ggl_state_changed(c, GGL_PIXEL_PIPELINE_STATE); 296 } 297} 298 299// ---------------------------------------------------------------------------- 300 301static void ggl_blendFunc(void* con, GGLenum src, GGLenum dst) 302{ 303 GGL_CONTEXT(c, con); 304 c->state.blend.src = src; 305 c->state.blend.src_alpha = src; 306 c->state.blend.dst = dst; 307 c->state.blend.dst_alpha = dst; 308 c->state.blend.alpha_separate = 0; 309 if (c->state.enables & GGL_ENABLE_BLENDING) { 310 ggl_state_changed(c, GGL_PIXEL_PIPELINE_STATE); 311 } 312} 313 314static void ggl_blendFuncSeparate(void* con, 315 GGLenum src, GGLenum dst, 316 GGLenum srcAlpha, GGLenum dstAplha) 317{ 318 GGL_CONTEXT(c, con); 319 c->state.blend.src = src; 320 c->state.blend.src_alpha = srcAlpha; 321 c->state.blend.dst = dst; 322 c->state.blend.dst_alpha = dstAplha; 323 c->state.blend.alpha_separate = 1; 324 if (c->state.enables & GGL_ENABLE_BLENDING) { 325 ggl_state_changed(c, GGL_PIXEL_PIPELINE_STATE); 326 } 327} 328 329// ---------------------------------------------------------------------------- 330 331static void ggl_texEnvi(void* con, GGLenum target, 332 GGLenum pname, 333 GGLint param) 334{ 335 GGL_CONTEXT(c, con); 336 if (target != GGL_TEXTURE_ENV || pname != GGL_TEXTURE_ENV_MODE) { 337 ggl_error(c, GGL_INVALID_ENUM); 338 return; 339 } 340 switch (param) { 341 case GGL_REPLACE: 342 case GGL_MODULATE: 343 case GGL_DECAL: 344 case GGL_BLEND: 345 case GGL_ADD: 346 if (c->activeTMU->env != param) { 347 c->activeTMU->env = param; 348 ggl_state_changed(c, GGL_TMU_STATE); 349 } 350 break; 351 default: 352 ggl_error(c, GGL_INVALID_ENUM); 353 } 354} 355 356static void ggl_texEnvxv(void* con, GGLenum target, 357 GGLenum pname, const GGLfixed* params) 358{ 359 GGL_CONTEXT(c, con); 360 if (target != GGL_TEXTURE_ENV) { 361 ggl_error(c, GGL_INVALID_ENUM); 362 return; 363 } 364 switch (pname) { 365 case GGL_TEXTURE_ENV_MODE: 366 ggl_texEnvi(con, target, pname, params[0]); 367 break; 368 case GGL_TEXTURE_ENV_COLOR: { 369 uint8_t* const color = c->activeTMU->env_color; 370 const GGLclampx r = gglClampx(params[0]); 371 const GGLclampx g = gglClampx(params[1]); 372 const GGLclampx b = gglClampx(params[2]); 373 const GGLclampx a = gglClampx(params[3]); 374 color[0] = (a-(a>>8))>>8; 375 color[1] = (r-(r>>8))>>8; 376 color[2] = (g-(g>>8))>>8; 377 color[3] = (b-(b>>8))>>8; 378 break; 379 } 380 default: 381 ggl_error(c, GGL_INVALID_ENUM); 382 return; 383 } 384} 385 386 387static void ggl_texParameteri(void* con, 388 GGLenum target, 389 GGLenum pname, 390 GGLint param) 391{ 392 GGL_CONTEXT(c, con); 393 if (target != GGL_TEXTURE_2D) { 394 ggl_error(c, GGL_INVALID_ENUM); 395 return; 396 } 397 398 if (param == GGL_CLAMP_TO_EDGE) 399 param = GGL_CLAMP; 400 401 uint16_t* what = 0; 402 switch (pname) { 403 case GGL_TEXTURE_WRAP_S: 404 if ((param == GGL_CLAMP) || 405 (param == GGL_REPEAT)) { 406 what = &c->activeTMU->s_wrap; 407 } 408 break; 409 case GGL_TEXTURE_WRAP_T: 410 if ((param == GGL_CLAMP) || 411 (param == GGL_REPEAT)) { 412 what = &c->activeTMU->t_wrap; 413 } 414 break; 415 case GGL_TEXTURE_MIN_FILTER: 416 if ((param == GGL_NEAREST) || 417 (param == GGL_NEAREST_MIPMAP_NEAREST) || 418 (param == GGL_NEAREST_MIPMAP_LINEAR)) { 419 what = &c->activeTMU->min_filter; 420 param = GGL_NEAREST; 421 } 422 if ((param == GGL_LINEAR) || 423 (param == GGL_LINEAR_MIPMAP_NEAREST) || 424 (param == GGL_LINEAR_MIPMAP_LINEAR)) { 425 what = &c->activeTMU->min_filter; 426 param = GGL_LINEAR; 427 } 428 break; 429 case GGL_TEXTURE_MAG_FILTER: 430 if ((param == GGL_NEAREST) || 431 (param == GGL_LINEAR)) { 432 what = &c->activeTMU->mag_filter; 433 } 434 break; 435 } 436 437 if (!what) { 438 ggl_error(c, GGL_INVALID_ENUM); 439 return; 440 } 441 442 if (*what != param) { 443 *what = param; 444 ggl_state_changed(c, GGL_TMU_STATE); 445 } 446} 447 448static void ggl_texCoordGradScale8xv(void* con, GGLint tmu, const int32_t* grad) 449{ 450 GGL_CONTEXT(c, con); 451 texture_t& u = c->state.texture[tmu]; 452 u.shade.is0 = grad[0]; 453 u.shade.idsdx = grad[1]; 454 u.shade.idsdy = grad[2]; 455 u.shade.it0 = grad[3]; 456 u.shade.idtdx = grad[4]; 457 u.shade.idtdy = grad[5]; 458 u.shade.sscale= grad[6]; 459 u.shade.tscale= grad[7]; 460} 461 462static void ggl_texCoord2x(void* con, GGLfixed s, GGLfixed t) 463{ 464 GGL_CONTEXT(c, con); 465 c->activeTMU->shade.is0 = s; 466 c->activeTMU->shade.it0 = t; 467 c->activeTMU->shade.sscale= 0; 468 c->activeTMU->shade.tscale= 0; 469} 470 471static void ggl_texCoord2i(void* con, GGLint s, GGLint t) 472{ 473 ggl_texCoord2x(con, s<<16, t<<16); 474} 475 476static void ggl_texGeni(void* con, GGLenum coord, GGLenum pname, GGLint param) 477{ 478 GGL_CONTEXT(c, con); 479 if (pname != GGL_TEXTURE_GEN_MODE) { 480 ggl_error(c, GGL_INVALID_ENUM); 481 return; 482 } 483 484 uint32_t* coord_ptr = 0; 485 if (coord == GGL_S) coord_ptr = &(c->activeTMU->s_coord); 486 else if (coord == GGL_T) coord_ptr = &(c->activeTMU->t_coord); 487 488 if (coord_ptr) { 489 if (*coord_ptr != uint32_t(param)) { 490 *coord_ptr = uint32_t(param); 491 ggl_state_changed(c, GGL_TMU_STATE); 492 } 493 } else { 494 ggl_error(c, GGL_INVALID_ENUM); 495 } 496} 497 498static void ggl_activeTexture(void* con, GGLuint tmu) 499{ 500 GGL_CONTEXT(c, con); 501 if (tmu >= GGLuint(GGL_TEXTURE_UNIT_COUNT)) { 502 ggl_error(c, GGL_INVALID_ENUM); 503 return; 504 } 505 c->activeTMUIndex = tmu; 506 c->activeTMU = &(c->state.texture[tmu]); 507} 508 509// ---------------------------------------------------------------------------- 510 511static void ggl_colorMask(void* con, GGLboolean r, 512 GGLboolean g, 513 GGLboolean b, 514 GGLboolean a) 515{ 516 GGL_CONTEXT(c, con); 517 int mask = 0; 518 if (a) mask |= 1 << GGLFormat::ALPHA; 519 if (r) mask |= 1 << GGLFormat::RED; 520 if (g) mask |= 1 << GGLFormat::GREEN; 521 if (b) mask |= 1 << GGLFormat::BLUE; 522 if (c->state.mask.color != mask) { 523 c->state.mask.color = mask; 524 ggl_state_changed(c, GGL_PIXEL_PIPELINE_STATE); 525 } 526} 527 528static void ggl_depthMask(void* con, GGLboolean flag) 529{ 530 GGL_CONTEXT(c, con); 531 if (c->state.mask.depth != flag?1:0) { 532 c->state.mask.depth = flag?1:0; 533 ggl_state_changed(c, GGL_PIXEL_PIPELINE_STATE); 534 } 535} 536 537static void ggl_stencilMask(void* con, GGLuint mask) 538{ 539 GGL_CONTEXT(c, con); 540 if (c->state.mask.stencil != mask) { 541 c->state.mask.stencil = mask; 542 ggl_state_changed(c, GGL_PIXEL_PIPELINE_STATE); 543 } 544} 545 546// ---------------------------------------------------------------------------- 547 548static void ggl_alphaFuncx(void* con, GGLenum func, GGLclampx ref) 549{ 550 GGL_CONTEXT(c, con); 551 if ((func < GGL_NEVER) || (func > GGL_ALWAYS)) { 552 ggl_error(c, GGL_INVALID_ENUM); 553 return; 554 } 555 c->state.alpha_test.ref = gglFixedToIteratedColor(gglClampx(ref)); 556 if (c->state.alpha_test.func != func) { 557 c->state.alpha_test.func = func; 558 ggl_state_changed(c, GGL_PIXEL_PIPELINE_STATE); 559 } 560} 561 562// ---------------------------------------------------------------------------- 563 564static void ggl_depthFunc(void* con, GGLenum func) 565{ 566 GGL_CONTEXT(c, con); 567 if ((func < GGL_NEVER) || (func > GGL_ALWAYS)) { 568 ggl_error(c, GGL_INVALID_ENUM); 569 return; 570 } 571 if (c->state.depth_test.func != func) { 572 c->state.depth_test.func = func; 573 ggl_state_changed(c, GGL_PIXEL_PIPELINE_STATE); 574 } 575} 576 577// ---------------------------------------------------------------------------- 578 579static void ggl_logicOp(void* con, GGLenum opcode) 580{ 581 GGL_CONTEXT(c, con); 582 if ((opcode < GGL_CLEAR) || (opcode > GGL_SET)) { 583 ggl_error(c, GGL_INVALID_ENUM); 584 return; 585 } 586 if (c->state.logic_op.opcode != opcode) { 587 c->state.logic_op.opcode = opcode; 588 ggl_state_changed(c, GGL_PIXEL_PIPELINE_STATE); 589 } 590} 591 592 593// ---------------------------------------------------------------------------- 594 595void ggl_set_scissor(context_t* c) 596{ 597 if (c->state.enables & GGL_ENABLE_SCISSOR_TEST) { 598 const int32_t l = c->state.scissor.user_left; 599 const int32_t t = c->state.scissor.user_top; 600 const int32_t r = c->state.scissor.user_right; 601 const int32_t b = c->state.scissor.user_bottom; 602 c->state.scissor.left = max(0, l); 603 c->state.scissor.right = min(c->state.buffers.color.width, r); 604 c->state.scissor.top = max(0, t); 605 c->state.scissor.bottom = min(c->state.buffers.color.height, b); 606 } else { 607 c->state.scissor.left = 0; 608 c->state.scissor.top = 0; 609 c->state.scissor.right = c->state.buffers.color.width; 610 c->state.scissor.bottom = c->state.buffers.color.height; 611 } 612} 613 614void ggl_enable_blending(context_t* c, int enable) 615{ 616 const int e = (c->state.enables & GGL_ENABLE_BLENDING)?1:0; 617 if (e != enable) { 618 if (enable) c->state.enables |= GGL_ENABLE_BLENDING; 619 else c->state.enables &= ~GGL_ENABLE_BLENDING; 620 ggl_state_changed(c, GGL_PIXEL_PIPELINE_STATE); 621 } 622} 623 624void ggl_enable_scissor_test(context_t* c, int enable) 625{ 626 const int e = (c->state.enables & GGL_ENABLE_SCISSOR_TEST)?1:0; 627 if (e != enable) { 628 if (enable) c->state.enables |= GGL_ENABLE_SCISSOR_TEST; 629 else c->state.enables &= ~GGL_ENABLE_SCISSOR_TEST; 630 ggl_set_scissor(c); 631 } 632} 633 634void ggl_enable_alpha_test(context_t* c, int enable) 635{ 636 const int e = (c->state.enables & GGL_ENABLE_ALPHA_TEST)?1:0; 637 if (e != enable) { 638 if (enable) c->state.enables |= GGL_ENABLE_ALPHA_TEST; 639 else c->state.enables &= ~GGL_ENABLE_ALPHA_TEST; 640 ggl_state_changed(c, GGL_PIXEL_PIPELINE_STATE); 641 } 642} 643 644void ggl_enable_logic_op(context_t* c, int enable) 645{ 646 const int e = (c->state.enables & GGL_ENABLE_LOGIC_OP)?1:0; 647 if (e != enable) { 648 if (enable) c->state.enables |= GGL_ENABLE_LOGIC_OP; 649 else c->state.enables &= ~GGL_ENABLE_LOGIC_OP; 650 ggl_state_changed(c, GGL_PIXEL_PIPELINE_STATE); 651 } 652} 653 654void ggl_enable_dither(context_t* c, int enable) 655{ 656 const int e = (c->state.enables & GGL_ENABLE_DITHER)?1:0; 657 if (e != enable) { 658 if (enable) c->state.enables |= GGL_ENABLE_DITHER; 659 else c->state.enables &= ~GGL_ENABLE_DITHER; 660 ggl_state_changed(c, GGL_PIXEL_PIPELINE_STATE); 661 } 662} 663 664void ggl_enable_stencil_test(context_t* c, int enable) 665{ 666} 667 668void ggl_enable_depth_test(context_t* c, int enable) 669{ 670 if (c->state.buffers.depth.format == 0) 671 enable = 0; 672 const int e = (c->state.enables & GGL_ENABLE_DEPTH_TEST)?1:0; 673 if (e != enable) { 674 if (enable) c->state.enables |= GGL_ENABLE_DEPTH_TEST; 675 else c->state.enables &= ~GGL_ENABLE_DEPTH_TEST; 676 ggl_state_changed(c, GGL_PIXEL_PIPELINE_STATE); 677 } 678} 679 680void ggl_enable_aa(context_t* c, int enable) 681{ 682 const int e = (c->state.enables & GGL_ENABLE_AA)?1:0; 683 if (e != enable) { 684 if (enable) c->state.enables |= GGL_ENABLE_AA; 685 else c->state.enables &= ~GGL_ENABLE_AA; 686 ggl_state_changed(c, GGL_PIXEL_PIPELINE_STATE); 687 } 688} 689 690void ggl_enable_point_aa_nice(context_t* c, int enable) 691{ 692 const int e = (c->state.enables & GGL_ENABLE_POINT_AA_NICE)?1:0; 693 if (e != enable) { 694 if (enable) c->state.enables |= GGL_ENABLE_POINT_AA_NICE; 695 else c->state.enables &= ~GGL_ENABLE_POINT_AA_NICE; 696 ggl_state_changed(c, GGL_PIXEL_PIPELINE_STATE); 697 } 698} 699 700void ggl_enable_w_lerp(context_t* c, int enable) 701{ 702 const int e = (c->state.enables & GGL_ENABLE_W)?1:0; 703 if (e != enable) { 704 if (enable) c->state.enables |= GGL_ENABLE_W; 705 else c->state.enables &= ~GGL_ENABLE_W; 706 ggl_state_changed(c, GGL_PIXEL_PIPELINE_STATE); 707 } 708} 709 710void ggl_enable_texture2d(context_t* c, int enable) 711{ 712 if (c->activeTMU->enable != enable) { 713 const uint32_t tmu = c->activeTMUIndex; 714 c->activeTMU->enable = enable; 715 const uint32_t mask = 1UL << tmu; 716 if (enable) c->state.enabled_tmu |= mask; 717 else c->state.enabled_tmu &= ~mask; 718 if (c->state.enabled_tmu) c->state.enables |= GGL_ENABLE_TMUS; 719 else c->state.enables &= ~GGL_ENABLE_TMUS; 720 ggl_state_changed(c, GGL_TMU_STATE); 721 } 722} 723 724 725// ---------------------------------------------------------------------------- 726 727int64_t ggl_system_time() 728{ 729#if defined(HAVE_POSIX_CLOCKS) 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#else 735 // we don't support the clocks here. 736 struct timeval t; 737 t.tv_sec = t.tv_usec = 0; 738 gettimeofday(&t, NULL); 739 return int64_t(t.tv_sec)*1000000000LL + int64_t(t.tv_usec)*1000LL; 740#endif 741} 742 743// ---------------------------------------------------------------------------- 744 745void ggl_init_procs(context_t* c) 746{ 747 GGLContext& procs = *(GGLContext*)c; 748 GGL_INIT_PROC(procs, scissor); 749 GGL_INIT_PROC(procs, activeTexture); 750 GGL_INIT_PROC(procs, bindTexture); 751 GGL_INIT_PROC(procs, bindTextureLod); 752 GGL_INIT_PROC(procs, colorBuffer); 753 GGL_INIT_PROC(procs, readBuffer); 754 GGL_INIT_PROC(procs, depthBuffer); 755 GGL_INIT_PROC(procs, enable); 756 GGL_INIT_PROC(procs, disable); 757 GGL_INIT_PROC(procs, enableDisable); 758 GGL_INIT_PROC(procs, shadeModel); 759 GGL_INIT_PROC(procs, color4xv); 760 GGL_INIT_PROC(procs, colorGrad12xv); 761 GGL_INIT_PROC(procs, zGrad3xv); 762 GGL_INIT_PROC(procs, wGrad3xv); 763 GGL_INIT_PROC(procs, fogGrad3xv); 764 GGL_INIT_PROC(procs, fogColor3xv); 765 GGL_INIT_PROC(procs, blendFunc); 766 GGL_INIT_PROC(procs, blendFuncSeparate); 767 GGL_INIT_PROC(procs, texEnvi); 768 GGL_INIT_PROC(procs, texEnvxv); 769 GGL_INIT_PROC(procs, texParameteri); 770 GGL_INIT_PROC(procs, texCoord2i); 771 GGL_INIT_PROC(procs, texCoord2x); 772 GGL_INIT_PROC(procs, texCoordGradScale8xv); 773 GGL_INIT_PROC(procs, texGeni); 774 GGL_INIT_PROC(procs, colorMask); 775 GGL_INIT_PROC(procs, depthMask); 776 GGL_INIT_PROC(procs, stencilMask); 777 GGL_INIT_PROC(procs, alphaFuncx); 778 GGL_INIT_PROC(procs, depthFunc); 779 GGL_INIT_PROC(procs, logicOp); 780 ggl_init_clear(c); 781} 782 783void ggl_init_context(context_t* c) 784{ 785 memset(c, 0, sizeof(context_t)); 786 ggl_init_procs(c); 787 ggl_init_trap(c); 788 ggl_init_scanline(c); 789 ggl_init_texture(c); 790 ggl_init_picker(c); 791 ggl_init_raster(c); 792 c->formats = gglGetPixelFormatTable(); 793 c->state.blend.src = GGL_ONE; 794 c->state.blend.dst = GGL_ZERO; 795 c->state.blend.src_alpha = GGL_ONE; 796 c->state.blend.dst_alpha = GGL_ZERO; 797 c->state.mask.color = 0xF; 798 c->state.mask.depth = 0; 799 c->state.mask.stencil = 0xFFFFFFFF; 800 c->state.logic_op.opcode = GGL_COPY; 801 c->state.alpha_test.func = GGL_ALWAYS; 802 c->state.depth_test.func = GGL_LESS; 803 c->state.depth_test.clearValue = FIXED_ONE; 804 c->shade.w0 = FIXED_ONE; 805 memcpy(c->ditherMatrix, gDitherMatrix, sizeof(gDitherMatrix)); 806} 807 808void ggl_uninit_context(context_t* c) 809{ 810 ggl_uninit_scanline(c); 811} 812 813// ---------------------------------------------------------------------------- 814}; // namespace android 815// ---------------------------------------------------------------------------- 816 817 818 819using namespace android; 820 821ssize_t gglInit(GGLContext** context) 822{ 823 void* const base = malloc(sizeof(context_t) + 32); 824 if (base) { 825 // always align the context on cache lines 826 context_t *c = (context_t *)((ptrdiff_t(base)+31) & ~0x1FL); 827 ggl_init_context(c); 828 c->base = base; 829 *context = (GGLContext*)c; 830 } else { 831 return -1; 832 } 833 return 0; 834} 835 836ssize_t gglUninit(GGLContext* con) 837{ 838 GGL_CONTEXT(c, (void*)con); 839 ggl_uninit_context(c); 840 free(c->base); 841 return 0; 842} 843 844