Subversion Repositories Kolibri OS

Rev

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 "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.0, 65535.);
  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.0, 65535.);
  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.