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