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