Squashed commit of gallium-no-texture-blanket
[mesa.git] / src / gallium / state_trackers / egl / x11 / native_ximage.c
1 /*
2 * Mesa 3-D graphics library
3 * Version: 7.8
4 *
5 * Copyright (C) 2009-2010 Chia-I Wu <olv@0xlab.org>
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 <assert.h>
26 #include <sys/ipc.h>
27 #include <sys/types.h>
28 #include <sys/shm.h>
29 #include <X11/Xlib.h>
30 #include <X11/Xutil.h>
31 #include <X11/extensions/XShm.h>
32 #include "util/u_memory.h"
33 #include "util/u_math.h"
34 #include "util/u_format.h"
35 #include "pipe/p_compiler.h"
36 #include "util/u_simple_screen.h"
37 #include "util/u_inlines.h"
38 #include "softpipe/sp_winsys.h"
39 #include "egllog.h"
40
41 #include "sw_winsys.h"
42 #include "native_x11.h"
43 #include "x11_screen.h"
44
45 enum ximage_surface_type {
46 XIMAGE_SURFACE_TYPE_WINDOW,
47 XIMAGE_SURFACE_TYPE_PIXMAP,
48 XIMAGE_SURFACE_TYPE_PBUFFER
49 };
50
51 struct ximage_display {
52 struct native_display base;
53 Display *dpy;
54 boolean own_dpy;
55
56 struct x11_screen *xscr;
57 int xscr_number;
58
59 struct native_event_handler *event_handler;
60
61 boolean use_xshm;
62
63 struct pipe_winsys *winsys;
64 struct ximage_config *configs;
65 int num_configs;
66 };
67
68 struct ximage_buffer {
69 XImage *ximage;
70
71 struct pipe_texture *texture;
72 XShmSegmentInfo *shm_info;
73 boolean xshm_attached;
74 };
75
76 struct ximage_surface {
77 struct native_surface base;
78 Drawable drawable;
79 enum ximage_surface_type type;
80 enum pipe_format color_format;
81 XVisualInfo visual;
82 struct ximage_display *xdpy;
83
84 GC gc;
85
86 unsigned int server_stamp;
87 unsigned int client_stamp;
88 int width, height;
89 struct ximage_buffer buffers[NUM_NATIVE_ATTACHMENTS];
90 uint valid_mask;
91 };
92
93 struct ximage_config {
94 struct native_config base;
95 const XVisualInfo *visual;
96 };
97
98 static INLINE struct ximage_display *
99 ximage_display(const struct native_display *ndpy)
100 {
101 return (struct ximage_display *) ndpy;
102 }
103
104 static INLINE struct ximage_surface *
105 ximage_surface(const struct native_surface *nsurf)
106 {
107 return (struct ximage_surface *) nsurf;
108 }
109
110 static INLINE struct ximage_config *
111 ximage_config(const struct native_config *nconf)
112 {
113 return (struct ximage_config *) nconf;
114 }
115
116 static void
117 ximage_surface_free_buffer(struct native_surface *nsurf,
118 enum native_attachment which)
119 {
120 struct ximage_surface *xsurf = ximage_surface(nsurf);
121 struct ximage_buffer *xbuf = &xsurf->buffers[which];
122
123 pipe_texture_reference(&xbuf->texture, NULL);
124
125 if (xbuf->shm_info) {
126 if (xbuf->xshm_attached)
127 XShmDetach(xsurf->xdpy->dpy, xbuf->shm_info);
128 if (xbuf->shm_info->shmaddr != (void *) -1)
129 shmdt(xbuf->shm_info->shmaddr);
130 if (xbuf->shm_info->shmid != -1)
131 shmctl(xbuf->shm_info->shmid, IPC_RMID, 0);
132
133 xbuf->shm_info->shmaddr = (void *) -1;
134 xbuf->shm_info->shmid = -1;
135 }
136 }
137
138 static boolean
139 ximage_surface_alloc_buffer(struct native_surface *nsurf,
140 enum native_attachment which)
141 {
142 struct ximage_surface *xsurf = ximage_surface(nsurf);
143 struct ximage_buffer *xbuf = &xsurf->buffers[which];
144 struct pipe_screen *screen = xsurf->xdpy->base.screen;
145 struct pipe_texture templ;
146
147 /* free old data */
148 if (xbuf->texture)
149 ximage_surface_free_buffer(&xsurf->base, which);
150
151 memset(&templ, 0, sizeof(templ));
152 templ.target = PIPE_TEXTURE_2D;
153 templ.format = xsurf->color_format;
154 templ.width0 = xsurf->width;
155 templ.height0 = xsurf->height;
156 templ.depth0 = 1;
157 templ.tex_usage = PIPE_TEXTURE_USAGE_RENDER_TARGET;
158
159 #if 0
160 /* Interesting and suprising use of texture_blanket +
161 * user_buffer_create... To be superceded by the sw_winsys branch,
162 * but currently disabled.
163 */
164 if (xbuf->shm_info) {
165 struct pipe_buffer *pbuf;
166 unsigned stride, size;
167 void *addr = NULL;
168
169 stride = util_format_get_stride(xsurf->color_format, xsurf->width);
170 /* alignment should depend on visual? */
171 stride = align(stride, 4);
172 size = stride * xsurf->height;
173
174 /* create and attach shm object */
175 xbuf->shm_info->shmid = shmget(IPC_PRIVATE, size, 0755);
176 if (xbuf->shm_info->shmid != -1) {
177 xbuf->shm_info->shmaddr =
178 shmat(xbuf->shm_info->shmid, NULL, 0);
179 if (xbuf->shm_info->shmaddr != (void *) -1) {
180 if (XShmAttach(xsurf->xdpy->dpy, xbuf->shm_info)) {
181 addr = xbuf->shm_info->shmaddr;
182 xbuf->xshm_attached = TRUE;
183 }
184 }
185 }
186
187 if (addr) {
188 pbuf = screen->user_buffer_create(screen, addr, size);
189 if (pbuf) {
190 xbuf->texture =
191 screen->texture_blanket(screen, &templ, &stride, pbuf);
192 pipe_buffer_reference(&pbuf, NULL);
193 }
194 }
195 }
196 else
197 #endif
198 {
199 xbuf->texture = screen->texture_create(screen, &templ);
200 }
201
202 /* clean up the buffer if allocation failed */
203 if (!xbuf->texture)
204 ximage_surface_free_buffer(&xsurf->base, which);
205
206 return (xbuf->texture != NULL);
207 }
208
209 /**
210 * Update the geometry of the surface. Return TRUE if the geometry has changed
211 * since last call.
212 */
213 static boolean
214 ximage_surface_update_geometry(struct native_surface *nsurf)
215 {
216 struct ximage_surface *xsurf = ximage_surface(nsurf);
217 Status ok;
218 Window root;
219 int x, y;
220 unsigned int w, h, border, depth;
221 boolean updated = FALSE;
222
223 /* pbuffer has fixed geometry */
224 if (xsurf->type == XIMAGE_SURFACE_TYPE_PBUFFER)
225 return FALSE;
226
227 ok = XGetGeometry(xsurf->xdpy->dpy, xsurf->drawable,
228 &root, &x, &y, &w, &h, &border, &depth);
229 if (ok && (xsurf->width != w || xsurf->height != h)) {
230 xsurf->width = w;
231 xsurf->height = h;
232
233 xsurf->server_stamp++;
234 updated = TRUE;
235 }
236
237 return updated;
238 }
239
240 static void
241 ximage_surface_notify_invalid(struct native_surface *nsurf)
242 {
243 struct ximage_surface *xsurf = ximage_surface(nsurf);
244 struct ximage_display *xdpy = xsurf->xdpy;
245
246 xdpy->event_handler->invalid_surface(&xdpy->base,
247 &xsurf->base, xsurf->server_stamp);
248 }
249
250 /**
251 * Update the buffers of the surface. It is a slow function due to the
252 * round-trip to the server.
253 */
254 static boolean
255 ximage_surface_update_buffers(struct native_surface *nsurf, uint buffer_mask)
256 {
257 struct ximage_surface *xsurf = ximage_surface(nsurf);
258 boolean updated;
259 uint new_valid;
260 int att;
261
262 updated = ximage_surface_update_geometry(&xsurf->base);
263 if (updated) {
264 /* all buffers become invalid */
265 xsurf->valid_mask = 0x0;
266 }
267 else {
268 buffer_mask &= ~xsurf->valid_mask;
269 /* all requested buffers are valid */
270 if (!buffer_mask) {
271 xsurf->client_stamp = xsurf->server_stamp;
272 return TRUE;
273 }
274 }
275
276 new_valid = 0x0;
277 for (att = 0; att < NUM_NATIVE_ATTACHMENTS; att++) {
278 if (native_attachment_mask_test(buffer_mask, att)) {
279 struct ximage_buffer *xbuf = &xsurf->buffers[att];
280
281 /* reallocate the texture */
282 if (!ximage_surface_alloc_buffer(&xsurf->base, att))
283 break;
284
285 /* update ximage */
286 if (xbuf->ximage) {
287 xbuf->ximage->width = xsurf->width;
288 xbuf->ximage->height = xsurf->height;
289 }
290
291 new_valid |= (1 << att);
292 if (buffer_mask == new_valid)
293 break;
294 }
295 }
296
297 xsurf->valid_mask |= new_valid;
298 xsurf->client_stamp = xsurf->server_stamp;
299
300 return (new_valid == buffer_mask);
301 }
302
303 static boolean
304 ximage_surface_draw_buffer(struct native_surface *nsurf,
305 enum native_attachment which)
306 {
307 struct ximage_surface *xsurf = ximage_surface(nsurf);
308 struct ximage_buffer *xbuf = &xsurf->buffers[which];
309 struct pipe_screen *screen = xsurf->xdpy->base.screen;
310 struct pipe_transfer *transfer;
311
312 if (xsurf->type == XIMAGE_SURFACE_TYPE_PBUFFER)
313 return TRUE;
314
315 assert(xsurf->drawable && xbuf->ximage && xbuf->texture);
316
317 transfer = screen->get_tex_transfer(screen, xbuf->texture,
318 0, 0, 0, PIPE_TRANSFER_READ, 0, 0, xsurf->width, xsurf->height);
319 if (!transfer)
320 return FALSE;
321
322 xbuf->ximage->bytes_per_line = transfer->stride;
323 xbuf->ximage->data = screen->transfer_map(screen, transfer);
324 if (!xbuf->ximage->data) {
325 screen->tex_transfer_destroy(transfer);
326 return FALSE;
327 }
328
329
330 if (xbuf->shm_info)
331 XShmPutImage(xsurf->xdpy->dpy, xsurf->drawable, xsurf->gc,
332 xbuf->ximage, 0, 0, 0, 0, xsurf->width, xsurf->height, False);
333 else
334 XPutImage(xsurf->xdpy->dpy, xsurf->drawable, xsurf->gc,
335 xbuf->ximage, 0, 0, 0, 0, xsurf->width, xsurf->height);
336
337 xbuf->ximage->data = NULL;
338 screen->transfer_unmap(screen, transfer);
339
340 /*
341 * softpipe allows the pipe transfer to be re-used, but we don't want to
342 * rely on that behavior.
343 */
344 screen->tex_transfer_destroy(transfer);
345
346 XSync(xsurf->xdpy->dpy, FALSE);
347
348 return TRUE;
349 }
350
351 static boolean
352 ximage_surface_flush_frontbuffer(struct native_surface *nsurf)
353 {
354 struct ximage_surface *xsurf = ximage_surface(nsurf);
355 boolean ret;
356
357 ret = ximage_surface_draw_buffer(&xsurf->base,
358 NATIVE_ATTACHMENT_FRONT_LEFT);
359 /* force buffers to be updated in next validation call */
360 xsurf->server_stamp++;
361 ximage_surface_notify_invalid(&xsurf->base);
362
363 return ret;
364 }
365
366 static boolean
367 ximage_surface_swap_buffers(struct native_surface *nsurf)
368 {
369 struct ximage_surface *xsurf = ximage_surface(nsurf);
370 struct ximage_buffer *xfront, *xback, xtmp;
371 boolean ret;
372
373 /* display the back buffer first */
374 ret = ximage_surface_draw_buffer(nsurf, NATIVE_ATTACHMENT_BACK_LEFT);
375 /* force buffers to be updated in next validation call */
376 xsurf->server_stamp++;
377 ximage_surface_notify_invalid(&xsurf->base);
378
379 xfront = &xsurf->buffers[NATIVE_ATTACHMENT_FRONT_LEFT];
380 xback = &xsurf->buffers[NATIVE_ATTACHMENT_BACK_LEFT];
381
382 /* skip swapping so that the front buffer is allocated only when needed */
383 if (!xfront->texture)
384 return ret;
385
386 xtmp = *xfront;
387 *xfront = *xback;
388 *xback = xtmp;
389
390 return ret;
391 }
392
393 static boolean
394 ximage_surface_validate(struct native_surface *nsurf, uint attachment_mask,
395 unsigned int *seq_num, struct pipe_texture **textures,
396 int *width, int *height)
397 {
398 struct ximage_surface *xsurf = ximage_surface(nsurf);
399
400 if (xsurf->client_stamp != xsurf->server_stamp ||
401 (xsurf->valid_mask & attachment_mask) != attachment_mask) {
402 if (!ximage_surface_update_buffers(&xsurf->base, attachment_mask))
403 return FALSE;
404 }
405
406 if (seq_num)
407 *seq_num = xsurf->client_stamp;
408
409 if (textures) {
410 int att;
411 for (att = 0; att < NUM_NATIVE_ATTACHMENTS; att++) {
412 if (native_attachment_mask_test(attachment_mask, att)) {
413 struct ximage_buffer *xbuf = &xsurf->buffers[att];
414
415 textures[att] = NULL;
416 pipe_texture_reference(&textures[att], xbuf->texture);
417 }
418 }
419 }
420
421 if (width)
422 *width = xsurf->width;
423 if (height)
424 *height = xsurf->height;
425
426 return TRUE;
427 }
428
429 static void
430 ximage_surface_wait(struct native_surface *nsurf)
431 {
432 struct ximage_surface *xsurf = ximage_surface(nsurf);
433 XSync(xsurf->xdpy->dpy, FALSE);
434 /* TODO XGetImage and update the front texture */
435 }
436
437 static void
438 ximage_surface_destroy(struct native_surface *nsurf)
439 {
440 struct ximage_surface *xsurf = ximage_surface(nsurf);
441 int i;
442
443 for (i = 0; i < NUM_NATIVE_ATTACHMENTS; i++) {
444 struct ximage_buffer *xbuf = &xsurf->buffers[i];
445 ximage_surface_free_buffer(&xsurf->base, i);
446 /* xbuf->shm_info is owned by xbuf->ximage? */
447 if (xbuf->ximage) {
448 XDestroyImage(xbuf->ximage);
449 xbuf->ximage = NULL;
450 }
451 }
452
453 if (xsurf->type != XIMAGE_SURFACE_TYPE_PBUFFER)
454 XFreeGC(xsurf->xdpy->dpy, xsurf->gc);
455 free(xsurf);
456 }
457
458 static struct ximage_surface *
459 ximage_display_create_surface(struct native_display *ndpy,
460 enum ximage_surface_type type,
461 Drawable drawable,
462 const struct native_config *nconf)
463 {
464 struct ximage_display *xdpy = ximage_display(ndpy);
465 struct ximage_config *xconf = ximage_config(nconf);
466 struct ximage_surface *xsurf;
467 int i;
468
469 xsurf = CALLOC_STRUCT(ximage_surface);
470 if (!xsurf)
471 return NULL;
472
473 xsurf->xdpy = xdpy;
474 xsurf->type = type;
475 xsurf->color_format = xconf->base.color_format;
476 xsurf->drawable = drawable;
477
478 if (xsurf->type != XIMAGE_SURFACE_TYPE_PBUFFER) {
479 xsurf->drawable = drawable;
480 xsurf->visual = *xconf->visual;
481
482 xsurf->gc = XCreateGC(xdpy->dpy, xsurf->drawable, 0, NULL);
483 if (!xsurf->gc) {
484 free(xsurf);
485 return NULL;
486 }
487
488 /* initialize the geometry */
489 ximage_surface_update_buffers(&xsurf->base, 0x0);
490
491 for (i = 0; i < NUM_NATIVE_ATTACHMENTS; i++) {
492 struct ximage_buffer *xbuf = &xsurf->buffers[i];
493
494 if (xdpy->use_xshm) {
495 xbuf->shm_info = calloc(1, sizeof(*xbuf->shm_info));
496 if (xbuf->shm_info) {
497 /* initialize shm info */
498 xbuf->shm_info->shmid = -1;
499 xbuf->shm_info->shmaddr = (void *) -1;
500 xbuf->shm_info->readOnly = TRUE;
501
502 xbuf->ximage = XShmCreateImage(xsurf->xdpy->dpy,
503 xsurf->visual.visual,
504 xsurf->visual.depth,
505 ZPixmap, NULL,
506 xbuf->shm_info,
507 0, 0);
508 }
509 }
510 else {
511 xbuf->ximage = XCreateImage(xsurf->xdpy->dpy,
512 xsurf->visual.visual,
513 xsurf->visual.depth,
514 ZPixmap, 0, /* format, offset */
515 NULL, /* data */
516 0, 0, /* size */
517 8, /* bitmap_pad */
518 0); /* bytes_per_line */
519 }
520
521 if (!xbuf->ximage) {
522 XFreeGC(xdpy->dpy, xsurf->gc);
523 free(xsurf);
524 return NULL;
525 }
526 }
527 }
528
529 xsurf->base.destroy = ximage_surface_destroy;
530 xsurf->base.swap_buffers = ximage_surface_swap_buffers;
531 xsurf->base.flush_frontbuffer = ximage_surface_flush_frontbuffer;
532 xsurf->base.validate = ximage_surface_validate;
533 xsurf->base.wait = ximage_surface_wait;
534
535 return xsurf;
536 }
537
538 static struct native_surface *
539 ximage_display_create_window_surface(struct native_display *ndpy,
540 EGLNativeWindowType win,
541 const struct native_config *nconf)
542 {
543 struct ximage_surface *xsurf;
544
545 xsurf = ximage_display_create_surface(ndpy, XIMAGE_SURFACE_TYPE_WINDOW,
546 (Drawable) win, nconf);
547 return (xsurf) ? &xsurf->base : NULL;
548 }
549
550 static struct native_surface *
551 ximage_display_create_pixmap_surface(struct native_display *ndpy,
552 EGLNativePixmapType pix,
553 const struct native_config *nconf)
554 {
555 struct ximage_surface *xsurf;
556
557 xsurf = ximage_display_create_surface(ndpy, XIMAGE_SURFACE_TYPE_PIXMAP,
558 (Drawable) pix, nconf);
559 return (xsurf) ? &xsurf->base : NULL;
560 }
561
562 static struct native_surface *
563 ximage_display_create_pbuffer_surface(struct native_display *ndpy,
564 const struct native_config *nconf,
565 uint width, uint height)
566 {
567 struct ximage_surface *xsurf;
568
569 xsurf = ximage_display_create_surface(ndpy, XIMAGE_SURFACE_TYPE_PBUFFER,
570 (Drawable) None, nconf);
571 if (xsurf) {
572 xsurf->width = width;
573 xsurf->height = height;
574 }
575 return (xsurf) ? &xsurf->base : NULL;
576 }
577
578 static enum pipe_format
579 choose_format(const XVisualInfo *vinfo)
580 {
581 enum pipe_format fmt;
582 /* TODO elaborate the formats */
583 switch (vinfo->depth) {
584 case 32:
585 fmt = PIPE_FORMAT_B8G8R8A8_UNORM;
586 break;
587 case 24:
588 fmt = PIPE_FORMAT_B8G8R8X8_UNORM;
589 break;
590 case 16:
591 fmt = PIPE_FORMAT_B5G6R5_UNORM;
592 break;
593 default:
594 fmt = PIPE_FORMAT_NONE;
595 break;
596 }
597
598 return fmt;
599 }
600
601 static const struct native_config **
602 ximage_display_get_configs(struct native_display *ndpy, int *num_configs)
603 {
604 struct ximage_display *xdpy = ximage_display(ndpy);
605 const struct native_config **configs;
606 int i;
607
608 /* first time */
609 if (!xdpy->configs) {
610 const XVisualInfo *visuals;
611 int num_visuals, count, j;
612
613 visuals = x11_screen_get_visuals(xdpy->xscr, &num_visuals);
614 if (!visuals)
615 return NULL;
616
617 /*
618 * Create two configs for each visual.
619 * One with depth/stencil buffer; one without
620 */
621 xdpy->configs = calloc(num_visuals * 2, sizeof(*xdpy->configs));
622 if (!xdpy->configs)
623 return NULL;
624
625 count = 0;
626 for (i = 0; i < num_visuals; i++) {
627 for (j = 0; j < 2; j++) {
628 struct ximage_config *xconf = &xdpy->configs[count];
629 __GLcontextModes *mode = &xconf->base.mode;
630
631 xconf->visual = &visuals[i];
632 xconf->base.color_format = choose_format(xconf->visual);
633 if (xconf->base.color_format == PIPE_FORMAT_NONE)
634 continue;
635
636 x11_screen_convert_visual(xdpy->xscr, xconf->visual, mode);
637 /* support double buffer mode */
638 mode->doubleBufferMode = TRUE;
639
640 xconf->base.depth_format = PIPE_FORMAT_NONE;
641 xconf->base.stencil_format = PIPE_FORMAT_NONE;
642 /* create the second config with depth/stencil buffer */
643 if (j == 1) {
644 xconf->base.depth_format = PIPE_FORMAT_Z24S8_UNORM;
645 xconf->base.stencil_format = PIPE_FORMAT_Z24S8_UNORM;
646 mode->depthBits = 24;
647 mode->stencilBits = 8;
648 mode->haveDepthBuffer = TRUE;
649 mode->haveStencilBuffer = TRUE;
650 }
651
652 mode->maxPbufferWidth = 4096;
653 mode->maxPbufferHeight = 4096;
654 mode->maxPbufferPixels = 4096 * 4096;
655 mode->drawableType =
656 GLX_WINDOW_BIT | GLX_PIXMAP_BIT | GLX_PBUFFER_BIT;
657 mode->swapMethod = GLX_SWAP_EXCHANGE_OML;
658
659 if (mode->alphaBits)
660 mode->bindToTextureRgba = TRUE;
661 else
662 mode->bindToTextureRgb = TRUE;
663
664 count++;
665 }
666 }
667
668 xdpy->num_configs = count;
669 }
670
671 configs = malloc(xdpy->num_configs * sizeof(*configs));
672 if (configs) {
673 for (i = 0; i < xdpy->num_configs; i++)
674 configs[i] = (const struct native_config *) &xdpy->configs[i];
675 if (num_configs)
676 *num_configs = xdpy->num_configs;
677 }
678 return configs;
679 }
680
681 static boolean
682 ximage_display_is_pixmap_supported(struct native_display *ndpy,
683 EGLNativePixmapType pix,
684 const struct native_config *nconf)
685 {
686 struct ximage_display *xdpy = ximage_display(ndpy);
687 enum pipe_format fmt;
688 uint depth;
689
690 depth = x11_drawable_get_depth(xdpy->xscr, (Drawable) pix);
691 switch (depth) {
692 case 32:
693 fmt = PIPE_FORMAT_B8G8R8A8_UNORM;
694 break;
695 case 24:
696 fmt = PIPE_FORMAT_B8G8R8X8_UNORM;
697 break;
698 case 16:
699 fmt = PIPE_FORMAT_B5G6R5_UNORM;
700 break;
701 default:
702 fmt = PIPE_FORMAT_NONE;
703 break;
704 }
705
706 return (fmt == nconf->color_format);
707 }
708
709 static int
710 ximage_display_get_param(struct native_display *ndpy,
711 enum native_param_type param)
712 {
713 int val;
714
715 switch (param) {
716 case NATIVE_PARAM_USE_NATIVE_BUFFER:
717 /* private buffers are allocated */
718 val = FALSE;
719 break;
720 default:
721 val = 0;
722 break;
723 }
724
725 return val;
726 }
727
728 static void
729 ximage_display_destroy(struct native_display *ndpy)
730 {
731 struct ximage_display *xdpy = ximage_display(ndpy);
732
733 if (xdpy->configs)
734 free(xdpy->configs);
735
736 xdpy->base.screen->destroy(xdpy->base.screen);
737 free(xdpy->winsys);
738
739 x11_screen_destroy(xdpy->xscr);
740 if (xdpy->own_dpy)
741 XCloseDisplay(xdpy->dpy);
742 free(xdpy);
743 }
744
745 struct native_display *
746 x11_create_ximage_display(EGLNativeDisplayType dpy,
747 struct native_event_handler *event_handler,
748 boolean use_xshm)
749 {
750 struct ximage_display *xdpy;
751
752 xdpy = CALLOC_STRUCT(ximage_display);
753 if (!xdpy)
754 return NULL;
755
756 xdpy->dpy = dpy;
757 if (!xdpy->dpy) {
758 xdpy->dpy = XOpenDisplay(NULL);
759 if (!xdpy->dpy) {
760 free(xdpy);
761 return NULL;
762 }
763 xdpy->own_dpy = TRUE;
764 }
765
766 xdpy->xscr_number = DefaultScreen(xdpy->dpy);
767 xdpy->xscr = x11_screen_create(xdpy->dpy, xdpy->xscr_number);
768 if (!xdpy->xscr) {
769 free(xdpy);
770 return NULL;
771 }
772
773 xdpy->event_handler = event_handler;
774
775 xdpy->use_xshm =
776 (use_xshm && x11_screen_support(xdpy->xscr, X11_SCREEN_EXTENSION_XSHM));
777
778 xdpy->winsys = create_sw_winsys();
779 xdpy->base.screen = softpipe_create_screen(xdpy->winsys);
780
781 xdpy->base.destroy = ximage_display_destroy;
782 xdpy->base.get_param = ximage_display_get_param;
783
784 xdpy->base.get_configs = ximage_display_get_configs;
785 xdpy->base.is_pixmap_supported = ximage_display_is_pixmap_supported;
786 xdpy->base.create_window_surface = ximage_display_create_window_surface;
787 xdpy->base.create_pixmap_surface = ximage_display_create_pixmap_surface;
788 xdpy->base.create_pbuffer_surface = ximage_display_create_pbuffer_surface;
789
790 return &xdpy->base;
791 }