6a0664858517b8a51fd1847391e9c60a1b546777
[mesa.git] / src / mesa / drivers / x11 / xm_span.c
1 /*
2 * Mesa 3-D graphics library
3 * Version: 6.3
4 *
5 * Copyright (C) 1999-2004 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 #include "glxheader.h"
26 #include "main/context.h"
27 #include "main/macros.h"
28 #include "main/imports.h"
29 #include "main/mtypes.h"
30 #include "xmesaP.h"
31
32 #include "swrast/swrast.h"
33
34
35 /*
36 * The following functions are used to trap XGetImage() calls which
37 * generate BadMatch errors if the drawable isn't mapped.
38 */
39
40 static int caught_xgetimage_error = 0;
41 static int (*old_xerror_handler)( XMesaDisplay *dpy, XErrorEvent *ev );
42 static unsigned long xgetimage_serial;
43
44 /*
45 * This is the error handler which will be called if XGetImage fails.
46 */
47 static int xgetimage_error_handler( XMesaDisplay *dpy, XErrorEvent *ev )
48 {
49 if (ev->serial==xgetimage_serial && ev->error_code==BadMatch) {
50 /* caught the expected error */
51 caught_xgetimage_error = 0;
52 }
53 else {
54 /* call the original X error handler, if any. otherwise ignore */
55 if (old_xerror_handler) {
56 (*old_xerror_handler)( dpy, ev );
57 }
58 }
59 return 0;
60 }
61
62
63 /*
64 * Call this right before XGetImage to setup error trap.
65 */
66 static void catch_xgetimage_errors( XMesaDisplay *dpy )
67 {
68 xgetimage_serial = NextRequest( dpy );
69 old_xerror_handler = XSetErrorHandler( xgetimage_error_handler );
70 caught_xgetimage_error = 0;
71 }
72
73
74 /*
75 * Call this right after XGetImage to check if an error occured.
76 */
77 static int check_xgetimage_errors( void )
78 {
79 /* restore old handler */
80 (void) XSetErrorHandler( old_xerror_handler );
81 /* return 0=no error, 1=error caught */
82 return caught_xgetimage_error;
83 }
84
85
86 /*
87 * Read a pixel from an X drawable.
88 */
89 static unsigned long read_pixel( XMesaDisplay *dpy,
90 XMesaDrawable d, int x, int y )
91 {
92 unsigned long p;
93 XMesaImage *pixel = NULL;
94 int error;
95
96 catch_xgetimage_errors( dpy );
97 pixel = XGetImage( dpy, d, x, y, 1, 1, AllPlanes, ZPixmap );
98 error = check_xgetimage_errors();
99 if (pixel && !error) {
100 p = XMesaGetPixel( pixel, 0, 0 );
101 }
102 else {
103 p = 0;
104 }
105 if (pixel) {
106 XMesaDestroyImage( pixel );
107 }
108 return p;
109 }
110
111
112
113 /*
114 * The Mesa library needs to be able to draw pixels in a number of ways:
115 * 1. RGB vs Color Index
116 * 2. as horizontal spans (polygons, images) vs random locations (points,
117 * lines)
118 * 3. different color per-pixel or same color for all pixels
119 *
120 * Furthermore, the X driver needs to support rendering to 3 possible
121 * "buffers", usually one, but sometimes two at a time:
122 * 1. The front buffer as an X window
123 * 2. The back buffer as a Pixmap
124 * 3. The back buffer as an XImage
125 *
126 * Finally, if the back buffer is an XImage, we can avoid using XPutPixel and
127 * optimize common cases such as 24-bit and 8-bit modes.
128 *
129 * By multiplication, there's at least 48 possible combinations of the above.
130 *
131 * Below are implementations of the most commonly used combinations. They are
132 * accessed through function pointers which get initialized here and are used
133 * directly from the Mesa library. The 8 function pointers directly correspond
134 * to the first 3 cases listed above.
135 *
136 *
137 * The function naming convention is:
138 *
139 * [put|get]_[row|values]_[format]_[pixmap|ximage]
140 *
141 * New functions optimized for specific cases can be added without too much
142 * trouble. An example might be the 24-bit TrueColor mode 8A8R8G8B which is
143 * found on IBM RS/6000 X servers.
144 */
145
146
147
148
149 /**********************************************************************/
150 /*** Write COLOR SPAN functions ***/
151 /**********************************************************************/
152
153
154 #define PUT_ROW_ARGS \
155 struct gl_context *ctx, \
156 struct gl_renderbuffer *rb, \
157 GLuint n, GLint x, GLint y, \
158 const void *values, const GLubyte mask[]
159
160 #define RGB_SPAN_ARGS \
161 struct gl_context *ctx, \
162 struct gl_renderbuffer *rb, \
163 GLuint n, GLint x, GLint y, \
164 const void *values, const GLubyte mask[]
165
166
167 #define GET_XRB(XRB) \
168 struct xmesa_renderbuffer *XRB = xmesa_renderbuffer(rb)
169
170
171 /*
172 * Write a span of PF_TRUECOLOR pixels to a pixmap.
173 */
174 static void put_row_TRUECOLOR_pixmap( PUT_ROW_ARGS )
175 {
176 const GLubyte (*rgba)[4] = (const GLubyte (*)[4]) values;
177 const XMesaContext xmesa = XMESA_CONTEXT(ctx);
178 GET_XRB(xrb);
179 XMesaDisplay *dpy = XMESA_BUFFER(ctx->DrawBuffer)->display;
180 XMesaDrawable buffer = xrb->drawable;
181 XMesaGC gc = XMESA_BUFFER(ctx->DrawBuffer)->gc;
182 register GLuint i;
183
184 y = YFLIP(xrb, y);
185 if (mask) {
186 for (i=0;i<n;i++,x++) {
187 if (mask[i]) {
188 unsigned long p;
189 PACK_TRUECOLOR( p, rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP] );
190 XMesaSetForeground( dpy, gc, p );
191 XMesaDrawPoint( dpy, buffer, gc, (int) x, (int) y );
192 }
193 }
194 }
195 else {
196 /* draw all pixels */
197 XMesaImage *rowimg = XMESA_BUFFER(ctx->DrawBuffer)->rowimage;
198 for (i=0;i<n;i++) {
199 unsigned long p;
200 PACK_TRUECOLOR( p, rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP] );
201 XMesaPutPixel( rowimg, i, 0, p );
202 }
203 XMesaPutImage( dpy, buffer, gc, rowimg, 0, 0, x, y, n, 1 );
204 }
205 }
206
207
208 /*
209 * Write a span of PF_TRUECOLOR pixels to a pixmap.
210 */
211 static void put_row_rgb_TRUECOLOR_pixmap( RGB_SPAN_ARGS )
212 {
213 const GLubyte (*rgb)[3] = (const GLubyte (*)[3]) values;
214 const XMesaContext xmesa = XMESA_CONTEXT(ctx);
215 GET_XRB(xrb);
216 XMesaDisplay *dpy = xmesa->xm_visual->display;
217 XMesaDrawable buffer = xrb->drawable;
218 XMesaGC gc = XMESA_BUFFER(ctx->DrawBuffer)->gc;
219 register GLuint i;
220 y = YFLIP(xrb, y);
221 if (mask) {
222 for (i=0;i<n;i++,x++) {
223 if (mask[i]) {
224 unsigned long p;
225 PACK_TRUECOLOR( p, rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP] );
226 XMesaSetForeground( dpy, gc, p );
227 XMesaDrawPoint( dpy, buffer, gc, (int) x, (int) y );
228 }
229 }
230 }
231 else {
232 /* draw all pixels */
233 XMesaImage *rowimg = XMESA_BUFFER(ctx->DrawBuffer)->rowimage;
234 for (i=0;i<n;i++) {
235 unsigned long p;
236 PACK_TRUECOLOR( p, rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP] );
237 XMesaPutPixel( rowimg, i, 0, p );
238 }
239 XMesaPutImage( dpy, buffer, gc, rowimg, 0, 0, x, y, n, 1 );
240 }
241 }
242
243 /*
244 * Write a span of PF_TRUEDITHER pixels to a pixmap.
245 */
246 static void put_row_TRUEDITHER_pixmap( PUT_ROW_ARGS )
247 {
248 const GLubyte (*rgba)[4] = (const GLubyte (*)[4]) values;
249 const XMesaContext xmesa = XMESA_CONTEXT(ctx);
250 GET_XRB(xrb);
251 XMesaDisplay *dpy = xmesa->xm_visual->display;
252 XMesaDrawable buffer = xrb->drawable;
253 XMesaGC gc = XMESA_BUFFER(ctx->DrawBuffer)->gc;
254 register GLuint i;
255 y = YFLIP(xrb, y);
256 if (mask) {
257 for (i=0;i<n;i++,x++) {
258 if (mask[i]) {
259 unsigned long p;
260 PACK_TRUEDITHER(p, x, y, rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP]);
261 XMesaSetForeground( dpy, gc, p );
262 XMesaDrawPoint( dpy, buffer, gc, (int) x, (int) y );
263 }
264 }
265 }
266 else {
267 XMesaImage *rowimg = XMESA_BUFFER(ctx->DrawBuffer)->rowimage;
268 for (i=0;i<n;i++) {
269 unsigned long p;
270 PACK_TRUEDITHER(p, x+i, y, rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP]);
271 XMesaPutPixel( rowimg, i, 0, p );
272 }
273 XMesaPutImage( dpy, buffer, gc, rowimg, 0, 0, x, y, n, 1 );
274 }
275 }
276
277
278 /*
279 * Write a span of PF_TRUEDITHER pixels to a pixmap (no alpha).
280 */
281 static void put_row_rgb_TRUEDITHER_pixmap( RGB_SPAN_ARGS )
282 {
283 const GLubyte (*rgb)[3] = (const GLubyte (*)[3]) values;
284 const XMesaContext xmesa = XMESA_CONTEXT(ctx);
285 GET_XRB(xrb);
286 XMesaDisplay *dpy = xmesa->xm_visual->display;
287 XMesaDrawable buffer = xrb->drawable;
288 XMesaGC gc = XMESA_BUFFER(ctx->DrawBuffer)->gc;
289 register GLuint i;
290 y = YFLIP(xrb, y);
291 if (mask) {
292 for (i=0;i<n;i++,x++) {
293 if (mask[i]) {
294 unsigned long p;
295 PACK_TRUEDITHER(p, x, y, rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP]);
296 XMesaSetForeground( dpy, gc, p );
297 XMesaDrawPoint( dpy, buffer, gc, (int) x, (int) y );
298 }
299 }
300 }
301 else {
302 XMesaImage *rowimg = XMESA_BUFFER(ctx->DrawBuffer)->rowimage;
303 for (i=0;i<n;i++) {
304 unsigned long p;
305 PACK_TRUEDITHER(p, x+i, y, rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP]);
306 XMesaPutPixel( rowimg, i, 0, p );
307 }
308 XMesaPutImage( dpy, buffer, gc, rowimg, 0, 0, x, y, n, 1 );
309 }
310 }
311
312
313 /*
314 * Write a span of PF_8A8B8G8R pixels to a pixmap.
315 */
316 static void put_row_8A8B8G8R_pixmap( PUT_ROW_ARGS )
317 {
318 const GLubyte (*rgba)[4] = (const GLubyte (*)[4]) values;
319 const XMesaContext xmesa = XMESA_CONTEXT(ctx);
320 GET_XRB(xrb);
321 XMesaDisplay *dpy = xmesa->xm_visual->display;
322 XMesaDrawable buffer = xrb->drawable;
323 XMesaGC gc = XMESA_BUFFER(ctx->DrawBuffer)->gc;
324 register GLuint i;
325 y = YFLIP(xrb, y);
326 if (mask) {
327 for (i=0;i<n;i++,x++) {
328 if (mask[i]) {
329 XMesaSetForeground( dpy, gc,
330 PACK_8A8B8G8R(rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP], rgba[i][ACOMP]) );
331 XMesaDrawPoint( dpy, buffer, gc, (int) x, (int) y );
332 }
333 }
334 }
335 else {
336 /* draw all pixels */
337 XMesaImage *rowimg = XMESA_BUFFER(ctx->DrawBuffer)->rowimage;
338 register GLuint *ptr4 = (GLuint *) rowimg->data;
339 for (i=0;i<n;i++) {
340 *ptr4++ = PACK_8A8B8G8R( rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP], rgba[i][ACOMP] );
341 }
342 XMesaPutImage( dpy, buffer, gc, rowimg, 0, 0, x, y, n, 1 );
343 }
344 }
345
346
347 /*
348 * Write a span of PF_8A8B8G8R pixels to a pixmap (no alpha).
349 */
350 static void put_row_rgb_8A8B8G8R_pixmap( RGB_SPAN_ARGS )
351 {
352 const GLubyte (*rgb)[3] = (const GLubyte (*)[3]) values;
353 const XMesaContext xmesa = XMESA_CONTEXT(ctx);
354 GET_XRB(xrb);
355 XMesaDisplay *dpy = xmesa->xm_visual->display;
356 XMesaDrawable buffer = xrb->drawable;
357 XMesaGC gc = XMESA_BUFFER(ctx->DrawBuffer)->gc;
358 register GLuint i;
359 y = YFLIP(xrb, y);
360 if (mask) {
361 for (i=0;i<n;i++,x++) {
362 if (mask[i]) {
363 XMesaSetForeground( dpy, gc,
364 PACK_8B8G8R(rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP]) );
365 XMesaDrawPoint( dpy, buffer, gc, (int) x, (int) y );
366 }
367 }
368 }
369 else {
370 /* draw all pixels */
371 XMesaImage *rowimg = XMESA_BUFFER(ctx->DrawBuffer)->rowimage;
372 register GLuint *ptr4 = (GLuint *) rowimg->data;
373 for (i=0;i<n;i++) {
374 *ptr4++ = PACK_8B8G8R(rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP]);
375 }
376 XMesaPutImage( dpy, buffer, gc, rowimg, 0, 0, x, y, n, 1 );
377 }
378 }
379
380 /*
381 * Write a span of PF_8A8R8G8B pixels to a pixmap.
382 */
383 static void put_row_8A8R8G8B_pixmap( PUT_ROW_ARGS )
384 {
385 const GLubyte (*rgba)[4] = (const GLubyte (*)[4]) values;
386 const XMesaContext xmesa = XMESA_CONTEXT(ctx);
387 GET_XRB(xrb);
388 XMesaDisplay *dpy = xmesa->xm_visual->display;
389 XMesaDrawable buffer = xrb->drawable;
390 XMesaGC gc = XMESA_BUFFER(ctx->DrawBuffer)->gc;
391 register GLuint i;
392 y = YFLIP(xrb, y);
393 if (mask) {
394 for (i=0;i<n;i++,x++) {
395 if (mask[i]) {
396 XMesaSetForeground( dpy, gc,
397 PACK_8A8R8G8B(rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP], rgba[i][ACOMP]) );
398 XMesaDrawPoint( dpy, buffer, gc, (int) x, (int) y );
399 }
400 }
401 }
402 else {
403 /* draw all pixels */
404 XMesaImage *rowimg = XMESA_BUFFER(ctx->DrawBuffer)->rowimage;
405 register GLuint *ptr4 = (GLuint *) rowimg->data;
406 for (i=0;i<n;i++) {
407 *ptr4++ = PACK_8A8R8G8B( rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP], rgba[i][ACOMP] );
408 }
409 XMesaPutImage( dpy, buffer, gc, rowimg, 0, 0, x, y, n, 1 );
410 }
411 }
412
413
414 /*
415 * Write a span of PF_8A8R8G8B pixels to a pixmap (no alpha).
416 */
417 static void put_row_rgb_8A8R8G8B_pixmap( RGB_SPAN_ARGS )
418 {
419 const GLubyte (*rgb)[3] = (const GLubyte (*)[3]) values;
420 const XMesaContext xmesa = XMESA_CONTEXT(ctx);
421 GET_XRB(xrb);
422 XMesaDisplay *dpy = xmesa->xm_visual->display;
423 XMesaDrawable buffer = xrb->drawable;
424 XMesaGC gc = XMESA_BUFFER(ctx->DrawBuffer)->gc;
425 register GLuint i;
426 y = YFLIP(xrb, y);
427 if (mask) {
428 for (i=0;i<n;i++,x++) {
429 if (mask[i]) {
430 XMesaSetForeground( dpy, gc,
431 PACK_8R8G8B(rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP]) );
432 XMesaDrawPoint( dpy, buffer, gc, (int) x, (int) y );
433 }
434 }
435 }
436 else {
437 /* draw all pixels */
438 XMesaImage *rowimg = XMESA_BUFFER(ctx->DrawBuffer)->rowimage;
439 register GLuint *ptr4 = (GLuint *) rowimg->data;
440 for (i=0;i<n;i++) {
441 *ptr4++ = PACK_8R8G8B(rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP]);
442 }
443 XMesaPutImage( dpy, buffer, gc, rowimg, 0, 0, x, y, n, 1 );
444 }
445 }
446
447 /*
448 * Write a span of PF_8R8G8B pixels to a pixmap.
449 */
450 static void put_row_8R8G8B_pixmap( PUT_ROW_ARGS )
451 {
452 const GLubyte (*rgba)[4] = (const GLubyte (*)[4]) values;
453 const XMesaContext xmesa = XMESA_CONTEXT(ctx);
454 GET_XRB(xrb);
455 XMesaDisplay *dpy = xmesa->xm_visual->display;
456 XMesaDrawable buffer = xrb->drawable;
457 XMesaGC gc = XMESA_BUFFER(ctx->DrawBuffer)->gc;
458 register GLuint i;
459 y = YFLIP(xrb, y);
460 if (mask) {
461 for (i=0;i<n;i++,x++) {
462 if (mask[i]) {
463 #if 1
464 /*
465 * XXX Something funny is going on here.
466 * If we're drawing into a window that uses a depth 32 TrueColor
467 * visual, we see the right pixels on screen, but when we read
468 * them back with XGetImage() we get random colors.
469 * The alternative code below which uses XPutImage() instead
470 * seems to mostly fix the problem, but not always.
471 * We don't normally create windows with this visual, but glean
472 * does and we're seeing some failures there.
473 */
474 XMesaSetForeground( dpy, gc, PACK_8R8G8B( rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP] ));
475 XMesaDrawPoint( dpy, buffer, gc, (int) x, (int) y );
476 #else
477 /* This code works more often, but not always */
478 XMesaImage *rowimg = XMESA_BUFFER(ctx->DrawBuffer)->rowimage;
479 GLuint *ptr4 = (GLuint *) rowimg->data;
480 *ptr4 = PACK_8R8G8B( rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP] );
481 XMesaPutImage( dpy, buffer, gc, rowimg, 0, 0, x, y, 1, 1 );
482 #endif
483 }
484 }
485 }
486 else {
487 /* draw all pixels */
488 XMesaImage *rowimg = XMESA_BUFFER(ctx->DrawBuffer)->rowimage;
489 register GLuint *ptr4 = (GLuint *) rowimg->data;
490 for (i=0;i<n;i++) {
491 *ptr4++ = PACK_8R8G8B( rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP] );
492 }
493 XMesaPutImage( dpy, buffer, gc, rowimg, 0, 0, x, y, n, 1 );
494 }
495 }
496
497
498 /*
499 * Write a span of PF_8R8G8B24 pixels to a pixmap.
500 */
501 static void put_row_8R8G8B24_pixmap( PUT_ROW_ARGS )
502 {
503 const GLubyte (*rgba)[4] = (const GLubyte (*)[4]) values;
504 const XMesaContext xmesa = XMESA_CONTEXT(ctx);
505 GET_XRB(xrb);
506 XMesaDisplay *dpy = xmesa->xm_visual->display;
507 XMesaDrawable buffer = xrb->drawable;
508 XMesaGC gc = XMESA_BUFFER(ctx->DrawBuffer)->gc;
509 y = YFLIP(xrb, y);
510 if (mask) {
511 register GLuint i;
512 for (i=0;i<n;i++,x++) {
513 if (mask[i]) {
514 XMesaSetForeground( dpy, gc,
515 PACK_8R8G8B( rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP] ));
516 XMesaDrawPoint( dpy, buffer, gc, (int) x, (int) y );
517 }
518 }
519 }
520 else {
521 /* draw all pixels */
522 XMesaImage *rowimg = XMESA_BUFFER(ctx->DrawBuffer)->rowimage;
523 register GLuint *ptr4 = (GLuint *) rowimg->data;
524 register GLuint pixel;
525 static const GLuint shift[4] = {0, 8, 16, 24};
526 register GLuint i = 0;
527 int w = n;
528 while (w > 3) {
529 pixel = rgba[i][BCOMP] /* << shift[0]*/;
530 pixel |= rgba[i][GCOMP] << shift[1];
531 pixel |= rgba[i++][RCOMP] << shift[2];
532 pixel |= rgba[i][BCOMP] << shift[3];
533 *ptr4++ = pixel;
534
535 pixel = rgba[i][GCOMP] /* << shift[0]*/;
536 pixel |= rgba[i++][RCOMP] << shift[1];
537 pixel |= rgba[i][BCOMP] << shift[2];
538 pixel |= rgba[i][GCOMP] << shift[3];
539 *ptr4++ = pixel;
540
541 pixel = rgba[i++][RCOMP]/* << shift[0]*/;
542 pixel |= rgba[i][BCOMP] << shift[1];
543 pixel |= rgba[i][GCOMP] << shift[2];
544 pixel |= rgba[i++][RCOMP] << shift[3];
545 *ptr4++ = pixel;
546
547 w -= 4;
548 }
549 switch (w) {
550 case 3:
551 pixel = 0;
552 pixel |= rgba[i][BCOMP] /*<< shift[0]*/;
553 pixel |= rgba[i][GCOMP] << shift[1];
554 pixel |= rgba[i++][RCOMP] << shift[2];
555 pixel |= rgba[i][BCOMP] << shift[3];
556 *ptr4++ = pixel;
557 pixel = 0;
558 pixel |= rgba[i][GCOMP] /*<< shift[0]*/;
559 pixel |= rgba[i++][RCOMP] << shift[1];
560 pixel |= rgba[i][BCOMP] << shift[2];
561 pixel |= rgba[i][GCOMP] << shift[3];
562 *ptr4++ = pixel;
563 pixel = 0xffffff00 & *ptr4;
564 pixel |= rgba[i][RCOMP] /*<< shift[0]*/;
565 *ptr4 = pixel;
566 break;
567 case 2:
568 pixel = 0;
569 pixel |= rgba[i][BCOMP] /*<< shift[0]*/;
570 pixel |= rgba[i][GCOMP] << shift[1];
571 pixel |= rgba[i++][RCOMP] << shift[2];
572 pixel |= rgba[i][BCOMP] << shift[3];
573 *ptr4++ = pixel;
574 pixel = 0xffff0000 & *ptr4;
575 pixel |= rgba[i][GCOMP] /*<< shift[0]*/;
576 pixel |= rgba[i][RCOMP] << shift[1];
577 *ptr4 = pixel;
578 break;
579 case 1:
580 pixel = 0xff000000 & *ptr4;
581 pixel |= rgba[i][BCOMP] /*<< shift[0]*/;
582 pixel |= rgba[i][GCOMP] << shift[1];
583 pixel |= rgba[i][RCOMP] << shift[2];
584 *ptr4 = pixel;
585 break;
586 case 0:
587 break;
588 }
589 XMesaPutImage( dpy, buffer, gc, rowimg, 0, 0, x, y, n, 1 );
590 }
591 }
592
593
594 /*
595 * Write a span of PF_8R8G8B pixels to a pixmap (no alpha).
596 */
597 static void put_row_rgb_8R8G8B_pixmap( RGB_SPAN_ARGS )
598 {
599 const GLubyte (*rgb)[3] = (const GLubyte (*)[3]) values;
600 const XMesaContext xmesa = XMESA_CONTEXT(ctx);
601 GET_XRB(xrb);
602 XMesaDisplay *dpy = xmesa->xm_visual->display;
603 XMesaDrawable buffer = xrb->drawable;
604 XMesaGC gc = XMESA_BUFFER(ctx->DrawBuffer)->gc;
605 register GLuint i;
606 y = YFLIP(xrb, y);
607 if (mask) {
608 for (i=0;i<n;i++,x++) {
609 if (mask[i]) {
610 XMesaSetForeground( dpy, gc, PACK_8R8G8B( rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP] ));
611 XMesaDrawPoint( dpy, buffer, gc, (int) x, (int) y );
612 }
613 }
614 }
615 else {
616 /* draw all pixels */
617 XMesaImage *rowimg = XMESA_BUFFER(ctx->DrawBuffer)->rowimage;
618 register GLuint *ptr4 = (GLuint *) rowimg->data;
619 for (i=0;i<n;i++) {
620 *ptr4++ = PACK_8R8G8B( rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP] );
621 }
622 XMesaPutImage( dpy, buffer, gc, rowimg, 0, 0, x, y, n, 1 );
623 }
624 }
625
626 /*
627 * Write a span of PF_8R8G8B24 pixels to a pixmap (no alpha).
628 */
629 static void put_row_rgb_8R8G8B24_pixmap( RGB_SPAN_ARGS )
630 {
631 const GLubyte (*rgb)[3] = (const GLubyte (*)[3]) values;
632 const XMesaContext xmesa = XMESA_CONTEXT(ctx);
633 GET_XRB(xrb);
634 XMesaDisplay *dpy = xmesa->xm_visual->display;
635 XMesaDrawable buffer = xrb->drawable;
636 XMesaGC gc = XMESA_BUFFER(ctx->DrawBuffer)->gc;
637 y = YFLIP(xrb, y);
638 if (mask) {
639 register GLuint i;
640 for (i=0;i<n;i++,x++) {
641 if (mask[i]) {
642 XMesaSetForeground( dpy, gc,
643 PACK_8R8G8B( rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP] ));
644 XMesaDrawPoint( dpy, buffer, gc, (int) x, (int) y );
645 }
646 }
647 }
648 else {
649 /* draw all pixels */
650 XMesaImage *rowimg = XMESA_BUFFER(ctx->DrawBuffer)->rowimage;
651 register GLuint *ptr4 = (GLuint *) rowimg->data;
652 register GLuint pixel;
653 static const GLuint shift[4] = {0, 8, 16, 24};
654 unsigned w = n;
655 register GLuint i = 0;
656 while (w > 3) {
657 pixel = 0;
658 pixel |= rgb[i][BCOMP]/* << shift[0]*/;
659 pixel |= rgb[i][GCOMP] << shift[1];
660 pixel |= rgb[i++][RCOMP] << shift[2];
661 pixel |= rgb[i][BCOMP] <<shift[3];
662 *ptr4++ = pixel;
663
664 pixel = 0;
665 pixel |= rgb[i][GCOMP]/* << shift[0]*/;
666 pixel |= rgb[i++][RCOMP] << shift[1];
667 pixel |= rgb[i][BCOMP] << shift[2];
668 pixel |= rgb[i][GCOMP] << shift[3];
669 *ptr4++ = pixel;
670
671 pixel = 0;
672 pixel |= rgb[i++][RCOMP]/* << shift[0]*/;
673 pixel |= rgb[i][BCOMP] << shift[1];
674 pixel |= rgb[i][GCOMP] << shift[2];
675 pixel |= rgb[i++][RCOMP] << shift[3];
676 *ptr4++ = pixel;
677 w -= 4;
678 }
679 switch (w) {
680 case 3:
681 pixel = 0;
682 pixel |= rgb[i][BCOMP]/* << shift[0]*/;
683 pixel |= rgb[i][GCOMP] << shift[1];
684 pixel |= rgb[i++][RCOMP] << shift[2];
685 pixel |= rgb[i][BCOMP] << shift[3];
686 *ptr4++ = pixel;
687 pixel = 0;
688 pixel |= rgb[i][GCOMP]/* << shift[0]*/;
689 pixel |= rgb[i++][RCOMP] << shift[1];
690 pixel |= rgb[i][BCOMP] << shift[2];
691 pixel |= rgb[i][GCOMP] << shift[3];
692 *ptr4++ = pixel;
693 pixel = *ptr4;
694 pixel &= 0xffffff00;
695 pixel |= rgb[i++][RCOMP]/* << shift[0]*/;
696 *ptr4++ = pixel;
697 break;
698 case 2:
699 pixel = 0;
700 pixel |= rgb[i][BCOMP]/* << shift[0]*/;
701 pixel |= rgb[i][GCOMP] << shift[1];
702 pixel |= rgb[i++][RCOMP] << shift[2];
703 pixel |= rgb[i][BCOMP] << shift[3];
704 *ptr4++ = pixel;
705 pixel = *ptr4;
706 pixel &= 0xffff0000;
707 pixel |= rgb[i][GCOMP]/* << shift[0]*/;
708 pixel |= rgb[i++][RCOMP] << shift[1];
709 *ptr4++ = pixel;
710 break;
711 case 1:
712 pixel = *ptr4;
713 pixel &= 0xff000000;
714 pixel |= rgb[i][BCOMP]/* << shift[0]*/;
715 pixel |= rgb[i][GCOMP] << shift[1];
716 pixel |= rgb[i++][RCOMP] << shift[2];
717 *ptr4++ = pixel;
718 break;
719 case 0:
720 break;
721 }
722 XMesaPutImage( dpy, buffer, gc, rowimg, 0, 0, x, y, n, 1 );
723 }
724 }
725
726
727 /*
728 * Write a span of PF_5R6G5B pixels to a pixmap.
729 */
730 static void put_row_5R6G5B_pixmap( PUT_ROW_ARGS )
731 {
732 const GLubyte (*rgba)[4] = (const GLubyte (*)[4]) values;
733 const XMesaContext xmesa = XMESA_CONTEXT(ctx);
734 GET_XRB(xrb);
735 XMesaDisplay *dpy = xmesa->xm_visual->display;
736 XMesaDrawable buffer = xrb->drawable;
737 XMesaGC gc = XMESA_BUFFER(ctx->DrawBuffer)->gc;
738 register GLuint i;
739 y = YFLIP(xrb, y);
740 if (mask) {
741 for (i=0;i<n;i++,x++) {
742 if (mask[i]) {
743 XMesaSetForeground( dpy, gc, PACK_5R6G5B( rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP] ));
744 XMesaDrawPoint( dpy, buffer, gc, (int) x, (int) y );
745 }
746 }
747 }
748 else {
749 /* draw all pixels */
750 XMesaImage *rowimg = XMESA_BUFFER(ctx->DrawBuffer)->rowimage;
751 register GLushort *ptr2 = (GLushort *) rowimg->data;
752 for (i=0;i<n;i++) {
753 ptr2[i] = PACK_5R6G5B( rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP] );
754 }
755 XMesaPutImage( dpy, buffer, gc, rowimg, 0, 0, x, y, n, 1 );
756 }
757 }
758
759
760 /*
761 * Write a span of PF_DITHER_5R6G5B pixels to a pixmap.
762 */
763 static void put_row_DITHER_5R6G5B_pixmap( PUT_ROW_ARGS )
764 {
765 const GLubyte (*rgba)[4] = (const GLubyte (*)[4]) values;
766 const XMesaContext xmesa = XMESA_CONTEXT(ctx);
767 GET_XRB(xrb);
768 XMesaDisplay *dpy = xmesa->xm_visual->display;
769 XMesaDrawable buffer = xrb->drawable;
770 XMesaGC gc = XMESA_BUFFER(ctx->DrawBuffer)->gc;
771 register GLuint i;
772 y = YFLIP(xrb, y);
773 if (mask) {
774 for (i=0;i<n;i++,x++) {
775 if (mask[i]) {
776 unsigned long p;
777 PACK_TRUEDITHER(p, x, y, rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP]);
778 XMesaSetForeground( dpy, gc, p );
779 XMesaDrawPoint( dpy, buffer, gc, (int) x, (int) y );
780 }
781 }
782 }
783 else {
784 /* draw all pixels */
785 XMesaImage *rowimg = XMESA_BUFFER(ctx->DrawBuffer)->rowimage;
786 register GLushort *ptr2 = (GLushort *) rowimg->data;
787 for (i=0;i<n;i++) {
788 PACK_TRUEDITHER( ptr2[i], x+i, y, rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP] );
789 }
790 XMesaPutImage( dpy, buffer, gc, rowimg, 0, 0, x, y, n, 1 );
791 }
792 }
793
794
795 /*
796 * Write a span of PF_5R6G5B pixels to a pixmap (no alpha).
797 */
798 static void put_row_rgb_5R6G5B_pixmap( RGB_SPAN_ARGS )
799 {
800 const GLubyte (*rgb)[3] = (const GLubyte (*)[3]) values;
801 const XMesaContext xmesa = XMESA_CONTEXT(ctx);
802 GET_XRB(xrb);
803 XMesaDisplay *dpy = xmesa->xm_visual->display;
804 XMesaDrawable buffer = xrb->drawable;
805 XMesaGC gc = XMESA_BUFFER(ctx->DrawBuffer)->gc;
806 register GLuint i;
807 y = YFLIP(xrb, y);
808 if (mask) {
809 for (i=0;i<n;i++,x++) {
810 if (mask[i]) {
811 XMesaSetForeground( dpy, gc, PACK_5R6G5B( rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP] ));
812 XMesaDrawPoint( dpy, buffer, gc, (int) x, (int) y );
813 }
814 }
815 }
816 else {
817 /* draw all pixels */
818 XMesaImage *rowimg = XMESA_BUFFER(ctx->DrawBuffer)->rowimage;
819 register GLushort *ptr2 = (GLushort *) rowimg->data;
820 for (i=0;i<n;i++) {
821 ptr2[i] = PACK_5R6G5B( rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP] );
822 }
823 XMesaPutImage( dpy, buffer, gc, rowimg, 0, 0, x, y, n, 1 );
824 }
825 }
826
827
828 /*
829 * Write a span of PF_DITHER_5R6G5B pixels to a pixmap (no alpha).
830 */
831 static void put_row_rgb_DITHER_5R6G5B_pixmap( RGB_SPAN_ARGS )
832 {
833 const GLubyte (*rgb)[3] = (const GLubyte (*)[3]) values;
834 const XMesaContext xmesa = XMESA_CONTEXT(ctx);
835 GET_XRB(xrb);
836 XMesaDisplay *dpy = xmesa->xm_visual->display;
837 XMesaDrawable buffer = xrb->drawable;
838 XMesaGC gc = XMESA_BUFFER(ctx->DrawBuffer)->gc;
839 register GLuint i;
840 y = YFLIP(xrb, y);
841 if (mask) {
842 for (i=0;i<n;i++,x++) {
843 if (mask[i]) {
844 unsigned long p;
845 PACK_TRUEDITHER(p, x, y, rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP]);
846 XMesaSetForeground( dpy, gc, p );
847 XMesaDrawPoint( dpy, buffer, gc, (int) x, (int) y );
848 }
849 }
850 }
851 else {
852 /* draw all pixels */
853 XMesaImage *rowimg = XMESA_BUFFER(ctx->DrawBuffer)->rowimage;
854 register GLushort *ptr2 = (GLushort *) rowimg->data;
855 for (i=0;i<n;i++) {
856 PACK_TRUEDITHER( ptr2[i], x+i, y, rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP] );
857 }
858 XMesaPutImage( dpy, buffer, gc, rowimg, 0, 0, x, y, n, 1 );
859 }
860 }
861
862
863 /*
864 * Write a span of PF_TRUECOLOR pixels to an XImage.
865 */
866 static void put_row_TRUECOLOR_ximage( PUT_ROW_ARGS )
867 {
868 const GLubyte (*rgba)[4] = (const GLubyte (*)[4]) values;
869 const XMesaContext xmesa = XMESA_CONTEXT(ctx);
870 GET_XRB(xrb);
871 XMesaImage *img = xrb->ximage;
872 register GLuint i;
873 y = YFLIP(xrb, y);
874 if (mask) {
875 for (i=0;i<n;i++,x++) {
876 if (mask[i]) {
877 unsigned long p;
878 PACK_TRUECOLOR( p, rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP] );
879 XMesaPutPixel( img, x, y, p );
880 }
881 }
882 }
883 else {
884 /* draw all pixels */
885 for (i=0;i<n;i++,x++) {
886 unsigned long p;
887 PACK_TRUECOLOR( p, rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP] );
888 XMesaPutPixel( img, x, y, p );
889 }
890 }
891 }
892
893
894 /*
895 * Write a span of PF_TRUECOLOR pixels to an XImage (no alpha).
896 */
897 static void put_row_rgb_TRUECOLOR_ximage( RGB_SPAN_ARGS )
898 {
899 const GLubyte (*rgb)[3] = (const GLubyte (*)[3]) values;
900 const XMesaContext xmesa = XMESA_CONTEXT(ctx);
901 GET_XRB(xrb);
902 XMesaImage *img = xrb->ximage;
903 register GLuint i;
904 y = YFLIP(xrb, y);
905 if (mask) {
906 for (i=0;i<n;i++,x++) {
907 if (mask[i]) {
908 unsigned long p;
909 PACK_TRUECOLOR( p, rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP] );
910 XMesaPutPixel( img, x, y, p );
911 }
912 }
913 }
914 else {
915 /* draw all pixels */
916 for (i=0;i<n;i++,x++) {
917 unsigned long p;
918 PACK_TRUECOLOR( p, rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP] );
919 XMesaPutPixel( img, x, y, p );
920 }
921 }
922 }
923
924
925 /*
926 * Write a span of PF_TRUEDITHER pixels to an XImage.
927 */
928 static void put_row_TRUEDITHER_ximage( PUT_ROW_ARGS )
929 {
930 const GLubyte (*rgba)[4] = (const GLubyte (*)[4]) values;
931 const XMesaContext xmesa = XMESA_CONTEXT(ctx);
932 GET_XRB(xrb);
933 XMesaImage *img = xrb->ximage;
934 register GLuint i;
935 y = YFLIP(xrb, y);
936 if (mask) {
937 for (i=0;i<n;i++,x++) {
938 if (mask[i]) {
939 unsigned long p;
940 PACK_TRUEDITHER(p, x, y, rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP]);
941 XMesaPutPixel( img, x, y, p );
942 }
943 }
944 }
945 else {
946 /* draw all pixels */
947 for (i=0;i<n;i++,x++) {
948 unsigned long p;
949 PACK_TRUEDITHER(p, x, y, rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP]);
950 XMesaPutPixel( img, x, y, p );
951 }
952 }
953 }
954
955
956 /*
957 * Write a span of PF_TRUEDITHER pixels to an XImage (no alpha).
958 */
959 static void put_row_rgb_TRUEDITHER_ximage( RGB_SPAN_ARGS )
960 {
961 const GLubyte (*rgb)[3] = (const GLubyte (*)[3]) values;
962 const XMesaContext xmesa = XMESA_CONTEXT(ctx);
963 GET_XRB(xrb);
964 XMesaImage *img = xrb->ximage;
965 register GLuint i;
966 y = YFLIP(xrb, y);
967 if (mask) {
968 for (i=0;i<n;i++,x++) {
969 if (mask[i]) {
970 unsigned long p;
971 PACK_TRUEDITHER(p, x, y, rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP]);
972 XMesaPutPixel( img, x, y, p );
973 }
974 }
975 }
976 else {
977 /* draw all pixels */
978 for (i=0;i<n;i++,x++) {
979 unsigned long p;
980 PACK_TRUEDITHER(p, x, y, rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP]);
981 XMesaPutPixel( img, x, y, p );
982 }
983 }
984 }
985
986
987 /*
988 * Write a span of PF_8A8B8G8R-format pixels to an ximage.
989 */
990 static void put_row_8A8B8G8R_ximage( PUT_ROW_ARGS )
991 {
992 const GLubyte (*rgba)[4] = (const GLubyte (*)[4]) values;
993 GET_XRB(xrb);
994 register GLuint i;
995 register GLuint *ptr = PIXEL_ADDR4(xrb, x, y);
996 (void) ctx;
997 if (mask) {
998 for (i=0;i<n;i++) {
999 if (mask[i]) {
1000 ptr[i] = PACK_8A8B8G8R( rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP], rgba[i][ACOMP] );
1001 }
1002 }
1003 }
1004 else {
1005 /* draw all pixels */
1006 for (i=0;i<n;i++) {
1007 ptr[i] = PACK_8A8B8G8R( rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP], rgba[i][ACOMP] );
1008 }
1009 }
1010 }
1011
1012
1013 /*
1014 * Write a span of PF_8A8B8G8R-format pixels to an ximage (no alpha).
1015 */
1016 static void put_row_rgb_8A8B8G8R_ximage( RGB_SPAN_ARGS )
1017 {
1018 const GLubyte (*rgb)[3] = (const GLubyte (*)[3]) values;
1019 GET_XRB(xrb);
1020 register GLuint i;
1021 register GLuint *ptr = PIXEL_ADDR4(xrb, x, y);
1022 if (mask) {
1023 for (i=0;i<n;i++) {
1024 if (mask[i]) {
1025 ptr[i] = PACK_8A8B8G8R( rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP], 255 );
1026 }
1027 }
1028 }
1029 else {
1030 /* draw all pixels */
1031 for (i=0;i<n;i++) {
1032 ptr[i] = PACK_8A8B8G8R( rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP], 255 );
1033 }
1034 }
1035 }
1036
1037 /*
1038 * Write a span of PF_8A8R8G8B-format pixels to an ximage.
1039 */
1040 static void put_row_8A8R8G8B_ximage( PUT_ROW_ARGS )
1041 {
1042 const GLubyte (*rgba)[4] = (const GLubyte (*)[4]) values;
1043 GET_XRB(xrb);
1044 register GLuint i;
1045 register GLuint *ptr = PIXEL_ADDR4(xrb, x, y);
1046 if (mask) {
1047 for (i=0;i<n;i++) {
1048 if (mask[i]) {
1049 ptr[i] = PACK_8A8R8G8B( rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP], rgba[i][ACOMP] );
1050 }
1051 }
1052 }
1053 else {
1054 /* draw all pixels */
1055 for (i=0;i<n;i++) {
1056 ptr[i] = PACK_8A8R8G8B( rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP], rgba[i][ACOMP] );
1057 }
1058 }
1059 }
1060
1061
1062 /*
1063 * Write a span of PF_8A8R8G8B-format pixels to an ximage (no alpha).
1064 */
1065 static void put_row_rgb_8A8R8G8B_ximage( RGB_SPAN_ARGS )
1066 {
1067 const GLubyte (*rgb)[3] = (const GLubyte (*)[3]) values;
1068 GET_XRB(xrb);
1069 register GLuint i;
1070 register GLuint *ptr = PIXEL_ADDR4(xrb, x, y);
1071 if (mask) {
1072 for (i=0;i<n;i++) {
1073 if (mask[i]) {
1074 ptr[i] = PACK_8A8R8G8B( rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP], 255 );
1075 }
1076 }
1077 }
1078 else {
1079 /* draw all pixels */
1080 for (i=0;i<n;i++) {
1081 ptr[i] = PACK_8A8R8G8B( rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP], 255 );
1082 }
1083 }
1084 }
1085
1086
1087 /*
1088 * Write a span of PF_8R8G8B-format pixels to an ximage.
1089 */
1090 static void put_row_8R8G8B_ximage( PUT_ROW_ARGS )
1091 {
1092 const GLubyte (*rgba)[4] = (const GLubyte (*)[4]) values;
1093 GET_XRB(xrb);
1094 register GLuint i;
1095 register GLuint *ptr = PIXEL_ADDR4(xrb, x, y);
1096 if (mask) {
1097 for (i=0;i<n;i++) {
1098 if (mask[i]) {
1099 ptr[i] = PACK_8R8G8B(rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP]);
1100 }
1101 }
1102 }
1103 else {
1104 for (i=0;i<n;i++) {
1105 ptr[i] = PACK_8R8G8B(rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP]);
1106 }
1107 }
1108 }
1109
1110
1111 /*
1112 * Write a span of PF_8R8G8B24-format pixels to an ximage.
1113 */
1114 static void put_row_8R8G8B24_ximage( PUT_ROW_ARGS )
1115 {
1116 const GLubyte (*rgba)[4] = (const GLubyte (*)[4]) values;
1117 GET_XRB(xrb);
1118 register GLuint i;
1119 register GLubyte *ptr = (GLubyte *) PIXEL_ADDR3(xrb, x, y );
1120 if (mask) {
1121 for (i=0;i<n;i++) {
1122 if (mask[i]) {
1123 GLuint *ptr4 = (GLuint *) ptr;
1124 register GLuint pixel = *ptr4;
1125 switch (3 & (int)(ptr - (GLubyte*)ptr4)) {
1126 case 0:
1127 pixel &= 0xff000000;
1128 pixel |= rgba[i][BCOMP];
1129 pixel |= rgba[i][GCOMP] << 8;
1130 pixel |= rgba[i][RCOMP] << 16;
1131 *ptr4 = pixel;
1132 break;
1133 case 3:
1134 pixel &= 0x00ffffff;
1135 pixel |= rgba[i][BCOMP] << 24;
1136 *ptr4++ = pixel;
1137 pixel = *ptr4 & 0xffff0000;
1138 pixel |= rgba[i][GCOMP];
1139 pixel |= rgba[i][RCOMP] << 8;
1140 *ptr4 = pixel;
1141 break;
1142 case 2:
1143 pixel &= 0x0000ffff;
1144 pixel |= rgba[i][BCOMP] << 16;
1145 pixel |= rgba[i][GCOMP] << 24;
1146 *ptr4++ = pixel;
1147 pixel = *ptr4 & 0xffffff00;
1148 pixel |= rgba[i][RCOMP];
1149 *ptr4 = pixel;
1150 break;
1151 case 1:
1152 pixel &= 0x000000ff;
1153 pixel |= rgba[i][BCOMP] << 8;
1154 pixel |= rgba[i][GCOMP] << 16;
1155 pixel |= rgba[i][RCOMP] << 24;
1156 *ptr4 = pixel;
1157 break;
1158 }
1159 }
1160 ptr += 3;
1161 }
1162 }
1163 else {
1164 /* write all pixels */
1165 int w = n;
1166 GLuint *ptr4 = (GLuint *) ptr;
1167 register GLuint pixel = *ptr4;
1168 int index = (int)(ptr - (GLubyte *)ptr4);
1169 register GLuint i = 0;
1170 switch (index) {
1171 case 0:
1172 break;
1173 case 1:
1174 pixel &= 0x00ffffff;
1175 pixel |= rgba[i][BCOMP] << 24;
1176 *ptr4++ = pixel;
1177 pixel = *ptr4 & 0xffff0000;
1178 pixel |= rgba[i][GCOMP];
1179 pixel |= rgba[i++][RCOMP] << 8;
1180 *ptr4 = pixel;
1181 if (0 == --w)
1182 break;
1183 case 2:
1184 pixel &= 0x0000ffff;
1185 pixel |= rgba[i][BCOMP] << 16;
1186 pixel |= rgba[i][GCOMP] << 24;
1187 *ptr4++ = pixel;
1188 pixel = *ptr4 & 0xffffff00;
1189 pixel |= rgba[i++][RCOMP];
1190 *ptr4 = pixel;
1191 if (0 == --w)
1192 break;
1193 case 3:
1194 pixel &= 0x000000ff;
1195 pixel |= rgba[i][BCOMP] << 8;
1196 pixel |= rgba[i][GCOMP] << 16;
1197 pixel |= rgba[i++][RCOMP] << 24;
1198 *ptr4++ = pixel;
1199 if (0 == --w)
1200 break;
1201 break;
1202 }
1203 while (w > 3) {
1204 pixel = rgba[i][BCOMP];
1205 pixel |= rgba[i][GCOMP] << 8;
1206 pixel |= rgba[i++][RCOMP] << 16;
1207 pixel |= rgba[i][BCOMP] << 24;
1208 *ptr4++ = pixel;
1209 pixel = rgba[i][GCOMP];
1210 pixel |= rgba[i++][RCOMP] << 8;
1211 pixel |= rgba[i][BCOMP] << 16;
1212 pixel |= rgba[i][GCOMP] << 24;
1213 *ptr4++ = pixel;
1214 pixel = rgba[i++][RCOMP];
1215 pixel |= rgba[i][BCOMP] << 8;
1216 pixel |= rgba[i][GCOMP] << 16;
1217 pixel |= rgba[i++][RCOMP] << 24;
1218 *ptr4++ = pixel;
1219 w -= 4;
1220 }
1221 switch (w) {
1222 case 0:
1223 break;
1224 case 1:
1225 pixel = *ptr4 & 0xff000000;
1226 pixel |= rgba[i][BCOMP];
1227 pixel |= rgba[i][GCOMP] << 8;
1228 pixel |= rgba[i][RCOMP] << 16;
1229 *ptr4 = pixel;
1230 break;
1231 case 2:
1232 pixel = rgba[i][BCOMP];
1233 pixel |= rgba[i][GCOMP] << 8;
1234 pixel |= rgba[i++][RCOMP] << 16;
1235 pixel |= rgba[i][BCOMP] << 24;
1236 *ptr4++ = pixel;
1237 pixel = *ptr4 & 0xffff0000;
1238 pixel |= rgba[i][GCOMP];
1239 pixel |= rgba[i][RCOMP] << 8;
1240 *ptr4 = pixel;
1241 break;
1242 case 3:
1243 pixel = rgba[i][BCOMP];
1244 pixel |= rgba[i][GCOMP] << 8;
1245 pixel |= rgba[i++][RCOMP] << 16;
1246 pixel |= rgba[i][BCOMP] << 24;
1247 *ptr4++ = pixel;
1248 pixel = rgba[i][GCOMP];
1249 pixel |= rgba[i++][RCOMP] << 8;
1250 pixel |= rgba[i][BCOMP] << 16;
1251 pixel |= rgba[i][GCOMP] << 24;
1252 *ptr4++ = pixel;
1253 pixel = *ptr4 & 0xffffff00;
1254 pixel |= rgba[i][RCOMP];
1255 *ptr4 = pixel;
1256 break;
1257 }
1258 }
1259 }
1260
1261
1262 /*
1263 * Write a span of PF_8R8G8B-format pixels to an ximage (no alpha).
1264 */
1265 static void put_row_rgb_8R8G8B_ximage( RGB_SPAN_ARGS )
1266 {
1267 const GLubyte (*rgb)[3] = (const GLubyte (*)[3]) values;
1268 GET_XRB(xrb);
1269 register GLuint i;
1270 register GLuint *ptr = PIXEL_ADDR4(xrb, x, y);
1271 if (mask) {
1272 for (i=0;i<n;i++) {
1273 if (mask[i]) {
1274 ptr[i] = PACK_8R8G8B(rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP]);
1275 }
1276 }
1277 }
1278 else {
1279 /* draw all pixels */
1280 for (i=0;i<n;i++) {
1281 ptr[i] = PACK_8R8G8B(rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP]);
1282 }
1283 }
1284 }
1285
1286
1287 /*
1288 * Write a span of PF_8R8G8B24-format pixels to an ximage (no alpha).
1289 */
1290 static void put_row_rgb_8R8G8B24_ximage( RGB_SPAN_ARGS )
1291 {
1292 const GLubyte (*rgb)[3] = (const GLubyte (*)[3]) values;
1293 GET_XRB(xrb);
1294 register GLuint i;
1295 register GLubyte *ptr = (GLubyte *) PIXEL_ADDR3(xrb, x, y);
1296 if (mask) {
1297 for (i=0;i<n;i++) {
1298 if (mask[i]) {
1299 *ptr++ = rgb[i][BCOMP];
1300 *ptr++ = rgb[i][GCOMP];
1301 *ptr++ = rgb[i][RCOMP];
1302 }
1303 else {
1304 ptr += 3;
1305 }
1306 }
1307 }
1308 else {
1309 /* draw all pixels */
1310 for (i=0;i<n;i++) {
1311 *ptr++ = rgb[i][BCOMP];
1312 *ptr++ = rgb[i][GCOMP];
1313 *ptr++ = rgb[i][RCOMP];
1314 }
1315 }
1316 }
1317
1318
1319 /*
1320 * Write a span of PF_5R6G5B-format pixels to an ximage.
1321 */
1322 static void put_row_5R6G5B_ximage( PUT_ROW_ARGS )
1323 {
1324 const GLubyte (*rgba)[4] = (const GLubyte (*)[4]) values;
1325 GET_XRB(xrb);
1326 register GLuint i;
1327 register GLushort *ptr = PIXEL_ADDR2(xrb, x, y);
1328 if (mask) {
1329 for (i=0;i<n;i++) {
1330 if (mask[i]) {
1331 ptr[i] = PACK_5R6G5B( rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP] );
1332 }
1333 }
1334 }
1335 else {
1336 /* draw all pixels */
1337 #if defined(__i386__) /* word stores don't have to be on 4-byte boundaries */
1338 GLuint *ptr32 = (GLuint *) ptr;
1339 GLuint extraPixel = (n & 1);
1340 n -= extraPixel;
1341 for (i = 0; i < n; i += 2) {
1342 GLuint p0, p1;
1343 p0 = PACK_5R6G5B(rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP]);
1344 p1 = PACK_5R6G5B(rgba[i+1][RCOMP], rgba[i+1][GCOMP], rgba[i+1][BCOMP]);
1345 *ptr32++ = (p1 << 16) | p0;
1346 }
1347 if (extraPixel) {
1348 ptr[n] = PACK_5R6G5B(rgba[n][RCOMP], rgba[n][GCOMP], rgba[n][BCOMP]);
1349 }
1350 #else
1351 for (i = 0; i < n; i++) {
1352 ptr[i] = PACK_5R6G5B(rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP]);
1353 }
1354 #endif
1355 }
1356 }
1357
1358
1359 /*
1360 * Write a span of PF_DITHER_5R6G5B-format pixels to an ximage.
1361 */
1362 static void put_row_DITHER_5R6G5B_ximage( PUT_ROW_ARGS )
1363 {
1364 const GLubyte (*rgba)[4] = (const GLubyte (*)[4]) values;
1365 GET_XRB(xrb);
1366 const XMesaContext xmesa = XMESA_CONTEXT(ctx);
1367 register GLuint i;
1368 register GLushort *ptr = PIXEL_ADDR2(xrb, x, y);
1369 const GLint y2 = YFLIP(xrb, y);
1370 if (mask) {
1371 for (i=0;i<n;i++,x++) {
1372 if (mask[i]) {
1373 PACK_TRUEDITHER( ptr[i], x, y2, rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP] );
1374 }
1375 }
1376 }
1377 else {
1378 /* draw all pixels */
1379 #if defined(__i386__) /* word stores don't have to be on 4-byte boundaries */
1380 GLuint *ptr32 = (GLuint *) ptr;
1381 GLuint extraPixel = (n & 1);
1382 n -= extraPixel;
1383 for (i = 0; i < n; i += 2, x += 2) {
1384 GLuint p0, p1;
1385 PACK_TRUEDITHER( p0, x, y2, rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP] );
1386 PACK_TRUEDITHER( p1, x+1, y2, rgba[i+1][RCOMP], rgba[i+1][GCOMP], rgba[i+1][BCOMP] );
1387 *ptr32++ = (p1 << 16) | p0;
1388 }
1389 if (extraPixel) {
1390 PACK_TRUEDITHER( ptr[n], x+n, y2, rgba[n][RCOMP], rgba[n][GCOMP], rgba[n][BCOMP]);
1391 }
1392 #else
1393 for (i = 0; i < n; i++, x++) {
1394 PACK_TRUEDITHER( ptr[i], x, y2, rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP]);
1395 }
1396 #endif
1397 }
1398 }
1399
1400
1401 /*
1402 * Write a span of PF_5R6G5B-format pixels to an ximage (no alpha).
1403 */
1404 static void put_row_rgb_5R6G5B_ximage( RGB_SPAN_ARGS )
1405 {
1406 const GLubyte (*rgb)[3] = (const GLubyte (*)[3]) values;
1407 GET_XRB(xrb);
1408 register GLuint i;
1409 register GLushort *ptr = PIXEL_ADDR2(xrb, x, y);
1410 if (mask) {
1411 for (i=0;i<n;i++) {
1412 if (mask[i]) {
1413 ptr[i] = PACK_5R6G5B( rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP] );
1414 }
1415 }
1416 }
1417 else {
1418 /* draw all pixels */
1419 #if defined(__i386__) /* word stores don't have to be on 4-byte boundaries */
1420 GLuint *ptr32 = (GLuint *) ptr;
1421 GLuint extraPixel = (n & 1);
1422 n -= extraPixel;
1423 for (i = 0; i < n; i += 2) {
1424 GLuint p0, p1;
1425 p0 = PACK_5R6G5B(rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP]);
1426 p1 = PACK_5R6G5B(rgb[i+1][RCOMP], rgb[i+1][GCOMP], rgb[i+1][BCOMP]);
1427 *ptr32++ = (p1 << 16) | p0;
1428 }
1429 if (extraPixel) {
1430 ptr[n] = PACK_5R6G5B(rgb[n][RCOMP], rgb[n][GCOMP], rgb[n][BCOMP]);
1431 }
1432 #else
1433 for (i=0;i<n;i++) {
1434 ptr[i] = PACK_5R6G5B( rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP] );
1435 }
1436 #endif
1437 }
1438 }
1439
1440
1441 /*
1442 * Write a span of PF_DITHER_5R6G5B-format pixels to an ximage (no alpha).
1443 */
1444 static void put_row_rgb_DITHER_5R6G5B_ximage( RGB_SPAN_ARGS )
1445 {
1446 const GLubyte (*rgb)[3] = (const GLubyte (*)[3]) values;
1447 GET_XRB(xrb);
1448 const XMesaContext xmesa = XMESA_CONTEXT(ctx);
1449 register GLuint i;
1450 register GLushort *ptr = PIXEL_ADDR2(xrb, x, y );
1451 if (mask) {
1452 for (i=0;i<n;i++,x++) {
1453 if (mask[i]) {
1454 PACK_TRUEDITHER( ptr[i], x, y, rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP] );
1455 }
1456 }
1457 }
1458 else {
1459 /* draw all pixels */
1460 #if defined(__i386__) /* word stores don't have to be on 4-byte boundaries */
1461 GLuint *ptr32 = (GLuint *) ptr;
1462 GLuint extraPixel = (n & 1);
1463 n -= extraPixel;
1464 for (i = 0; i < n; i += 2, x += 2) {
1465 GLuint p0, p1;
1466 PACK_TRUEDITHER( p0, x, y, rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP] );
1467 PACK_TRUEDITHER( p1, x+1, y, rgb[i+1][RCOMP], rgb[i+1][GCOMP], rgb[i+1][BCOMP] );
1468 *ptr32++ = (p1 << 16) | p0;
1469 }
1470 if (extraPixel) {
1471 PACK_TRUEDITHER( ptr[n], x+n, y, rgb[n][RCOMP], rgb[n][GCOMP], rgb[n][BCOMP]);
1472 }
1473 #else
1474 for (i=0;i<n;i++,x++) {
1475 PACK_TRUEDITHER( ptr[i], x, y, rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP] );
1476 }
1477 #endif
1478 }
1479 }
1480
1481
1482
1483 /**********************************************************************/
1484 /*** Write COLOR PIXEL functions ***/
1485 /**********************************************************************/
1486
1487
1488 #define PUT_VALUES_ARGS \
1489 struct gl_context *ctx, struct gl_renderbuffer *rb, \
1490 GLuint n, const GLint x[], const GLint y[], \
1491 const void *values, const GLubyte mask[]
1492
1493
1494 /*
1495 * Write an array of PF_TRUECOLOR pixels to a pixmap.
1496 */
1497 static void put_values_TRUECOLOR_pixmap( PUT_VALUES_ARGS )
1498 {
1499 const GLubyte (*rgba)[4] = (const GLubyte (*)[4]) values;
1500 const XMesaContext xmesa = XMESA_CONTEXT(ctx);
1501 GET_XRB(xrb);
1502 XMesaDisplay *dpy = xmesa->xm_visual->display;
1503 XMesaDrawable buffer = xrb->drawable;
1504 XMesaGC gc = XMESA_BUFFER(ctx->DrawBuffer)->gc;
1505 register GLuint i;
1506 for (i=0;i<n;i++) {
1507 if (mask[i]) {
1508 unsigned long p;
1509 PACK_TRUECOLOR( p, rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP] );
1510 XMesaSetForeground( dpy, gc, p );
1511 XMesaDrawPoint( dpy, buffer, gc, (int) x[i], (int) YFLIP(xrb, y[i]) );
1512 }
1513 }
1514 }
1515
1516
1517 /*
1518 * Write an array of PF_TRUEDITHER pixels to a pixmap.
1519 */
1520 static void put_values_TRUEDITHER_pixmap( PUT_VALUES_ARGS )
1521 {
1522 const GLubyte (*rgba)[4] = (const GLubyte (*)[4]) values;
1523 const XMesaContext xmesa = XMESA_CONTEXT(ctx);
1524 GET_XRB(xrb);
1525 XMesaDisplay *dpy = xmesa->xm_visual->display;
1526 XMesaDrawable buffer = xrb->drawable;
1527 XMesaGC gc = XMESA_BUFFER(ctx->DrawBuffer)->gc;
1528 register GLuint i;
1529 for (i=0;i<n;i++) {
1530 if (mask[i]) {
1531 unsigned long p;
1532 PACK_TRUEDITHER(p, x[i], y[i], rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP]);
1533 XMesaSetForeground( dpy, gc, p );
1534 XMesaDrawPoint( dpy, buffer, gc, (int) x[i], (int) YFLIP(xrb, y[i]) );
1535 }
1536 }
1537 }
1538
1539
1540 /*
1541 * Write an array of PF_8A8B8G8R pixels to a pixmap.
1542 */
1543 static void put_values_8A8B8G8R_pixmap( PUT_VALUES_ARGS )
1544 {
1545 const GLubyte (*rgba)[4] = (const GLubyte (*)[4]) values;
1546 const XMesaContext xmesa = XMESA_CONTEXT(ctx);
1547 GET_XRB(xrb);
1548 XMesaDisplay *dpy = xmesa->xm_visual->display;
1549 XMesaDrawable buffer = xrb->drawable;
1550 XMesaGC gc = XMESA_BUFFER(ctx->DrawBuffer)->gc;
1551 register GLuint i;
1552 for (i=0;i<n;i++) {
1553 if (mask[i]) {
1554 XMesaSetForeground( dpy, gc,
1555 PACK_8A8B8G8R( rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP], rgba[i][ACOMP] ));
1556 XMesaDrawPoint( dpy, buffer, gc, (int) x[i], (int) YFLIP(xrb, y[i]) );
1557 }
1558 }
1559 }
1560
1561 /*
1562 * Write an array of PF_8A8R8G8B pixels to a pixmap.
1563 */
1564 static void put_values_8A8R8G8B_pixmap( PUT_VALUES_ARGS )
1565 {
1566 const GLubyte (*rgba)[4] = (const GLubyte (*)[4]) values;
1567 const XMesaContext xmesa = XMESA_CONTEXT(ctx);
1568 GET_XRB(xrb);
1569 XMesaDisplay *dpy = xmesa->xm_visual->display;
1570 XMesaDrawable buffer = xrb->drawable;
1571 XMesaGC gc = XMESA_BUFFER(ctx->DrawBuffer)->gc;
1572 register GLuint i;
1573 for (i=0;i<n;i++) {
1574 if (mask[i]) {
1575 XMesaSetForeground( dpy, gc,
1576 PACK_8A8R8G8B( rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP], rgba[i][ACOMP] ));
1577 XMesaDrawPoint( dpy, buffer, gc, (int) x[i], (int) YFLIP(xrb, y[i]) );
1578 }
1579 }
1580 }
1581
1582 /*
1583 * Write an array of PF_8R8G8B pixels to a pixmap.
1584 */
1585 static void put_values_8R8G8B_pixmap( PUT_VALUES_ARGS )
1586 {
1587 const GLubyte (*rgba)[4] = (const GLubyte (*)[4]) values;
1588 const XMesaContext xmesa = XMESA_CONTEXT(ctx);
1589 GET_XRB(xrb);
1590 XMesaDisplay *dpy = xmesa->xm_visual->display;
1591 XMesaDrawable buffer = xrb->drawable;
1592 XMesaGC gc = XMESA_BUFFER(ctx->DrawBuffer)->gc;
1593 register GLuint i;
1594 for (i=0;i<n;i++) {
1595 if (mask[i]) {
1596 XMesaSetForeground( dpy, gc, PACK_8R8G8B( rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP] ) );
1597 XMesaDrawPoint( dpy, buffer, gc, (int) x[i], (int) YFLIP(xrb, y[i]) );
1598 }
1599 }
1600 }
1601
1602
1603 /*
1604 * Write an array of PF_8R8G8B24 pixels to a pixmap.
1605 */
1606 static void put_values_8R8G8B24_pixmap( PUT_VALUES_ARGS )
1607 {
1608 const GLubyte (*rgba)[4] = (const GLubyte (*)[4]) values;
1609 const XMesaContext xmesa = XMESA_CONTEXT(ctx);
1610 GET_XRB(xrb);
1611 XMesaDisplay *dpy = xmesa->xm_visual->display;
1612 XMesaDrawable buffer = xrb->drawable;
1613 XMesaGC gc = XMESA_BUFFER(ctx->DrawBuffer)->gc;
1614 register GLuint i;
1615 for (i=0;i<n;i++) {
1616 if (mask[i]) {
1617 XMesaSetForeground( dpy, gc, PACK_8R8G8B( rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP] ) );
1618 XMesaDrawPoint( dpy, buffer, gc, (int) x[i], (int) YFLIP(xrb, y[i]) );
1619 }
1620 }
1621 }
1622
1623
1624 /*
1625 * Write an array of PF_5R6G5B pixels to a pixmap.
1626 */
1627 static void put_values_5R6G5B_pixmap( PUT_VALUES_ARGS )
1628 {
1629 const GLubyte (*rgba)[4] = (const GLubyte (*)[4]) values;
1630 const XMesaContext xmesa = XMESA_CONTEXT(ctx);
1631 GET_XRB(xrb);
1632 XMesaDisplay *dpy = xmesa->xm_visual->display;
1633 XMesaDrawable buffer = xrb->drawable;
1634 XMesaGC gc = XMESA_BUFFER(ctx->DrawBuffer)->gc;
1635 register GLuint i;
1636 for (i=0;i<n;i++) {
1637 if (mask[i]) {
1638 XMesaSetForeground( dpy, gc, PACK_5R6G5B( rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP] ) );
1639 XMesaDrawPoint( dpy, buffer, gc, (int) x[i], (int) YFLIP(xrb, y[i]) );
1640 }
1641 }
1642 }
1643
1644
1645 /*
1646 * Write an array of PF_DITHER_5R6G5B pixels to a pixmap.
1647 */
1648 static void put_values_DITHER_5R6G5B_pixmap( PUT_VALUES_ARGS )
1649 {
1650 const GLubyte (*rgba)[4] = (const GLubyte (*)[4]) values;
1651 const XMesaContext xmesa = XMESA_CONTEXT(ctx);
1652 GET_XRB(xrb);
1653 XMesaDisplay *dpy = xmesa->xm_visual->display;
1654 XMesaDrawable buffer = xrb->drawable;
1655 XMesaGC gc = XMESA_BUFFER(ctx->DrawBuffer)->gc;
1656 register GLuint i;
1657 for (i=0;i<n;i++) {
1658 if (mask[i]) {
1659 unsigned long p;
1660 PACK_TRUEDITHER(p, x[i], y[i], rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP] );
1661 XMesaSetForeground( dpy, gc, p );
1662 XMesaDrawPoint( dpy, buffer, gc, (int) x[i], (int) YFLIP(xrb, y[i]) );
1663 }
1664 }
1665 }
1666
1667
1668 /*
1669 * Write an array of PF_TRUECOLOR pixels to an ximage.
1670 */
1671 static void put_values_TRUECOLOR_ximage( PUT_VALUES_ARGS )
1672 {
1673 const GLubyte (*rgba)[4] = (const GLubyte (*)[4]) values;
1674 const XMesaContext xmesa = XMESA_CONTEXT(ctx);
1675 GET_XRB(xrb);
1676 XMesaImage *img = xrb->ximage;
1677 register GLuint i;
1678 for (i=0;i<n;i++) {
1679 if (mask[i]) {
1680 unsigned long p;
1681 PACK_TRUECOLOR( p, rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP] );
1682 XMesaPutPixel( img, x[i], YFLIP(xrb, y[i]), p );
1683 }
1684 }
1685 }
1686
1687
1688 /*
1689 * Write an array of PF_TRUEDITHER pixels to an XImage.
1690 */
1691 static void put_values_TRUEDITHER_ximage( PUT_VALUES_ARGS )
1692 {
1693 const GLubyte (*rgba)[4] = (const GLubyte (*)[4]) values;
1694 const XMesaContext xmesa = XMESA_CONTEXT(ctx);
1695 GET_XRB(xrb);
1696 XMesaImage *img = xrb->ximage;
1697 register GLuint i;
1698 for (i=0;i<n;i++) {
1699 if (mask[i]) {
1700 unsigned long p;
1701 PACK_TRUEDITHER(p, x[i], y[i], rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP]);
1702 XMesaPutPixel( img, x[i], YFLIP(xrb, y[i]), p );
1703 }
1704 }
1705 }
1706
1707
1708 /*
1709 * Write an array of PF_8A8B8G8R pixels to an ximage.
1710 */
1711 static void put_values_8A8B8G8R_ximage( PUT_VALUES_ARGS )
1712 {
1713 const GLubyte (*rgba)[4] = (const GLubyte (*)[4]) values;
1714 GET_XRB(xrb);
1715 register GLuint i;
1716 for (i=0;i<n;i++) {
1717 if (mask[i]) {
1718 GLuint *ptr = PIXEL_ADDR4(xrb, x[i], y[i] );
1719 *ptr = PACK_8A8B8G8R( rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP], rgba[i][ACOMP] );
1720 }
1721 }
1722 }
1723
1724 /*
1725 * Write an array of PF_8A8R8G8B pixels to an ximage.
1726 */
1727 static void put_values_8A8R8G8B_ximage( PUT_VALUES_ARGS )
1728 {
1729 const GLubyte (*rgba)[4] = (const GLubyte (*)[4]) values;
1730 GET_XRB(xrb);
1731 register GLuint i;
1732 for (i=0;i<n;i++) {
1733 if (mask[i]) {
1734 GLuint *ptr = PIXEL_ADDR4(xrb, x[i], y[i]);
1735 *ptr = PACK_8A8R8G8B( rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP], rgba[i][ACOMP] );
1736 }
1737 }
1738 }
1739
1740
1741 /*
1742 * Write an array of PF_8R8G8B pixels to an ximage.
1743 */
1744 static void put_values_8R8G8B_ximage( PUT_VALUES_ARGS )
1745 {
1746 const GLubyte (*rgba)[4] = (const GLubyte (*)[4]) values;
1747 GET_XRB(xrb);
1748 register GLuint i;
1749 for (i=0;i<n;i++) {
1750 if (mask[i]) {
1751 GLuint *ptr = PIXEL_ADDR4(xrb, x[i], y[i]);
1752 *ptr = PACK_8R8G8B( rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP] );
1753 }
1754 }
1755 }
1756
1757
1758 /*
1759 * Write an array of PF_8R8G8B24 pixels to an ximage.
1760 */
1761 static void put_values_8R8G8B24_ximage( PUT_VALUES_ARGS )
1762 {
1763 const GLubyte (*rgba)[4] = (const GLubyte (*)[4]) values;
1764 GET_XRB(xrb);
1765 register GLuint i;
1766 for (i=0;i<n;i++) {
1767 if (mask[i]) {
1768 bgr_t *ptr = PIXEL_ADDR3(xrb, x[i], y[i] );
1769 ptr->r = rgba[i][RCOMP];
1770 ptr->g = rgba[i][GCOMP];
1771 ptr->b = rgba[i][BCOMP];
1772 }
1773 }
1774 }
1775
1776
1777 /*
1778 * Write an array of PF_5R6G5B pixels to an ximage.
1779 */
1780 static void put_values_5R6G5B_ximage( PUT_VALUES_ARGS )
1781 {
1782 const GLubyte (*rgba)[4] = (const GLubyte (*)[4]) values;
1783 GET_XRB(xrb);
1784 register GLuint i;
1785 for (i=0;i<n;i++) {
1786 if (mask[i]) {
1787 GLushort *ptr = PIXEL_ADDR2(xrb, x[i], y[i] );
1788 *ptr = PACK_5R6G5B( rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP] );
1789 }
1790 }
1791 }
1792
1793
1794 /*
1795 * Write an array of PF_DITHER_5R6G5B pixels to an ximage.
1796 */
1797 static void put_values_DITHER_5R6G5B_ximage( PUT_VALUES_ARGS )
1798 {
1799 const GLubyte (*rgba)[4] = (const GLubyte (*)[4]) values;
1800 GET_XRB(xrb);
1801 const XMesaContext xmesa = XMESA_CONTEXT(ctx);
1802 register GLuint i;
1803 for (i=0;i<n;i++) {
1804 if (mask[i]) {
1805 GLushort *ptr = PIXEL_ADDR2(xrb, x[i], y[i] );
1806 PACK_TRUEDITHER( *ptr, x[i], y[i], rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP] );
1807 }
1808 }
1809 }
1810
1811
1812
1813 /**********************************************************************/
1814 /***** Pixel reading *****/
1815 /**********************************************************************/
1816
1817 /**
1818 * Do clip testing prior to calling XGetImage. If any of the region lies
1819 * outside the screen's bounds, XGetImage will return NULL.
1820 * We use XTranslateCoordinates() to check if that's the case and
1821 * adjust the x, y and length parameters accordingly.
1822 * \return -1 if span is totally clipped away,
1823 * else return number of pixels to skip in the destination array.
1824 */
1825 static int
1826 clip_for_xgetimage(struct gl_context *ctx, XMesaPixmap pixmap, GLuint *n, GLint *x, GLint *y)
1827 {
1828 XMesaContext xmesa = XMESA_CONTEXT(ctx);
1829 XMesaBuffer source = XMESA_BUFFER(ctx->DrawBuffer);
1830 Window rootWin = RootWindow(xmesa->display, 0);
1831 Window child;
1832 GLint screenWidth = WidthOfScreen(DefaultScreenOfDisplay(xmesa->display));
1833 GLint dx, dy;
1834 if (source->type == PBUFFER || source->type == PIXMAP)
1835 return 0;
1836 XTranslateCoordinates(xmesa->display, pixmap, rootWin,
1837 *x, *y, &dx, &dy, &child);
1838 if (dx >= screenWidth) {
1839 /* totally clipped on right */
1840 return -1;
1841 }
1842 if (dx < 0) {
1843 /* clipped on left */
1844 GLint clip = -dx;
1845 if (clip >= (GLint) *n)
1846 return -1; /* totally clipped on left */
1847 *x += clip;
1848 *n -= clip;
1849 dx = 0;
1850 return clip;
1851 }
1852 if ((GLint) (dx + *n) > screenWidth) {
1853 /* clipped on right */
1854 GLint clip = dx + *n - screenWidth;
1855 *n -= clip;
1856 }
1857 return 0;
1858 }
1859
1860
1861 /*
1862 * Read a horizontal span of color pixels.
1863 */
1864 static void
1865 get_row_rgba(struct gl_context *ctx, struct gl_renderbuffer *rb,
1866 GLuint n, GLint x, GLint y, void *values)
1867 {
1868 GLubyte (*rgba)[4] = (GLubyte (*)[4]) values;
1869 const XMesaContext xmesa = XMESA_CONTEXT(ctx);
1870 GET_XRB(xrb);
1871
1872 if (xrb->pixmap) {
1873 /* Read from Pixmap or Window */
1874 XMesaImage *span = NULL;
1875 int error;
1876 int k;
1877 y = YFLIP(xrb, y);
1878 k = clip_for_xgetimage(ctx, xrb->pixmap, &n, &x, &y);
1879 if (k < 0)
1880 return;
1881 rgba += k;
1882 catch_xgetimage_errors( xmesa->display );
1883 span = XGetImage( xmesa->display, xrb->pixmap,
1884 x, y, n, 1, AllPlanes, ZPixmap );
1885 error = check_xgetimage_errors();
1886 if (span && !error) {
1887 switch (xmesa->pixelformat) {
1888 case PF_Truecolor:
1889 case PF_Dither_True:
1890 {
1891 const GLubyte *pixelToR = xmesa->xm_visual->PixelToR;
1892 const GLubyte *pixelToG = xmesa->xm_visual->PixelToG;
1893 const GLubyte *pixelToB = xmesa->xm_visual->PixelToB;
1894 unsigned long rMask = GET_REDMASK(xmesa->xm_visual);
1895 unsigned long gMask = GET_GREENMASK(xmesa->xm_visual);
1896 unsigned long bMask = GET_BLUEMASK(xmesa->xm_visual);
1897 GLint rShift = xmesa->xm_visual->rshift;
1898 GLint gShift = xmesa->xm_visual->gshift;
1899 GLint bShift = xmesa->xm_visual->bshift;
1900 GLuint i;
1901 for (i=0;i<n;i++) {
1902 unsigned long p;
1903 p = XMesaGetPixel( span, i, 0 );
1904 rgba[i][RCOMP] = pixelToR[(p & rMask) >> rShift];
1905 rgba[i][GCOMP] = pixelToG[(p & gMask) >> gShift];
1906 rgba[i][BCOMP] = pixelToB[(p & bMask) >> bShift];
1907 rgba[i][ACOMP] = 255;
1908 }
1909 }
1910 break;
1911 case PF_5R6G5B:
1912 case PF_Dither_5R6G5B:
1913 {
1914 const GLubyte *pixelToR = xmesa->xm_visual->PixelToR;
1915 const GLubyte *pixelToG = xmesa->xm_visual->PixelToG;
1916 const GLubyte *pixelToB = xmesa->xm_visual->PixelToB;
1917 GLuint i;
1918 for (i=0;i<n;i++) {
1919 unsigned long p = XMesaGetPixel( span, i, 0 );
1920 /* fast, but not quite accurate
1921 rgba[i][RCOMP] = ((p >> 8) & 0xf8);
1922 rgba[i][GCOMP] = ((p >> 3) & 0xfc);
1923 rgba[i][BCOMP] = ((p << 3) & 0xff);
1924 */
1925 rgba[i][RCOMP] = pixelToR[p >> 11];
1926 rgba[i][GCOMP] = pixelToG[(p >> 5) & 0x3f];
1927 rgba[i][BCOMP] = pixelToB[p & 0x1f];
1928 rgba[i][ACOMP] = 255;
1929 }
1930 }
1931 break;
1932 case PF_8A8B8G8R:
1933 {
1934 const GLuint *ptr4 = (GLuint *) span->data;
1935 GLuint i;
1936 for (i=0;i<n;i++) {
1937 GLuint p4 = *ptr4++;
1938 rgba[i][RCOMP] = (GLubyte) ( p4 & 0xff);
1939 rgba[i][GCOMP] = (GLubyte) ((p4 >> 8) & 0xff);
1940 rgba[i][BCOMP] = (GLubyte) ((p4 >> 16) & 0xff);
1941 rgba[i][ACOMP] = (GLubyte) ((p4 >> 24) & 0xff);
1942 }
1943 }
1944 break;
1945 case PF_8A8R8G8B:
1946 {
1947 const GLuint *ptr4 = (GLuint *) span->data;
1948 GLuint i;
1949 for (i=0;i<n;i++) {
1950 GLuint p4 = *ptr4++;
1951 rgba[i][RCOMP] = (GLubyte) ((p4 >> 16) & 0xff);
1952 rgba[i][GCOMP] = (GLubyte) ((p4 >> 8) & 0xff);
1953 rgba[i][BCOMP] = (GLubyte) ( p4 & 0xff);
1954 rgba[i][ACOMP] = (GLubyte) ((p4 >> 24) & 0xff);
1955 }
1956 }
1957 break;
1958 case PF_8R8G8B:
1959 {
1960 const GLuint *ptr4 = (GLuint *) span->data;
1961 GLuint i;
1962 for (i=0;i<n;i++) {
1963 GLuint p4 = *ptr4++;
1964 rgba[i][RCOMP] = (GLubyte) ((p4 >> 16) & 0xff);
1965 rgba[i][GCOMP] = (GLubyte) ((p4 >> 8) & 0xff);
1966 rgba[i][BCOMP] = (GLubyte) ( p4 & 0xff);
1967 rgba[i][ACOMP] = 255;
1968 }
1969 }
1970 break;
1971 case PF_8R8G8B24:
1972 {
1973 const bgr_t *ptr3 = (bgr_t *) span->data;
1974 GLuint i;
1975 for (i=0;i<n;i++) {
1976 rgba[i][RCOMP] = ptr3[i].r;
1977 rgba[i][GCOMP] = ptr3[i].g;
1978 rgba[i][BCOMP] = ptr3[i].b;
1979 rgba[i][ACOMP] = 255;
1980 }
1981 }
1982 break;
1983 default:
1984 _mesa_problem(NULL,"Problem in DD.read_color_span (1)");
1985 return;
1986 }
1987 }
1988 else {
1989 /* return black pixels */
1990 GLuint i;
1991 for (i=0;i<n;i++) {
1992 rgba[i][RCOMP] = rgba[i][GCOMP] = rgba[i][BCOMP] = rgba[i][ACOMP] = 0;
1993 }
1994 }
1995 if (span) {
1996 XMesaDestroyImage( span );
1997 }
1998 }
1999 else if (xrb->ximage) {
2000 /* Read from XImage back buffer */
2001 switch (xmesa->pixelformat) {
2002 case PF_Truecolor:
2003 case PF_Dither_True:
2004 {
2005 const GLubyte *pixelToR = xmesa->xm_visual->PixelToR;
2006 const GLubyte *pixelToG = xmesa->xm_visual->PixelToG;
2007 const GLubyte *pixelToB = xmesa->xm_visual->PixelToB;
2008 unsigned long rMask = GET_REDMASK(xmesa->xm_visual);
2009 unsigned long gMask = GET_GREENMASK(xmesa->xm_visual);
2010 unsigned long bMask = GET_BLUEMASK(xmesa->xm_visual);
2011 GLint rShift = xmesa->xm_visual->rshift;
2012 GLint gShift = xmesa->xm_visual->gshift;
2013 GLint bShift = xmesa->xm_visual->bshift;
2014 XMesaImage *img = xrb->ximage;
2015 GLuint i;
2016 y = YFLIP(xrb, y);
2017 for (i=0;i<n;i++) {
2018 unsigned long p;
2019 p = XMesaGetPixel( img, x+i, y );
2020 rgba[i][RCOMP] = pixelToR[(p & rMask) >> rShift];
2021 rgba[i][GCOMP] = pixelToG[(p & gMask) >> gShift];
2022 rgba[i][BCOMP] = pixelToB[(p & bMask) >> bShift];
2023 rgba[i][ACOMP] = 255;
2024 }
2025 }
2026 break;
2027 case PF_5R6G5B:
2028 case PF_Dither_5R6G5B:
2029 {
2030 const GLubyte *pixelToR = xmesa->xm_visual->PixelToR;
2031 const GLubyte *pixelToG = xmesa->xm_visual->PixelToG;
2032 const GLubyte *pixelToB = xmesa->xm_visual->PixelToB;
2033 const GLushort *ptr2 = PIXEL_ADDR2(xrb, x, y);
2034 GLuint i;
2035 #if defined(__i386__) /* word stores don't have to be on 4-byte boundaries */
2036 const GLuint *ptr4 = (const GLuint *) ptr2;
2037 GLuint extraPixel = (n & 1);
2038 n -= extraPixel;
2039 for (i = 0; i < n; i += 2) {
2040 const GLuint p = *ptr4++;
2041 const GLuint p0 = p & 0xffff;
2042 const GLuint p1 = p >> 16;
2043 /* fast, but not quite accurate
2044 rgba[i][RCOMP] = ((p >> 8) & 0xf8);
2045 rgba[i][GCOMP] = ((p >> 3) & 0xfc);
2046 rgba[i][BCOMP] = ((p << 3) & 0xff);
2047 */
2048 rgba[i][RCOMP] = pixelToR[p0 >> 11];
2049 rgba[i][GCOMP] = pixelToG[(p0 >> 5) & 0x3f];
2050 rgba[i][BCOMP] = pixelToB[p0 & 0x1f];
2051 rgba[i][ACOMP] = 255;
2052 rgba[i+1][RCOMP] = pixelToR[p1 >> 11];
2053 rgba[i+1][GCOMP] = pixelToG[(p1 >> 5) & 0x3f];
2054 rgba[i+1][BCOMP] = pixelToB[p1 & 0x1f];
2055 rgba[i+1][ACOMP] = 255;
2056 }
2057 if (extraPixel) {
2058 GLushort p = ptr2[n];
2059 rgba[n][RCOMP] = pixelToR[p >> 11];
2060 rgba[n][GCOMP] = pixelToG[(p >> 5) & 0x3f];
2061 rgba[n][BCOMP] = pixelToB[p & 0x1f];
2062 rgba[n][ACOMP] = 255;
2063 }
2064 #else
2065 for (i = 0; i < n; i++) {
2066 const GLushort p = ptr2[i];
2067 rgba[i][RCOMP] = pixelToR[p >> 11];
2068 rgba[i][GCOMP] = pixelToG[(p >> 5) & 0x3f];
2069 rgba[i][BCOMP] = pixelToB[p & 0x1f];
2070 rgba[i][ACOMP] = 255;
2071 }
2072 #endif
2073 }
2074 break;
2075 case PF_8A8B8G8R:
2076 {
2077 const GLuint *ptr4 = PIXEL_ADDR4(xrb, x, y);
2078 GLuint i;
2079 for (i=0;i<n;i++) {
2080 GLuint p4 = *ptr4++;
2081 rgba[i][RCOMP] = (GLubyte) ( p4 & 0xff);
2082 rgba[i][GCOMP] = (GLubyte) ((p4 >> 8) & 0xff);
2083 rgba[i][BCOMP] = (GLubyte) ((p4 >> 16) & 0xff);
2084 rgba[i][ACOMP] = (GLint) ((p4 >> 24) & 0xff);
2085 }
2086 }
2087 break;
2088 case PF_8A8R8G8B:
2089 {
2090 const GLuint *ptr4 = PIXEL_ADDR4(xrb, x, y);
2091 GLuint i;
2092 for (i=0;i<n;i++) {
2093 GLuint p4 = *ptr4++;
2094 rgba[i][RCOMP] = (GLubyte) ((p4 >> 16) & 0xff);
2095 rgba[i][GCOMP] = (GLubyte) ((p4 >> 8) & 0xff);
2096 rgba[i][BCOMP] = (GLubyte) ( p4 & 0xff);
2097 rgba[i][ACOMP] = (GLint) ((p4 >> 24) & 0xff);
2098 }
2099 }
2100 break;
2101 case PF_8R8G8B:
2102 {
2103 const GLuint *ptr4 = PIXEL_ADDR4(xrb, x, y);
2104 GLuint i;
2105 for (i=0;i<n;i++) {
2106 GLuint p4 = *ptr4++;
2107 rgba[i][RCOMP] = (GLubyte) ((p4 >> 16) & 0xff);
2108 rgba[i][GCOMP] = (GLubyte) ((p4 >> 8) & 0xff);
2109 rgba[i][BCOMP] = (GLubyte) ( p4 & 0xff);
2110 rgba[i][ACOMP] = 255;
2111 }
2112 }
2113 break;
2114 case PF_8R8G8B24:
2115 {
2116 const bgr_t *ptr3 = PIXEL_ADDR3(xrb, x, y);
2117 GLuint i;
2118 for (i=0;i<n;i++) {
2119 rgba[i][RCOMP] = ptr3[i].r;
2120 rgba[i][GCOMP] = ptr3[i].g;
2121 rgba[i][BCOMP] = ptr3[i].b;
2122 rgba[i][ACOMP] = 255;
2123 }
2124 }
2125 break;
2126 default:
2127 _mesa_problem(NULL,"Problem in DD.read_color_span (2)");
2128 return;
2129 }
2130 }
2131 }
2132
2133
2134
2135 static void
2136 get_values_rgba(struct gl_context *ctx, struct gl_renderbuffer *rb,
2137 GLuint n, const GLint x[], const GLint y[], void *values)
2138 {
2139 GLubyte (*rgba)[4] = (GLubyte (*)[4]) values;
2140 GET_XRB(xrb);
2141 const XMesaContext xmesa = XMESA_CONTEXT(ctx);
2142 XMesaDisplay *dpy = xmesa->xm_visual->display;
2143 register GLuint i;
2144
2145 if (xrb->pixmap) {
2146 XMesaDrawable buffer = xrb->drawable;
2147 switch (xmesa->pixelformat) {
2148 case PF_Truecolor:
2149 case PF_Dither_True:
2150 case PF_5R6G5B:
2151 case PF_Dither_5R6G5B:
2152 {
2153 unsigned long rMask = GET_REDMASK(xmesa->xm_visual);
2154 unsigned long gMask = GET_GREENMASK(xmesa->xm_visual);
2155 unsigned long bMask = GET_BLUEMASK(xmesa->xm_visual);
2156 GLubyte *pixelToR = xmesa->xm_visual->PixelToR;
2157 GLubyte *pixelToG = xmesa->xm_visual->PixelToG;
2158 GLubyte *pixelToB = xmesa->xm_visual->PixelToB;
2159 GLint rShift = xmesa->xm_visual->rshift;
2160 GLint gShift = xmesa->xm_visual->gshift;
2161 GLint bShift = xmesa->xm_visual->bshift;
2162 for (i=0;i<n;i++) {
2163 unsigned long p = read_pixel( dpy, buffer,
2164 x[i], YFLIP(xrb, y[i]) );
2165 rgba[i][RCOMP] = pixelToR[(p & rMask) >> rShift];
2166 rgba[i][GCOMP] = pixelToG[(p & gMask) >> gShift];
2167 rgba[i][BCOMP] = pixelToB[(p & bMask) >> bShift];
2168 rgba[i][ACOMP] = 255;
2169 }
2170 }
2171 break;
2172 case PF_8A8B8G8R:
2173 for (i=0;i<n;i++) {
2174 unsigned long p = read_pixel( dpy, buffer,
2175 x[i], YFLIP(xrb, y[i]) );
2176 rgba[i][RCOMP] = (GLubyte) ( p & 0xff);
2177 rgba[i][GCOMP] = (GLubyte) ((p >> 8) & 0xff);
2178 rgba[i][BCOMP] = (GLubyte) ((p >> 16) & 0xff);
2179 rgba[i][ACOMP] = (GLubyte) ((p >> 24) & 0xff);
2180 }
2181 break;
2182 case PF_8A8R8G8B:
2183 for (i=0;i<n;i++) {
2184 unsigned long p = read_pixel( dpy, buffer,
2185 x[i], YFLIP(xrb, y[i]) );
2186 rgba[i][RCOMP] = (GLubyte) ((p >> 16) & 0xff);
2187 rgba[i][GCOMP] = (GLubyte) ((p >> 8) & 0xff);
2188 rgba[i][BCOMP] = (GLubyte) ( p & 0xff);
2189 rgba[i][ACOMP] = (GLubyte) ((p >> 24) & 0xff);
2190 }
2191 break;
2192 case PF_8R8G8B:
2193 for (i=0;i<n;i++) {
2194 unsigned long p = read_pixel( dpy, buffer,
2195 x[i], YFLIP(xrb, y[i]) );
2196 rgba[i][RCOMP] = (GLubyte) ((p >> 16) & 0xff);
2197 rgba[i][GCOMP] = (GLubyte) ((p >> 8) & 0xff);
2198 rgba[i][BCOMP] = (GLubyte) ( p & 0xff);
2199 rgba[i][ACOMP] = 255;
2200 }
2201 break;
2202 case PF_8R8G8B24:
2203 for (i=0;i<n;i++) {
2204 unsigned long p = read_pixel( dpy, buffer,
2205 x[i], YFLIP(xrb, y[i]) );
2206 rgba[i][RCOMP] = (GLubyte) ((p >> 16) & 0xff);
2207 rgba[i][GCOMP] = (GLubyte) ((p >> 8) & 0xff);
2208 rgba[i][BCOMP] = (GLubyte) ( p & 0xff);
2209 rgba[i][ACOMP] = 255;
2210 }
2211 break;
2212 default:
2213 _mesa_problem(NULL,"Problem in DD.read_color_pixels (1)");
2214 return;
2215 }
2216 }
2217 else if (xrb->ximage) {
2218 /* Read from XImage back buffer */
2219 switch (xmesa->pixelformat) {
2220 case PF_Truecolor:
2221 case PF_Dither_True:
2222 case PF_5R6G5B:
2223 case PF_Dither_5R6G5B:
2224 {
2225 unsigned long rMask = GET_REDMASK(xmesa->xm_visual);
2226 unsigned long gMask = GET_GREENMASK(xmesa->xm_visual);
2227 unsigned long bMask = GET_BLUEMASK(xmesa->xm_visual);
2228 GLubyte *pixelToR = xmesa->xm_visual->PixelToR;
2229 GLubyte *pixelToG = xmesa->xm_visual->PixelToG;
2230 GLubyte *pixelToB = xmesa->xm_visual->PixelToB;
2231 GLint rShift = xmesa->xm_visual->rshift;
2232 GLint gShift = xmesa->xm_visual->gshift;
2233 GLint bShift = xmesa->xm_visual->bshift;
2234 XMesaImage *img = xrb->ximage;
2235 for (i=0;i<n;i++) {
2236 unsigned long p;
2237 p = XMesaGetPixel( img, x[i], YFLIP(xrb, y[i]) );
2238 rgba[i][RCOMP] = pixelToR[(p & rMask) >> rShift];
2239 rgba[i][GCOMP] = pixelToG[(p & gMask) >> gShift];
2240 rgba[i][BCOMP] = pixelToB[(p & bMask) >> bShift];
2241 rgba[i][ACOMP] = 255;
2242 }
2243 }
2244 break;
2245 case PF_8A8B8G8R:
2246 for (i=0;i<n;i++) {
2247 GLuint *ptr4 = PIXEL_ADDR4(xrb, x[i], y[i]);
2248 GLuint p4 = *ptr4;
2249 rgba[i][RCOMP] = (GLubyte) ( p4 & 0xff);
2250 rgba[i][GCOMP] = (GLubyte) ((p4 >> 8) & 0xff);
2251 rgba[i][BCOMP] = (GLubyte) ((p4 >> 16) & 0xff);
2252 rgba[i][ACOMP] = (GLubyte) ((p4 >> 24) & 0xff);
2253 }
2254 break;
2255 case PF_8A8R8G8B:
2256 for (i=0;i<n;i++) {
2257 GLuint *ptr4 = PIXEL_ADDR4(xrb, x[i], y[i]);
2258 GLuint p4 = *ptr4;
2259 rgba[i][RCOMP] = (GLubyte) ((p4 >> 16) & 0xff);
2260 rgba[i][GCOMP] = (GLubyte) ((p4 >> 8) & 0xff);
2261 rgba[i][BCOMP] = (GLubyte) ( p4 & 0xff);
2262 rgba[i][ACOMP] = (GLubyte) ((p4 >> 24) & 0xff);
2263 }
2264 break;
2265 case PF_8R8G8B:
2266 for (i=0;i<n;i++) {
2267 GLuint *ptr4 = PIXEL_ADDR4(xrb, x[i], y[i]);
2268 GLuint p4 = *ptr4;
2269 rgba[i][RCOMP] = (GLubyte) ((p4 >> 16) & 0xff);
2270 rgba[i][GCOMP] = (GLubyte) ((p4 >> 8) & 0xff);
2271 rgba[i][BCOMP] = (GLubyte) ( p4 & 0xff);
2272 rgba[i][ACOMP] = 255;
2273 }
2274 break;
2275 case PF_8R8G8B24:
2276 for (i=0;i<n;i++) {
2277 bgr_t *ptr3 = PIXEL_ADDR3(xrb, x[i], y[i]);
2278 rgba[i][RCOMP] = ptr3->r;
2279 rgba[i][GCOMP] = ptr3->g;
2280 rgba[i][BCOMP] = ptr3->b;
2281 rgba[i][ACOMP] = 255;
2282 }
2283 break;
2284 default:
2285 _mesa_problem(NULL,"Problem in DD.read_color_pixels (1)");
2286 return;
2287 }
2288 }
2289 }
2290
2291
2292 /**
2293 * Initialize the renderbuffer's PutRow, GetRow, etc. functions.
2294 * This would generally only need to be called once when the renderbuffer
2295 * is created. However, we can change pixel formats on the fly if dithering
2296 * is enabled/disabled. Therefore, we may call this more often than that.
2297 */
2298 void
2299 xmesa_set_renderbuffer_funcs(struct xmesa_renderbuffer *xrb,
2300 enum pixel_format pixelformat, GLint depth)
2301 {
2302 const GLboolean pixmap = xrb->pixmap ? GL_TRUE : GL_FALSE;
2303
2304 switch (pixelformat) {
2305 case PF_Truecolor:
2306 if (pixmap) {
2307 xrb->Base.PutRow = put_row_TRUECOLOR_pixmap;
2308 xrb->Base.PutRowRGB = put_row_rgb_TRUECOLOR_pixmap;
2309 xrb->Base.PutValues = put_values_TRUECOLOR_pixmap;
2310 }
2311 else {
2312 xrb->Base.PutRow = put_row_TRUECOLOR_ximage;
2313 xrb->Base.PutRowRGB = put_row_rgb_TRUECOLOR_ximage;
2314 xrb->Base.PutValues = put_values_TRUECOLOR_ximage;
2315 }
2316 break;
2317 case PF_Dither_True:
2318 if (pixmap) {
2319 xrb->Base.PutRow = put_row_TRUEDITHER_pixmap;
2320 xrb->Base.PutRowRGB = put_row_rgb_TRUEDITHER_pixmap;
2321 xrb->Base.PutValues = put_values_TRUEDITHER_pixmap;
2322 }
2323 else {
2324 xrb->Base.PutRow = put_row_TRUEDITHER_ximage;
2325 xrb->Base.PutRowRGB = put_row_rgb_TRUEDITHER_ximage;
2326 xrb->Base.PutValues = put_values_TRUEDITHER_ximage;
2327 }
2328 break;
2329 case PF_8A8B8G8R:
2330 if (pixmap) {
2331 xrb->Base.PutRow = put_row_8A8B8G8R_pixmap;
2332 xrb->Base.PutRowRGB = put_row_rgb_8A8B8G8R_pixmap;
2333 xrb->Base.PutValues = put_values_8A8B8G8R_pixmap;
2334 }
2335 else {
2336 xrb->Base.PutRow = put_row_8A8B8G8R_ximage;
2337 xrb->Base.PutRowRGB = put_row_rgb_8A8B8G8R_ximage;
2338 xrb->Base.PutValues = put_values_8A8B8G8R_ximage;
2339 }
2340 break;
2341 case PF_8A8R8G8B:
2342 if (pixmap) {
2343 xrb->Base.PutRow = put_row_8A8R8G8B_pixmap;
2344 xrb->Base.PutRowRGB = put_row_rgb_8A8R8G8B_pixmap;
2345 xrb->Base.PutValues = put_values_8A8R8G8B_pixmap;
2346 }
2347 else {
2348 xrb->Base.PutRow = put_row_8A8R8G8B_ximage;
2349 xrb->Base.PutRowRGB = put_row_rgb_8A8R8G8B_ximage;
2350 xrb->Base.PutValues = put_values_8A8R8G8B_ximage;
2351 }
2352 break;
2353 case PF_8R8G8B:
2354 if (pixmap) {
2355 xrb->Base.PutRow = put_row_8R8G8B_pixmap;
2356 xrb->Base.PutRowRGB = put_row_rgb_8R8G8B_pixmap;
2357 xrb->Base.PutValues = put_values_8R8G8B_pixmap;
2358 }
2359 else {
2360 xrb->Base.PutRow = put_row_8R8G8B_ximage;
2361 xrb->Base.PutRowRGB = put_row_rgb_8R8G8B_ximage;
2362 xrb->Base.PutValues = put_values_8R8G8B_ximage;
2363 }
2364 break;
2365 case PF_8R8G8B24:
2366 if (pixmap) {
2367 xrb->Base.PutRow = put_row_8R8G8B24_pixmap;
2368 xrb->Base.PutRowRGB = put_row_rgb_8R8G8B24_pixmap;
2369 xrb->Base.PutValues = put_values_8R8G8B24_pixmap;
2370 }
2371 else {
2372 xrb->Base.PutRow = put_row_8R8G8B24_ximage;
2373 xrb->Base.PutRowRGB = put_row_rgb_8R8G8B24_ximage;
2374 xrb->Base.PutValues = put_values_8R8G8B24_ximage;
2375 }
2376 break;
2377 case PF_5R6G5B:
2378 if (pixmap) {
2379 xrb->Base.PutRow = put_row_5R6G5B_pixmap;
2380 xrb->Base.PutRowRGB = put_row_rgb_5R6G5B_pixmap;
2381 xrb->Base.PutValues = put_values_5R6G5B_pixmap;
2382 }
2383 else {
2384 xrb->Base.PutRow = put_row_5R6G5B_ximage;
2385 xrb->Base.PutRowRGB = put_row_rgb_5R6G5B_ximage;
2386 xrb->Base.PutValues = put_values_5R6G5B_ximage;
2387 }
2388 break;
2389 case PF_Dither_5R6G5B:
2390 if (pixmap) {
2391 xrb->Base.PutRow = put_row_DITHER_5R6G5B_pixmap;
2392 xrb->Base.PutRowRGB = put_row_rgb_DITHER_5R6G5B_pixmap;
2393 xrb->Base.PutValues = put_values_DITHER_5R6G5B_pixmap;
2394 }
2395 else {
2396 xrb->Base.PutRow = put_row_DITHER_5R6G5B_ximage;
2397 xrb->Base.PutRowRGB = put_row_rgb_DITHER_5R6G5B_ximage;
2398 xrb->Base.PutValues = put_values_DITHER_5R6G5B_ximage;
2399 }
2400 break;
2401 default:
2402 _mesa_problem(NULL, "Bad pixel format in xmesa_update_state (1)");
2403 return;
2404 }
2405
2406
2407 /* Get functions */
2408 xrb->Base.GetRow = get_row_rgba;
2409 xrb->Base.GetValues = get_values_rgba;
2410 }
2411