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