Removed Driver.Color() and Driver.Index() functions.
[mesa.git] / src / mesa / drivers / x11 / xm_dd.c
1 /* $Id: xm_dd.c,v 1.5 2000/11/14 17:40:15 brianp Exp $ */
2
3 /*
4 * Mesa 3-D graphics library
5 * Version: 3.3
6 *
7 * Copyright (C) 1999-2000 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
27
28 #include "glxheader.h"
29 #include "context.h"
30 #include "drawpix.h"
31 #include "mem.h"
32 #include "state.h"
33 #include "depth.h"
34 #include "macros.h"
35 #include "vb.h"
36 #include "types.h"
37 #include "xmesaP.h"
38 #include "extensions.h"
39 #include "swrast/swrast.h"
40 #include "swrast_setup/swrast_setup.h"
41
42 /*
43 * Return the size (width,height of the current color buffer.
44 * This function should be called by the glViewport function because
45 * glViewport is often called when the window gets resized. We need to
46 * update some X/Mesa stuff when that happens.
47 * Output: width - width of buffer in pixels.
48 * height - height of buffer in pixels.
49 */
50 static void
51 get_buffer_size( GLcontext *ctx, GLuint *width, GLuint *height )
52 {
53 const XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
54 unsigned int winwidth, winheight;
55 #ifndef XFree86Server
56 Window root;
57 int winx, winy;
58 unsigned int bw, d;
59
60 _glthread_LOCK_MUTEX(_xmesa_lock);
61 XGetGeometry( xmesa->display, xmesa->xm_buffer->frontbuffer, &root,
62 &winx, &winy, &winwidth, &winheight, &bw, &d );
63 _glthread_UNLOCK_MUTEX(_xmesa_lock);
64 #else
65
66 winwidth = xmesa->xm_buffer->frontbuffer->width;
67 winheight = xmesa->xm_buffer->frontbuffer->height;
68 #endif
69
70 *width = winwidth;
71 *height = winheight;
72
73 if ( winwidth!=xmesa->xm_buffer->width
74 || winheight!=xmesa->xm_buffer->height) {
75 xmesa->xm_buffer->width = winwidth;
76 xmesa->xm_buffer->height = winheight;
77 xmesa_alloc_back_buffer( xmesa->xm_buffer );
78 }
79
80 /* Needed by FLIP macro */
81 xmesa->xm_buffer->bottom = (int) winheight - 1;
82
83 if (xmesa->xm_buffer->backimage) {
84 /* Needed by PIXELADDR1 macro */
85 xmesa->xm_buffer->ximage_width1
86 = xmesa->xm_buffer->backimage->bytes_per_line;
87 xmesa->xm_buffer->ximage_origin1
88 = (GLubyte *) xmesa->xm_buffer->backimage->data
89 + xmesa->xm_buffer->ximage_width1 * (winheight-1);
90
91 /* Needed by PIXELADDR2 macro */
92 xmesa->xm_buffer->ximage_width2
93 = xmesa->xm_buffer->backimage->bytes_per_line / 2;
94 xmesa->xm_buffer->ximage_origin2
95 = (GLushort *) xmesa->xm_buffer->backimage->data
96 + xmesa->xm_buffer->ximage_width2 * (winheight-1);
97
98 /* Needed by PIXELADDR3 macro */
99 xmesa->xm_buffer->ximage_width3
100 = xmesa->xm_buffer->backimage->bytes_per_line;
101 xmesa->xm_buffer->ximage_origin3
102 = (GLubyte *) xmesa->xm_buffer->backimage->data
103 + xmesa->xm_buffer->ximage_width3 * (winheight-1);
104
105 /* Needed by PIXELADDR4 macro */
106 xmesa->xm_buffer->ximage_width4 = xmesa->xm_buffer->backimage->width;
107 xmesa->xm_buffer->ximage_origin4
108 = (GLuint *) xmesa->xm_buffer->backimage->data
109 + xmesa->xm_buffer->ximage_width4 * (winheight-1);
110 }
111 }
112
113
114 static void
115 finish( GLcontext *ctx )
116 {
117 #ifdef XFree86Server
118 /* NOT_NEEDED */
119 #else
120 const XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
121 if (xmesa) {
122 _glthread_LOCK_MUTEX(_xmesa_lock);
123 XSync( xmesa->display, False );
124 _glthread_UNLOCK_MUTEX(_xmesa_lock);
125 }
126 #endif
127 }
128
129
130 static void
131 flush( GLcontext *ctx )
132 {
133 #ifdef XFree86Server
134 /* NOT_NEEDED */
135 #else
136 const XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
137 if (xmesa) {
138 _glthread_LOCK_MUTEX(_xmesa_lock);
139 XFlush( xmesa->display );
140 _glthread_UNLOCK_MUTEX(_xmesa_lock);
141 }
142 #endif
143 }
144
145
146
147
148 static GLboolean
149 set_draw_buffer( GLcontext *ctx, GLenum mode )
150 {
151 const XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
152 if (mode == GL_FRONT_LEFT) {
153 /* write to front buffer */
154 xmesa->xm_buffer->buffer = xmesa->xm_buffer->frontbuffer;
155 xmesa_update_span_funcs(ctx);
156 return GL_TRUE;
157 }
158 else if (mode==GL_BACK_LEFT && xmesa->xm_buffer->db_state) {
159 /* write to back buffer */
160 if (xmesa->xm_buffer->backpixmap) {
161 xmesa->xm_buffer->buffer =
162 (XMesaDrawable)xmesa->xm_buffer->backpixmap;
163 }
164 else if (xmesa->xm_buffer->backimage) {
165 xmesa->xm_buffer->buffer = None;
166 }
167 else {
168 /* just in case there wasn't enough memory for back buffer */
169 xmesa->xm_buffer->buffer = xmesa->xm_buffer->frontbuffer;
170 }
171 xmesa_update_span_funcs(ctx);
172 return GL_TRUE;
173 }
174 else {
175 return GL_FALSE;
176 }
177 }
178
179
180 static void
181 set_read_buffer( GLcontext *ctx, GLframebuffer *buffer, GLenum mode )
182 {
183 XMesaBuffer target;
184 const XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
185
186 if (buffer == ctx->DrawBuffer) {
187 target = xmesa->xm_buffer;
188 xmesa->use_read_buffer = GL_FALSE;
189 }
190 else {
191 ASSERT(buffer == ctx->ReadBuffer);
192 target = xmesa->xm_read_buffer;
193 xmesa->use_read_buffer = GL_TRUE;
194 }
195
196 if (mode == GL_FRONT_LEFT) {
197 target->buffer = target->frontbuffer;
198 xmesa_update_span_funcs(ctx);
199 }
200 else if (mode==GL_BACK_LEFT && xmesa->xm_read_buffer->db_state) {
201 if (target->backpixmap) {
202 target->buffer = (XMesaDrawable)xmesa->xm_buffer->backpixmap;
203 }
204 else if (target->backimage) {
205 target->buffer = None;
206 }
207 else {
208 /* just in case there wasn't enough memory for back buffer */
209 target->buffer = target->frontbuffer;
210 }
211 xmesa_update_span_funcs(ctx);
212 }
213 else {
214 gl_problem(ctx, "invalid buffer in set_read_buffer() in xmesa2.c");
215 }
216 }
217
218
219
220 static void
221 clear_index( GLcontext *ctx, GLuint index )
222 {
223 const XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
224 xmesa->clearpixel = (unsigned long) index;
225 XMesaSetForeground( xmesa->display, xmesa->xm_buffer->cleargc,
226 (unsigned long) index );
227 }
228
229
230 static void
231 clear_color( GLcontext *ctx, GLubyte r, GLubyte g, GLubyte b, GLubyte a )
232 {
233 const XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
234 xmesa->clearcolor[0] = r;
235 xmesa->clearcolor[1] = g;
236 xmesa->clearcolor[2] = b;
237 xmesa->clearcolor[3] = a;
238 xmesa->clearpixel = xmesa_color_to_pixel( xmesa, r, g, b, a,
239 xmesa->xm_visual->undithered_pf );
240 _glthread_LOCK_MUTEX(_xmesa_lock);
241 XMesaSetForeground( xmesa->display, xmesa->xm_buffer->cleargc,
242 xmesa->clearpixel );
243 _glthread_UNLOCK_MUTEX(_xmesa_lock);
244 }
245
246
247
248 /* Set index mask ala glIndexMask */
249 static void
250 index_mask( GLcontext *ctx, GLuint mask )
251 {
252 const XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
253 if (xmesa->xm_buffer->buffer != XIMAGE) {
254 unsigned long m;
255 if (mask==0xffffffff) {
256 m = ((unsigned long)~0L);
257 }
258 else {
259 m = (unsigned long) mask;
260 }
261 XMesaSetPlaneMask( xmesa->display, xmesa->xm_buffer->cleargc, m );
262 }
263 }
264
265
266 /* Implements glColorMask() */
267 static void
268 color_mask(GLcontext *ctx,
269 GLboolean rmask, GLboolean gmask, GLboolean bmask, GLboolean amask)
270 {
271 const XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
272 int xclass = GET_VISUAL_CLASS(xmesa->xm_visual);
273 (void) amask;
274
275 if (xmesa->xm_buffer->buffer != XIMAGE
276 && (xclass == TrueColor || xclass == DirectColor)) {
277 unsigned long m;
278 if (rmask && gmask && bmask) {
279 m = ((unsigned long)~0L);
280 }
281 else {
282 m = 0;
283 if (rmask) m |= GET_REDMASK(xmesa->xm_visual);
284 if (gmask) m |= GET_GREENMASK(xmesa->xm_visual);
285 if (bmask) m |= GET_BLUEMASK(xmesa->xm_visual);
286 }
287 XMesaSetPlaneMask( xmesa->display, xmesa->xm_buffer->cleargc, m );
288 }
289 }
290
291
292
293 /**********************************************************************/
294 /*** glClear implementations ***/
295 /**********************************************************************/
296
297
298 static void
299 clear_front_pixmap( GLcontext *ctx, GLboolean all,
300 GLint x, GLint y, GLint width, GLint height )
301 {
302 const XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
303 if (all) {
304 XMesaFillRectangle( xmesa->display, xmesa->xm_buffer->frontbuffer,
305 xmesa->xm_buffer->cleargc,
306 0, 0,
307 xmesa->xm_buffer->width+1,
308 xmesa->xm_buffer->height+1 );
309 }
310 else {
311 XMesaFillRectangle( xmesa->display, xmesa->xm_buffer->frontbuffer,
312 xmesa->xm_buffer->cleargc,
313 x, xmesa->xm_buffer->height - y - height,
314 width, height );
315 }
316 }
317
318
319 static void
320 clear_back_pixmap( GLcontext *ctx, GLboolean all,
321 GLint x, GLint y, GLint width, GLint height )
322 {
323 const XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
324 if (all) {
325 XMesaFillRectangle( xmesa->display, xmesa->xm_buffer->backpixmap,
326 xmesa->xm_buffer->cleargc,
327 0, 0,
328 xmesa->xm_buffer->width+1,
329 xmesa->xm_buffer->height+1 );
330 }
331 else {
332 XMesaFillRectangle( xmesa->display, xmesa->xm_buffer->backpixmap,
333 xmesa->xm_buffer->cleargc,
334 x, xmesa->xm_buffer->height - y - height,
335 width, height );
336 }
337 }
338
339
340 static void
341 clear_8bit_ximage( GLcontext *ctx, GLboolean all,
342 GLint x, GLint y, GLint width, GLint height )
343 {
344 const XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
345 if (all) {
346 size_t n = xmesa->xm_buffer->backimage->bytes_per_line
347 * xmesa->xm_buffer->backimage->height;
348 MEMSET( xmesa->xm_buffer->backimage->data, xmesa->clearpixel, n );
349 }
350 else {
351 GLint i;
352 for (i=0;i<height;i++) {
353 GLubyte *ptr = PIXELADDR1( xmesa->xm_buffer, x, y+i );
354 MEMSET( ptr, xmesa->clearpixel, width );
355 }
356 }
357 }
358
359
360 static void
361 clear_HPCR_ximage( GLcontext *ctx, GLboolean all,
362 GLint x, GLint y, GLint width, GLint height )
363 {
364 const XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
365 if (all) {
366 GLint i, c16 = (xmesa->xm_buffer->backimage->bytes_per_line>>4)<<4;
367 GLubyte *ptr = (GLubyte *)xmesa->xm_buffer->backimage->data;
368 for (i=0; i<xmesa->xm_buffer->backimage->height; i++) {
369 GLint j;
370 GLubyte *sptr = xmesa->xm_visual->hpcr_clear_ximage_pattern[0];
371 if (i&1) {
372 sptr += 16;
373 }
374 for (j=0; j<c16; j+=16) {
375 ptr[0] = sptr[0];
376 ptr[1] = sptr[1];
377 ptr[2] = sptr[2];
378 ptr[3] = sptr[3];
379 ptr[4] = sptr[4];
380 ptr[5] = sptr[5];
381 ptr[6] = sptr[6];
382 ptr[7] = sptr[7];
383 ptr[8] = sptr[8];
384 ptr[9] = sptr[9];
385 ptr[10] = sptr[10];
386 ptr[11] = sptr[11];
387 ptr[12] = sptr[12];
388 ptr[13] = sptr[13];
389 ptr[14] = sptr[14];
390 ptr[15] = sptr[15];
391 ptr += 16;
392 }
393 for (; j<xmesa->xm_buffer->backimage->bytes_per_line; j++) {
394 *ptr = sptr[j&15];
395 ptr++;
396 }
397 }
398 }
399 else {
400 GLint i;
401 for (i=y; i<y+height; i++) {
402 GLubyte *ptr = PIXELADDR1( xmesa->xm_buffer, x, i );
403 int j;
404 GLubyte *sptr = xmesa->xm_visual->hpcr_clear_ximage_pattern[0];
405 if (i&1) {
406 sptr += 16;
407 }
408 for (j=x; j<x+width; j++) {
409 *ptr = sptr[j&15];
410 ptr++;
411 }
412 }
413 }
414 }
415
416
417 static void
418 clear_16bit_ximage( GLcontext *ctx, GLboolean all,
419 GLint x, GLint y, GLint width, GLint height )
420 {
421 const XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
422 register GLuint pixel = (GLuint) xmesa->clearpixel;
423 if (xmesa->swapbytes) {
424 pixel = ((pixel >> 8) & 0x00ff) | ((pixel << 8) & 0xff00);
425 }
426 if (all) {
427 register GLuint n;
428 register GLuint *ptr4 = (GLuint *) xmesa->xm_buffer->backimage->data;
429 if ((pixel & 0xff) == ((pixel >> 8) & 0xff)) {
430 /* low and high bytes are equal so use memset() */
431 n = xmesa->xm_buffer->backimage->bytes_per_line
432 * xmesa->xm_buffer->height;
433 MEMSET( ptr4, pixel & 0xff, n );
434 }
435 else {
436 pixel = pixel | (pixel<<16);
437 n = xmesa->xm_buffer->backimage->bytes_per_line
438 * xmesa->xm_buffer->height / 4;
439 do {
440 *ptr4++ = pixel;
441 n--;
442 } while (n!=0);
443
444 if ((xmesa->xm_buffer->backimage->bytes_per_line *
445 xmesa->xm_buffer->height) & 0x2)
446 *(GLushort *)ptr4 = pixel & 0xffff;
447 }
448 }
449 else {
450 register int i, j;
451 for (j=0;j<height;j++) {
452 register GLushort *ptr2 = PIXELADDR2( xmesa->xm_buffer, x, y+j );
453 for (i=0;i<width;i++) {
454 *ptr2++ = pixel;
455 }
456 }
457 }
458 }
459
460
461 /* Optimized code provided by Nozomi Ytow <noz@xfree86.org> */
462 static void
463 clear_24bit_ximage( GLcontext *ctx, GLboolean all,
464 GLint x, GLint y, GLint width, GLint height )
465 {
466 const XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
467 const GLubyte r = xmesa->clearcolor[0];
468 const GLubyte g = xmesa->clearcolor[1];
469 const GLubyte b = xmesa->clearcolor[2];
470 register GLuint clearPixel;
471 if (xmesa->swapbytes) {
472 clearPixel = (b << 16) | (g << 8) | r;
473 }
474 else {
475 clearPixel = (r << 16) | (g << 8) | b;
476 }
477
478 if (all) {
479 if (r==g && g==b) {
480 /* same value for all three components (gray) */
481 const GLint w3 = xmesa->xm_buffer->width * 3;
482 const GLint h = xmesa->xm_buffer->height;
483 GLint i;
484 for (i = 0; i < h; i++) {
485 bgr_t *ptr3 = PIXELADDR3(xmesa->xm_buffer, 0, i);
486 MEMSET(ptr3, r, w3);
487 }
488 }
489 else {
490 /* the usual case */
491 const GLint w = xmesa->xm_buffer->width;
492 const GLint h = xmesa->xm_buffer->height;
493 GLint i, j;
494 for (i = 0; i < h; i++) {
495 bgr_t *ptr3 = PIXELADDR3(xmesa->xm_buffer, 0, i);
496 for (j = 0; j < w; j++) {
497 ptr3->r = r;
498 ptr3->g = g;
499 ptr3->b = b;
500 ptr3++;
501 }
502 }
503 #if 0 /* this code doesn't work for all window widths */
504 register GLuint *ptr4 = (GLuint *) ptr3;
505 register GLuint px;
506 GLuint pixel4[3];
507 register GLuint *p = pixel4;
508 pixel4[0] = clearPixel | (clearPixel << 24);
509 pixel4[1] = (clearPixel << 16) | (clearPixel >> 8);
510 pixel4[2] = (clearPixel << 8) | (clearPixel >> 16);
511 switch (3 & (int)(ptr3 - (bgr_t*) ptr4)){
512 case 0:
513 break;
514 case 1:
515 px = *ptr4 & 0x00ffffff;
516 px |= pixel4[0] & 0xff000000;
517 *ptr4++ = px;
518 px = *ptr4 & 0xffff0000;
519 px |= pixel4[2] & 0x0000ffff;
520 *ptr4 = px;
521 if (0 == --n)
522 break;
523 case 2:
524 px = *ptr4 & 0x0000fffff;
525 px |= pixel4[1] & 0xffff0000;
526 *ptr4++ = px;
527 px = *ptr4 & 0xffffff00;
528 px |= pixel4[2] & 0x000000ff;
529 *ptr4 = px;
530 if (0 == --n)
531 break;
532 case 3:
533 px = *ptr4 & 0x000000ff;
534 px |= pixel4[2] & 0xffffff00;
535 *ptr4++ = px;
536 --n;
537 break;
538 }
539 while (n > 3) {
540 p = pixel4;
541 *ptr4++ = *p++;
542 *ptr4++ = *p++;
543 *ptr4++ = *p++;
544 n -= 4;
545 }
546 switch (n) {
547 case 3:
548 p = pixel4;
549 *ptr4++ = *p++;
550 *ptr4++ = *p++;
551 px = *ptr4 & 0xffffff00;
552 px |= clearPixel & 0xff;
553 *ptr4 = px;
554 break;
555 case 2:
556 p = pixel4;
557 *ptr4++ = *p++;
558 px = *ptr4 & 0xffff0000;
559 px |= *p & 0xffff;
560 *ptr4 = px;
561 break;
562 case 1:
563 px = *ptr4 & 0xff000000;
564 px |= *p & 0xffffff;
565 *ptr4 = px;
566 break;
567 case 0:
568 break;
569 }
570 #endif
571 }
572 }
573 else {
574 /* only clear subrect of color buffer */
575 if (r==g && g==b) {
576 /* same value for all three components (gray) */
577 GLint j;
578 for (j=0;j<height;j++) {
579 bgr_t *ptr3 = PIXELADDR3( xmesa->xm_buffer, x, y+j );
580 MEMSET(ptr3, r, 3 * width);
581 }
582 }
583 else {
584 /* non-gray clear color */
585 GLint i, j;
586 for (j = 0; j < height; j++) {
587 bgr_t *ptr3 = PIXELADDR3( xmesa->xm_buffer, x, y+j );
588 for (i = 0; i < width; i++) {
589 ptr3->r = r;
590 ptr3->g = g;
591 ptr3->b = b;
592 ptr3++;
593 }
594 }
595 #if 0 /* this code might not always (seems ptr3 always == ptr4) */
596 GLint j;
597 GLuint pixel4[3];
598 pixel4[0] = clearPixel | (clearPixel << 24);
599 pixel4[1] = (clearPixel << 16) | (clearPixel >> 8);
600 pixel4[2] = (clearPixel << 8) | (clearPixel >> 16);
601 for (j=0;j<height;j++) {
602 bgr_t *ptr3 = PIXELADDR3( xmesa->xm_buffer, x, y+j );
603 register GLuint *ptr4 = (GLuint *)ptr3;
604 register GLuint *p, px;
605 GLuint w = width;
606 switch (3 & (int)(ptr3 - (bgr_t*) ptr4)){
607 case 0:
608 break;
609 case 1:
610 px = *ptr4 & 0x00ffffff;
611 px |= pixel4[0] & 0xff000000;
612 *ptr4++ = px;
613 px = *ptr4 & 0xffff0000;
614 px |= pixel4[2] & 0x0000ffff;
615 *ptr4 = px;
616 if (0 == --w)
617 break;
618 case 2:
619 px = *ptr4 & 0x0000fffff;
620 px |= pixel4[1] & 0xffff0000;
621 *ptr4++ = px;
622 px = *ptr4 & 0xffffff00;
623 px |= pixel4[2] & 0x000000ff;
624 *ptr4 = px;
625 if (0 == --w)
626 break;
627 case 3:
628 px = *ptr4 & 0x000000ff;
629 px |= pixel4[2] & 0xffffff00;
630 *ptr4++ = px;
631 --w;
632 break;
633 }
634 while (w > 3){
635 p = pixel4;
636 *ptr4++ = *p++;
637 *ptr4++ = *p++;
638 *ptr4++ = *p++;
639 w -= 4;
640 }
641 switch (w) {
642 case 3:
643 p = pixel4;
644 *ptr4++ = *p++;
645 *ptr4++ = *p++;
646 px = *ptr4 & 0xffffff00;
647 px |= *p & 0xff;
648 *ptr4 = px;
649 break;
650 case 2:
651 p = pixel4;
652 *ptr4++ = *p++;
653 px = *ptr4 & 0xffff0000;
654 px |= *p & 0xffff;
655 *ptr4 = px;
656 break;
657 case 1:
658 px = *ptr4 & 0xff000000;
659 px |= pixel4[0] & 0xffffff;
660 *ptr4 = px;
661 break;
662 case 0:
663 break;
664 }
665 }
666 #endif
667 }
668 }
669 }
670
671
672 static void
673 clear_32bit_ximage( GLcontext *ctx, GLboolean all,
674 GLint x, GLint y, GLint width, GLint height )
675 {
676 const XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
677 if (all) {
678 register GLint n = xmesa->xm_buffer->width * xmesa->xm_buffer->height;
679 register GLuint *ptr4 = (GLuint *) xmesa->xm_buffer->backimage->data;
680 register GLuint pixel = (GLuint) xmesa->clearpixel;
681 if (xmesa->swapbytes) {
682 pixel = ((pixel >> 24) & 0x000000ff)
683 | ((pixel >> 8) & 0x0000ff00)
684 | ((pixel << 8) & 0x00ff0000)
685 | ((pixel << 24) & 0xff000000);
686 }
687 if (pixel==0) {
688 MEMSET( ptr4, pixel, 4*n );
689 }
690 else {
691 do {
692 *ptr4++ = pixel;
693 n--;
694 } while (n!=0);
695 }
696 }
697 else {
698 register int i, j;
699 register GLuint pixel = (GLuint) xmesa->clearpixel;
700 for (j=0;j<height;j++) {
701 register GLuint *ptr4 = PIXELADDR4( xmesa->xm_buffer, x, y+j );
702 for (i=0;i<width;i++) {
703 *ptr4++ = pixel;
704 }
705 }
706 }
707 }
708
709
710 static void
711 clear_nbit_ximage( GLcontext *ctx, GLboolean all,
712 GLint x, GLint y, GLint width, GLint height )
713 {
714 const XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
715 XMesaImage *img = xmesa->xm_buffer->backimage;
716 if (all) {
717 register int i, j;
718 width = xmesa->xm_buffer->width;
719 height = xmesa->xm_buffer->height;
720 for (j=0;j<height;j++) {
721 for (i=0;i<width;i++) {
722 XMesaPutPixel( img, i, j, xmesa->clearpixel );
723 }
724 }
725 }
726 else {
727 /* TODO: optimize this */
728 register int i, j;
729 y = FLIP(xmesa->xm_buffer, y);
730 for (j=0;j<height;j++) {
731 for (i=0;i<width;i++) {
732 XMesaPutPixel( img, x+i, y-j, xmesa->clearpixel );
733 }
734 }
735 }
736 }
737
738
739
740 static GLbitfield
741 clear_buffers( GLcontext *ctx, GLbitfield mask,
742 GLboolean all, GLint x, GLint y, GLint width, GLint height )
743 {
744 const XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
745 const GLuint *colorMask = (GLuint *) &ctx->Color.ColorMask;
746
747 /* we can't handle color or index masking */
748 if (mask & (DD_FRONT_LEFT_BIT | DD_BACK_LEFT_BIT)) {
749 if (*colorMask != 0xffffffff || ctx->Color.IndexMask != 0xffffffff)
750 return mask;
751 }
752
753 if (mask & DD_FRONT_LEFT_BIT) {
754 ASSERT(xmesa->xm_buffer->front_clear_func);
755 (*xmesa->xm_buffer->front_clear_func)( ctx, all, x, y, width, height );
756 }
757 if (mask & DD_BACK_LEFT_BIT) {
758 ASSERT(xmesa->xm_buffer->back_clear_func);
759 (*xmesa->xm_buffer->back_clear_func)( ctx, all, x, y, width, height );
760 }
761 return mask & (~(DD_FRONT_LEFT_BIT | DD_BACK_LEFT_BIT));
762 }
763
764
765
766 #if 0
767 /*
768 * This function implements glDrawPixels() with an XPutImage call when
769 * drawing to the front buffer (X Window drawable).
770 * The image format must be GL_BGRA to match the PF_8R8G8B pixel format.
771 * XXX top/bottom edge clipping is broken!
772 */
773 static GLboolean
774 drawpixels_8R8G8B( GLcontext *ctx,
775 GLint x, GLint y, GLsizei width, GLsizei height,
776 GLenum format, GLenum type,
777 const struct gl_pixelstore_attrib *unpack,
778 const GLvoid *pixels )
779 {
780 const XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
781 XMesaDisplay *dpy = xmesa->xm_visual->display;
782 XMesaDrawable buffer = xmesa->xm_buffer->buffer;
783 XMesaGC gc = xmesa->xm_buffer->gc;
784 assert(dpy);
785 assert(buffer);
786 assert(gc);
787
788 /* XXX also check for pixel scale/bias/lookup/zooming! */
789 if (format == GL_BGRA && type == GL_UNSIGNED_BYTE) {
790 int dstX = x;
791 int dstY = y;
792 int w = width;
793 int h = height;
794 int srcX = unpack->SkipPixels;
795 int srcY = unpack->SkipRows;
796 if (_mesa_clip_pixelrect(ctx, &dstX, &dstY, &w, &h, &srcX, &srcY)) {
797 XMesaImage ximage;
798 MEMSET(&ximage, 0, sizeof(XMesaImage));
799 ximage.width = width;
800 ximage.height = height;
801 ximage.format = ZPixmap;
802 ximage.data = (char *) pixels + (height - 1) * width * 4;
803 ximage.byte_order = LSBFirst;
804 ximage.bitmap_unit = 32;
805 ximage.bitmap_bit_order = LSBFirst;
806 ximage.bitmap_pad = 32;
807 ximage.depth = 24;
808 ximage.bytes_per_line = -width * 4;
809 ximage.bits_per_pixel = 32;
810 ximage.red_mask = 0xff0000;
811 ximage.green_mask = 0x00ff00;
812 ximage.blue_mask = 0x0000ff;
813 dstY = FLIP(xmesa->xm_buffer,dstY) - height + 1;
814 XPutImage(dpy, buffer, gc, &ximage, srcX, srcY, dstX, dstY, w, h);
815 return GL_TRUE;
816 }
817 }
818 return GL_FALSE;
819 }
820 #endif
821
822
823
824 static const GLubyte *
825 get_string( GLcontext *ctx, GLenum name )
826 {
827 (void) ctx;
828 switch (name) {
829 case GL_RENDERER:
830 #ifdef XFree86Server
831 return (const GLubyte *) "Mesa GLX Indirect";
832 #else
833 return (const GLubyte *) "Mesa X11";
834 #endif
835 case GL_VENDOR:
836 #ifdef XFree86Server
837 return (const GLubyte *) "VA Linux Systems, Inc.";
838 #else
839 return NULL;
840 #endif
841 default:
842 return NULL;
843 }
844 }
845
846
847 static void
848 enable( GLcontext *ctx, GLenum pname, GLboolean state )
849 {
850 const XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
851
852 switch (pname) {
853 case GL_DITHER:
854 if (state)
855 xmesa->pixelformat = xmesa->xm_visual->dithered_pf;
856 else
857 xmesa->pixelformat = xmesa->xm_visual->undithered_pf;
858 break;
859 default:
860 ; /* silence compiler warning */
861 }
862 }
863
864
865 void xmesa_update_state( GLcontext *ctx )
866 {
867 const XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
868
869 /* Propogate statechange information to swrast and swrast_setup
870 * modules. The X11 driver has no internal GL-dependent state.
871 */
872 _swrast_InvalidateState( ctx, ctx->NewState );
873 _swsetup_InvalidateState( ctx, ctx->NewState );
874
875
876 /* setup pointers to front and back buffer clear functions */
877 xmesa->xm_buffer->front_clear_func = clear_front_pixmap;
878 if (xmesa->xm_buffer->backpixmap != XIMAGE) {
879 xmesa->xm_buffer->back_clear_func = clear_back_pixmap;
880 }
881 else if (sizeof(GLushort)!=2 || sizeof(GLuint)!=4) {
882 xmesa->xm_buffer->back_clear_func = clear_nbit_ximage;
883 }
884 else switch (xmesa->xm_visual->BitsPerPixel) {
885 case 8:
886 if (xmesa->xm_visual->hpcr_clear_flag) {
887 xmesa->xm_buffer->back_clear_func = clear_HPCR_ximage;
888 }
889 else {
890 xmesa->xm_buffer->back_clear_func = clear_8bit_ximage;
891 }
892 break;
893 case 16:
894 xmesa->xm_buffer->back_clear_func = clear_16bit_ximage;
895 break;
896 case 24:
897 xmesa->xm_buffer->back_clear_func = clear_24bit_ximage;
898 break;
899 case 32:
900 xmesa->xm_buffer->back_clear_func = clear_32bit_ximage;
901 break;
902 default:
903 xmesa->xm_buffer->back_clear_func = clear_nbit_ximage;
904 break;
905 }
906
907 xmesa_update_span_funcs(ctx);
908 }
909
910
911
912 /* Setup pointers and other driver state that is constant for the life
913 * of a context.
914 */
915 void xmesa_init_pointers( GLcontext *ctx )
916 {
917 ctx->Driver.GetString = get_string;
918 ctx->Driver.GetBufferSize = get_buffer_size;
919 ctx->Driver.Flush = flush;
920 ctx->Driver.Finish = finish;
921
922 ctx->Driver.RenderStart = 0;
923 ctx->Driver.RenderFinish = _swrast_flush;
924
925 ctx->Driver.SetDrawBuffer = set_draw_buffer;
926 ctx->Driver.SetReadBuffer = set_read_buffer;
927
928 ctx->Driver.ClearIndex = clear_index;
929 ctx->Driver.ClearColor = clear_color;
930 ctx->Driver.Clear = clear_buffers;
931 ctx->Driver.IndexMask = index_mask;
932 ctx->Driver.ColorMask = color_mask;
933 ctx->Driver.Enable = enable;
934
935 ctx->Driver.PointsFunc = _swsetup_Points;
936 ctx->Driver.LineFunc = _swsetup_Line;
937 ctx->Driver.TriangleFunc = _swsetup_Triangle;
938 ctx->Driver.QuadFunc = _swsetup_Quad;
939 ctx->Driver.RasterSetup = _swsetup_RasterSetup;
940 ctx->Driver.RegisterVB = _swsetup_RegisterVB;
941 ctx->Driver.UnregisterVB = _swsetup_UnregisterVB;
942
943 (void) DitherValues; /* silenced unused var warning */
944 }