2 * Mesa 3-D graphics library
5 * Copyright (C) 2009-2010 Chia-I Wu <olv@0xlab.org>
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:
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23 * DEALINGS IN THE SOFTWARE.
26 #include "util/u_memory.h"
27 #include "util/u_math.h"
28 #include "util/u_format.h"
29 #include "util/u_inlines.h"
30 #include "util/u_hash_table.h"
31 #include "pipe/p_compiler.h"
32 #include "pipe/p_screen.h"
33 #include "pipe/p_context.h"
34 #include "pipe/p_state.h"
35 #include "state_tracker/drm_driver.h"
38 #include "native_x11.h"
39 #include "x11_screen.h"
41 #ifdef HAVE_WAYLAND_BACKEND
42 #include "common/native_wayland_drm_bufmgr_helper.h"
45 #ifdef GLX_DIRECT_RENDERING
48 struct native_display base;
52 const struct native_event_handler *event_handler;
54 struct x11_screen *xscr;
56 const char *dri_driver;
57 int dri_major, dri_minor;
59 struct dri2_config *configs;
62 struct util_hash_table *surfaces;
63 #ifdef HAVE_WAYLAND_BACKEND
64 struct wl_drm *wl_server_drm; /* for EGL_WL_bind_wayland_display */
69 struct native_surface base;
71 enum pipe_format color_format;
72 struct dri2_display *dri2dpy;
74 unsigned int server_stamp;
75 unsigned int client_stamp;
77 struct pipe_resource *textures[NUM_NATIVE_ATTACHMENTS];
80 boolean have_back, have_fake;
82 struct x11_drawable_buffer *last_xbufs;
87 struct native_config base;
90 static INLINE struct dri2_display *
91 dri2_display(const struct native_display *ndpy)
93 return (struct dri2_display *) ndpy;
96 static INLINE struct dri2_surface *
97 dri2_surface(const struct native_surface *nsurf)
99 return (struct dri2_surface *) nsurf;
102 static INLINE struct dri2_config *
103 dri2_config(const struct native_config *nconf)
105 return (struct dri2_config *) nconf;
109 * Process the buffers returned by the server.
112 dri2_surface_process_drawable_buffers(struct native_surface *nsurf,
113 struct x11_drawable_buffer *xbufs,
116 struct dri2_surface *dri2surf = dri2_surface(nsurf);
117 struct dri2_display *dri2dpy = dri2surf->dri2dpy;
118 struct pipe_resource templ;
119 struct winsys_handle whandle;
123 /* free the old textures */
124 for (i = 0; i < NUM_NATIVE_ATTACHMENTS; i++)
125 pipe_resource_reference(&dri2surf->textures[i], NULL);
126 dri2surf->valid_mask = 0x0;
128 dri2surf->have_back = FALSE;
129 dri2surf->have_fake = FALSE;
134 memset(&templ, 0, sizeof(templ));
135 templ.target = PIPE_TEXTURE_2D;
136 templ.last_level = 0;
137 templ.width0 = dri2surf->width;
138 templ.height0 = dri2surf->height;
140 templ.array_size = 1;
141 templ.format = dri2surf->color_format;
142 templ.bind = PIPE_BIND_RENDER_TARGET;
145 for (i = 0; i < num_xbufs; i++) {
146 struct x11_drawable_buffer *xbuf = &xbufs[i];
148 enum native_attachment natt;
150 switch (xbuf->attachment) {
151 case DRI2BufferFrontLeft:
152 natt = NATIVE_ATTACHMENT_FRONT_LEFT;
153 desc = "DRI2 Front Buffer";
155 case DRI2BufferFakeFrontLeft:
156 natt = NATIVE_ATTACHMENT_FRONT_LEFT;
157 desc = "DRI2 Fake Front Buffer";
158 dri2surf->have_fake = TRUE;
160 case DRI2BufferBackLeft:
161 natt = NATIVE_ATTACHMENT_BACK_LEFT;
162 desc = "DRI2 Back Buffer";
163 dri2surf->have_back = TRUE;
170 if (!desc || dri2surf->textures[natt]) {
172 _eglLog(_EGL_WARNING, "unknown buffer %d", xbuf->attachment);
174 _eglLog(_EGL_WARNING, "both real and fake front buffers are listed");
178 memset(&whandle, 0, sizeof(whandle));
179 whandle.stride = xbuf->pitch;
180 whandle.handle = xbuf->name;
181 dri2surf->textures[natt] = dri2dpy->base.screen->resource_from_handle(
182 dri2dpy->base.screen, &templ, &whandle);
183 if (dri2surf->textures[natt])
184 valid_mask |= 1 << natt;
187 dri2surf->valid_mask = valid_mask;
191 * Get the buffers from the server.
194 dri2_surface_get_buffers(struct native_surface *nsurf, uint buffer_mask)
196 struct dri2_surface *dri2surf = dri2_surface(nsurf);
197 struct dri2_display *dri2dpy = dri2surf->dri2dpy;
198 unsigned int dri2atts[NUM_NATIVE_ATTACHMENTS * 2];
199 int num_ins, num_outs, att;
200 struct x11_drawable_buffer *xbufs;
201 uint bpp = util_format_get_blocksizebits(dri2surf->color_format);
202 boolean with_format = FALSE; /* never ask for depth/stencil */
204 /* We must get the front on servers which doesn't support with format
205 * due to a silly bug in core dri2. You can't copy to/from a buffer
206 * that you haven't requested and you recive BadValue errors */
207 if (dri2surf->dri2dpy->dri_minor < 1) {
209 buffer_mask |= (1 << NATIVE_ATTACHMENT_FRONT_LEFT);
212 /* prepare the attachments */
214 for (att = 0; att < NUM_NATIVE_ATTACHMENTS; att++) {
215 if (native_attachment_mask_test(buffer_mask, att)) {
216 unsigned int dri2att;
219 case NATIVE_ATTACHMENT_FRONT_LEFT:
220 dri2att = DRI2BufferFrontLeft;
222 case NATIVE_ATTACHMENT_BACK_LEFT:
223 dri2att = DRI2BufferBackLeft;
225 case NATIVE_ATTACHMENT_FRONT_RIGHT:
226 dri2att = DRI2BufferFrontRight;
228 case NATIVE_ATTACHMENT_BACK_RIGHT:
229 dri2att = DRI2BufferBackRight;
237 dri2atts[num_ins++] = dri2att;
239 dri2atts[num_ins++] = bpp;
245 xbufs = x11_drawable_get_buffers(dri2dpy->xscr, dri2surf->drawable,
246 &dri2surf->width, &dri2surf->height,
247 dri2atts, with_format, num_ins, &num_outs);
249 /* we should be able to do better... */
250 if (xbufs && dri2surf->last_num_xbufs == num_outs &&
251 memcmp(dri2surf->last_xbufs, xbufs, sizeof(*xbufs) * num_outs) == 0) {
253 dri2surf->client_stamp = dri2surf->server_stamp;
257 dri2_surface_process_drawable_buffers(&dri2surf->base, xbufs, num_outs);
259 dri2surf->server_stamp++;
260 dri2surf->client_stamp = dri2surf->server_stamp;
262 if (dri2surf->last_xbufs)
263 FREE(dri2surf->last_xbufs);
264 dri2surf->last_xbufs = xbufs;
265 dri2surf->last_num_xbufs = num_outs;
269 * Update the buffers of the surface. This is a slow function due to the
270 * round-trip to the server.
273 dri2_surface_update_buffers(struct native_surface *nsurf, uint buffer_mask)
275 struct dri2_surface *dri2surf = dri2_surface(nsurf);
277 dri2_surface_get_buffers(&dri2surf->base, buffer_mask);
279 return ((dri2surf->valid_mask & buffer_mask) == buffer_mask);
283 * Return TRUE if the surface receives DRI2_InvalidateBuffers events.
285 static INLINE boolean
286 dri2_surface_receive_events(struct native_surface *nsurf)
288 struct dri2_surface *dri2surf = dri2_surface(nsurf);
289 return (dri2surf->dri2dpy->dri_minor >= 3);
293 dri2_surface_flush_frontbuffer(struct native_surface *nsurf)
295 struct dri2_surface *dri2surf = dri2_surface(nsurf);
296 struct dri2_display *dri2dpy = dri2surf->dri2dpy;
298 /* copy to real front buffer */
299 if (dri2surf->have_fake)
300 x11_drawable_copy_buffers(dri2dpy->xscr, dri2surf->drawable,
301 0, 0, dri2surf->width, dri2surf->height,
302 DRI2BufferFakeFrontLeft, DRI2BufferFrontLeft);
304 /* force buffers to be updated in next validation call */
305 if (!dri2_surface_receive_events(&dri2surf->base)) {
306 dri2surf->server_stamp++;
307 dri2dpy->event_handler->invalid_surface(&dri2dpy->base,
308 &dri2surf->base, dri2surf->server_stamp);
315 dri2_surface_swap_buffers(struct native_surface *nsurf)
317 struct dri2_surface *dri2surf = dri2_surface(nsurf);
318 struct dri2_display *dri2dpy = dri2surf->dri2dpy;
320 /* copy to front buffer */
321 if (dri2surf->have_back)
322 x11_drawable_copy_buffers(dri2dpy->xscr, dri2surf->drawable,
323 0, 0, dri2surf->width, dri2surf->height,
324 DRI2BufferBackLeft, DRI2BufferFrontLeft);
326 /* and update fake front buffer */
327 if (dri2surf->have_fake)
328 x11_drawable_copy_buffers(dri2dpy->xscr, dri2surf->drawable,
329 0, 0, dri2surf->width, dri2surf->height,
330 DRI2BufferFrontLeft, DRI2BufferFakeFrontLeft);
332 /* force buffers to be updated in next validation call */
333 if (!dri2_surface_receive_events(&dri2surf->base)) {
334 dri2surf->server_stamp++;
335 dri2dpy->event_handler->invalid_surface(&dri2dpy->base,
336 &dri2surf->base, dri2surf->server_stamp);
343 dri2_surface_present(struct native_surface *nsurf,
344 enum native_attachment natt,
354 case NATIVE_ATTACHMENT_FRONT_LEFT:
355 ret = dri2_surface_flush_frontbuffer(nsurf);
357 case NATIVE_ATTACHMENT_BACK_LEFT:
358 ret = dri2_surface_swap_buffers(nsurf);
369 dri2_surface_validate(struct native_surface *nsurf, uint attachment_mask,
370 unsigned int *seq_num, struct pipe_resource **textures,
371 int *width, int *height)
373 struct dri2_surface *dri2surf = dri2_surface(nsurf);
375 if (dri2surf->server_stamp != dri2surf->client_stamp ||
376 (dri2surf->valid_mask & attachment_mask) != attachment_mask) {
377 if (!dri2_surface_update_buffers(&dri2surf->base, attachment_mask))
382 *seq_num = dri2surf->client_stamp;
386 for (att = 0; att < NUM_NATIVE_ATTACHMENTS; att++) {
387 if (native_attachment_mask_test(attachment_mask, att)) {
388 struct pipe_resource *ptex = dri2surf->textures[att];
390 textures[att] = NULL;
391 pipe_resource_reference(&textures[att], ptex);
397 *width = dri2surf->width;
399 *height = dri2surf->height;
405 dri2_surface_wait(struct native_surface *nsurf)
407 struct dri2_surface *dri2surf = dri2_surface(nsurf);
408 struct dri2_display *dri2dpy = dri2surf->dri2dpy;
410 if (dri2surf->have_fake) {
411 x11_drawable_copy_buffers(dri2dpy->xscr, dri2surf->drawable,
412 0, 0, dri2surf->width, dri2surf->height,
413 DRI2BufferFrontLeft, DRI2BufferFakeFrontLeft);
418 dri2_surface_destroy(struct native_surface *nsurf)
420 struct dri2_surface *dri2surf = dri2_surface(nsurf);
423 if (dri2surf->last_xbufs)
424 FREE(dri2surf->last_xbufs);
426 for (i = 0; i < NUM_NATIVE_ATTACHMENTS; i++) {
427 struct pipe_resource *ptex = dri2surf->textures[i];
428 pipe_resource_reference(&ptex, NULL);
431 if (dri2surf->drawable) {
432 x11_drawable_enable_dri2(dri2surf->dri2dpy->xscr,
433 dri2surf->drawable, FALSE);
435 util_hash_table_remove(dri2surf->dri2dpy->surfaces,
436 (void *) dri2surf->drawable);
441 static struct dri2_surface *
442 dri2_display_create_surface(struct native_display *ndpy,
444 enum pipe_format color_format)
446 struct dri2_display *dri2dpy = dri2_display(ndpy);
447 struct dri2_surface *dri2surf;
449 dri2surf = CALLOC_STRUCT(dri2_surface);
453 dri2surf->dri2dpy = dri2dpy;
454 dri2surf->drawable = drawable;
455 dri2surf->color_format = color_format;
457 dri2surf->base.destroy = dri2_surface_destroy;
458 dri2surf->base.present = dri2_surface_present;
459 dri2surf->base.validate = dri2_surface_validate;
460 dri2surf->base.wait = dri2_surface_wait;
463 x11_drawable_enable_dri2(dri2dpy->xscr, drawable, TRUE);
464 /* initialize the geometry */
465 dri2_surface_update_buffers(&dri2surf->base, 0x0);
467 util_hash_table_set(dri2surf->dri2dpy->surfaces,
468 (void *) dri2surf->drawable, (void *) &dri2surf->base);
474 static struct native_surface *
475 dri2_display_create_window_surface(struct native_display *ndpy,
476 EGLNativeWindowType win,
477 const struct native_config *nconf)
479 struct dri2_surface *dri2surf;
481 dri2surf = dri2_display_create_surface(ndpy,
482 (Drawable) win, nconf->color_format);
483 return (dri2surf) ? &dri2surf->base : NULL;
486 static struct native_surface *
487 dri2_display_create_pixmap_surface(struct native_display *ndpy,
488 EGLNativePixmapType pix,
489 const struct native_config *nconf)
491 struct dri2_surface *dri2surf;
494 struct dri2_display *dri2dpy = dri2_display(ndpy);
495 uint depth, nconf_depth;
498 depth = x11_drawable_get_depth(dri2dpy->xscr, (Drawable) pix);
499 for (i = 0; i < dri2dpy->num_configs; i++) {
500 nconf_depth = util_format_get_blocksizebits(
501 dri2dpy->configs[i].base.color_format);
502 /* simple depth match for now */
503 if (depth == nconf_depth ||
504 (depth == 24 && depth + 8 == nconf_depth)) {
505 nconf = &dri2dpy->configs[i].base;
514 dri2surf = dri2_display_create_surface(ndpy,
515 (Drawable) pix, nconf->color_format);
516 return (dri2surf) ? &dri2surf->base : NULL;
520 choose_color_format(const __GLcontextModes *mode, enum pipe_format formats[32])
524 switch (mode->rgbBits) {
526 formats[count++] = PIPE_FORMAT_B8G8R8A8_UNORM;
527 formats[count++] = PIPE_FORMAT_A8R8G8B8_UNORM;
530 formats[count++] = PIPE_FORMAT_B8G8R8X8_UNORM;
531 formats[count++] = PIPE_FORMAT_X8R8G8B8_UNORM;
532 formats[count++] = PIPE_FORMAT_B8G8R8A8_UNORM;
533 formats[count++] = PIPE_FORMAT_A8R8G8B8_UNORM;
536 formats[count++] = PIPE_FORMAT_B5G6R5_UNORM;
546 is_format_supported(struct pipe_screen *screen,
547 enum pipe_format fmt, unsigned sample_count, boolean is_color)
549 return screen->is_format_supported(screen, fmt, PIPE_TEXTURE_2D, sample_count,
550 (is_color) ? PIPE_BIND_RENDER_TARGET :
551 PIPE_BIND_DEPTH_STENCIL);
555 dri2_display_convert_config(struct native_display *ndpy,
556 const __GLcontextModes *mode,
557 struct native_config *nconf)
559 enum pipe_format formats[32];
561 int sample_count = 0;
563 if (!(mode->renderType & GLX_RGBA_BIT) || !mode->rgbMode)
566 /* only interested in native renderable configs */
567 if (!mode->xRenderable || !mode->drawableType)
570 /* fast/slow configs are probably not relevant */
571 if (mode->visualRating == GLX_SLOW_CONFIG)
574 nconf->buffer_mask = 1 << NATIVE_ATTACHMENT_FRONT_LEFT;
575 if (mode->doubleBufferMode)
576 nconf->buffer_mask |= 1 << NATIVE_ATTACHMENT_BACK_LEFT;
577 if (mode->stereoMode) {
578 nconf->buffer_mask |= 1 << NATIVE_ATTACHMENT_FRONT_RIGHT;
579 if (mode->doubleBufferMode)
580 nconf->buffer_mask |= 1 << NATIVE_ATTACHMENT_BACK_RIGHT;
583 /* choose color format */
584 num_formats = choose_color_format(mode, formats);
585 for (i = 0; i < num_formats; i++) {
586 if (is_format_supported(ndpy->screen, formats[i], sample_count, TRUE)) {
587 nconf->color_format = formats[i];
591 if (nconf->color_format == PIPE_FORMAT_NONE)
594 if ((mode->drawableType & GLX_WINDOW_BIT) && mode->visualID)
595 nconf->window_bit = TRUE;
596 if (mode->drawableType & GLX_PIXMAP_BIT)
597 nconf->pixmap_bit = TRUE;
599 nconf->native_visual_id = mode->visualID;
600 switch (mode->visualType) {
602 nconf->native_visual_type = TrueColor;
604 case GLX_DIRECT_COLOR:
605 nconf->native_visual_type = DirectColor;
607 case GLX_PSEUDO_COLOR:
608 nconf->native_visual_type = PseudoColor;
610 case GLX_STATIC_COLOR:
611 nconf->native_visual_type = StaticColor;
614 nconf->native_visual_type = GrayScale;
616 case GLX_STATIC_GRAY:
617 nconf->native_visual_type = StaticGray;
620 nconf->level = mode->level;
622 if (mode->transparentPixel == GLX_TRANSPARENT_RGB) {
623 nconf->transparent_rgb = TRUE;
624 nconf->transparent_rgb_values[0] = mode->transparentRed;
625 nconf->transparent_rgb_values[1] = mode->transparentGreen;
626 nconf->transparent_rgb_values[2] = mode->transparentBlue;
632 static const struct native_config **
633 dri2_display_get_configs(struct native_display *ndpy, int *num_configs)
635 struct dri2_display *dri2dpy = dri2_display(ndpy);
636 const struct native_config **configs;
640 if (!dri2dpy->configs) {
641 const __GLcontextModes *modes;
642 int num_modes, count;
644 modes = x11_screen_get_glx_configs(dri2dpy->xscr);
647 num_modes = x11_context_modes_count(modes);
649 dri2dpy->configs = CALLOC(num_modes, sizeof(*dri2dpy->configs));
650 if (!dri2dpy->configs)
654 for (i = 0; i < num_modes; i++) {
655 struct native_config *nconf = &dri2dpy->configs[count].base;
657 if (dri2_display_convert_config(&dri2dpy->base, modes, nconf)) {
659 /* look for duplicates */
660 for (j = 0; j < count; j++) {
661 if (memcmp(&dri2dpy->configs[j], nconf, sizeof(*nconf)) == 0)
670 dri2dpy->num_configs = count;
673 configs = MALLOC(dri2dpy->num_configs * sizeof(*configs));
675 for (i = 0; i < dri2dpy->num_configs; i++)
676 configs[i] = (const struct native_config *) &dri2dpy->configs[i];
678 *num_configs = dri2dpy->num_configs;
685 dri2_display_is_pixmap_supported(struct native_display *ndpy,
686 EGLNativePixmapType pix,
687 const struct native_config *nconf)
689 struct dri2_display *dri2dpy = dri2_display(ndpy);
690 uint depth, nconf_depth;
692 depth = x11_drawable_get_depth(dri2dpy->xscr, (Drawable) pix);
693 nconf_depth = util_format_get_blocksizebits(nconf->color_format);
695 /* simple depth match for now */
696 return (depth == nconf_depth || (depth == 24 && depth + 8 == nconf_depth));
700 dri2_display_get_param(struct native_display *ndpy,
701 enum native_param_type param)
706 case NATIVE_PARAM_USE_NATIVE_BUFFER:
707 /* DRI2GetBuffers uses the native buffers */
710 case NATIVE_PARAM_PRESERVE_BUFFER:
711 /* DRI2CopyRegion is used */
714 case NATIVE_PARAM_MAX_SWAP_INTERVAL:
724 dri2_display_destroy(struct native_display *ndpy)
726 struct dri2_display *dri2dpy = dri2_display(ndpy);
728 if (dri2dpy->configs)
729 FREE(dri2dpy->configs);
731 if (dri2dpy->base.screen)
732 dri2dpy->base.screen->destroy(dri2dpy->base.screen);
734 if (dri2dpy->surfaces)
735 util_hash_table_destroy(dri2dpy->surfaces);
738 x11_screen_destroy(dri2dpy->xscr);
739 if (dri2dpy->own_dpy)
740 XCloseDisplay(dri2dpy->dpy);
745 dri2_display_invalidate_buffers(struct x11_screen *xscr, Drawable drawable,
748 struct native_display *ndpy = (struct native_display* ) user_data;
749 struct dri2_display *dri2dpy = dri2_display(ndpy);
750 struct native_surface *nsurf;
751 struct dri2_surface *dri2surf;
753 nsurf = (struct native_surface *)
754 util_hash_table_get(dri2dpy->surfaces, (void *) drawable);
758 dri2surf = dri2_surface(nsurf);
760 dri2surf->server_stamp++;
761 dri2dpy->event_handler->invalid_surface(&dri2dpy->base,
762 &dri2surf->base, dri2surf->server_stamp);
766 * Initialize DRI2 and pipe screen.
769 dri2_display_init_screen(struct native_display *ndpy)
771 struct dri2_display *dri2dpy = dri2_display(ndpy);
774 if (!x11_screen_support(dri2dpy->xscr, X11_SCREEN_EXTENSION_DRI2) ||
775 !x11_screen_support(dri2dpy->xscr, X11_SCREEN_EXTENSION_GLX)) {
776 _eglLog(_EGL_WARNING, "GLX/DRI2 is not supported");
780 dri2dpy->dri_driver = x11_screen_probe_dri2(dri2dpy->xscr,
781 &dri2dpy->dri_major, &dri2dpy->dri_minor);
783 fd = x11_screen_enable_dri2(dri2dpy->xscr,
784 dri2_display_invalidate_buffers, &dri2dpy->base);
788 dri2dpy->base.screen =
789 dri2dpy->event_handler->new_drm_screen(&dri2dpy->base,
790 dri2dpy->dri_driver, fd);
791 if (!dri2dpy->base.screen) {
792 _eglLog(_EGL_DEBUG, "failed to create DRM screen");
800 dri2_display_hash_table_hash(void *key)
802 XID drawable = pointer_to_uintptr(key);
803 return (unsigned) drawable;
807 dri2_display_hash_table_compare(void *key1, void *key2)
809 return ((char *) key1 - (char *) key2);
813 dri2_display_authenticate(void *user_data, uint32_t magic)
815 struct native_display *ndpy = user_data;
816 struct dri2_display *dri2dpy = dri2_display(ndpy);
818 return x11_screen_authenticate(dri2dpy->xscr, magic);
821 #ifdef HAVE_WAYLAND_BACKEND
823 static struct wayland_drm_callbacks wl_drm_callbacks = {
824 dri2_display_authenticate,
825 egl_g3d_wl_drm_helper_reference_buffer,
826 egl_g3d_wl_drm_helper_unreference_buffer
830 dri2_display_bind_wayland_display(struct native_display *ndpy,
831 struct wl_display *wl_dpy)
833 struct dri2_display *dri2dpy = dri2_display(ndpy);
835 if (dri2dpy->wl_server_drm)
838 dri2dpy->wl_server_drm = wayland_drm_init(wl_dpy,
839 x11_screen_get_device_name(dri2dpy->xscr),
840 &wl_drm_callbacks, ndpy);
842 if (!dri2dpy->wl_server_drm)
849 dri2_display_unbind_wayland_display(struct native_display *ndpy,
850 struct wl_display *wl_dpy)
852 struct dri2_display *dri2dpy = dri2_display(ndpy);
854 if (!dri2dpy->wl_server_drm)
857 wayland_drm_uninit(dri2dpy->wl_server_drm);
858 dri2dpy->wl_server_drm = NULL;
863 static struct native_display_wayland_bufmgr dri2_display_wayland_bufmgr = {
864 dri2_display_bind_wayland_display,
865 dri2_display_unbind_wayland_display,
866 egl_g3d_wl_drm_common_wl_buffer_get_resource
869 #endif /* HAVE_WAYLAND_BACKEND */
871 struct native_display *
872 x11_create_dri2_display(Display *dpy,
873 const struct native_event_handler *event_handler)
875 struct dri2_display *dri2dpy;
877 dri2dpy = CALLOC_STRUCT(dri2_display);
881 dri2dpy->event_handler = event_handler;
885 dri2dpy->dpy = XOpenDisplay(NULL);
887 dri2_display_destroy(&dri2dpy->base);
890 dri2dpy->own_dpy = TRUE;
893 dri2dpy->xscr_number = DefaultScreen(dri2dpy->dpy);
894 dri2dpy->xscr = x11_screen_create(dri2dpy->dpy, dri2dpy->xscr_number);
895 if (!dri2dpy->xscr) {
896 dri2_display_destroy(&dri2dpy->base);
900 dri2dpy->surfaces = util_hash_table_create(dri2_display_hash_table_hash,
901 dri2_display_hash_table_compare);
902 if (!dri2dpy->surfaces) {
903 dri2_display_destroy(&dri2dpy->base);
907 dri2dpy->base.init_screen = dri2_display_init_screen;
908 dri2dpy->base.destroy = dri2_display_destroy;
909 dri2dpy->base.get_param = dri2_display_get_param;
910 dri2dpy->base.get_configs = dri2_display_get_configs;
911 dri2dpy->base.is_pixmap_supported = dri2_display_is_pixmap_supported;
912 dri2dpy->base.create_window_surface = dri2_display_create_window_surface;
913 dri2dpy->base.create_pixmap_surface = dri2_display_create_pixmap_surface;
914 #ifdef HAVE_WAYLAND_BACKEND
915 dri2dpy->base.wayland_bufmgr = &dri2_display_wayland_bufmgr;
918 return &dri2dpy->base;
921 #else /* GLX_DIRECT_RENDERING */
923 struct native_display *
924 x11_create_dri2_display(Display *dpy,
925 const struct native_event_handler *event_handler)
930 #endif /* GLX_DIRECT_RENDERING */