Eliminate struct pipe_region.
[mesa.git] / src / mesa / pipe / xlib / xm_surface.c
1 /*
2 * Mesa 3-D graphics library
3 * Version: 7.1
4 *
5 * Copyright (C) 1999-2007 Brian Paul All Rights Reserved.
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 */
24
25
26 /**
27 * \file xm_surface.c
28 * Code to allow the softpipe code to write to X windows/buffers.
29 * This is a bit of a hack for now. We've basically got two different
30 * abstractions for color buffers: gl_renderbuffer and pipe_surface.
31 * They'll need to get merged someday...
32 * For now, they're separate things that point to each other.
33 */
34
35
36 #include "GL/xmesa.h"
37 #include "glxheader.h"
38 #include "xmesaP.h"
39 #include "main/context.h"
40 #include "main/imports.h"
41 #include "main/macros.h"
42
43 #include "pipe/p_context.h"
44 #include "pipe/p_defines.h"
45 #include "pipe/p_winsys.h"
46 #include "pipe/softpipe/sp_context.h"
47 #include "pipe/softpipe/sp_clear.h"
48 #include "pipe/softpipe/sp_tile_cache.h"
49 #include "pipe/softpipe/sp_surface.h"
50 #include "state_tracker/st_context.h"
51
52
53 /*
54 * Dithering kernels and lookup tables.
55 */
56
57 const int xmesa_kernel8[DITH_DY * DITH_DX] = {
58 0 * MAXC, 8 * MAXC, 2 * MAXC, 10 * MAXC,
59 12 * MAXC, 4 * MAXC, 14 * MAXC, 6 * MAXC,
60 3 * MAXC, 11 * MAXC, 1 * MAXC, 9 * MAXC,
61 15 * MAXC, 7 * MAXC, 13 * MAXC, 5 * MAXC,
62 };
63
64 const int xmesa_kernel1[16] = {
65 0*47, 9*47, 4*47, 12*47, /* 47 = (255*3)/16 */
66 6*47, 2*47, 14*47, 8*47,
67 10*47, 1*47, 5*47, 11*47,
68 7*47, 13*47, 3*47, 15*47
69 };
70
71
72
73 #define CLIP_TILE \
74 do { \
75 if (x >= ps->width) \
76 return; \
77 if (y >= ps->height) \
78 return; \
79 if (x + w > ps->width) \
80 w = ps->width - x; \
81 if (y + h > ps->height) \
82 h = ps->height -y; \
83 } while(0)
84
85
86
87 /*
88 * The following functions are used to trap XGetImage() calls which
89 * generate BadMatch errors if the drawable isn't mapped.
90 */
91
92 #ifndef XFree86Server
93 static int caught_xgetimage_error = 0;
94 static int (*old_xerror_handler)( XMesaDisplay *dpy, XErrorEvent *ev );
95 static unsigned long xgetimage_serial;
96
97 /*
98 * This is the error handler which will be called if XGetImage fails.
99 */
100 static int xgetimage_error_handler( XMesaDisplay *dpy, XErrorEvent *ev )
101 {
102 if (ev->serial==xgetimage_serial && ev->error_code==BadMatch) {
103 /* caught the expected error */
104 caught_xgetimage_error = 0;
105 }
106 else {
107 /* call the original X error handler, if any. otherwise ignore */
108 if (old_xerror_handler) {
109 (*old_xerror_handler)( dpy, ev );
110 }
111 }
112 return 0;
113 }
114
115
116 /*
117 * Call this right before XGetImage to setup error trap.
118 */
119 static void catch_xgetimage_errors( XMesaDisplay *dpy )
120 {
121 xgetimage_serial = NextRequest( dpy );
122 old_xerror_handler = XSetErrorHandler( xgetimage_error_handler );
123 caught_xgetimage_error = 0;
124 }
125
126
127 /*
128 * Call this right after XGetImage to check if an error occured.
129 */
130 static int check_xgetimage_errors( void )
131 {
132 /* restore old handler */
133 (void) XSetErrorHandler( old_xerror_handler );
134 /* return 0=no error, 1=error caught */
135 return caught_xgetimage_error;
136 }
137 #endif
138
139
140 /**
141 * Wrapper for XGetImage() that catches BadMatch errors that can occur
142 * when the window is unmapped or the x/y/w/h extend beyond the window
143 * bounds.
144 * If build into xserver, wrap the internal GetImage method.
145 */
146 static XMesaImage *
147 xget_image(XMesaDisplay *dpy, Drawable d, int x, int y, uint w, uint h)
148 {
149 #ifdef XFree86Server
150 uint bpp = 4; /* XXX fix this */
151 XMesaImage *ximage = (XMesaImage *) malloc(sizeof(XMesaImage));
152 if (ximage) {
153 ximage->data = malloc(width * height * bpp);
154 }
155 (*dpy->GetImage)(d, x, y, w, h, ZPixmap, ~0L, (pointer)ximage->data);
156 ximage->width = w;
157 ximage->height = h;
158 ximage->bytes_per_row = w * bpp;
159 return ximage;
160 #else
161 int error;
162 XMesaImage *ximage;
163 catch_xgetimage_errors(dpy);
164 ximage = XGetImage(dpy, d, x, y, w, h, AllPlanes, ZPixmap);
165 error = check_xgetimage_errors();
166 return ximage;
167 #endif
168 }
169
170
171
172 /**
173 * Return raw pixels from pixmap or XImage.
174 */
175 void
176 xmesa_get_tile(struct pipe_context *pipe, struct pipe_surface *ps,
177 uint x, uint y, uint w, uint h, void *p, int dst_stride)
178 {
179 const uint w0 = w;
180 struct xmesa_surface *xms = xmesa_surface(ps);
181 XMesaImage *ximage = NULL;
182 ubyte *dst = (ubyte *) p;
183 uint i;
184
185 if (!xms->drawable && !xms->ximage) {
186 /* not an X surface */
187 softpipe_get_tile(pipe, ps, x, y, w, h, p, dst_stride);
188 return;
189 }
190
191 CLIP_TILE;
192
193 if (!xms->ximage) {
194 /* XImage = pixmap data */
195 assert(xms->drawable);
196 ximage = xget_image(xms->display, xms->drawable, x, y, w, h);
197 if (!ximage)
198 return;
199 x = y = 0;
200 }
201 else {
202 ximage = xms->ximage;
203 }
204
205 /* this could be optimized/simplified */
206 switch (ps->format) {
207 case PIPE_FORMAT_U_A8_R8_G8_B8:
208 if (!dst_stride) {
209 dst_stride = w0 * 4;
210 }
211 for (i = 0; i < h; i++) {
212 memcpy(dst, ximage->data + y * ximage->bytes_per_line + x * 4, 4 * w);
213 dst += dst_stride;
214 }
215 break;
216 case PIPE_FORMAT_U_R5_G6_B5:
217 if (!dst_stride) {
218 dst_stride = w0 * 2;
219 }
220 for (i = 0; i < h; i++) {
221 memcpy(dst, ximage->data + y * ximage->bytes_per_line + x * 2, 4 * 2);
222 dst += dst_stride;
223 }
224 break;
225 default:
226 assert(0);
227 }
228
229 if (!xms->ximage) {
230 XMesaDestroyImage(ximage);
231 }
232 }
233
234
235 /**
236 * Put raw pixels into pixmap or XImage.
237 */
238 void
239 xmesa_put_tile(struct pipe_context *pipe, struct pipe_surface *ps,
240 uint x, uint y, uint w, uint h, const void *p, int src_stride)
241 {
242 const uint w0 = w;
243 struct xmesa_surface *xms = xmesa_surface(ps);
244 const ubyte *src = (const ubyte *) p;
245 XMesaImage *ximage;
246
247 if (!xms->drawable && !xms->ximage) {
248 /* not an X surface */
249 softpipe_put_tile(pipe, ps, x, y, w, h, p, src_stride);
250 return;
251 }
252
253 CLIP_TILE;
254
255 if (xms->ximage) {
256 /* put to ximage */
257 ximage = xms->ximage;
258 char *dst;
259 uint i;
260
261 /* this could be optimized/simplified */
262 switch (ps->format) {
263 case PIPE_FORMAT_U_A8_R8_G8_B8:
264 if (!src_stride) {
265 src_stride = w0 * 4;
266 }
267 dst = ximage->data + y * ximage->bytes_per_line + x * 4;
268 for (i = 0; i < h; i++) {
269 memcpy(dst, src, w * 4);
270 dst += ximage->bytes_per_line;
271 src += src_stride;
272 }
273 break;
274 case PIPE_FORMAT_U_R5_G6_B5:
275 if (!src_stride) {
276 src_stride = w0 * 2;
277 }
278 dst = ximage->data + y * ximage->bytes_per_line + x * 2;
279 for (i = 0; i < h; i++) {
280 memcpy(dst, src, w * 2);
281 dst += ximage->bytes_per_line;
282 src += src_stride;
283 }
284 break;
285 default:
286 assert(0);
287 }
288 }
289 else {
290 /* put to pixmap/window */
291 /* Create temp XImage for data */
292 #ifdef XFree86Server
293 ximage = XMesaCreateImage(GET_VISUAL_DEPTH(v), w, h, p);
294 #else
295 XVisualInfo *visinfo = xms->xrb->Parent->xm_visual->visinfo;
296 ximage = XCreateImage(xms->display,
297 visinfo->visual,
298 visinfo->depth,
299 ZPixmap, 0, /* format, offset */
300 (char *) p, /* data */
301 w, h, /* width, height */
302 32, /* bitmap_pad */
303 0); /* bytes_per_line */
304 #endif
305
306 /* send XImage data to pixmap */
307 XPutImage(xms->display, xms->drawable, xms->gc,
308 ximage, 0, 0, x, y, w, h);
309 /* clean-up */
310 ximage->data = NULL; /* prevents freeing user data at 'p' */
311 XMesaDestroyImage(ximage);
312 }
313 }
314
315
316 void
317 xmesa_get_tile_rgba(struct pipe_context *pipe, struct pipe_surface *ps,
318 uint x, uint y, uint w, uint h, float *pixels)
319 {
320 const uint w0 = w;
321 struct xmesa_surface *xms = xmesa_surface(ps);
322 XMesaImage *ximage = NULL;
323 float *pRow = pixels;
324 uint i, j;
325
326 if (!xms->drawable && !xms->ximage) {
327 /* not an X surface */
328 softpipe_get_tile_rgba(pipe, ps, x, y, w, h, pixels);
329 return;
330 }
331
332 CLIP_TILE;
333
334 if (!xms->ximage) {
335 /* XImage = pixmap data */
336 assert(xms->drawable);
337 ximage = xget_image(xms->display, xms->drawable, x, y, w, h);
338 if (!ximage)
339 return;
340 x = y = 0;
341 }
342 else {
343 ximage = xms->ximage;
344 }
345
346 switch (ps->format) {
347 case PIPE_FORMAT_U_A8_R8_G8_B8:
348 {
349 const uint *src
350 = (uint *) (ximage->data + y * ximage->bytes_per_line + x * 4);
351 for (i = 0; i < h; i++) {
352 float *p = pRow;
353 for (j = 0; j < w; j++) {
354 uint pix = src[j];
355 ubyte r = ((pix >> 16) & 0xff);
356 ubyte g = ((pix >> 8) & 0xff);
357 ubyte b = ( pix & 0xff);
358 ubyte a = ((pix >> 24) & 0xff);
359 p[0] = UBYTE_TO_FLOAT(r);
360 p[1] = UBYTE_TO_FLOAT(g);
361 p[2] = UBYTE_TO_FLOAT(b);
362 p[3] = UBYTE_TO_FLOAT(a);
363 p += 4;
364 }
365 src += ximage->width;
366 pRow += 4 * w0;
367 }
368 }
369 break;
370 case PIPE_FORMAT_U_B8_G8_R8_A8:
371 {
372 const uint *src
373 = (uint *) (ximage->data + y * ximage->bytes_per_line + x * 4);
374 for (i = 0; i < h; i++) {
375 float *p = pRow;
376 for (j = 0; j < w; j++) {
377 uint pix = src[j];
378 ubyte r = ((pix >> 8) & 0xff);
379 ubyte g = ((pix >> 16) & 0xff);
380 ubyte b = ((pix >> 24) & 0xff);
381 ubyte a = ( pix & 0xff);
382 p[0] = UBYTE_TO_FLOAT(r);
383 p[1] = UBYTE_TO_FLOAT(g);
384 p[2] = UBYTE_TO_FLOAT(b);
385 p[3] = UBYTE_TO_FLOAT(a);
386 p += 4;
387 }
388 src += ximage->width;
389 pRow += 4 * w0;
390 }
391 }
392 break;
393 case PIPE_FORMAT_U_R5_G6_B5:
394 {
395 ushort *src
396 = (ushort *) (ximage->data + y * ximage->bytes_per_line + x * 2);
397 for (i = 0; i < h; i++) {
398 float *p = pRow;
399 for (j = 0; j < w; j++) {
400 uint pix = src[j];
401 ubyte r = (pix >> 8) | ((pix >> 13) & 0x7);
402 ubyte g = (pix >> 3) | ((pix >> 9) & 0x3);
403 ubyte b = ((pix & 0x1f) << 3) | ((pix >> 2) & 0x3);
404 p[0] = UBYTE_TO_FLOAT(r);
405 p[1] = UBYTE_TO_FLOAT(g);
406 p[2] = UBYTE_TO_FLOAT(b);
407 p[3] = 1.0;
408 p += 4;
409 }
410 src += ximage->width;
411 pRow += 4 * w0;
412 }
413 }
414 break;
415 default:
416 fprintf(stderr, "Bad format in xmesa_get_tile_rgba()\n");
417 assert(0);
418 }
419
420 if (!xms->ximage) {
421 XMesaDestroyImage(ximage);
422 }
423 }
424
425
426 void
427 xmesa_put_tile_rgba(struct pipe_context *pipe, struct pipe_surface *ps,
428 uint x, uint y, uint w, uint h, const float *pixels)
429 {
430 const uint x0 = x, y0 = y, w0 = w;
431 struct xmesa_surface *xms = xmesa_surface(ps);
432 XMesaImage *ximage;
433 uint i, j;
434
435 if (!xms->drawable && !xms->ximage) {
436 /* not an X surface */
437 softpipe_put_tile_rgba(pipe, ps, x, y, w, h, pixels);
438 return;
439 }
440
441 CLIP_TILE;
442
443 if (!xms->ximage) {
444 /* create temp XImage */
445 char *data = (char *) malloc(w * h * 4);
446 #ifdef XFree86Server
447 ximage = XMesaCreateImage(GET_VISUAL_DEPTH(v), w, h, data);
448 #else
449 XVisualInfo *visinfo = xms->xrb->Parent->xm_visual->visinfo;
450 ximage = XCreateImage(xms->display,
451 visinfo->visual,
452 visinfo->depth,
453 ZPixmap, 0, /* format, offset */
454 data, /* data */
455 w, h, /* width, height */
456 32, /* bitmap_pad */
457 0); /* bytes_per_line */
458 #endif
459 x = y = 0;
460 }
461 else {
462 ximage = xms->ximage;
463 }
464
465 /* convert floats to ximage's format */
466 switch (ps->format) {
467 case PIPE_FORMAT_U_A8_R8_G8_B8:
468 {
469 uint *dst
470 = (uint *) (ximage->data + y * ximage->bytes_per_line + x * 4);
471 const float *pRow = pixels;
472 for (i = 0; i < h; i++) {
473 const float *p = pRow;
474 for (j = 0; j < w; j++) {
475 ubyte r, g, b, a;
476 UNCLAMPED_FLOAT_TO_UBYTE(r, p[0]);
477 UNCLAMPED_FLOAT_TO_UBYTE(g, p[1]);
478 UNCLAMPED_FLOAT_TO_UBYTE(b, p[2]);
479 UNCLAMPED_FLOAT_TO_UBYTE(a, p[3]);
480 dst[j] = PACK_8A8R8G8B(r, g, b, a);
481 p += 4;
482 }
483 dst += ximage->width;
484 pRow += 4 * w0;
485 }
486 }
487 break;
488 case PIPE_FORMAT_U_B8_G8_R8_A8:
489 {
490 uint *dst
491 = (uint *) (ximage->data + y * ximage->bytes_per_line + x * 4);
492 const float *pRow = pixels;
493 for (i = 0; i < h; i++) {
494 const float *p = pRow;
495 for (j = 0; j < w; j++) {
496 ubyte r, g, b, a;
497 UNCLAMPED_FLOAT_TO_UBYTE(r, p[0]);
498 UNCLAMPED_FLOAT_TO_UBYTE(g, p[1]);
499 UNCLAMPED_FLOAT_TO_UBYTE(b, p[2]);
500 UNCLAMPED_FLOAT_TO_UBYTE(a, p[3]);
501 dst[j] = PACK_8B8G8R8A(r, g, b, a);
502 p += 4;
503 }
504 dst += ximage->width;
505 pRow += 4 * w0;
506 }
507 }
508 break;
509 case PIPE_FORMAT_U_R5_G6_B5:
510 {
511 ushort *dst =
512 (ushort *) (ximage->data + y * ximage->bytes_per_line + x * 2);
513 const float *pRow = pixels;
514 for (i = 0; i < h; i++) {
515 const float *p = pRow;
516 for (j = 0; j < w; j++) {
517 ubyte r, g, b;
518 UNCLAMPED_FLOAT_TO_UBYTE(r, p[0]);
519 UNCLAMPED_FLOAT_TO_UBYTE(g, p[1]);
520 UNCLAMPED_FLOAT_TO_UBYTE(b, p[2]);
521 dst[j] = PACK_5R6G5B(r, g, b);
522 p += 4;
523 }
524 dst += ximage->width;
525 pRow += 4 * w0;
526 }
527 }
528 break;
529
530 default:
531 fprintf(stderr, "Bad format in xmesa_put_tile_rgba()\n");
532 assert(0);
533 }
534
535 if (!xms->ximage) {
536 /* send XImage data to pixmap */
537 XPutImage(xms->display, xms->drawable, xms->gc,
538 ximage, 0, 0, x0, y0, w, h);
539 /* clean-up */
540 free(ximage->data);
541 ximage->data = NULL;
542 XMesaDestroyImage(ximage);
543 }
544 }
545
546
547 static void
548 clear_pixmap_surface(struct pipe_context *pipe, struct pipe_surface *ps,
549 uint value)
550 {
551 struct xmesa_surface *xms = xmesa_surface(ps);
552 assert(xms);
553 assert(xms->display);
554 assert(xms->drawable);
555 assert(xms->gc);
556 XMesaSetForeground( xms->display, xms->gc, value );
557 XMesaFillRectangle( xms->display, xms->drawable, xms->gc,
558 0, 0, ps->width, ps->height);
559 }
560
561 static void
562 clear_nbit_ximage_surface(struct pipe_context *pipe, struct pipe_surface *ps,
563 uint value)
564 {
565 struct xmesa_surface *xms = xmesa_surface(ps);
566 int width = xms->surface.width;
567 int height = xms->surface.height;
568 int i, j;
569 for (j = 0; j < height; j++) {
570 for (i = 0; i < width; i++) {
571 XMesaPutPixel(xms->ximage, i, j, value);
572 }
573 }
574 }
575
576 static void
577 clear_8bit_ximage_surface(struct pipe_context *pipe, struct pipe_surface *ps,
578 uint value)
579 {
580 struct xmesa_surface *xms = xmesa_surface(ps);
581 memset(xms->ximage->data,
582 value,
583 xms->ximage->bytes_per_line * xms->ximage->height);
584 }
585
586 static void
587 clear_16bit_ximage_surface(struct pipe_context *pipe, struct pipe_surface *ps,
588 uint value)
589 {
590 struct xmesa_surface *xms = xmesa_surface(ps);
591 const int n = xms->ximage->width * xms->ximage->height;
592 ushort *dst = (ushort *) xms->ximage->data;
593 int i;
594 for (i = 0; i < n; i++) {
595 dst[i] = value;
596 }
597 }
598
599
600 /* Optimized code provided by Nozomi Ytow <noz@xfree86.org> */
601 static void
602 clear_24bit_ximage_surface(struct pipe_context *pipe, struct pipe_surface *ps,
603 uint value)
604 {
605 struct xmesa_surface *xms = xmesa_surface(ps);
606 const ubyte r = (value ) & 0xff;
607 const ubyte g = (value >> 8) & 0xff;
608 const ubyte b = (value >> 16) & 0xff;
609
610 if (r == g && g == b) {
611 /* same value for all three components (gray) */
612 memset(xms->ximage->data, r,
613 xms->ximage->bytes_per_line * xms->ximage->height);
614 }
615 else {
616 /* non-gray clear color */
617 const int n = xms->ximage->width * xms->ximage->height;
618 int i;
619 bgr_t *ptr3 = (bgr_t *) xms->ximage->data;
620 for (i = 0; i < n; i++) {
621 ptr3->r = r;
622 ptr3->g = g;
623 ptr3->b = b;
624 ptr3++;
625 }
626 }
627 }
628
629 static void
630 clear_32bit_ximage_surface(struct pipe_context *pipe, struct pipe_surface *ps,
631 uint value)
632 {
633 struct xmesa_surface *xms = xmesa_surface(ps);
634
635 if (value == 0) {
636 /* common case */
637 memset(xms->ximage->data, value,
638 xms->ximage->bytes_per_line * xms->ximage->height);
639 }
640 else {
641 const int n = xms->ximage->width * xms->ximage->height;
642 uint *dst = (uint *) xms->ximage->data;
643 int i;
644 for (i = 0; i < n; i++)
645 dst[i] = value;
646 }
647 }
648
649
650
651
652 /**
653 * Called to create a pipe_surface for each X renderbuffer.
654 * Note: this is being used instead of pipe->surface_alloc() since we
655 * have special/unique quad read/write functions for X.
656 */
657 struct pipe_surface *
658 xmesa_new_color_surface(struct pipe_winsys *winsys, GLuint pipeFormat)
659 {
660 struct xmesa_surface *xms = CALLOC_STRUCT(xmesa_surface);
661
662 assert(pipeFormat);
663
664 xms->surface.format = pipeFormat;
665 xms->surface.refcount = 1;
666 xms->surface.winsys = winsys;
667
668 /* Note, the buffer we allocate doesn't actually have any storage
669 * since we're drawing into an XImage or Pixmap.
670 * The surface's size will get set in the xmesa_alloc_front/back_storage()
671 * functions.
672 */
673 xms->surface.buffer = winsys->buffer_create(winsys, 0x0);
674
675 return &xms->surface;
676 }
677
678
679 /**
680 * Called via pipe->surface_alloc() to create new surfaces (textures,
681 * renderbuffers, etc.
682 */
683 struct pipe_surface *
684 xmesa_surface_alloc(struct pipe_context *pipe, GLuint pipeFormat)
685 {
686 struct xmesa_surface *xms = CALLOC_STRUCT(xmesa_surface);
687
688 assert(pipe);
689 assert(pipeFormat);
690
691 xms->surface.format = pipeFormat;
692 xms->surface.refcount = 1;
693 xms->surface.winsys = pipe->winsys;
694
695 return &xms->surface;
696 }
697
698
699 /**
700 * Called via pipe->clear() to clear entire surface to a certain value.
701 * If the surface is not an X pixmap or XImage, pass the call to
702 * softpipe_clear().
703 */
704 void
705 xmesa_clear(struct pipe_context *pipe, struct pipe_surface *ps, uint value)
706 {
707 struct xmesa_surface *xms = xmesa_surface(ps);
708
709 /* XXX actually, we should just discard any cached tiles from this
710 * surface since we don't want to accidentally re-use them after clearing.
711 */
712 pipe->flush(pipe, 0);
713
714 {
715 struct softpipe_context *sp = softpipe_context(pipe);
716 if (ps == sp_tile_cache_get_surface(sp, sp->cbuf_cache[0])) {
717 float clear[4];
718 clear[0] = 0.2; /* XXX hack */
719 clear[1] = 0.2;
720 clear[2] = 0.2;
721 clear[3] = 0.2;
722 sp_tile_cache_clear(sp->cbuf_cache[0], clear);
723 }
724 }
725
726 #if 1
727 (void) clear_8bit_ximage_surface;
728 (void) clear_24bit_ximage_surface;
729 #endif
730
731 if (xms->ximage) {
732 /* back color buffer */
733 switch (xms->surface.format) {
734 case PIPE_FORMAT_U_R5_G6_B5:
735 clear_16bit_ximage_surface(pipe, ps, value);
736 break;
737 case PIPE_FORMAT_U_A8_R8_G8_B8:
738 case PIPE_FORMAT_U_B8_G8_R8_A8:
739 clear_32bit_ximage_surface(pipe, ps, value);
740 break;
741 default:
742 clear_nbit_ximage_surface(pipe, ps, value);
743 break;
744 }
745 }
746 else if (xms->drawable) {
747 /* front color buffer */
748 clear_pixmap_surface(pipe, ps, value);
749 }
750 else {
751 /* other kind of buffer */
752 softpipe_clear(pipe, ps, value);
753 }
754 }
755
756
757 /** XXX unfinished sketch... */
758 struct pipe_surface *
759 xmesa_create_front_surface(XMesaVisual vis, Window win)
760 {
761 struct xmesa_surface *xms = CALLOC_STRUCT(xmesa_surface);
762 if (!xms) {
763 return NULL;
764 }
765
766 xms->display = vis->display;
767 xms->drawable = win;
768
769 xms->surface.format = PIPE_FORMAT_U_A8_R8_G8_B8;
770 xms->surface.refcount = 1;
771 #if 0
772 xms->surface.region = pipe->winsys->region_alloc(pipe->winsys,
773 1, 0, 0, 0x0);
774 #endif
775 return &xms->surface;
776 }
777