pixel.c revision 7126e38d9037da66fd531c4cb02b3843b68b84ff
1/* 2 * Mesa 3-D graphics library 3 * Version: 7.1 4 * 5 * Copyright (C) 1999-2008 Brian Paul All Rights Reserved. 6 * 7 * Permission is hereby granted, free of charge, to any person obtaining a 8 * copy of this software and associated documentation files (the "Software"), 9 * to deal in the Software without restriction, including without limitation 10 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 11 * and/or sell copies of the Software, and to permit persons to whom the 12 * Software is furnished to do so, subject to the following conditions: 13 * 14 * The above copyright notice and this permission notice shall be included 15 * in all copies or substantial portions of the Software. 16 * 17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 21 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 */ 24 25 26/** 27 * \file pixel.c 28 * Pixel transfer functions (glPixelZoom, glPixelMap, glPixelTransfer) 29 */ 30 31#include "glheader.h" 32#include "bufferobj.h" 33#include "colormac.h" 34#include "context.h" 35#include "macros.h" 36#include "pixel.h" 37#include "mtypes.h" 38#include "main/dispatch.h" 39 40 41#if FEATURE_pixel_transfer 42 43 44/**********************************************************************/ 45/***** glPixelZoom *****/ 46/**********************************************************************/ 47 48static void GLAPIENTRY 49_mesa_PixelZoom( GLfloat xfactor, GLfloat yfactor ) 50{ 51 GET_CURRENT_CONTEXT(ctx); 52 53 if (ctx->Pixel.ZoomX == xfactor && 54 ctx->Pixel.ZoomY == yfactor) 55 return; 56 57 FLUSH_VERTICES(ctx, _NEW_PIXEL); 58 ctx->Pixel.ZoomX = xfactor; 59 ctx->Pixel.ZoomY = yfactor; 60} 61 62 63 64/**********************************************************************/ 65/***** glPixelMap *****/ 66/**********************************************************************/ 67 68/** 69 * Return pointer to a pixelmap by name. 70 */ 71static struct gl_pixelmap * 72get_pixelmap(GLcontext *ctx, GLenum map) 73{ 74 switch (map) { 75 case GL_PIXEL_MAP_I_TO_I: 76 return &ctx->PixelMaps.ItoI; 77 case GL_PIXEL_MAP_S_TO_S: 78 return &ctx->PixelMaps.StoS; 79 case GL_PIXEL_MAP_I_TO_R: 80 return &ctx->PixelMaps.ItoR; 81 case GL_PIXEL_MAP_I_TO_G: 82 return &ctx->PixelMaps.ItoG; 83 case GL_PIXEL_MAP_I_TO_B: 84 return &ctx->PixelMaps.ItoB; 85 case GL_PIXEL_MAP_I_TO_A: 86 return &ctx->PixelMaps.ItoA; 87 case GL_PIXEL_MAP_R_TO_R: 88 return &ctx->PixelMaps.RtoR; 89 case GL_PIXEL_MAP_G_TO_G: 90 return &ctx->PixelMaps.GtoG; 91 case GL_PIXEL_MAP_B_TO_B: 92 return &ctx->PixelMaps.BtoB; 93 case GL_PIXEL_MAP_A_TO_A: 94 return &ctx->PixelMaps.AtoA; 95 default: 96 return NULL; 97 } 98} 99 100 101/** 102 * Helper routine used by the other _mesa_PixelMap() functions. 103 */ 104static void 105store_pixelmap(GLcontext *ctx, GLenum map, GLsizei mapsize, 106 const GLfloat *values) 107{ 108 GLint i; 109 struct gl_pixelmap *pm = get_pixelmap(ctx, map); 110 if (!pm) { 111 _mesa_error(ctx, GL_INVALID_ENUM, "glPixelMap(map)"); 112 return; 113 } 114 115 switch (map) { 116 case GL_PIXEL_MAP_S_TO_S: 117 /* special case */ 118 ctx->PixelMaps.StoS.Size = mapsize; 119 for (i = 0; i < mapsize; i++) { 120 ctx->PixelMaps.StoS.Map[i] = (GLfloat)IROUND(values[i]); 121 } 122 break; 123 case GL_PIXEL_MAP_I_TO_I: 124 /* special case */ 125 ctx->PixelMaps.ItoI.Size = mapsize; 126 for (i = 0; i < mapsize; i++) { 127 ctx->PixelMaps.ItoI.Map[i] = values[i]; 128 } 129 break; 130 default: 131 /* general case */ 132 pm->Size = mapsize; 133 for (i = 0; i < mapsize; i++) { 134 GLfloat val = CLAMP(values[i], 0.0F, 1.0F); 135 pm->Map[i] = val; 136 pm->Map8[i] = (GLint) (val * 255.0F); 137 } 138 } 139} 140 141 142/** 143 * Convenience wrapper for _mesa_validate_pbo_access() for gl[Get]PixelMap(). 144 */ 145static GLboolean 146validate_pbo_access(GLcontext *ctx, struct gl_pixelstore_attrib *pack, 147 GLsizei mapsize, GLenum format, GLenum type, 148 const GLvoid *ptr) 149{ 150 GLboolean ok; 151 152 /* Note, need to use DefaultPacking and Unpack's buffer object */ 153 _mesa_reference_buffer_object(ctx, 154 &ctx->DefaultPacking.BufferObj, 155 pack->BufferObj); 156 157 ok = _mesa_validate_pbo_access(1, &ctx->DefaultPacking, mapsize, 1, 1, 158 format, type, ptr); 159 160 /* restore */ 161 _mesa_reference_buffer_object(ctx, 162 &ctx->DefaultPacking.BufferObj, 163 ctx->Shared->NullBufferObj); 164 165 if (!ok) { 166 _mesa_error(ctx, GL_INVALID_OPERATION, 167 "glPixelMap(invalid PBO access)"); 168 } 169 return ok; 170} 171 172 173static void GLAPIENTRY 174_mesa_PixelMapfv( GLenum map, GLsizei mapsize, const GLfloat *values ) 175{ 176 GET_CURRENT_CONTEXT(ctx); 177 ASSERT_OUTSIDE_BEGIN_END(ctx); 178 179 /* XXX someday, test against ctx->Const.MaxPixelMapTableSize */ 180 if (mapsize < 1 || mapsize > MAX_PIXEL_MAP_TABLE) { 181 _mesa_error( ctx, GL_INVALID_VALUE, "glPixelMapfv(mapsize)" ); 182 return; 183 } 184 185 if (map >= GL_PIXEL_MAP_S_TO_S && map <= GL_PIXEL_MAP_I_TO_A) { 186 /* test that mapsize is a power of two */ 187 if (!_mesa_is_pow_two(mapsize)) { 188 _mesa_error( ctx, GL_INVALID_VALUE, "glPixelMapfv(mapsize)" ); 189 return; 190 } 191 } 192 193 FLUSH_VERTICES(ctx, _NEW_PIXEL); 194 195 if (!validate_pbo_access(ctx, &ctx->Unpack, mapsize, 196 GL_INTENSITY, GL_FLOAT, values)) { 197 return; 198 } 199 200 values = (const GLfloat *) _mesa_map_pbo_source(ctx, &ctx->Unpack, values); 201 if (!values) { 202 if (_mesa_is_bufferobj(ctx->Unpack.BufferObj)) { 203 _mesa_error(ctx, GL_INVALID_OPERATION, 204 "glPixelMapfv(PBO is mapped)"); 205 } 206 return; 207 } 208 209 store_pixelmap(ctx, map, mapsize, values); 210 211 _mesa_unmap_pbo_source(ctx, &ctx->Unpack); 212} 213 214 215static void GLAPIENTRY 216_mesa_PixelMapuiv(GLenum map, GLsizei mapsize, const GLuint *values ) 217{ 218 GLfloat fvalues[MAX_PIXEL_MAP_TABLE]; 219 GET_CURRENT_CONTEXT(ctx); 220 ASSERT_OUTSIDE_BEGIN_END(ctx); 221 222 if (mapsize < 1 || mapsize > MAX_PIXEL_MAP_TABLE) { 223 _mesa_error( ctx, GL_INVALID_VALUE, "glPixelMapuiv(mapsize)" ); 224 return; 225 } 226 227 if (map >= GL_PIXEL_MAP_S_TO_S && map <= GL_PIXEL_MAP_I_TO_A) { 228 /* test that mapsize is a power of two */ 229 if (!_mesa_is_pow_two(mapsize)) { 230 _mesa_error( ctx, GL_INVALID_VALUE, "glPixelMapuiv(mapsize)" ); 231 return; 232 } 233 } 234 235 FLUSH_VERTICES(ctx, _NEW_PIXEL); 236 237 if (!validate_pbo_access(ctx, &ctx->Unpack, mapsize, 238 GL_INTENSITY, GL_UNSIGNED_INT, values)) { 239 return; 240 } 241 242 values = (const GLuint *) _mesa_map_pbo_source(ctx, &ctx->Unpack, values); 243 if (!values) { 244 if (_mesa_is_bufferobj(ctx->Unpack.BufferObj)) { 245 _mesa_error(ctx, GL_INVALID_OPERATION, 246 "glPixelMapuiv(PBO is mapped)"); 247 } 248 return; 249 } 250 251 /* convert to floats */ 252 if (map == GL_PIXEL_MAP_I_TO_I || map == GL_PIXEL_MAP_S_TO_S) { 253 GLint i; 254 for (i = 0; i < mapsize; i++) { 255 fvalues[i] = (GLfloat) values[i]; 256 } 257 } 258 else { 259 GLint i; 260 for (i = 0; i < mapsize; i++) { 261 fvalues[i] = UINT_TO_FLOAT( values[i] ); 262 } 263 } 264 265 _mesa_unmap_pbo_source(ctx, &ctx->Unpack); 266 267 store_pixelmap(ctx, map, mapsize, fvalues); 268} 269 270 271static void GLAPIENTRY 272_mesa_PixelMapusv(GLenum map, GLsizei mapsize, const GLushort *values ) 273{ 274 GLfloat fvalues[MAX_PIXEL_MAP_TABLE]; 275 GET_CURRENT_CONTEXT(ctx); 276 ASSERT_OUTSIDE_BEGIN_END(ctx); 277 278 if (mapsize < 1 || mapsize > MAX_PIXEL_MAP_TABLE) { 279 _mesa_error( ctx, GL_INVALID_VALUE, "glPixelMapusv(mapsize)" ); 280 return; 281 } 282 283 if (map >= GL_PIXEL_MAP_S_TO_S && map <= GL_PIXEL_MAP_I_TO_A) { 284 /* test that mapsize is a power of two */ 285 if (!_mesa_is_pow_two(mapsize)) { 286 _mesa_error( ctx, GL_INVALID_VALUE, "glPixelMapuiv(mapsize)" ); 287 return; 288 } 289 } 290 291 FLUSH_VERTICES(ctx, _NEW_PIXEL); 292 293 if (!validate_pbo_access(ctx, &ctx->Unpack, mapsize, 294 GL_INTENSITY, GL_UNSIGNED_SHORT, values)) { 295 return; 296 } 297 298 values = (const GLushort *) _mesa_map_pbo_source(ctx, &ctx->Unpack, values); 299 if (!values) { 300 if (_mesa_is_bufferobj(ctx->Unpack.BufferObj)) { 301 _mesa_error(ctx, GL_INVALID_OPERATION, 302 "glPixelMapusv(PBO is mapped)"); 303 } 304 return; 305 } 306 307 /* convert to floats */ 308 if (map == GL_PIXEL_MAP_I_TO_I || map == GL_PIXEL_MAP_S_TO_S) { 309 GLint i; 310 for (i = 0; i < mapsize; i++) { 311 fvalues[i] = (GLfloat) values[i]; 312 } 313 } 314 else { 315 GLint i; 316 for (i = 0; i < mapsize; i++) { 317 fvalues[i] = USHORT_TO_FLOAT( values[i] ); 318 } 319 } 320 321 _mesa_unmap_pbo_source(ctx, &ctx->Unpack); 322 323 store_pixelmap(ctx, map, mapsize, fvalues); 324} 325 326 327static void GLAPIENTRY 328_mesa_GetPixelMapfv( GLenum map, GLfloat *values ) 329{ 330 GET_CURRENT_CONTEXT(ctx); 331 GLuint mapsize, i; 332 const struct gl_pixelmap *pm; 333 334 ASSERT_OUTSIDE_BEGIN_END(ctx); 335 336 pm = get_pixelmap(ctx, map); 337 if (!pm) { 338 _mesa_error(ctx, GL_INVALID_ENUM, "glGetPixelMapfv(map)"); 339 return; 340 } 341 342 mapsize = pm->Size; 343 344 if (!validate_pbo_access(ctx, &ctx->Pack, mapsize, 345 GL_INTENSITY, GL_FLOAT, values)) { 346 return; 347 } 348 349 values = (GLfloat *) _mesa_map_pbo_dest(ctx, &ctx->Pack, values); 350 if (!values) { 351 if (_mesa_is_bufferobj(ctx->Pack.BufferObj)) { 352 _mesa_error(ctx, GL_INVALID_OPERATION, 353 "glGetPixelMapfv(PBO is mapped)"); 354 } 355 return; 356 } 357 358 if (map == GL_PIXEL_MAP_S_TO_S) { 359 /* special case */ 360 for (i = 0; i < mapsize; i++) { 361 values[i] = (GLfloat) ctx->PixelMaps.StoS.Map[i]; 362 } 363 } 364 else { 365 memcpy(values, pm->Map, mapsize * sizeof(GLfloat)); 366 } 367 368 _mesa_unmap_pbo_dest(ctx, &ctx->Pack); 369} 370 371 372static void GLAPIENTRY 373_mesa_GetPixelMapuiv( GLenum map, GLuint *values ) 374{ 375 GET_CURRENT_CONTEXT(ctx); 376 GLint mapsize, i; 377 const struct gl_pixelmap *pm; 378 379 ASSERT_OUTSIDE_BEGIN_END(ctx); 380 381 pm = get_pixelmap(ctx, map); 382 if (!pm) { 383 _mesa_error(ctx, GL_INVALID_ENUM, "glGetPixelMapuiv(map)"); 384 return; 385 } 386 mapsize = pm->Size; 387 388 if (!validate_pbo_access(ctx, &ctx->Pack, mapsize, 389 GL_INTENSITY, GL_UNSIGNED_INT, values)) { 390 return; 391 } 392 393 values = (GLuint *) _mesa_map_pbo_dest(ctx, &ctx->Pack, values); 394 if (!values) { 395 if (_mesa_is_bufferobj(ctx->Pack.BufferObj)) { 396 _mesa_error(ctx, GL_INVALID_OPERATION, 397 "glGetPixelMapuiv(PBO is mapped)"); 398 } 399 return; 400 } 401 402 if (map == GL_PIXEL_MAP_S_TO_S) { 403 /* special case */ 404 memcpy(values, ctx->PixelMaps.StoS.Map, mapsize * sizeof(GLint)); 405 } 406 else { 407 for (i = 0; i < mapsize; i++) { 408 values[i] = FLOAT_TO_UINT( pm->Map[i] ); 409 } 410 } 411 412 _mesa_unmap_pbo_dest(ctx, &ctx->Pack); 413} 414 415 416static void GLAPIENTRY 417_mesa_GetPixelMapusv( GLenum map, GLushort *values ) 418{ 419 GET_CURRENT_CONTEXT(ctx); 420 GLint mapsize, i; 421 const struct gl_pixelmap *pm; 422 423 ASSERT_OUTSIDE_BEGIN_END(ctx); 424 425 pm = get_pixelmap(ctx, map); 426 if (!pm) { 427 _mesa_error(ctx, GL_INVALID_ENUM, "glGetPixelMapusv(map)"); 428 return; 429 } 430 mapsize = pm->Size; 431 432 if (!validate_pbo_access(ctx, &ctx->Pack, mapsize, 433 GL_INTENSITY, GL_UNSIGNED_SHORT, values)) { 434 return; 435 } 436 437 values = (GLushort *) _mesa_map_pbo_dest(ctx, &ctx->Pack, values); 438 if (!values) { 439 if (_mesa_is_bufferobj(ctx->Pack.BufferObj)) { 440 _mesa_error(ctx, GL_INVALID_OPERATION, 441 "glGetPixelMapusv(PBO is mapped)"); 442 } 443 return; 444 } 445 446 switch (map) { 447 /* special cases */ 448 case GL_PIXEL_MAP_I_TO_I: 449 for (i = 0; i < mapsize; i++) { 450 values[i] = (GLushort) CLAMP(ctx->PixelMaps.ItoI.Map[i], 0.0, 65535.); 451 } 452 break; 453 case GL_PIXEL_MAP_S_TO_S: 454 for (i = 0; i < mapsize; i++) { 455 values[i] = (GLushort) CLAMP(ctx->PixelMaps.StoS.Map[i], 0.0, 65535.); 456 } 457 break; 458 default: 459 for (i = 0; i < mapsize; i++) { 460 CLAMPED_FLOAT_TO_USHORT(values[i], pm->Map[i] ); 461 } 462 } 463 464 _mesa_unmap_pbo_dest(ctx, &ctx->Pack); 465} 466 467 468 469/**********************************************************************/ 470/***** glPixelTransfer *****/ 471/**********************************************************************/ 472 473 474/* 475 * Implements glPixelTransfer[fi] whether called immediately or from a 476 * display list. 477 */ 478static void GLAPIENTRY 479_mesa_PixelTransferf( GLenum pname, GLfloat param ) 480{ 481 GET_CURRENT_CONTEXT(ctx); 482 ASSERT_OUTSIDE_BEGIN_END(ctx); 483 484 switch (pname) { 485 case GL_MAP_COLOR: 486 if (ctx->Pixel.MapColorFlag == (param ? GL_TRUE : GL_FALSE)) 487 return; 488 FLUSH_VERTICES(ctx, _NEW_PIXEL); 489 ctx->Pixel.MapColorFlag = param ? GL_TRUE : GL_FALSE; 490 break; 491 case GL_MAP_STENCIL: 492 if (ctx->Pixel.MapStencilFlag == (param ? GL_TRUE : GL_FALSE)) 493 return; 494 FLUSH_VERTICES(ctx, _NEW_PIXEL); 495 ctx->Pixel.MapStencilFlag = param ? GL_TRUE : GL_FALSE; 496 break; 497 case GL_INDEX_SHIFT: 498 if (ctx->Pixel.IndexShift == (GLint) param) 499 return; 500 FLUSH_VERTICES(ctx, _NEW_PIXEL); 501 ctx->Pixel.IndexShift = (GLint) param; 502 break; 503 case GL_INDEX_OFFSET: 504 if (ctx->Pixel.IndexOffset == (GLint) param) 505 return; 506 FLUSH_VERTICES(ctx, _NEW_PIXEL); 507 ctx->Pixel.IndexOffset = (GLint) param; 508 break; 509 case GL_RED_SCALE: 510 if (ctx->Pixel.RedScale == param) 511 return; 512 FLUSH_VERTICES(ctx, _NEW_PIXEL); 513 ctx->Pixel.RedScale = param; 514 break; 515 case GL_RED_BIAS: 516 if (ctx->Pixel.RedBias == param) 517 return; 518 FLUSH_VERTICES(ctx, _NEW_PIXEL); 519 ctx->Pixel.RedBias = param; 520 break; 521 case GL_GREEN_SCALE: 522 if (ctx->Pixel.GreenScale == param) 523 return; 524 FLUSH_VERTICES(ctx, _NEW_PIXEL); 525 ctx->Pixel.GreenScale = param; 526 break; 527 case GL_GREEN_BIAS: 528 if (ctx->Pixel.GreenBias == param) 529 return; 530 FLUSH_VERTICES(ctx, _NEW_PIXEL); 531 ctx->Pixel.GreenBias = param; 532 break; 533 case GL_BLUE_SCALE: 534 if (ctx->Pixel.BlueScale == param) 535 return; 536 FLUSH_VERTICES(ctx, _NEW_PIXEL); 537 ctx->Pixel.BlueScale = param; 538 break; 539 case GL_BLUE_BIAS: 540 if (ctx->Pixel.BlueBias == param) 541 return; 542 FLUSH_VERTICES(ctx, _NEW_PIXEL); 543 ctx->Pixel.BlueBias = param; 544 break; 545 case GL_ALPHA_SCALE: 546 if (ctx->Pixel.AlphaScale == param) 547 return; 548 FLUSH_VERTICES(ctx, _NEW_PIXEL); 549 ctx->Pixel.AlphaScale = param; 550 break; 551 case GL_ALPHA_BIAS: 552 if (ctx->Pixel.AlphaBias == param) 553 return; 554 FLUSH_VERTICES(ctx, _NEW_PIXEL); 555 ctx->Pixel.AlphaBias = param; 556 break; 557 case GL_DEPTH_SCALE: 558 if (ctx->Pixel.DepthScale == param) 559 return; 560 FLUSH_VERTICES(ctx, _NEW_PIXEL); 561 ctx->Pixel.DepthScale = param; 562 break; 563 case GL_DEPTH_BIAS: 564 if (ctx->Pixel.DepthBias == param) 565 return; 566 FLUSH_VERTICES(ctx, _NEW_PIXEL); 567 ctx->Pixel.DepthBias = param; 568 break; 569 case GL_POST_COLOR_MATRIX_RED_SCALE: 570 if (ctx->Pixel.PostColorMatrixScale[0] == param) 571 return; 572 FLUSH_VERTICES(ctx, _NEW_PIXEL); 573 ctx->Pixel.PostColorMatrixScale[0] = param; 574 break; 575 case GL_POST_COLOR_MATRIX_RED_BIAS: 576 if (ctx->Pixel.PostColorMatrixBias[0] == param) 577 return; 578 FLUSH_VERTICES(ctx, _NEW_PIXEL); 579 ctx->Pixel.PostColorMatrixBias[0] = param; 580 break; 581 case GL_POST_COLOR_MATRIX_GREEN_SCALE: 582 if (ctx->Pixel.PostColorMatrixScale[1] == param) 583 return; 584 FLUSH_VERTICES(ctx, _NEW_PIXEL); 585 ctx->Pixel.PostColorMatrixScale[1] = param; 586 break; 587 case GL_POST_COLOR_MATRIX_GREEN_BIAS: 588 if (ctx->Pixel.PostColorMatrixBias[1] == param) 589 return; 590 FLUSH_VERTICES(ctx, _NEW_PIXEL); 591 ctx->Pixel.PostColorMatrixBias[1] = param; 592 break; 593 case GL_POST_COLOR_MATRIX_BLUE_SCALE: 594 if (ctx->Pixel.PostColorMatrixScale[2] == param) 595 return; 596 FLUSH_VERTICES(ctx, _NEW_PIXEL); 597 ctx->Pixel.PostColorMatrixScale[2] = param; 598 break; 599 case GL_POST_COLOR_MATRIX_BLUE_BIAS: 600 if (ctx->Pixel.PostColorMatrixBias[2] == param) 601 return; 602 FLUSH_VERTICES(ctx, _NEW_PIXEL); 603 ctx->Pixel.PostColorMatrixBias[2] = param; 604 break; 605 case GL_POST_COLOR_MATRIX_ALPHA_SCALE: 606 if (ctx->Pixel.PostColorMatrixScale[3] == param) 607 return; 608 FLUSH_VERTICES(ctx, _NEW_PIXEL); 609 ctx->Pixel.PostColorMatrixScale[3] = param; 610 break; 611 case GL_POST_COLOR_MATRIX_ALPHA_BIAS: 612 if (ctx->Pixel.PostColorMatrixBias[3] == param) 613 return; 614 FLUSH_VERTICES(ctx, _NEW_PIXEL); 615 ctx->Pixel.PostColorMatrixBias[3] = param; 616 break; 617 case GL_POST_CONVOLUTION_RED_SCALE: 618 if (ctx->Pixel.PostConvolutionScale[0] == param) 619 return; 620 FLUSH_VERTICES(ctx, _NEW_PIXEL); 621 ctx->Pixel.PostConvolutionScale[0] = param; 622 break; 623 case GL_POST_CONVOLUTION_RED_BIAS: 624 if (ctx->Pixel.PostConvolutionBias[0] == param) 625 return; 626 FLUSH_VERTICES(ctx, _NEW_PIXEL); 627 ctx->Pixel.PostConvolutionBias[0] = param; 628 break; 629 case GL_POST_CONVOLUTION_GREEN_SCALE: 630 if (ctx->Pixel.PostConvolutionScale[1] == param) 631 return; 632 FLUSH_VERTICES(ctx, _NEW_PIXEL); 633 ctx->Pixel.PostConvolutionScale[1] = param; 634 break; 635 case GL_POST_CONVOLUTION_GREEN_BIAS: 636 if (ctx->Pixel.PostConvolutionBias[1] == param) 637 return; 638 FLUSH_VERTICES(ctx, _NEW_PIXEL); 639 ctx->Pixel.PostConvolutionBias[1] = param; 640 break; 641 case GL_POST_CONVOLUTION_BLUE_SCALE: 642 if (ctx->Pixel.PostConvolutionScale[2] == param) 643 return; 644 FLUSH_VERTICES(ctx, _NEW_PIXEL); 645 ctx->Pixel.PostConvolutionScale[2] = param; 646 break; 647 case GL_POST_CONVOLUTION_BLUE_BIAS: 648 if (ctx->Pixel.PostConvolutionBias[2] == param) 649 return; 650 FLUSH_VERTICES(ctx, _NEW_PIXEL); 651 ctx->Pixel.PostConvolutionBias[2] = param; 652 break; 653 case GL_POST_CONVOLUTION_ALPHA_SCALE: 654 if (ctx->Pixel.PostConvolutionScale[3] == param) 655 return; 656 FLUSH_VERTICES(ctx, _NEW_PIXEL); 657 ctx->Pixel.PostConvolutionScale[3] = param; 658 break; 659 case GL_POST_CONVOLUTION_ALPHA_BIAS: 660 if (ctx->Pixel.PostConvolutionBias[3] == param) 661 return; 662 FLUSH_VERTICES(ctx, _NEW_PIXEL); 663 ctx->Pixel.PostConvolutionBias[3] = param; 664 break; 665 default: 666 _mesa_error( ctx, GL_INVALID_ENUM, "glPixelTransfer(pname)" ); 667 return; 668 } 669} 670 671 672static void GLAPIENTRY 673_mesa_PixelTransferi( GLenum pname, GLint param ) 674{ 675 _mesa_PixelTransferf( pname, (GLfloat) param ); 676} 677 678 679 680/**********************************************************************/ 681/***** State Management *****/ 682/**********************************************************************/ 683 684/* 685 * Return a bitmask of IMAGE_*_BIT flags which to indicate which 686 * pixel transfer operations are enabled. 687 */ 688static void 689update_image_transfer_state(GLcontext *ctx) 690{ 691 GLuint mask = 0; 692 693 if (ctx->Pixel.RedScale != 1.0F || ctx->Pixel.RedBias != 0.0F || 694 ctx->Pixel.GreenScale != 1.0F || ctx->Pixel.GreenBias != 0.0F || 695 ctx->Pixel.BlueScale != 1.0F || ctx->Pixel.BlueBias != 0.0F || 696 ctx->Pixel.AlphaScale != 1.0F || ctx->Pixel.AlphaBias != 0.0F) 697 mask |= IMAGE_SCALE_BIAS_BIT; 698 699 if (ctx->Pixel.IndexShift || ctx->Pixel.IndexOffset) 700 mask |= IMAGE_SHIFT_OFFSET_BIT; 701 702 if (ctx->Pixel.MapColorFlag) 703 mask |= IMAGE_MAP_COLOR_BIT; 704 705 if (ctx->Pixel.ColorTableEnabled[COLORTABLE_PRECONVOLUTION]) 706 mask |= IMAGE_COLOR_TABLE_BIT; 707 708 if (ctx->Pixel.Convolution1DEnabled || 709 ctx->Pixel.Convolution2DEnabled || 710 ctx->Pixel.Separable2DEnabled) { 711 mask |= IMAGE_CONVOLUTION_BIT; 712 if (ctx->Pixel.PostConvolutionScale[0] != 1.0F || 713 ctx->Pixel.PostConvolutionScale[1] != 1.0F || 714 ctx->Pixel.PostConvolutionScale[2] != 1.0F || 715 ctx->Pixel.PostConvolutionScale[3] != 1.0F || 716 ctx->Pixel.PostConvolutionBias[0] != 0.0F || 717 ctx->Pixel.PostConvolutionBias[1] != 0.0F || 718 ctx->Pixel.PostConvolutionBias[2] != 0.0F || 719 ctx->Pixel.PostConvolutionBias[3] != 0.0F) { 720 mask |= IMAGE_POST_CONVOLUTION_SCALE_BIAS; 721 } 722 } 723 724 if (ctx->Pixel.ColorTableEnabled[COLORTABLE_POSTCONVOLUTION]) 725 mask |= IMAGE_POST_CONVOLUTION_COLOR_TABLE_BIT; 726 727 if (ctx->ColorMatrixStack.Top->type != MATRIX_IDENTITY || 728 ctx->Pixel.PostColorMatrixScale[0] != 1.0F || 729 ctx->Pixel.PostColorMatrixBias[0] != 0.0F || 730 ctx->Pixel.PostColorMatrixScale[1] != 1.0F || 731 ctx->Pixel.PostColorMatrixBias[1] != 0.0F || 732 ctx->Pixel.PostColorMatrixScale[2] != 1.0F || 733 ctx->Pixel.PostColorMatrixBias[2] != 0.0F || 734 ctx->Pixel.PostColorMatrixScale[3] != 1.0F || 735 ctx->Pixel.PostColorMatrixBias[3] != 0.0F) 736 mask |= IMAGE_COLOR_MATRIX_BIT; 737 738 if (ctx->Pixel.ColorTableEnabled[COLORTABLE_POSTCOLORMATRIX]) 739 mask |= IMAGE_POST_COLOR_MATRIX_COLOR_TABLE_BIT; 740 741 ctx->_ImageTransferState = mask; 742} 743 744 745/** 746 * Update mesa pixel transfer derived state. 747 */ 748void _mesa_update_pixel( GLcontext *ctx, GLuint new_state ) 749{ 750 if (new_state & _NEW_COLOR_MATRIX) 751 _math_matrix_analyse( ctx->ColorMatrixStack.Top ); 752 753 /* References ColorMatrix.type (derived above). 754 */ 755 if (new_state & _MESA_NEW_TRANSFER_STATE) 756 update_image_transfer_state(ctx); 757} 758 759 760void 761_mesa_init_pixel_dispatch(struct _glapi_table *disp) 762{ 763 SET_GetPixelMapfv(disp, _mesa_GetPixelMapfv); 764 SET_GetPixelMapuiv(disp, _mesa_GetPixelMapuiv); 765 SET_GetPixelMapusv(disp, _mesa_GetPixelMapusv); 766 SET_PixelMapfv(disp, _mesa_PixelMapfv); 767 SET_PixelMapuiv(disp, _mesa_PixelMapuiv); 768 SET_PixelMapusv(disp, _mesa_PixelMapusv); 769 SET_PixelTransferf(disp, _mesa_PixelTransferf); 770 SET_PixelTransferi(disp, _mesa_PixelTransferi); 771 SET_PixelZoom(disp, _mesa_PixelZoom); 772} 773 774 775#endif /* FEATURE_pixel_transfer */ 776 777 778/**********************************************************************/ 779/***** Initialization *****/ 780/**********************************************************************/ 781 782static void 783init_pixelmap(struct gl_pixelmap *map) 784{ 785 map->Size = 1; 786 map->Map[0] = 0.0; 787 map->Map8[0] = 0; 788} 789 790 791/** 792 * Initialize the context's PIXEL attribute group. 793 */ 794void 795_mesa_init_pixel( GLcontext *ctx ) 796{ 797 int i; 798 799 /* Pixel group */ 800 ctx->Pixel.RedBias = 0.0; 801 ctx->Pixel.RedScale = 1.0; 802 ctx->Pixel.GreenBias = 0.0; 803 ctx->Pixel.GreenScale = 1.0; 804 ctx->Pixel.BlueBias = 0.0; 805 ctx->Pixel.BlueScale = 1.0; 806 ctx->Pixel.AlphaBias = 0.0; 807 ctx->Pixel.AlphaScale = 1.0; 808 ctx->Pixel.DepthBias = 0.0; 809 ctx->Pixel.DepthScale = 1.0; 810 ctx->Pixel.IndexOffset = 0; 811 ctx->Pixel.IndexShift = 0; 812 ctx->Pixel.ZoomX = 1.0; 813 ctx->Pixel.ZoomY = 1.0; 814 ctx->Pixel.MapColorFlag = GL_FALSE; 815 ctx->Pixel.MapStencilFlag = GL_FALSE; 816 init_pixelmap(&ctx->PixelMaps.StoS); 817 init_pixelmap(&ctx->PixelMaps.ItoI); 818 init_pixelmap(&ctx->PixelMaps.ItoR); 819 init_pixelmap(&ctx->PixelMaps.ItoG); 820 init_pixelmap(&ctx->PixelMaps.ItoB); 821 init_pixelmap(&ctx->PixelMaps.ItoA); 822 init_pixelmap(&ctx->PixelMaps.RtoR); 823 init_pixelmap(&ctx->PixelMaps.GtoG); 824 init_pixelmap(&ctx->PixelMaps.BtoB); 825 init_pixelmap(&ctx->PixelMaps.AtoA); 826 ASSIGN_4V(ctx->Pixel.PostColorMatrixScale, 1.0, 1.0, 1.0, 1.0); 827 ASSIGN_4V(ctx->Pixel.PostColorMatrixBias, 0.0, 0.0, 0.0, 0.0); 828 for (i = 0; i < COLORTABLE_MAX; i++) { 829 ASSIGN_4V(ctx->Pixel.ColorTableScale[i], 1.0, 1.0, 1.0, 1.0); 830 ASSIGN_4V(ctx->Pixel.ColorTableBias[i], 0.0, 0.0, 0.0, 0.0); 831 ctx->Pixel.ColorTableEnabled[i] = GL_FALSE; 832 } 833 ctx->Pixel.Convolution1DEnabled = GL_FALSE; 834 ctx->Pixel.Convolution2DEnabled = GL_FALSE; 835 ctx->Pixel.Separable2DEnabled = GL_FALSE; 836 for (i = 0; i < 3; i++) { 837 ASSIGN_4V(ctx->Pixel.ConvolutionBorderColor[i], 0.0, 0.0, 0.0, 0.0); 838 ctx->Pixel.ConvolutionBorderMode[i] = GL_REDUCE; 839 ASSIGN_4V(ctx->Pixel.ConvolutionFilterScale[i], 1.0, 1.0, 1.0, 1.0); 840 ASSIGN_4V(ctx->Pixel.ConvolutionFilterBias[i], 0.0, 0.0, 0.0, 0.0); 841 } 842 for (i = 0; i < MAX_CONVOLUTION_WIDTH * MAX_CONVOLUTION_WIDTH * 4; i++) { 843 ctx->Convolution1D.Filter[i] = 0.0; 844 ctx->Convolution2D.Filter[i] = 0.0; 845 ctx->Separable2D.Filter[i] = 0.0; 846 } 847 ASSIGN_4V(ctx->Pixel.PostConvolutionScale, 1.0, 1.0, 1.0, 1.0); 848 ASSIGN_4V(ctx->Pixel.PostConvolutionBias, 0.0, 0.0, 0.0, 0.0); 849 /* GL_SGI_texture_color_table */ 850 ASSIGN_4V(ctx->Pixel.TextureColorTableScale, 1.0, 1.0, 1.0, 1.0); 851 ASSIGN_4V(ctx->Pixel.TextureColorTableBias, 0.0, 0.0, 0.0, 0.0); 852 853 if (ctx->Visual.doubleBufferMode) { 854 ctx->Pixel.ReadBuffer = GL_BACK; 855 } 856 else { 857 ctx->Pixel.ReadBuffer = GL_FRONT; 858 } 859 860 /* Miscellaneous */ 861 ctx->_ImageTransferState = 0; 862} 863