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