silence gcc warnings (Marc La France)
[mesa.git] / src / mesa / drivers / x11 / xm_dd.c
1 /* $Id: xm_dd.c,v 1.29 2002/03/01 04:28:32 brianp Exp $ */
2
3 /*
4 * Mesa 3-D graphics library
5 * Version: 4.1
6 *
7 * Copyright (C) 1999-2002 Brian Paul All Rights Reserved.
8 *
9 * Permission is hereby granted, free of charge, to any person obtaining a
10 * copy of this software and associated documentation files (the "Software"),
11 * to deal in the Software without restriction, including without limitation
12 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
13 * and/or sell copies of the Software, and to permit persons to whom the
14 * Software is furnished to do so, subject to the following conditions:
15 *
16 * The above copyright notice and this permission notice shall be included
17 * in all copies or substantial portions of the Software.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
23 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
24 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 */
26 /* $XFree86: xc/extras/Mesa/src/X/xm_dd.c,v 1.2 2002/02/26 23:37:31 tsi Exp $ */
27
28 #include "glxheader.h"
29 #include "context.h"
30 #include "depth.h"
31 #include "drawpix.h"
32 #include "extensions.h"
33 #include "macros.h"
34 #include "mem.h"
35 #include "mtypes.h"
36 #include "state.h"
37 #include "texstore.h"
38 #include "texformat.h"
39 #include "xmesaP.h"
40 #include "array_cache/acache.h"
41 #include "swrast/s_context.h"
42 #include "swrast/swrast.h"
43 #include "swrast/s_alphabuf.h"
44 #include "swrast_setup/swrast_setup.h"
45 #include "tnl/tnl.h"
46 #include "tnl/t_context.h"
47 #include "tnl/t_pipeline.h"
48
49
50 /*
51 * Return the size (width,height of the current color buffer.
52 * This function should be called by the glViewport function because
53 * glViewport is often called when the window gets resized. We need to
54 * update some X/Mesa stuff when that happens.
55 * Output: width - width of buffer in pixels.
56 * height - height of buffer in pixels.
57 */
58 static void
59 get_buffer_size( GLcontext *ctx, GLuint *width, GLuint *height )
60 {
61 const XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
62 unsigned int winwidth, winheight;
63 #ifndef XFree86Server
64 Window root;
65 int winx, winy;
66 unsigned int bw, d;
67
68 _glthread_LOCK_MUTEX(_xmesa_lock);
69 XGetGeometry( xmesa->display, xmesa->xm_buffer->frontbuffer, &root,
70 &winx, &winy, &winwidth, &winheight, &bw, &d );
71 _glthread_UNLOCK_MUTEX(_xmesa_lock);
72 #else
73
74 winwidth = xmesa->xm_buffer->frontbuffer->width;
75 winheight = xmesa->xm_buffer->frontbuffer->height;
76 #endif
77
78 (void)kernel8; /* Muffle compiler */
79
80 *width = winwidth;
81 *height = winheight;
82
83 if ( winwidth!=xmesa->xm_buffer->width
84 || winheight!=xmesa->xm_buffer->height) {
85 xmesa->xm_buffer->width = winwidth;
86 xmesa->xm_buffer->height = winheight;
87 xmesa_alloc_back_buffer( xmesa->xm_buffer );
88 }
89
90 /* Needed by FLIP macro */
91 xmesa->xm_buffer->bottom = (int) winheight - 1;
92
93 if (xmesa->xm_buffer->backimage) {
94 /* Needed by PIXELADDR1 macro */
95 xmesa->xm_buffer->ximage_width1
96 = xmesa->xm_buffer->backimage->bytes_per_line;
97 xmesa->xm_buffer->ximage_origin1
98 = (GLubyte *) xmesa->xm_buffer->backimage->data
99 + xmesa->xm_buffer->ximage_width1 * (winheight-1);
100
101 /* Needed by PIXELADDR2 macro */
102 xmesa->xm_buffer->ximage_width2
103 = xmesa->xm_buffer->backimage->bytes_per_line / 2;
104 xmesa->xm_buffer->ximage_origin2
105 = (GLushort *) xmesa->xm_buffer->backimage->data
106 + xmesa->xm_buffer->ximage_width2 * (winheight-1);
107
108 /* Needed by PIXELADDR3 macro */
109 xmesa->xm_buffer->ximage_width3
110 = xmesa->xm_buffer->backimage->bytes_per_line;
111 xmesa->xm_buffer->ximage_origin3
112 = (GLubyte *) xmesa->xm_buffer->backimage->data
113 + xmesa->xm_buffer->ximage_width3 * (winheight-1);
114
115 /* Needed by PIXELADDR4 macro */
116 xmesa->xm_buffer->ximage_width4 = xmesa->xm_buffer->backimage->width;
117 xmesa->xm_buffer->ximage_origin4
118 = (GLuint *) xmesa->xm_buffer->backimage->data
119 + xmesa->xm_buffer->ximage_width4 * (winheight-1);
120 }
121 }
122
123
124 static void
125 finish( GLcontext *ctx )
126 {
127 #ifdef XFree86Server
128 /* NOT_NEEDED */
129 #else
130 const XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
131 if (xmesa) {
132 _glthread_LOCK_MUTEX(_xmesa_lock);
133 XSync( xmesa->display, False );
134 _glthread_UNLOCK_MUTEX(_xmesa_lock);
135 }
136 #endif
137 }
138
139
140 static void
141 flush( GLcontext *ctx )
142 {
143 #ifdef XFree86Server
144 /* NOT_NEEDED */
145 #else
146 const XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
147 if (xmesa) {
148 _glthread_LOCK_MUTEX(_xmesa_lock);
149 XFlush( xmesa->display );
150 _glthread_UNLOCK_MUTEX(_xmesa_lock);
151 }
152 #endif
153 }
154
155
156
157
158 static GLboolean
159 set_draw_buffer( GLcontext *ctx, GLenum mode )
160 {
161 const XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
162 if (mode == GL_FRONT_LEFT) {
163 /* write to front buffer */
164 xmesa->xm_buffer->buffer = xmesa->xm_buffer->frontbuffer;
165 xmesa_update_span_funcs(ctx);
166 return GL_TRUE;
167 }
168 else if (mode==GL_BACK_LEFT && xmesa->xm_buffer->db_state) {
169 /* write to back buffer */
170 if (xmesa->xm_buffer->backpixmap) {
171 xmesa->xm_buffer->buffer =
172 (XMesaDrawable)xmesa->xm_buffer->backpixmap;
173 }
174 else if (xmesa->xm_buffer->backimage) {
175 xmesa->xm_buffer->buffer = None;
176 }
177 else {
178 /* just in case there wasn't enough memory for back buffer */
179 xmesa->xm_buffer->buffer = xmesa->xm_buffer->frontbuffer;
180 }
181 xmesa_update_span_funcs(ctx);
182 return GL_TRUE;
183 }
184 else {
185 return GL_FALSE;
186 }
187 }
188
189
190 void
191 xmesa_set_read_buffer( GLcontext *ctx, GLframebuffer *buffer, GLenum mode )
192 {
193 XMesaBuffer target;
194 const XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
195
196 if (buffer == ctx->DrawBuffer) {
197 target = xmesa->xm_buffer;
198 xmesa->use_read_buffer = GL_FALSE;
199 }
200 else {
201 ASSERT(buffer == ctx->ReadBuffer);
202 target = xmesa->xm_read_buffer;
203 xmesa->use_read_buffer = GL_TRUE;
204 }
205
206 if (mode == GL_FRONT_LEFT) {
207 target->buffer = target->frontbuffer;
208 xmesa_update_span_funcs(ctx);
209 }
210 else if (mode==GL_BACK_LEFT && xmesa->xm_read_buffer->db_state) {
211 if (target->backpixmap) {
212 target->buffer = (XMesaDrawable)xmesa->xm_buffer->backpixmap;
213 }
214 else if (target->backimage) {
215 target->buffer = None;
216 }
217 else {
218 /* just in case there wasn't enough memory for back buffer */
219 target->buffer = target->frontbuffer;
220 }
221 xmesa_update_span_funcs(ctx);
222 }
223 else {
224 _mesa_problem(ctx, "invalid buffer in set_read_buffer() in xmesa2.c");
225 }
226 }
227
228
229
230 static void
231 clear_index( GLcontext *ctx, GLuint index )
232 {
233 const XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
234 xmesa->clearpixel = (unsigned long) index;
235 XMesaSetForeground( xmesa->display, xmesa->xm_buffer->cleargc,
236 (unsigned long) index );
237 }
238
239
240 static void
241 clear_color( GLcontext *ctx, const GLchan color[4] )
242 {
243 const XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
244 xmesa->clearcolor[0] = color[0];
245 xmesa->clearcolor[1] = color[1];
246 xmesa->clearcolor[2] = color[2];
247 xmesa->clearcolor[3] = color[3];
248 xmesa->clearpixel = xmesa_color_to_pixel( xmesa, color[0], color[1],
249 color[2], color[3],
250 xmesa->xm_visual->undithered_pf );
251 _glthread_LOCK_MUTEX(_xmesa_lock);
252 XMesaSetForeground( xmesa->display, xmesa->xm_buffer->cleargc,
253 xmesa->clearpixel );
254 _glthread_UNLOCK_MUTEX(_xmesa_lock);
255 }
256
257
258
259 /* Set index mask ala glIndexMask */
260 static void
261 index_mask( GLcontext *ctx, GLuint mask )
262 {
263 const XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
264 if (xmesa->xm_buffer->buffer != XIMAGE) {
265 unsigned long m;
266 if (mask==0xffffffff) {
267 m = ((unsigned long)~0L);
268 }
269 else {
270 m = (unsigned long) mask;
271 }
272 XMesaSetPlaneMask( xmesa->display, xmesa->xm_buffer->gc, m );
273 XMesaSetPlaneMask( xmesa->display, xmesa->xm_buffer->cleargc, m );
274 }
275 }
276
277
278 /* Implements glColorMask() */
279 static void
280 color_mask(GLcontext *ctx,
281 GLboolean rmask, GLboolean gmask, GLboolean bmask, GLboolean amask)
282 {
283 const XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
284 int xclass = GET_VISUAL_CLASS(xmesa->xm_visual);
285 (void) amask;
286
287 if (xclass == TrueColor || xclass == DirectColor) {
288 unsigned long m;
289 if (rmask && gmask && bmask) {
290 m = ((unsigned long)~0L);
291 }
292 else {
293 m = 0;
294 if (rmask) m |= GET_REDMASK(xmesa->xm_visual);
295 if (gmask) m |= GET_GREENMASK(xmesa->xm_visual);
296 if (bmask) m |= GET_BLUEMASK(xmesa->xm_visual);
297 }
298 XMesaSetPlaneMask( xmesa->display, xmesa->xm_buffer->gc, m );
299 XMesaSetPlaneMask( xmesa->display, xmesa->xm_buffer->cleargc, m );
300 }
301 }
302
303
304
305 /**********************************************************************/
306 /*** glClear implementations ***/
307 /**********************************************************************/
308
309
310 static void
311 clear_front_pixmap( GLcontext *ctx, GLboolean all,
312 GLint x, GLint y, GLint width, GLint height )
313 {
314 const XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
315 if (all) {
316 XMesaFillRectangle( xmesa->display, xmesa->xm_buffer->frontbuffer,
317 xmesa->xm_buffer->cleargc,
318 0, 0,
319 xmesa->xm_buffer->width+1,
320 xmesa->xm_buffer->height+1 );
321 }
322 else {
323 XMesaFillRectangle( xmesa->display, xmesa->xm_buffer->frontbuffer,
324 xmesa->xm_buffer->cleargc,
325 x, xmesa->xm_buffer->height - y - height,
326 width, height );
327 }
328 }
329
330
331 static void
332 clear_back_pixmap( GLcontext *ctx, GLboolean all,
333 GLint x, GLint y, GLint width, GLint height )
334 {
335 const XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
336 if (all) {
337 XMesaFillRectangle( xmesa->display, xmesa->xm_buffer->backpixmap,
338 xmesa->xm_buffer->cleargc,
339 0, 0,
340 xmesa->xm_buffer->width+1,
341 xmesa->xm_buffer->height+1 );
342 }
343 else {
344 XMesaFillRectangle( xmesa->display, xmesa->xm_buffer->backpixmap,
345 xmesa->xm_buffer->cleargc,
346 x, xmesa->xm_buffer->height - y - height,
347 width, height );
348 }
349 }
350
351
352 static void
353 clear_8bit_ximage( GLcontext *ctx, GLboolean all,
354 GLint x, GLint y, GLint width, GLint height )
355 {
356 const XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
357 if (all) {
358 size_t n = xmesa->xm_buffer->backimage->bytes_per_line
359 * xmesa->xm_buffer->backimage->height;
360 MEMSET( xmesa->xm_buffer->backimage->data, xmesa->clearpixel, n );
361 }
362 else {
363 GLint i;
364 for (i=0;i<height;i++) {
365 GLubyte *ptr = PIXELADDR1( xmesa->xm_buffer, x, y+i );
366 MEMSET( ptr, xmesa->clearpixel, width );
367 }
368 }
369 }
370
371
372 static void
373 clear_HPCR_ximage( GLcontext *ctx, GLboolean all,
374 GLint x, GLint y, GLint width, GLint height )
375 {
376 const XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
377 if (all) {
378 GLint i, c16 = (xmesa->xm_buffer->backimage->bytes_per_line>>4)<<4;
379 GLubyte *ptr = (GLubyte *)xmesa->xm_buffer->backimage->data;
380 for (i=0; i<xmesa->xm_buffer->backimage->height; i++) {
381 GLint j;
382 GLubyte *sptr = xmesa->xm_visual->hpcr_clear_ximage_pattern[0];
383 if (i&1) {
384 sptr += 16;
385 }
386 for (j=0; j<c16; j+=16) {
387 ptr[0] = sptr[0];
388 ptr[1] = sptr[1];
389 ptr[2] = sptr[2];
390 ptr[3] = sptr[3];
391 ptr[4] = sptr[4];
392 ptr[5] = sptr[5];
393 ptr[6] = sptr[6];
394 ptr[7] = sptr[7];
395 ptr[8] = sptr[8];
396 ptr[9] = sptr[9];
397 ptr[10] = sptr[10];
398 ptr[11] = sptr[11];
399 ptr[12] = sptr[12];
400 ptr[13] = sptr[13];
401 ptr[14] = sptr[14];
402 ptr[15] = sptr[15];
403 ptr += 16;
404 }
405 for (; j<xmesa->xm_buffer->backimage->bytes_per_line; j++) {
406 *ptr = sptr[j&15];
407 ptr++;
408 }
409 }
410 }
411 else {
412 GLint i;
413 for (i=y; i<y+height; i++) {
414 GLubyte *ptr = PIXELADDR1( xmesa->xm_buffer, x, i );
415 int j;
416 GLubyte *sptr = xmesa->xm_visual->hpcr_clear_ximage_pattern[0];
417 if (i&1) {
418 sptr += 16;
419 }
420 for (j=x; j<x+width; j++) {
421 *ptr = sptr[j&15];
422 ptr++;
423 }
424 }
425 }
426 }
427
428
429 static void
430 clear_16bit_ximage( GLcontext *ctx, GLboolean all,
431 GLint x, GLint y, GLint width, GLint height )
432 {
433 const XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
434 register GLuint pixel = (GLuint) xmesa->clearpixel;
435 if (xmesa->swapbytes) {
436 pixel = ((pixel >> 8) & 0x00ff) | ((pixel << 8) & 0xff00);
437 }
438 if (all) {
439 register GLuint n;
440 register GLuint *ptr4 = (GLuint *) xmesa->xm_buffer->backimage->data;
441 if ((pixel & 0xff) == ((pixel >> 8) & 0xff)) {
442 /* low and high bytes are equal so use memset() */
443 n = xmesa->xm_buffer->backimage->bytes_per_line
444 * xmesa->xm_buffer->height;
445 MEMSET( ptr4, pixel & 0xff, n );
446 }
447 else {
448 pixel = pixel | (pixel<<16);
449 n = xmesa->xm_buffer->backimage->bytes_per_line
450 * xmesa->xm_buffer->height / 4;
451 do {
452 *ptr4++ = pixel;
453 n--;
454 } while (n!=0);
455
456 if ((xmesa->xm_buffer->backimage->bytes_per_line *
457 xmesa->xm_buffer->height) & 0x2)
458 *(GLushort *)ptr4 = pixel & 0xffff;
459 }
460 }
461 else {
462 register int i, j;
463 for (j=0;j<height;j++) {
464 register GLushort *ptr2 = PIXELADDR2( xmesa->xm_buffer, x, y+j );
465 for (i=0;i<width;i++) {
466 *ptr2++ = pixel;
467 }
468 }
469 }
470 }
471
472
473 /* Optimized code provided by Nozomi Ytow <noz@xfree86.org> */
474 static void
475 clear_24bit_ximage( GLcontext *ctx, GLboolean all,
476 GLint x, GLint y, GLint width, GLint height )
477 {
478 const XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
479 const GLubyte r = xmesa->clearcolor[0];
480 const GLubyte g = xmesa->clearcolor[1];
481 const GLubyte b = xmesa->clearcolor[2];
482 register GLuint clearPixel;
483 if (xmesa->swapbytes) {
484 clearPixel = (b << 16) | (g << 8) | r;
485 }
486 else {
487 clearPixel = (r << 16) | (g << 8) | b;
488 }
489
490 if (all) {
491 if (r==g && g==b) {
492 /* same value for all three components (gray) */
493 const GLint w3 = xmesa->xm_buffer->width * 3;
494 const GLint h = xmesa->xm_buffer->height;
495 GLint i;
496 for (i = 0; i < h; i++) {
497 bgr_t *ptr3 = PIXELADDR3(xmesa->xm_buffer, 0, i);
498 MEMSET(ptr3, r, w3);
499 }
500 }
501 else {
502 /* the usual case */
503 const GLint w = xmesa->xm_buffer->width;
504 const GLint h = xmesa->xm_buffer->height;
505 GLint i, j;
506 for (i = 0; i < h; i++) {
507 bgr_t *ptr3 = PIXELADDR3(xmesa->xm_buffer, 0, i);
508 for (j = 0; j < w; j++) {
509 ptr3->r = r;
510 ptr3->g = g;
511 ptr3->b = b;
512 ptr3++;
513 }
514 }
515 #if 0 /* this code doesn't work for all window widths */
516 register GLuint *ptr4 = (GLuint *) ptr3;
517 register GLuint px;
518 GLuint pixel4[3];
519 register GLuint *p = pixel4;
520 pixel4[0] = clearPixel | (clearPixel << 24);
521 pixel4[1] = (clearPixel << 16) | (clearPixel >> 8);
522 pixel4[2] = (clearPixel << 8) | (clearPixel >> 16);
523 switch (3 & (int)(ptr3 - (bgr_t*) ptr4)){
524 case 0:
525 break;
526 case 1:
527 px = *ptr4 & 0x00ffffff;
528 px |= pixel4[0] & 0xff000000;
529 *ptr4++ = px;
530 px = *ptr4 & 0xffff0000;
531 px |= pixel4[2] & 0x0000ffff;
532 *ptr4 = px;
533 if (0 == --n)
534 break;
535 case 2:
536 px = *ptr4 & 0x0000fffff;
537 px |= pixel4[1] & 0xffff0000;
538 *ptr4++ = px;
539 px = *ptr4 & 0xffffff00;
540 px |= pixel4[2] & 0x000000ff;
541 *ptr4 = px;
542 if (0 == --n)
543 break;
544 case 3:
545 px = *ptr4 & 0x000000ff;
546 px |= pixel4[2] & 0xffffff00;
547 *ptr4++ = px;
548 --n;
549 break;
550 }
551 while (n > 3) {
552 p = pixel4;
553 *ptr4++ = *p++;
554 *ptr4++ = *p++;
555 *ptr4++ = *p++;
556 n -= 4;
557 }
558 switch (n) {
559 case 3:
560 p = pixel4;
561 *ptr4++ = *p++;
562 *ptr4++ = *p++;
563 px = *ptr4 & 0xffffff00;
564 px |= clearPixel & 0xff;
565 *ptr4 = px;
566 break;
567 case 2:
568 p = pixel4;
569 *ptr4++ = *p++;
570 px = *ptr4 & 0xffff0000;
571 px |= *p & 0xffff;
572 *ptr4 = px;
573 break;
574 case 1:
575 px = *ptr4 & 0xff000000;
576 px |= *p & 0xffffff;
577 *ptr4 = px;
578 break;
579 case 0:
580 break;
581 }
582 #endif
583 }
584 }
585 else {
586 /* only clear subrect of color buffer */
587 if (r==g && g==b) {
588 /* same value for all three components (gray) */
589 GLint j;
590 for (j=0;j<height;j++) {
591 bgr_t *ptr3 = PIXELADDR3( xmesa->xm_buffer, x, y+j );
592 MEMSET(ptr3, r, 3 * width);
593 }
594 }
595 else {
596 /* non-gray clear color */
597 GLint i, j;
598 for (j = 0; j < height; j++) {
599 bgr_t *ptr3 = PIXELADDR3( xmesa->xm_buffer, x, y+j );
600 for (i = 0; i < width; i++) {
601 ptr3->r = r;
602 ptr3->g = g;
603 ptr3->b = b;
604 ptr3++;
605 }
606 }
607 #if 0 /* this code might not always (seems ptr3 always == ptr4) */
608 GLint j;
609 GLuint pixel4[3];
610 pixel4[0] = clearPixel | (clearPixel << 24);
611 pixel4[1] = (clearPixel << 16) | (clearPixel >> 8);
612 pixel4[2] = (clearPixel << 8) | (clearPixel >> 16);
613 for (j=0;j<height;j++) {
614 bgr_t *ptr3 = PIXELADDR3( xmesa->xm_buffer, x, y+j );
615 register GLuint *ptr4 = (GLuint *)ptr3;
616 register GLuint *p, px;
617 GLuint w = width;
618 switch (3 & (int)(ptr3 - (bgr_t*) ptr4)){
619 case 0:
620 break;
621 case 1:
622 px = *ptr4 & 0x00ffffff;
623 px |= pixel4[0] & 0xff000000;
624 *ptr4++ = px;
625 px = *ptr4 & 0xffff0000;
626 px |= pixel4[2] & 0x0000ffff;
627 *ptr4 = px;
628 if (0 == --w)
629 break;
630 case 2:
631 px = *ptr4 & 0x0000fffff;
632 px |= pixel4[1] & 0xffff0000;
633 *ptr4++ = px;
634 px = *ptr4 & 0xffffff00;
635 px |= pixel4[2] & 0x000000ff;
636 *ptr4 = px;
637 if (0 == --w)
638 break;
639 case 3:
640 px = *ptr4 & 0x000000ff;
641 px |= pixel4[2] & 0xffffff00;
642 *ptr4++ = px;
643 --w;
644 break;
645 }
646 while (w > 3){
647 p = pixel4;
648 *ptr4++ = *p++;
649 *ptr4++ = *p++;
650 *ptr4++ = *p++;
651 w -= 4;
652 }
653 switch (w) {
654 case 3:
655 p = pixel4;
656 *ptr4++ = *p++;
657 *ptr4++ = *p++;
658 px = *ptr4 & 0xffffff00;
659 px |= *p & 0xff;
660 *ptr4 = px;
661 break;
662 case 2:
663 p = pixel4;
664 *ptr4++ = *p++;
665 px = *ptr4 & 0xffff0000;
666 px |= *p & 0xffff;
667 *ptr4 = px;
668 break;
669 case 1:
670 px = *ptr4 & 0xff000000;
671 px |= pixel4[0] & 0xffffff;
672 *ptr4 = px;
673 break;
674 case 0:
675 break;
676 }
677 }
678 #endif
679 }
680 }
681 }
682
683
684 static void
685 clear_32bit_ximage( GLcontext *ctx, GLboolean all,
686 GLint x, GLint y, GLint width, GLint height )
687 {
688 const XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
689 register GLuint pixel = (GLuint) xmesa->clearpixel;
690 if (xmesa->swapbytes) {
691 pixel = ((pixel >> 24) & 0x000000ff)
692 | ((pixel >> 8) & 0x0000ff00)
693 | ((pixel << 8) & 0x00ff0000)
694 | ((pixel << 24) & 0xff000000);
695 }
696 if (all) {
697 register GLint n = xmesa->xm_buffer->width * xmesa->xm_buffer->height;
698 register GLuint *ptr4 = (GLuint *) xmesa->xm_buffer->backimage->data;
699 if (pixel==0) {
700 MEMSET( ptr4, pixel, 4*n );
701 }
702 else {
703 do {
704 *ptr4++ = pixel;
705 n--;
706 } while (n!=0);
707 }
708 }
709 else {
710 register int i, j;
711 for (j=0;j<height;j++) {
712 register GLuint *ptr4 = PIXELADDR4( xmesa->xm_buffer, x, y+j );
713 for (i=0;i<width;i++) {
714 *ptr4++ = pixel;
715 }
716 }
717 }
718 }
719
720
721 static void
722 clear_nbit_ximage( GLcontext *ctx, GLboolean all,
723 GLint x, GLint y, GLint width, GLint height )
724 {
725 const XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
726 XMesaImage *img = xmesa->xm_buffer->backimage;
727 if (all) {
728 register int i, j;
729 width = xmesa->xm_buffer->width;
730 height = xmesa->xm_buffer->height;
731 for (j=0;j<height;j++) {
732 for (i=0;i<width;i++) {
733 XMesaPutPixel( img, i, j, xmesa->clearpixel );
734 }
735 }
736 }
737 else {
738 /* TODO: optimize this */
739 register int i, j;
740 y = FLIP(xmesa->xm_buffer, y);
741 for (j=0;j<height;j++) {
742 for (i=0;i<width;i++) {
743 XMesaPutPixel( img, x+i, y-j, xmesa->clearpixel );
744 }
745 }
746 }
747 }
748
749
750
751 static void
752 clear_buffers( GLcontext *ctx, GLbitfield mask,
753 GLboolean all, GLint x, GLint y, GLint width, GLint height )
754 {
755 const XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
756 const GLuint *colorMask = (GLuint *) &ctx->Color.ColorMask;
757
758 if ((mask & (DD_FRONT_LEFT_BIT | DD_BACK_LEFT_BIT)) &&
759 xmesa->xm_buffer->mesa_buffer.UseSoftwareAlphaBuffers &&
760 ctx->Color.ColorMask[ACOMP]) {
761 _mesa_clear_alpha_buffers(ctx);
762 }
763
764 /* we can't handle color or index masking */
765 if (*colorMask == 0xffffffff && ctx->Color.IndexMask == 0xffffffff) {
766 if (mask & DD_FRONT_LEFT_BIT) {
767 ASSERT(xmesa->xm_buffer->front_clear_func);
768 (*xmesa->xm_buffer->front_clear_func)( ctx, all, x, y, width, height );
769 mask &= ~DD_FRONT_LEFT_BIT;
770 }
771 if (mask & DD_BACK_LEFT_BIT) {
772 ASSERT(xmesa->xm_buffer->back_clear_func);
773 (*xmesa->xm_buffer->back_clear_func)( ctx, all, x, y, width, height );
774 mask &= ~DD_BACK_LEFT_BIT;
775 }
776 }
777
778 if (mask)
779 _swrast_Clear( ctx, mask, all, x, y, width, height );
780 }
781
782
783 static void
784 resize_buffers( GLcontext *ctx )
785 {
786 _swrast_alloc_buffers( ctx );
787 }
788
789 #if 0
790 /*
791 * This function implements glDrawPixels() with an XPutImage call when
792 * drawing to the front buffer (X Window drawable).
793 * The image format must be GL_BGRA to match the PF_8R8G8B pixel format.
794 * XXX top/bottom edge clipping is broken!
795 */
796 static GLboolean
797 drawpixels_8R8G8B( GLcontext *ctx,
798 GLint x, GLint y, GLsizei width, GLsizei height,
799 GLenum format, GLenum type,
800 const struct gl_pixelstore_attrib *unpack,
801 const GLvoid *pixels )
802 {
803 const XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
804 XMesaDisplay *dpy = xmesa->xm_visual->display;
805 XMesaDrawable buffer = xmesa->xm_buffer->buffer;
806 XMesaGC gc = xmesa->xm_buffer->gc;
807 assert(dpy);
808 assert(buffer);
809 assert(gc);
810
811 /* XXX also check for pixel scale/bias/lookup/zooming! */
812 if (format == GL_BGRA && type == GL_UNSIGNED_BYTE) {
813 int dstX = x;
814 int dstY = y;
815 int w = width;
816 int h = height;
817 int srcX = unpack->SkipPixels;
818 int srcY = unpack->SkipRows;
819 if (_mesa_clip_pixelrect(ctx, &dstX, &dstY, &w, &h, &srcX, &srcY)) {
820 XMesaImage ximage;
821 MEMSET(&ximage, 0, sizeof(XMesaImage));
822 ximage.width = width;
823 ximage.height = height;
824 ximage.format = ZPixmap;
825 ximage.data = (char *) pixels + (height - 1) * width * 4;
826 ximage.byte_order = LSBFirst;
827 ximage.bitmap_unit = 32;
828 ximage.bitmap_bit_order = LSBFirst;
829 ximage.bitmap_pad = 32;
830 ximage.depth = 24;
831 ximage.bytes_per_line = -width * 4;
832 ximage.bits_per_pixel = 32;
833 ximage.red_mask = 0xff0000;
834 ximage.green_mask = 0x00ff00;
835 ximage.blue_mask = 0x0000ff;
836 dstY = FLIP(xmesa->xm_buffer,dstY) - height + 1;
837 XPutImage(dpy, buffer, gc, &ximage, srcX, srcY, dstX, dstY, w, h);
838 return GL_TRUE;
839 }
840 }
841 return GL_FALSE;
842 }
843 #endif
844
845
846
847 static const GLubyte *
848 get_string( GLcontext *ctx, GLenum name )
849 {
850 (void) ctx;
851 switch (name) {
852 case GL_RENDERER:
853 #ifdef XFree86Server
854 return (const GLubyte *) "Mesa GLX Indirect";
855 #else
856 return (const GLubyte *) "Mesa X11";
857 #endif
858 case GL_VENDOR:
859 #ifdef XFree86Server
860 return (const GLubyte *) "Mesa project: www.mesa3d.org";
861 #else
862 return NULL;
863 #endif
864 default:
865 return NULL;
866 }
867 }
868
869
870 static void
871 enable( GLcontext *ctx, GLenum pname, GLboolean state )
872 {
873 const XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
874
875 switch (pname) {
876 case GL_DITHER:
877 if (state)
878 xmesa->pixelformat = xmesa->xm_visual->dithered_pf;
879 else
880 xmesa->pixelformat = xmesa->xm_visual->undithered_pf;
881 break;
882 default:
883 ; /* silence compiler warning */
884 }
885 }
886
887
888 void xmesa_update_state( GLcontext *ctx, GLuint new_state )
889 {
890 const XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
891
892 /* Propogate statechange information to swrast and swrast_setup
893 * modules. The X11 driver has no internal GL-dependent state.
894 */
895 _swrast_InvalidateState( ctx, new_state );
896 _ac_InvalidateState( ctx, new_state );
897 _tnl_InvalidateState( ctx, new_state );
898 _swsetup_InvalidateState( ctx, new_state );
899
900
901 /* setup pointers to front and back buffer clear functions */
902 xmesa->xm_buffer->front_clear_func = clear_front_pixmap;
903 if (xmesa->xm_buffer->backpixmap != XIMAGE) {
904 xmesa->xm_buffer->back_clear_func = clear_back_pixmap;
905 }
906 else if (sizeof(GLushort)!=2 || sizeof(GLuint)!=4) {
907 xmesa->xm_buffer->back_clear_func = clear_nbit_ximage;
908 }
909 else switch (xmesa->xm_visual->BitsPerPixel) {
910 case 8:
911 if (xmesa->xm_visual->hpcr_clear_flag) {
912 xmesa->xm_buffer->back_clear_func = clear_HPCR_ximage;
913 }
914 else {
915 xmesa->xm_buffer->back_clear_func = clear_8bit_ximage;
916 }
917 break;
918 case 16:
919 xmesa->xm_buffer->back_clear_func = clear_16bit_ximage;
920 break;
921 case 24:
922 xmesa->xm_buffer->back_clear_func = clear_24bit_ximage;
923 break;
924 case 32:
925 xmesa->xm_buffer->back_clear_func = clear_32bit_ximage;
926 break;
927 default:
928 xmesa->xm_buffer->back_clear_func = clear_nbit_ximage;
929 break;
930 }
931
932 xmesa_update_span_funcs(ctx);
933 }
934
935
936
937 /* Setup pointers and other driver state that is constant for the life
938 * of a context.
939 */
940 void xmesa_init_pointers( GLcontext *ctx )
941 {
942 TNLcontext *tnl;
943
944 ctx->Driver.GetString = get_string;
945 ctx->Driver.GetBufferSize = get_buffer_size;
946 ctx->Driver.Flush = flush;
947 ctx->Driver.Finish = finish;
948
949 /* Software rasterizer pixel paths:
950 */
951 ctx->Driver.Accum = _swrast_Accum;
952 ctx->Driver.Bitmap = _swrast_Bitmap;
953 ctx->Driver.Clear = clear_buffers;
954 ctx->Driver.ResizeBuffersMESA = resize_buffers;
955 ctx->Driver.CopyPixels = _swrast_CopyPixels;
956 ctx->Driver.DrawPixels = _swrast_DrawPixels;
957 ctx->Driver.ReadPixels = _swrast_ReadPixels;
958
959 /* Software texture functions:
960 */
961 ctx->Driver.ChooseTextureFormat = _mesa_choose_tex_format;
962 ctx->Driver.TexImage1D = _mesa_store_teximage1d;
963 ctx->Driver.TexImage2D = _mesa_store_teximage2d;
964 ctx->Driver.TexImage3D = _mesa_store_teximage3d;
965 ctx->Driver.TexSubImage1D = _mesa_store_texsubimage1d;
966 ctx->Driver.TexSubImage2D = _mesa_store_texsubimage2d;
967 ctx->Driver.TexSubImage3D = _mesa_store_texsubimage3d;
968 ctx->Driver.TestProxyTexImage = _mesa_test_proxy_teximage;
969
970 ctx->Driver.CopyTexImage1D = _swrast_copy_teximage1d;
971 ctx->Driver.CopyTexImage2D = _swrast_copy_teximage2d;
972 ctx->Driver.CopyTexSubImage1D = _swrast_copy_texsubimage1d;
973 ctx->Driver.CopyTexSubImage2D = _swrast_copy_texsubimage2d;
974 ctx->Driver.CopyTexSubImage3D = _swrast_copy_texsubimage3d;
975
976 ctx->Driver.BaseCompressedTexFormat = _mesa_base_compressed_texformat;
977 ctx->Driver.CompressedTextureSize = _mesa_compressed_texture_size;
978 ctx->Driver.GetCompressedTexImage = _mesa_get_compressed_teximage;
979
980 /* Swrast hooks for imaging extensions:
981 */
982 ctx->Driver.CopyColorTable = _swrast_CopyColorTable;
983 ctx->Driver.CopyColorSubTable = _swrast_CopyColorSubTable;
984 ctx->Driver.CopyConvolutionFilter1D = _swrast_CopyConvolutionFilter1D;
985 ctx->Driver.CopyConvolutionFilter2D = _swrast_CopyConvolutionFilter2D;
986
987
988 /* Statechange callbacks:
989 */
990 ctx->Driver.SetDrawBuffer = set_draw_buffer;
991 ctx->Driver.ClearIndex = clear_index;
992 ctx->Driver.ClearColor = clear_color;
993 ctx->Driver.IndexMask = index_mask;
994 ctx->Driver.ColorMask = color_mask;
995 ctx->Driver.Enable = enable;
996
997
998 /* Initialize the TNL driver interface:
999 */
1000 tnl = TNL_CONTEXT(ctx);
1001 tnl->Driver.RunPipeline = _tnl_run_pipeline;
1002
1003 /* Install swsetup for tnl->Driver.Render.*:
1004 */
1005 _swsetup_Wakeup(ctx);
1006
1007 (void) DitherValues; /* silenced unused var warning */
1008 }
1009
1010
1011
1012
1013
1014 #define XMESA_NEW_POINT (_NEW_POINT | \
1015 _NEW_RENDERMODE | \
1016 _SWRAST_NEW_RASTERMASK)
1017
1018 #define XMESA_NEW_LINE (_NEW_LINE | \
1019 _NEW_TEXTURE | \
1020 _NEW_LIGHT | \
1021 _NEW_DEPTH | \
1022 _NEW_RENDERMODE | \
1023 _SWRAST_NEW_RASTERMASK)
1024
1025 #define XMESA_NEW_TRIANGLE (_NEW_POLYGON | \
1026 _NEW_TEXTURE | \
1027 _NEW_LIGHT | \
1028 _NEW_DEPTH | \
1029 _NEW_RENDERMODE | \
1030 _SWRAST_NEW_RASTERMASK)
1031
1032
1033 /* Extend the software rasterizer with our line/point/triangle
1034 * functions.
1035 */
1036 void xmesa_register_swrast_functions( GLcontext *ctx )
1037 {
1038 SWcontext *swrast = SWRAST_CONTEXT( ctx );
1039
1040 swrast->choose_point = xmesa_choose_point;
1041 swrast->choose_line = xmesa_choose_line;
1042 swrast->choose_triangle = xmesa_choose_triangle;
1043
1044 swrast->invalidate_point |= XMESA_NEW_POINT;
1045 swrast->invalidate_line |= XMESA_NEW_LINE;
1046 swrast->invalidate_triangle |= XMESA_NEW_TRIANGLE;
1047 }