Home | History | Annotate | Download | only in main
      1 /*
      2  * Mesa 3-D graphics library
      3  *
      4  * Copyright (C) 1999-2008  Brian Paul   All Rights Reserved.
      5  *
      6  * Permission is hereby granted, free of charge, to any person obtaining a
      7  * copy of this software and associated documentation files (the "Software"),
      8  * to deal in the Software without restriction, including without limitation
      9  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
     10  * and/or sell copies of the Software, and to permit persons to whom the
     11  * Software is furnished to do so, subject to the following conditions:
     12  *
     13  * The above copyright notice and this permission notice shall be included
     14  * in all copies or substantial portions of the Software.
     15  *
     16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
     17  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
     19  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
     20  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
     21  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
     22  * 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 "context.h"
     34 #include "macros.h"
     35 #include "pixel.h"
     36 #include "pbo.h"
     37 #include "mtypes.h"
     38 #include "main/dispatch.h"
     39 
     40 
     41 /**********************************************************************/
     42 /*****                    glPixelZoom                             *****/
     43 /**********************************************************************/
     44 
     45 void GLAPIENTRY
     46 _mesa_PixelZoom( GLfloat xfactor, GLfloat yfactor )
     47 {
     48    GET_CURRENT_CONTEXT(ctx);
     49 
     50    if (ctx->Pixel.ZoomX == xfactor &&
     51        ctx->Pixel.ZoomY == yfactor)
     52       return;
     53 
     54    FLUSH_VERTICES(ctx, _NEW_PIXEL);
     55    ctx->Pixel.ZoomX = xfactor;
     56    ctx->Pixel.ZoomY = yfactor;
     57 }
     58 
     59 
     60 
     61 /**********************************************************************/
     62 /*****                         glPixelMap                         *****/
     63 /**********************************************************************/
     64 
     65 /**
     66  * Return pointer to a pixelmap by name.
     67  */
     68 static struct gl_pixelmap *
     69 get_pixelmap(struct gl_context *ctx, GLenum map)
     70 {
     71    switch (map) {
     72    case GL_PIXEL_MAP_I_TO_I:
     73       return &ctx->PixelMaps.ItoI;
     74    case GL_PIXEL_MAP_S_TO_S:
     75       return &ctx->PixelMaps.StoS;
     76    case GL_PIXEL_MAP_I_TO_R:
     77       return &ctx->PixelMaps.ItoR;
     78    case GL_PIXEL_MAP_I_TO_G:
     79       return &ctx->PixelMaps.ItoG;
     80    case GL_PIXEL_MAP_I_TO_B:
     81       return &ctx->PixelMaps.ItoB;
     82    case GL_PIXEL_MAP_I_TO_A:
     83       return &ctx->PixelMaps.ItoA;
     84    case GL_PIXEL_MAP_R_TO_R:
     85       return &ctx->PixelMaps.RtoR;
     86    case GL_PIXEL_MAP_G_TO_G:
     87       return &ctx->PixelMaps.GtoG;
     88    case GL_PIXEL_MAP_B_TO_B:
     89       return &ctx->PixelMaps.BtoB;
     90    case GL_PIXEL_MAP_A_TO_A:
     91       return &ctx->PixelMaps.AtoA;
     92    default:
     93       return NULL;
     94    }
     95 }
     96 
     97 
     98 /**
     99  * Helper routine used by the other _mesa_PixelMap() functions.
    100  */
    101 static void
    102 store_pixelmap(struct gl_context *ctx, GLenum map, GLsizei mapsize,
    103                const GLfloat *values)
    104 {
    105    GLint i;
    106    struct gl_pixelmap *pm = get_pixelmap(ctx, map);
    107    if (!pm) {
    108       _mesa_error(ctx, GL_INVALID_ENUM, "glPixelMap(map)");
    109       return;
    110    }
    111 
    112    switch (map) {
    113    case GL_PIXEL_MAP_S_TO_S:
    114       /* special case */
    115       ctx->PixelMaps.StoS.Size = mapsize;
    116       for (i = 0; i < mapsize; i++) {
    117          ctx->PixelMaps.StoS.Map[i] = (GLfloat)IROUND(values[i]);
    118       }
    119       break;
    120    case GL_PIXEL_MAP_I_TO_I:
    121       /* special case */
    122       ctx->PixelMaps.ItoI.Size = mapsize;
    123       for (i = 0; i < mapsize; i++) {
    124          ctx->PixelMaps.ItoI.Map[i] = values[i];
    125       }
    126       break;
    127    default:
    128       /* general case */
    129       pm->Size = mapsize;
    130       for (i = 0; i < mapsize; i++) {
    131          GLfloat val = CLAMP(values[i], 0.0F, 1.0F);
    132          pm->Map[i] = val;
    133       }
    134    }
    135 }
    136 
    137 
    138 /**
    139  * Convenience wrapper for _mesa_validate_pbo_access() for gl[Get]PixelMap().
    140  */
    141 static GLboolean
    142 validate_pbo_access(struct gl_context *ctx,
    143                     struct gl_pixelstore_attrib *pack, GLsizei mapsize,
    144                     GLenum format, GLenum type, GLsizei clientMemSize,
    145                     const GLvoid *ptr)
    146 {
    147    GLboolean ok;
    148 
    149    /* Note, need to use DefaultPacking and Unpack's buffer object */
    150    _mesa_reference_buffer_object(ctx,
    151                                  &ctx->DefaultPacking.BufferObj,
    152                                  pack->BufferObj);
    153 
    154    ok = _mesa_validate_pbo_access(1, &ctx->DefaultPacking, mapsize, 1, 1,
    155                                   format, type, clientMemSize, ptr);
    156 
    157    /* restore */
    158    _mesa_reference_buffer_object(ctx,
    159                                  &ctx->DefaultPacking.BufferObj,
    160                                  ctx->Shared->NullBufferObj);
    161 
    162    if (!ok) {
    163       if (_mesa_is_bufferobj(pack->BufferObj)) {
    164          _mesa_error(ctx, GL_INVALID_OPERATION,
    165                      "gl[Get]PixelMap*v(out of bounds PBO access)");
    166       } else {
    167          _mesa_error(ctx, GL_INVALID_OPERATION,
    168                      "glGetnPixelMap*vARB(out of bounds access:"
    169                      " bufSize (%d) is too small)", clientMemSize);
    170       }
    171    }
    172    return ok;
    173 }
    174 
    175 
    176 void GLAPIENTRY
    177 _mesa_PixelMapfv( GLenum map, GLsizei mapsize, const GLfloat *values )
    178 {
    179    GET_CURRENT_CONTEXT(ctx);
    180 
    181    /* XXX someday, test against ctx->Const.MaxPixelMapTableSize */
    182    if (mapsize < 1 || mapsize > MAX_PIXEL_MAP_TABLE) {
    183       _mesa_error( ctx, GL_INVALID_VALUE, "glPixelMapfv(mapsize)" );
    184       return;
    185    }
    186 
    187    if (map >= GL_PIXEL_MAP_S_TO_S && map <= GL_PIXEL_MAP_I_TO_A) {
    188       /* test that mapsize is a power of two */
    189       if (!_mesa_is_pow_two(mapsize)) {
    190 	 _mesa_error( ctx, GL_INVALID_VALUE, "glPixelMapfv(mapsize)" );
    191          return;
    192       }
    193    }
    194 
    195    FLUSH_VERTICES(ctx, _NEW_PIXEL);
    196 
    197    if (!validate_pbo_access(ctx, &ctx->Unpack, mapsize, GL_INTENSITY,
    198                             GL_FLOAT, INT_MAX, values)) {
    199       return;
    200    }
    201 
    202    values = (const GLfloat *) _mesa_map_pbo_source(ctx, &ctx->Unpack, values);
    203    if (!values) {
    204       if (_mesa_is_bufferobj(ctx->Unpack.BufferObj)) {
    205          _mesa_error(ctx, GL_INVALID_OPERATION,
    206                      "glPixelMapfv(PBO is mapped)");
    207       }
    208       return;
    209    }
    210 
    211    store_pixelmap(ctx, map, mapsize, values);
    212 
    213    _mesa_unmap_pbo_source(ctx, &ctx->Unpack);
    214 }
    215 
    216 
    217 void GLAPIENTRY
    218 _mesa_PixelMapuiv(GLenum map, GLsizei mapsize, const GLuint *values )
    219 {
    220    GLfloat fvalues[MAX_PIXEL_MAP_TABLE];
    221    GET_CURRENT_CONTEXT(ctx);
    222 
    223    if (mapsize < 1 || mapsize > MAX_PIXEL_MAP_TABLE) {
    224       _mesa_error( ctx, GL_INVALID_VALUE, "glPixelMapuiv(mapsize)" );
    225       return;
    226    }
    227 
    228    if (map >= GL_PIXEL_MAP_S_TO_S && map <= GL_PIXEL_MAP_I_TO_A) {
    229       /* test that mapsize is a power of two */
    230       if (!_mesa_is_pow_two(mapsize)) {
    231 	 _mesa_error( ctx, GL_INVALID_VALUE, "glPixelMapuiv(mapsize)" );
    232          return;
    233       }
    234    }
    235 
    236    FLUSH_VERTICES(ctx, _NEW_PIXEL);
    237 
    238    if (!validate_pbo_access(ctx, &ctx->Unpack, mapsize, GL_INTENSITY,
    239                             GL_UNSIGNED_INT, INT_MAX, values)) {
    240       return;
    241    }
    242 
    243    values = (const GLuint *) _mesa_map_pbo_source(ctx, &ctx->Unpack, values);
    244    if (!values) {
    245       if (_mesa_is_bufferobj(ctx->Unpack.BufferObj)) {
    246          _mesa_error(ctx, GL_INVALID_OPERATION,
    247                      "glPixelMapuiv(PBO is mapped)");
    248       }
    249       return;
    250    }
    251 
    252    /* convert to floats */
    253    if (map == GL_PIXEL_MAP_I_TO_I || map == GL_PIXEL_MAP_S_TO_S) {
    254       GLint i;
    255       for (i = 0; i < mapsize; i++) {
    256          fvalues[i] = (GLfloat) values[i];
    257       }
    258    }
    259    else {
    260       GLint i;
    261       for (i = 0; i < mapsize; i++) {
    262          fvalues[i] = UINT_TO_FLOAT( values[i] );
    263       }
    264    }
    265 
    266    _mesa_unmap_pbo_source(ctx, &ctx->Unpack);
    267 
    268    store_pixelmap(ctx, map, mapsize, fvalues);
    269 }
    270 
    271 
    272 void GLAPIENTRY
    273 _mesa_PixelMapusv(GLenum map, GLsizei mapsize, const GLushort *values )
    274 {
    275    GLfloat fvalues[MAX_PIXEL_MAP_TABLE];
    276    GET_CURRENT_CONTEXT(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, GL_INTENSITY,
    294                             GL_UNSIGNED_SHORT, INT_MAX, 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 
    327 void GLAPIENTRY
    328 _mesa_GetnPixelMapfvARB( GLenum map, GLsizei bufSize, GLfloat *values )
    329 {
    330    GET_CURRENT_CONTEXT(ctx);
    331    GLint mapsize, i;
    332    const struct gl_pixelmap *pm;
    333 
    334    pm = get_pixelmap(ctx, map);
    335    if (!pm) {
    336       _mesa_error(ctx, GL_INVALID_ENUM, "glGetPixelMapfv(map)");
    337       return;
    338    }
    339 
    340    mapsize = pm->Size;
    341 
    342    if (!validate_pbo_access(ctx, &ctx->Pack, mapsize, GL_INTENSITY,
    343                             GL_FLOAT, bufSize, values)) {
    344       return;
    345    }
    346 
    347    values = (GLfloat *) _mesa_map_pbo_dest(ctx, &ctx->Pack, values);
    348    if (!values) {
    349       if (_mesa_is_bufferobj(ctx->Pack.BufferObj)) {
    350          _mesa_error(ctx, GL_INVALID_OPERATION,
    351                      "glGetPixelMapfv(PBO is mapped)");
    352       }
    353       return;
    354    }
    355 
    356    if (map == GL_PIXEL_MAP_S_TO_S) {
    357       /* special case */
    358       for (i = 0; i < mapsize; i++) {
    359          values[i] = (GLfloat) ctx->PixelMaps.StoS.Map[i];
    360       }
    361    }
    362    else {
    363       memcpy(values, pm->Map, mapsize * sizeof(GLfloat));
    364    }
    365 
    366    _mesa_unmap_pbo_dest(ctx, &ctx->Pack);
    367 }
    368 
    369 
    370 void GLAPIENTRY
    371 _mesa_GetPixelMapfv( GLenum map, GLfloat *values )
    372 {
    373    _mesa_GetnPixelMapfvARB(map, INT_MAX, values);
    374 }
    375 
    376 void GLAPIENTRY
    377 _mesa_GetnPixelMapuivARB( GLenum map, GLsizei bufSize, GLuint *values )
    378 {
    379    GET_CURRENT_CONTEXT(ctx);
    380    GLint mapsize, i;
    381    const struct gl_pixelmap *pm;
    382 
    383    pm = get_pixelmap(ctx, map);
    384    if (!pm) {
    385       _mesa_error(ctx, GL_INVALID_ENUM, "glGetPixelMapuiv(map)");
    386       return;
    387    }
    388 
    389    mapsize = pm->Size;
    390 
    391    if (!validate_pbo_access(ctx, &ctx->Pack, mapsize, GL_INTENSITY,
    392                             GL_UNSIGNED_INT, bufSize, values)) {
    393       return;
    394    }
    395 
    396    values = (GLuint *) _mesa_map_pbo_dest(ctx, &ctx->Pack, values);
    397    if (!values) {
    398       if (_mesa_is_bufferobj(ctx->Pack.BufferObj)) {
    399          _mesa_error(ctx, GL_INVALID_OPERATION,
    400                      "glGetPixelMapuiv(PBO is mapped)");
    401       }
    402       return;
    403    }
    404 
    405    if (map == GL_PIXEL_MAP_S_TO_S) {
    406       /* special case */
    407       memcpy(values, ctx->PixelMaps.StoS.Map, mapsize * sizeof(GLint));
    408    }
    409    else {
    410       for (i = 0; i < mapsize; i++) {
    411          values[i] = FLOAT_TO_UINT( pm->Map[i] );
    412       }
    413    }
    414 
    415    _mesa_unmap_pbo_dest(ctx, &ctx->Pack);
    416 }
    417 
    418 
    419 void GLAPIENTRY
    420 _mesa_GetPixelMapuiv( GLenum map, GLuint *values )
    421 {
    422    _mesa_GetnPixelMapuivARB(map, INT_MAX, values);
    423 }
    424 
    425 void GLAPIENTRY
    426 _mesa_GetnPixelMapusvARB( GLenum map, GLsizei bufSize, GLushort *values )
    427 {
    428    GET_CURRENT_CONTEXT(ctx);
    429    GLint mapsize, i;
    430    const struct gl_pixelmap *pm;
    431 
    432    pm = get_pixelmap(ctx, map);
    433    if (!pm) {
    434       _mesa_error(ctx, GL_INVALID_ENUM, "glGetPixelMapusv(map)");
    435       return;
    436    }
    437 
    438    mapsize = pm->Size;
    439 
    440    if (!validate_pbo_access(ctx, &ctx->Pack, mapsize, GL_INTENSITY,
    441                             GL_UNSIGNED_SHORT, bufSize, values)) {
    442       return;
    443    }
    444 
    445    values = (GLushort *) _mesa_map_pbo_dest(ctx, &ctx->Pack, values);
    446    if (!values) {
    447       if (_mesa_is_bufferobj(ctx->Pack.BufferObj)) {
    448          _mesa_error(ctx, GL_INVALID_OPERATION,
    449                      "glGetPixelMapusv(PBO is mapped)");
    450       }
    451       return;
    452    }
    453 
    454    switch (map) {
    455    /* special cases */
    456    case GL_PIXEL_MAP_I_TO_I:
    457       for (i = 0; i < mapsize; i++) {
    458          values[i] = (GLushort) CLAMP(ctx->PixelMaps.ItoI.Map[i], 0.0F, 65535.0F);
    459       }
    460       break;
    461    case GL_PIXEL_MAP_S_TO_S:
    462       for (i = 0; i < mapsize; i++) {
    463          values[i] = (GLushort) CLAMP(ctx->PixelMaps.StoS.Map[i], 0.0F, 65535.0F);
    464       }
    465       break;
    466    default:
    467       for (i = 0; i < mapsize; i++) {
    468          CLAMPED_FLOAT_TO_USHORT(values[i], pm->Map[i] );
    469       }
    470    }
    471 
    472    _mesa_unmap_pbo_dest(ctx, &ctx->Pack);
    473 }
    474 
    475 
    476 void GLAPIENTRY
    477 _mesa_GetPixelMapusv( GLenum map, GLushort *values )
    478 {
    479    _mesa_GetnPixelMapusvARB(map, INT_MAX, values);
    480 }
    481 
    482 
    483 /**********************************************************************/
    484 /*****                       glPixelTransfer                      *****/
    485 /**********************************************************************/
    486 
    487 
    488 /*
    489  * Implements glPixelTransfer[fi] whether called immediately or from a
    490  * display list.
    491  */
    492 void GLAPIENTRY
    493 _mesa_PixelTransferf( GLenum pname, GLfloat param )
    494 {
    495    GET_CURRENT_CONTEXT(ctx);
    496 
    497    switch (pname) {
    498       case GL_MAP_COLOR:
    499          if (ctx->Pixel.MapColorFlag == (param ? GL_TRUE : GL_FALSE))
    500 	    return;
    501 	 FLUSH_VERTICES(ctx, _NEW_PIXEL);
    502          ctx->Pixel.MapColorFlag = param ? GL_TRUE : GL_FALSE;
    503 	 break;
    504       case GL_MAP_STENCIL:
    505          if (ctx->Pixel.MapStencilFlag == (param ? GL_TRUE : GL_FALSE))
    506 	    return;
    507 	 FLUSH_VERTICES(ctx, _NEW_PIXEL);
    508          ctx->Pixel.MapStencilFlag = param ? GL_TRUE : GL_FALSE;
    509 	 break;
    510       case GL_INDEX_SHIFT:
    511          if (ctx->Pixel.IndexShift == (GLint) param)
    512 	    return;
    513 	 FLUSH_VERTICES(ctx, _NEW_PIXEL);
    514          ctx->Pixel.IndexShift = (GLint) param;
    515 	 break;
    516       case GL_INDEX_OFFSET:
    517          if (ctx->Pixel.IndexOffset == (GLint) param)
    518 	    return;
    519 	 FLUSH_VERTICES(ctx, _NEW_PIXEL);
    520          ctx->Pixel.IndexOffset = (GLint) param;
    521 	 break;
    522       case GL_RED_SCALE:
    523          if (ctx->Pixel.RedScale == param)
    524 	    return;
    525 	 FLUSH_VERTICES(ctx, _NEW_PIXEL);
    526          ctx->Pixel.RedScale = param;
    527 	 break;
    528       case GL_RED_BIAS:
    529          if (ctx->Pixel.RedBias == param)
    530 	    return;
    531 	 FLUSH_VERTICES(ctx, _NEW_PIXEL);
    532          ctx->Pixel.RedBias = param;
    533 	 break;
    534       case GL_GREEN_SCALE:
    535          if (ctx->Pixel.GreenScale == param)
    536 	    return;
    537 	 FLUSH_VERTICES(ctx, _NEW_PIXEL);
    538          ctx->Pixel.GreenScale = param;
    539 	 break;
    540       case GL_GREEN_BIAS:
    541          if (ctx->Pixel.GreenBias == param)
    542 	    return;
    543 	 FLUSH_VERTICES(ctx, _NEW_PIXEL);
    544          ctx->Pixel.GreenBias = param;
    545 	 break;
    546       case GL_BLUE_SCALE:
    547          if (ctx->Pixel.BlueScale == param)
    548 	    return;
    549 	 FLUSH_VERTICES(ctx, _NEW_PIXEL);
    550          ctx->Pixel.BlueScale = param;
    551 	 break;
    552       case GL_BLUE_BIAS:
    553          if (ctx->Pixel.BlueBias == param)
    554 	    return;
    555 	 FLUSH_VERTICES(ctx, _NEW_PIXEL);
    556          ctx->Pixel.BlueBias = param;
    557 	 break;
    558       case GL_ALPHA_SCALE:
    559          if (ctx->Pixel.AlphaScale == param)
    560 	    return;
    561 	 FLUSH_VERTICES(ctx, _NEW_PIXEL);
    562          ctx->Pixel.AlphaScale = param;
    563 	 break;
    564       case GL_ALPHA_BIAS:
    565          if (ctx->Pixel.AlphaBias == param)
    566 	    return;
    567 	 FLUSH_VERTICES(ctx, _NEW_PIXEL);
    568          ctx->Pixel.AlphaBias = param;
    569 	 break;
    570       case GL_DEPTH_SCALE:
    571          if (ctx->Pixel.DepthScale == param)
    572 	    return;
    573 	 FLUSH_VERTICES(ctx, _NEW_PIXEL);
    574          ctx->Pixel.DepthScale = param;
    575 	 break;
    576       case GL_DEPTH_BIAS:
    577          if (ctx->Pixel.DepthBias == param)
    578 	    return;
    579 	 FLUSH_VERTICES(ctx, _NEW_PIXEL);
    580          ctx->Pixel.DepthBias = param;
    581 	 break;
    582       default:
    583          _mesa_error( ctx, GL_INVALID_ENUM, "glPixelTransfer(pname)" );
    584          return;
    585    }
    586 }
    587 
    588 
    589 void GLAPIENTRY
    590 _mesa_PixelTransferi( GLenum pname, GLint param )
    591 {
    592    _mesa_PixelTransferf( pname, (GLfloat) param );
    593 }
    594 
    595 
    596 
    597 /**********************************************************************/
    598 /*****                    State Management                        *****/
    599 /**********************************************************************/
    600 
    601 /*
    602  * Return a bitmask of IMAGE_*_BIT flags which to indicate which
    603  * pixel transfer operations are enabled.
    604  */
    605 static void
    606 update_image_transfer_state(struct gl_context *ctx)
    607 {
    608    GLuint mask = 0;
    609 
    610    if (ctx->Pixel.RedScale   != 1.0F || ctx->Pixel.RedBias   != 0.0F ||
    611        ctx->Pixel.GreenScale != 1.0F || ctx->Pixel.GreenBias != 0.0F ||
    612        ctx->Pixel.BlueScale  != 1.0F || ctx->Pixel.BlueBias  != 0.0F ||
    613        ctx->Pixel.AlphaScale != 1.0F || ctx->Pixel.AlphaBias != 0.0F)
    614       mask |= IMAGE_SCALE_BIAS_BIT;
    615 
    616    if (ctx->Pixel.IndexShift || ctx->Pixel.IndexOffset)
    617       mask |= IMAGE_SHIFT_OFFSET_BIT;
    618 
    619    if (ctx->Pixel.MapColorFlag)
    620       mask |= IMAGE_MAP_COLOR_BIT;
    621 
    622    ctx->_ImageTransferState = mask;
    623 }
    624 
    625 
    626 /**
    627  * Update mesa pixel transfer derived state.
    628  */
    629 void _mesa_update_pixel( struct gl_context *ctx, GLuint new_state )
    630 {
    631    if (new_state & _NEW_PIXEL)
    632       update_image_transfer_state(ctx);
    633 }
    634 
    635 
    636 /**********************************************************************/
    637 /*****                      Initialization                        *****/
    638 /**********************************************************************/
    639 
    640 static void
    641 init_pixelmap(struct gl_pixelmap *map)
    642 {
    643    map->Size = 1;
    644    map->Map[0] = 0.0;
    645 }
    646 
    647 
    648 /**
    649  * Initialize the context's PIXEL attribute group.
    650  */
    651 void
    652 _mesa_init_pixel( struct gl_context *ctx )
    653 {
    654    /* Pixel group */
    655    ctx->Pixel.RedBias = 0.0;
    656    ctx->Pixel.RedScale = 1.0;
    657    ctx->Pixel.GreenBias = 0.0;
    658    ctx->Pixel.GreenScale = 1.0;
    659    ctx->Pixel.BlueBias = 0.0;
    660    ctx->Pixel.BlueScale = 1.0;
    661    ctx->Pixel.AlphaBias = 0.0;
    662    ctx->Pixel.AlphaScale = 1.0;
    663    ctx->Pixel.DepthBias = 0.0;
    664    ctx->Pixel.DepthScale = 1.0;
    665    ctx->Pixel.IndexOffset = 0;
    666    ctx->Pixel.IndexShift = 0;
    667    ctx->Pixel.ZoomX = 1.0;
    668    ctx->Pixel.ZoomY = 1.0;
    669    ctx->Pixel.MapColorFlag = GL_FALSE;
    670    ctx->Pixel.MapStencilFlag = GL_FALSE;
    671    init_pixelmap(&ctx->PixelMaps.StoS);
    672    init_pixelmap(&ctx->PixelMaps.ItoI);
    673    init_pixelmap(&ctx->PixelMaps.ItoR);
    674    init_pixelmap(&ctx->PixelMaps.ItoG);
    675    init_pixelmap(&ctx->PixelMaps.ItoB);
    676    init_pixelmap(&ctx->PixelMaps.ItoA);
    677    init_pixelmap(&ctx->PixelMaps.RtoR);
    678    init_pixelmap(&ctx->PixelMaps.GtoG);
    679    init_pixelmap(&ctx->PixelMaps.BtoB);
    680    init_pixelmap(&ctx->PixelMaps.AtoA);
    681 
    682    if (ctx->Visual.doubleBufferMode) {
    683       ctx->Pixel.ReadBuffer = GL_BACK;
    684    }
    685    else {
    686       ctx->Pixel.ReadBuffer = GL_FRONT;
    687    }
    688 
    689    /* Miscellaneous */
    690    ctx->_ImageTransferState = 0;
    691 }
    692