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 "api_exec_decl.h"
39
40 #include <math.h>
41
42 /**********************************************************************/
43 /***** glPixelZoom *****/
44 /**********************************************************************/
45
46 void GLAPIENTRY
_mesa_PixelZoom(GLfloat xfactor,GLfloat yfactor)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, GL_PIXEL_MODE_BIT);
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 *
get_pixelmap(struct gl_context * ctx,GLenum map)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
store_pixelmap(struct gl_context * ctx,GLenum map,GLsizei mapsize,const GLfloat * values)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] = roundf(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
validate_pbo_access(struct gl_context * ctx,struct gl_pixelstore_attrib * pack,GLsizei mapsize,GLenum format,GLenum type,GLsizei clientMemSize,const GLvoid * ptr)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, NULL);
161
162 if (!ok) {
163 if (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 (!util_is_power_of_two_or_zero(mapsize)) {
190 _mesa_error( ctx, GL_INVALID_VALUE, "glPixelMapfv(mapsize)" );
191 return;
192 }
193 }
194
195 FLUSH_VERTICES(ctx, _NEW_PIXEL, 0);
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 (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 (!util_is_power_of_two_or_zero(mapsize)) {
231 _mesa_error( ctx, GL_INVALID_VALUE, "glPixelMapuiv(mapsize)" );
232 return;
233 }
234 }
235
236 FLUSH_VERTICES(ctx, _NEW_PIXEL, 0);
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 (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 (!util_is_power_of_two_or_zero(mapsize)) {
286 _mesa_error( ctx, GL_INVALID_VALUE, "glPixelMapusv(mapsize)" );
287 return;
288 }
289 }
290
291 FLUSH_VERTICES(ctx, _NEW_PIXEL, 0);
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 (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 if (ctx->Pack.BufferObj)
348 ctx->Pack.BufferObj->UsageHistory |= USAGE_PIXEL_PACK_BUFFER;
349
350 values = (GLfloat *) _mesa_map_pbo_dest(ctx, &ctx->Pack, values);
351 if (!values) {
352 if (ctx->Pack.BufferObj) {
353 _mesa_error(ctx, GL_INVALID_OPERATION,
354 "glGetPixelMapfv(PBO is mapped)");
355 }
356 return;
357 }
358
359 if (map == GL_PIXEL_MAP_S_TO_S) {
360 /* special case */
361 for (i = 0; i < mapsize; i++) {
362 values[i] = (GLfloat) ctx->PixelMaps.StoS.Map[i];
363 }
364 }
365 else {
366 memcpy(values, pm->Map, mapsize * sizeof(GLfloat));
367 }
368
369 _mesa_unmap_pbo_dest(ctx, &ctx->Pack);
370 }
371
372
373 void GLAPIENTRY
_mesa_GetPixelMapfv(GLenum map,GLfloat * values)374 _mesa_GetPixelMapfv( GLenum map, GLfloat *values )
375 {
376 _mesa_GetnPixelMapfvARB(map, INT_MAX, values);
377 }
378
379 void GLAPIENTRY
_mesa_GetnPixelMapuivARB(GLenum map,GLsizei bufSize,GLuint * values)380 _mesa_GetnPixelMapuivARB( GLenum map, GLsizei bufSize, GLuint *values )
381 {
382 GET_CURRENT_CONTEXT(ctx);
383 GLint mapsize, i;
384 const struct gl_pixelmap *pm;
385
386 pm = get_pixelmap(ctx, map);
387 if (!pm) {
388 _mesa_error(ctx, GL_INVALID_ENUM, "glGetPixelMapuiv(map)");
389 return;
390 }
391
392 mapsize = pm->Size;
393
394 if (!validate_pbo_access(ctx, &ctx->Pack, mapsize, GL_INTENSITY,
395 GL_UNSIGNED_INT, bufSize, values)) {
396 return;
397 }
398
399 if (ctx->Pack.BufferObj)
400 ctx->Pack.BufferObj->UsageHistory |= USAGE_PIXEL_PACK_BUFFER;
401
402 values = (GLuint *) _mesa_map_pbo_dest(ctx, &ctx->Pack, values);
403 if (!values) {
404 if (ctx->Pack.BufferObj) {
405 _mesa_error(ctx, GL_INVALID_OPERATION,
406 "glGetPixelMapuiv(PBO is mapped)");
407 }
408 return;
409 }
410
411 if (map == GL_PIXEL_MAP_S_TO_S) {
412 /* special case */
413 memcpy(values, ctx->PixelMaps.StoS.Map, mapsize * sizeof(GLint));
414 }
415 else {
416 for (i = 0; i < mapsize; i++) {
417 values[i] = FLOAT_TO_UINT( pm->Map[i] );
418 }
419 }
420
421 _mesa_unmap_pbo_dest(ctx, &ctx->Pack);
422 }
423
424
425 void GLAPIENTRY
_mesa_GetPixelMapuiv(GLenum map,GLuint * values)426 _mesa_GetPixelMapuiv( GLenum map, GLuint *values )
427 {
428 _mesa_GetnPixelMapuivARB(map, INT_MAX, values);
429 }
430
431 void GLAPIENTRY
_mesa_GetnPixelMapusvARB(GLenum map,GLsizei bufSize,GLushort * values)432 _mesa_GetnPixelMapusvARB( GLenum map, GLsizei bufSize, GLushort *values )
433 {
434 GET_CURRENT_CONTEXT(ctx);
435 GLint mapsize, i;
436 const struct gl_pixelmap *pm;
437
438 pm = get_pixelmap(ctx, map);
439 if (!pm) {
440 _mesa_error(ctx, GL_INVALID_ENUM, "glGetPixelMapusv(map)");
441 return;
442 }
443
444 mapsize = pm->Size;
445
446 if (!validate_pbo_access(ctx, &ctx->Pack, mapsize, GL_INTENSITY,
447 GL_UNSIGNED_SHORT, bufSize, values)) {
448 return;
449 }
450
451 if (ctx->Pack.BufferObj)
452 ctx->Pack.BufferObj->UsageHistory |= USAGE_PIXEL_PACK_BUFFER;
453
454 values = (GLushort *) _mesa_map_pbo_dest(ctx, &ctx->Pack, values);
455 if (!values) {
456 if (ctx->Pack.BufferObj) {
457 _mesa_error(ctx, GL_INVALID_OPERATION,
458 "glGetPixelMapusv(PBO is mapped)");
459 }
460 return;
461 }
462
463 switch (map) {
464 /* special cases */
465 case GL_PIXEL_MAP_I_TO_I:
466 for (i = 0; i < mapsize; i++) {
467 values[i] = (GLushort) CLAMP(ctx->PixelMaps.ItoI.Map[i], 0.0F, 65535.0F);
468 }
469 break;
470 case GL_PIXEL_MAP_S_TO_S:
471 for (i = 0; i < mapsize; i++) {
472 values[i] = (GLushort) CLAMP(ctx->PixelMaps.StoS.Map[i], 0.0F, 65535.0F);
473 }
474 break;
475 default:
476 for (i = 0; i < mapsize; i++) {
477 CLAMPED_FLOAT_TO_USHORT(values[i], pm->Map[i] );
478 }
479 }
480
481 _mesa_unmap_pbo_dest(ctx, &ctx->Pack);
482 }
483
484
485 void GLAPIENTRY
_mesa_GetPixelMapusv(GLenum map,GLushort * values)486 _mesa_GetPixelMapusv( GLenum map, GLushort *values )
487 {
488 _mesa_GetnPixelMapusvARB(map, INT_MAX, values);
489 }
490
491
492 /**********************************************************************/
493 /***** glPixelTransfer *****/
494 /**********************************************************************/
495
496
497 /*
498 * Implements glPixelTransfer[fi] whether called immediately or from a
499 * display list.
500 */
501 void GLAPIENTRY
_mesa_PixelTransferf(GLenum pname,GLfloat param)502 _mesa_PixelTransferf( GLenum pname, GLfloat param )
503 {
504 GET_CURRENT_CONTEXT(ctx);
505
506 switch (pname) {
507 case GL_MAP_COLOR:
508 if (ctx->Pixel.MapColorFlag == (param ? GL_TRUE : GL_FALSE))
509 return;
510 FLUSH_VERTICES(ctx, _NEW_PIXEL, GL_PIXEL_MODE_BIT);
511 ctx->Pixel.MapColorFlag = param ? GL_TRUE : GL_FALSE;
512 break;
513 case GL_MAP_STENCIL:
514 if (ctx->Pixel.MapStencilFlag == (param ? GL_TRUE : GL_FALSE))
515 return;
516 FLUSH_VERTICES(ctx, _NEW_PIXEL, GL_PIXEL_MODE_BIT);
517 ctx->Pixel.MapStencilFlag = param ? GL_TRUE : GL_FALSE;
518 break;
519 case GL_INDEX_SHIFT:
520 if (ctx->Pixel.IndexShift == (GLint) param)
521 return;
522 FLUSH_VERTICES(ctx, _NEW_PIXEL, GL_PIXEL_MODE_BIT);
523 ctx->Pixel.IndexShift = (GLint) param;
524 break;
525 case GL_INDEX_OFFSET:
526 if (ctx->Pixel.IndexOffset == (GLint) param)
527 return;
528 FLUSH_VERTICES(ctx, _NEW_PIXEL, GL_PIXEL_MODE_BIT);
529 ctx->Pixel.IndexOffset = (GLint) param;
530 break;
531 case GL_RED_SCALE:
532 if (ctx->Pixel.RedScale == param)
533 return;
534 FLUSH_VERTICES(ctx, _NEW_PIXEL, GL_PIXEL_MODE_BIT);
535 ctx->Pixel.RedScale = param;
536 break;
537 case GL_RED_BIAS:
538 if (ctx->Pixel.RedBias == param)
539 return;
540 FLUSH_VERTICES(ctx, _NEW_PIXEL, GL_PIXEL_MODE_BIT);
541 ctx->Pixel.RedBias = param;
542 break;
543 case GL_GREEN_SCALE:
544 if (ctx->Pixel.GreenScale == param)
545 return;
546 FLUSH_VERTICES(ctx, _NEW_PIXEL, GL_PIXEL_MODE_BIT);
547 ctx->Pixel.GreenScale = param;
548 break;
549 case GL_GREEN_BIAS:
550 if (ctx->Pixel.GreenBias == param)
551 return;
552 FLUSH_VERTICES(ctx, _NEW_PIXEL, GL_PIXEL_MODE_BIT);
553 ctx->Pixel.GreenBias = param;
554 break;
555 case GL_BLUE_SCALE:
556 if (ctx->Pixel.BlueScale == param)
557 return;
558 FLUSH_VERTICES(ctx, _NEW_PIXEL, GL_PIXEL_MODE_BIT);
559 ctx->Pixel.BlueScale = param;
560 break;
561 case GL_BLUE_BIAS:
562 if (ctx->Pixel.BlueBias == param)
563 return;
564 FLUSH_VERTICES(ctx, _NEW_PIXEL, GL_PIXEL_MODE_BIT);
565 ctx->Pixel.BlueBias = param;
566 break;
567 case GL_ALPHA_SCALE:
568 if (ctx->Pixel.AlphaScale == param)
569 return;
570 FLUSH_VERTICES(ctx, _NEW_PIXEL, GL_PIXEL_MODE_BIT);
571 ctx->Pixel.AlphaScale = param;
572 break;
573 case GL_ALPHA_BIAS:
574 if (ctx->Pixel.AlphaBias == param)
575 return;
576 FLUSH_VERTICES(ctx, _NEW_PIXEL, GL_PIXEL_MODE_BIT);
577 ctx->Pixel.AlphaBias = param;
578 break;
579 case GL_DEPTH_SCALE:
580 if (ctx->Pixel.DepthScale == param)
581 return;
582 FLUSH_VERTICES(ctx, _NEW_PIXEL, GL_PIXEL_MODE_BIT);
583 ctx->Pixel.DepthScale = param;
584 break;
585 case GL_DEPTH_BIAS:
586 if (ctx->Pixel.DepthBias == param)
587 return;
588 FLUSH_VERTICES(ctx, _NEW_PIXEL, GL_PIXEL_MODE_BIT);
589 ctx->Pixel.DepthBias = param;
590 break;
591 default:
592 _mesa_error( ctx, GL_INVALID_ENUM, "glPixelTransfer(pname)" );
593 return;
594 }
595 }
596
597
598 void GLAPIENTRY
_mesa_PixelTransferi(GLenum pname,GLint param)599 _mesa_PixelTransferi( GLenum pname, GLint param )
600 {
601 _mesa_PixelTransferf( pname, (GLfloat) param );
602 }
603
604
605
606 /**********************************************************************/
607 /***** State Management *****/
608 /**********************************************************************/
609
610
611 /**
612 * Update mesa pixel transfer derived state to indicate which operations are
613 * enabled.
614 */
615 void
_mesa_update_pixel(struct gl_context * ctx)616 _mesa_update_pixel( struct gl_context *ctx )
617 {
618 GLuint mask = 0;
619
620 if (ctx->Pixel.RedScale != 1.0F || ctx->Pixel.RedBias != 0.0F ||
621 ctx->Pixel.GreenScale != 1.0F || ctx->Pixel.GreenBias != 0.0F ||
622 ctx->Pixel.BlueScale != 1.0F || ctx->Pixel.BlueBias != 0.0F ||
623 ctx->Pixel.AlphaScale != 1.0F || ctx->Pixel.AlphaBias != 0.0F)
624 mask |= IMAGE_SCALE_BIAS_BIT;
625
626 if (ctx->Pixel.IndexShift || ctx->Pixel.IndexOffset)
627 mask |= IMAGE_SHIFT_OFFSET_BIT;
628
629 if (ctx->Pixel.MapColorFlag)
630 mask |= IMAGE_MAP_COLOR_BIT;
631
632 ctx->_ImageTransferState = mask;
633 }
634
635
636 /**********************************************************************/
637 /***** Initialization *****/
638 /**********************************************************************/
639
640 static void
init_pixelmap(struct gl_pixelmap * map)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
_mesa_init_pixel(struct gl_context * ctx)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