Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

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