• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
_mesa_PixelZoom(GLfloat xfactor,GLfloat yfactor)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 *
get_pixelmap(struct gl_context * ctx,GLenum map)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
store_pixelmap(struct gl_context * ctx,GLenum map,GLsizei mapsize,const GLfloat * values)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
validate_pbo_access(struct gl_context * ctx,struct gl_pixelstore_attrib * pack,GLsizei mapsize,GLenum format,GLenum type,GLsizei clientMemSize,const GLvoid * ptr)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
_mesa_PixelMapfv(GLenum map,GLsizei mapsize,const GLfloat * values)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
_mesa_PixelMapuiv(GLenum map,GLsizei mapsize,const GLuint * values)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
_mesa_PixelMapusv(GLenum map,GLsizei mapsize,const GLushort * values)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, "glPixelMapusv(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
_mesa_GetnPixelMapfvARB(GLenum map,GLsizei bufSize,GLfloat * values)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
_mesa_GetPixelMapfv(GLenum map,GLfloat * values)371 _mesa_GetPixelMapfv( GLenum map, GLfloat *values )
372 {
373    _mesa_GetnPixelMapfvARB(map, INT_MAX, values);
374 }
375 
376 void GLAPIENTRY
_mesa_GetnPixelMapuivARB(GLenum map,GLsizei bufSize,GLuint * values)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
_mesa_GetPixelMapuiv(GLenum map,GLuint * values)420 _mesa_GetPixelMapuiv( GLenum map, GLuint *values )
421 {
422    _mesa_GetnPixelMapuivARB(map, INT_MAX, values);
423 }
424 
425 void GLAPIENTRY
_mesa_GetnPixelMapusvARB(GLenum map,GLsizei bufSize,GLushort * values)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
_mesa_GetPixelMapusv(GLenum map,GLushort * values)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
_mesa_PixelTransferf(GLenum pname,GLfloat param)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
_mesa_PixelTransferi(GLenum pname,GLint param)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 /**
603  * Update mesa pixel transfer derived state to indicate which operations are
604  * enabled.
605  */
606 void
_mesa_update_pixel(struct gl_context * ctx)607 _mesa_update_pixel( 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 /*****                      Initialization                        *****/
629 /**********************************************************************/
630 
631 static void
init_pixelmap(struct gl_pixelmap * map)632 init_pixelmap(struct gl_pixelmap *map)
633 {
634    map->Size = 1;
635    map->Map[0] = 0.0;
636 }
637 
638 
639 /**
640  * Initialize the context's PIXEL attribute group.
641  */
642 void
_mesa_init_pixel(struct gl_context * ctx)643 _mesa_init_pixel( struct gl_context *ctx )
644 {
645    /* Pixel group */
646    ctx->Pixel.RedBias = 0.0;
647    ctx->Pixel.RedScale = 1.0;
648    ctx->Pixel.GreenBias = 0.0;
649    ctx->Pixel.GreenScale = 1.0;
650    ctx->Pixel.BlueBias = 0.0;
651    ctx->Pixel.BlueScale = 1.0;
652    ctx->Pixel.AlphaBias = 0.0;
653    ctx->Pixel.AlphaScale = 1.0;
654    ctx->Pixel.DepthBias = 0.0;
655    ctx->Pixel.DepthScale = 1.0;
656    ctx->Pixel.IndexOffset = 0;
657    ctx->Pixel.IndexShift = 0;
658    ctx->Pixel.ZoomX = 1.0;
659    ctx->Pixel.ZoomY = 1.0;
660    ctx->Pixel.MapColorFlag = GL_FALSE;
661    ctx->Pixel.MapStencilFlag = GL_FALSE;
662    init_pixelmap(&ctx->PixelMaps.StoS);
663    init_pixelmap(&ctx->PixelMaps.ItoI);
664    init_pixelmap(&ctx->PixelMaps.ItoR);
665    init_pixelmap(&ctx->PixelMaps.ItoG);
666    init_pixelmap(&ctx->PixelMaps.ItoB);
667    init_pixelmap(&ctx->PixelMaps.ItoA);
668    init_pixelmap(&ctx->PixelMaps.RtoR);
669    init_pixelmap(&ctx->PixelMaps.GtoG);
670    init_pixelmap(&ctx->PixelMaps.BtoB);
671    init_pixelmap(&ctx->PixelMaps.AtoA);
672 
673    if (ctx->Visual.doubleBufferMode) {
674       ctx->Pixel.ReadBuffer = GL_BACK;
675    }
676    else {
677       ctx->Pixel.ReadBuffer = GL_FRONT;
678    }
679 
680    /* Miscellaneous */
681    ctx->_ImageTransferState = 0;
682 }
683