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 GLX_DIRECT_RENDERING
43 enum dri2_surface_type
{
44 DRI2_SURFACE_TYPE_WINDOW
,
45 DRI2_SURFACE_TYPE_PIXMAP
,
49 struct native_display base
;
53 struct native_event_handler
*event_handler
;
55 struct x11_screen
*xscr
;
57 const char *dri_driver
;
58 int dri_major
, dri_minor
;
60 struct dri2_config
*configs
;
63 struct util_hash_table
*surfaces
;
67 struct native_surface base
;
69 enum dri2_surface_type type
;
70 enum pipe_format color_format
;
71 struct dri2_display
*dri2dpy
;
73 unsigned int server_stamp
;
74 unsigned int client_stamp
;
76 struct pipe_resource
*textures
[NUM_NATIVE_ATTACHMENTS
];
79 boolean have_back
, have_fake
;
81 struct x11_drawable_buffer
*last_xbufs
;
86 struct native_config base
;
89 static INLINE
struct dri2_display
*
90 dri2_display(const struct native_display
*ndpy
)
92 return (struct dri2_display
*) ndpy
;
95 static INLINE
struct dri2_surface
*
96 dri2_surface(const struct native_surface
*nsurf
)
98 return (struct dri2_surface
*) nsurf
;
101 static INLINE
struct dri2_config
*
102 dri2_config(const struct native_config
*nconf
)
104 return (struct dri2_config
*) nconf
;
108 * Process the buffers returned by the server.
111 dri2_surface_process_drawable_buffers(struct native_surface
*nsurf
,
112 struct x11_drawable_buffer
*xbufs
,
115 struct dri2_surface
*dri2surf
= dri2_surface(nsurf
);
116 struct dri2_display
*dri2dpy
= dri2surf
->dri2dpy
;
117 struct pipe_resource templ
;
118 struct winsys_handle whandle
;
122 /* free the old textures */
123 for (i
= 0; i
< NUM_NATIVE_ATTACHMENTS
; i
++)
124 pipe_resource_reference(&dri2surf
->textures
[i
], NULL
);
125 dri2surf
->valid_mask
= 0x0;
127 dri2surf
->have_back
= FALSE
;
128 dri2surf
->have_fake
= FALSE
;
133 memset(&templ
, 0, sizeof(templ
));
134 templ
.target
= PIPE_TEXTURE_2D
;
135 templ
.last_level
= 0;
136 templ
.width0
= dri2surf
->width
;
137 templ
.height0
= dri2surf
->height
;
139 templ
.format
= dri2surf
->color_format
;
140 templ
.bind
= PIPE_BIND_RENDER_TARGET
;
143 for (i
= 0; i
< num_xbufs
; i
++) {
144 struct x11_drawable_buffer
*xbuf
= &xbufs
[i
];
146 enum native_attachment natt
;
148 switch (xbuf
->attachment
) {
149 case DRI2BufferFrontLeft
:
150 natt
= NATIVE_ATTACHMENT_FRONT_LEFT
;
151 desc
= "DRI2 Front Buffer";
153 case DRI2BufferFakeFrontLeft
:
154 natt
= NATIVE_ATTACHMENT_FRONT_LEFT
;
155 desc
= "DRI2 Fake Front Buffer";
156 dri2surf
->have_fake
= TRUE
;
158 case DRI2BufferBackLeft
:
159 natt
= NATIVE_ATTACHMENT_BACK_LEFT
;
160 desc
= "DRI2 Back Buffer";
161 dri2surf
->have_back
= TRUE
;
168 if (!desc
|| dri2surf
->textures
[natt
]) {
170 _eglLog(_EGL_WARNING
, "unknown buffer %d", xbuf
->attachment
);
172 _eglLog(_EGL_WARNING
, "both real and fake front buffers are listed");
176 memset(&whandle
, 0, sizeof(whandle
));
177 whandle
.stride
= xbuf
->pitch
;
178 whandle
.handle
= xbuf
->name
;
179 dri2surf
->textures
[natt
] = dri2dpy
->base
.screen
->resource_from_handle(
180 dri2dpy
->base
.screen
, &templ
, &whandle
);
181 if (dri2surf
->textures
[natt
])
182 valid_mask
|= 1 << natt
;
185 dri2surf
->valid_mask
= valid_mask
;
189 * Get the buffers from the server.
192 dri2_surface_get_buffers(struct native_surface
*nsurf
, uint buffer_mask
)
194 struct dri2_surface
*dri2surf
= dri2_surface(nsurf
);
195 struct dri2_display
*dri2dpy
= dri2surf
->dri2dpy
;
196 unsigned int dri2atts
[NUM_NATIVE_ATTACHMENTS
* 2];
197 int num_ins
, num_outs
, att
;
198 struct x11_drawable_buffer
*xbufs
;
199 uint bpp
= util_format_get_blocksizebits(dri2surf
->color_format
);
200 boolean with_format
= FALSE
; /* never ask for depth/stencil */
202 /* We must get the front on servers which doesn't support with format
203 * due to a silly bug in core dri2. You can't copy to/from a buffer
204 * that you haven't requested and you recive BadValue errors */
205 if (dri2surf
->dri2dpy
->dri_minor
< 1) {
207 buffer_mask
|= (1 << NATIVE_ATTACHMENT_FRONT_LEFT
);
210 /* prepare the attachments */
212 for (att
= 0; att
< NUM_NATIVE_ATTACHMENTS
; att
++) {
213 if (native_attachment_mask_test(buffer_mask
, att
)) {
214 unsigned int dri2att
;
217 case NATIVE_ATTACHMENT_FRONT_LEFT
:
218 dri2att
= DRI2BufferFrontLeft
;
220 case NATIVE_ATTACHMENT_BACK_LEFT
:
221 dri2att
= DRI2BufferBackLeft
;
223 case NATIVE_ATTACHMENT_FRONT_RIGHT
:
224 dri2att
= DRI2BufferFrontRight
;
226 case NATIVE_ATTACHMENT_BACK_RIGHT
:
227 dri2att
= DRI2BufferBackRight
;
235 dri2atts
[num_ins
++] = dri2att
;
237 dri2atts
[num_ins
++] = bpp
;
243 xbufs
= x11_drawable_get_buffers(dri2dpy
->xscr
, dri2surf
->drawable
,
244 &dri2surf
->width
, &dri2surf
->height
,
245 dri2atts
, with_format
, num_ins
, &num_outs
);
247 /* we should be able to do better... */
248 if (xbufs
&& dri2surf
->last_num_xbufs
== num_outs
&&
249 memcmp(dri2surf
->last_xbufs
, xbufs
, sizeof(*xbufs
) * num_outs
) == 0) {
251 dri2surf
->client_stamp
= dri2surf
->server_stamp
;
255 dri2_surface_process_drawable_buffers(&dri2surf
->base
, xbufs
, num_outs
);
257 dri2surf
->server_stamp
++;
258 dri2surf
->client_stamp
= dri2surf
->server_stamp
;
260 if (dri2surf
->last_xbufs
)
261 FREE(dri2surf
->last_xbufs
);
262 dri2surf
->last_xbufs
= xbufs
;
263 dri2surf
->last_num_xbufs
= num_outs
;
267 * Update the buffers of the surface. This is a slow function due to the
268 * round-trip to the server.
271 dri2_surface_update_buffers(struct native_surface
*nsurf
, uint buffer_mask
)
273 struct dri2_surface
*dri2surf
= dri2_surface(nsurf
);
275 dri2_surface_get_buffers(&dri2surf
->base
, buffer_mask
);
277 return ((dri2surf
->valid_mask
& buffer_mask
) == buffer_mask
);
281 * Return TRUE if the surface receives DRI2_InvalidateBuffers events.
283 static INLINE boolean
284 dri2_surface_receive_events(struct native_surface
*nsurf
)
286 struct dri2_surface
*dri2surf
= dri2_surface(nsurf
);
287 return (dri2surf
->dri2dpy
->dri_minor
>= 3);
291 dri2_surface_flush_frontbuffer(struct native_surface
*nsurf
)
293 struct dri2_surface
*dri2surf
= dri2_surface(nsurf
);
294 struct dri2_display
*dri2dpy
= dri2surf
->dri2dpy
;
296 /* copy to real front buffer */
297 if (dri2surf
->have_fake
)
298 x11_drawable_copy_buffers(dri2dpy
->xscr
, dri2surf
->drawable
,
299 0, 0, dri2surf
->width
, dri2surf
->height
,
300 DRI2BufferFakeFrontLeft
, DRI2BufferFrontLeft
);
302 /* force buffers to be updated in next validation call */
303 if (!dri2_surface_receive_events(&dri2surf
->base
)) {
304 dri2surf
->server_stamp
++;
305 dri2dpy
->event_handler
->invalid_surface(&dri2dpy
->base
,
306 &dri2surf
->base
, dri2surf
->server_stamp
);
313 dri2_surface_swap_buffers(struct native_surface
*nsurf
)
315 struct dri2_surface
*dri2surf
= dri2_surface(nsurf
);
316 struct dri2_display
*dri2dpy
= dri2surf
->dri2dpy
;
318 /* copy to front buffer */
319 if (dri2surf
->have_back
)
320 x11_drawable_copy_buffers(dri2dpy
->xscr
, dri2surf
->drawable
,
321 0, 0, dri2surf
->width
, dri2surf
->height
,
322 DRI2BufferBackLeft
, DRI2BufferFrontLeft
);
324 /* and update fake front buffer */
325 if (dri2surf
->have_fake
)
326 x11_drawable_copy_buffers(dri2dpy
->xscr
, dri2surf
->drawable
,
327 0, 0, dri2surf
->width
, dri2surf
->height
,
328 DRI2BufferFrontLeft
, DRI2BufferFakeFrontLeft
);
330 /* force buffers to be updated in next validation call */
331 if (!dri2_surface_receive_events(&dri2surf
->base
)) {
332 dri2surf
->server_stamp
++;
333 dri2dpy
->event_handler
->invalid_surface(&dri2dpy
->base
,
334 &dri2surf
->base
, dri2surf
->server_stamp
);
341 dri2_surface_validate(struct native_surface
*nsurf
, uint attachment_mask
,
342 unsigned int *seq_num
, struct pipe_resource
**textures
,
343 int *width
, int *height
)
345 struct dri2_surface
*dri2surf
= dri2_surface(nsurf
);
347 if (dri2surf
->server_stamp
!= dri2surf
->client_stamp
||
348 (dri2surf
->valid_mask
& attachment_mask
) != attachment_mask
) {
349 if (!dri2_surface_update_buffers(&dri2surf
->base
, attachment_mask
))
354 *seq_num
= dri2surf
->client_stamp
;
358 for (att
= 0; att
< NUM_NATIVE_ATTACHMENTS
; att
++) {
359 if (native_attachment_mask_test(attachment_mask
, att
)) {
360 struct pipe_resource
*ptex
= dri2surf
->textures
[att
];
362 textures
[att
] = NULL
;
363 pipe_resource_reference(&textures
[att
], ptex
);
369 *width
= dri2surf
->width
;
371 *height
= dri2surf
->height
;
377 dri2_surface_wait(struct native_surface
*nsurf
)
379 struct dri2_surface
*dri2surf
= dri2_surface(nsurf
);
380 struct dri2_display
*dri2dpy
= dri2surf
->dri2dpy
;
382 if (dri2surf
->have_fake
) {
383 x11_drawable_copy_buffers(dri2dpy
->xscr
, dri2surf
->drawable
,
384 0, 0, dri2surf
->width
, dri2surf
->height
,
385 DRI2BufferFrontLeft
, DRI2BufferFakeFrontLeft
);
390 dri2_surface_destroy(struct native_surface
*nsurf
)
392 struct dri2_surface
*dri2surf
= dri2_surface(nsurf
);
395 if (dri2surf
->last_xbufs
)
396 FREE(dri2surf
->last_xbufs
);
398 for (i
= 0; i
< NUM_NATIVE_ATTACHMENTS
; i
++) {
399 struct pipe_resource
*ptex
= dri2surf
->textures
[i
];
400 pipe_resource_reference(&ptex
, NULL
);
403 if (dri2surf
->drawable
) {
404 x11_drawable_enable_dri2(dri2surf
->dri2dpy
->xscr
,
405 dri2surf
->drawable
, FALSE
);
407 util_hash_table_remove(dri2surf
->dri2dpy
->surfaces
,
408 (void *) dri2surf
->drawable
);
413 static struct dri2_surface
*
414 dri2_display_create_surface(struct native_display
*ndpy
,
415 enum dri2_surface_type type
,
417 const struct native_config
*nconf
)
419 struct dri2_display
*dri2dpy
= dri2_display(ndpy
);
420 struct dri2_config
*dri2conf
= dri2_config(nconf
);
421 struct dri2_surface
*dri2surf
;
423 dri2surf
= CALLOC_STRUCT(dri2_surface
);
427 dri2surf
->dri2dpy
= dri2dpy
;
428 dri2surf
->type
= type
;
429 dri2surf
->drawable
= drawable
;
430 dri2surf
->color_format
= dri2conf
->base
.color_format
;
432 dri2surf
->base
.destroy
= dri2_surface_destroy
;
433 dri2surf
->base
.swap_buffers
= dri2_surface_swap_buffers
;
434 dri2surf
->base
.flush_frontbuffer
= dri2_surface_flush_frontbuffer
;
435 dri2surf
->base
.validate
= dri2_surface_validate
;
436 dri2surf
->base
.wait
= dri2_surface_wait
;
439 x11_drawable_enable_dri2(dri2dpy
->xscr
, drawable
, TRUE
);
440 /* initialize the geometry */
441 dri2_surface_update_buffers(&dri2surf
->base
, 0x0);
443 util_hash_table_set(dri2surf
->dri2dpy
->surfaces
,
444 (void *) dri2surf
->drawable
, (void *) &dri2surf
->base
);
450 static struct native_surface
*
451 dri2_display_create_window_surface(struct native_display
*ndpy
,
452 EGLNativeWindowType win
,
453 const struct native_config
*nconf
)
455 struct dri2_surface
*dri2surf
;
457 dri2surf
= dri2_display_create_surface(ndpy
, DRI2_SURFACE_TYPE_WINDOW
,
458 (Drawable
) win
, nconf
);
459 return (dri2surf
) ? &dri2surf
->base
: NULL
;
462 static struct native_surface
*
463 dri2_display_create_pixmap_surface(struct native_display
*ndpy
,
464 EGLNativePixmapType pix
,
465 const struct native_config
*nconf
)
467 struct dri2_surface
*dri2surf
;
469 dri2surf
= dri2_display_create_surface(ndpy
, DRI2_SURFACE_TYPE_PIXMAP
,
470 (Drawable
) pix
, nconf
);
471 return (dri2surf
) ? &dri2surf
->base
: NULL
;
475 choose_color_format(const __GLcontextModes
*mode
, enum pipe_format formats
[32])
479 switch (mode
->rgbBits
) {
481 formats
[count
++] = PIPE_FORMAT_B8G8R8A8_UNORM
;
482 formats
[count
++] = PIPE_FORMAT_A8R8G8B8_UNORM
;
485 formats
[count
++] = PIPE_FORMAT_B8G8R8X8_UNORM
;
486 formats
[count
++] = PIPE_FORMAT_X8R8G8B8_UNORM
;
487 formats
[count
++] = PIPE_FORMAT_B8G8R8A8_UNORM
;
488 formats
[count
++] = PIPE_FORMAT_A8R8G8B8_UNORM
;
491 formats
[count
++] = PIPE_FORMAT_B5G6R5_UNORM
;
501 is_format_supported(struct pipe_screen
*screen
,
502 enum pipe_format fmt
, unsigned sample_count
, boolean is_color
)
504 return screen
->is_format_supported(screen
, fmt
, PIPE_TEXTURE_2D
, sample_count
,
505 (is_color
) ? PIPE_BIND_RENDER_TARGET
:
506 PIPE_BIND_DEPTH_STENCIL
, 0);
510 dri2_display_convert_config(struct native_display
*ndpy
,
511 const __GLcontextModes
*mode
,
512 struct native_config
*nconf
)
514 enum pipe_format formats
[32];
516 int sample_count
= 0;
518 if (!(mode
->renderType
& GLX_RGBA_BIT
) || !mode
->rgbMode
)
521 /* skip single-buffered configs */
522 if (!mode
->doubleBufferMode
)
525 /* only interested in native renderable configs */
526 if (!mode
->xRenderable
|| !mode
->drawableType
)
529 nconf
->buffer_mask
= 1 << NATIVE_ATTACHMENT_FRONT_LEFT
;
530 if (mode
->doubleBufferMode
)
531 nconf
->buffer_mask
|= 1 << NATIVE_ATTACHMENT_BACK_LEFT
;
532 if (mode
->stereoMode
) {
533 nconf
->buffer_mask
|= 1 << NATIVE_ATTACHMENT_FRONT_RIGHT
;
534 if (mode
->doubleBufferMode
)
535 nconf
->buffer_mask
|= 1 << NATIVE_ATTACHMENT_BACK_RIGHT
;
538 /* choose color format */
539 num_formats
= choose_color_format(mode
, formats
);
540 for (i
= 0; i
< num_formats
; i
++) {
541 if (is_format_supported(ndpy
->screen
, formats
[i
], sample_count
, TRUE
)) {
542 nconf
->color_format
= formats
[i
];
546 if (nconf
->color_format
== PIPE_FORMAT_NONE
)
549 if (mode
->drawableType
& GLX_WINDOW_BIT
)
550 nconf
->window_bit
= TRUE
;
551 if (mode
->drawableType
& GLX_PIXMAP_BIT
)
552 nconf
->pixmap_bit
= TRUE
;
554 nconf
->native_visual_id
= mode
->visualID
;
555 nconf
->native_visual_type
= mode
->visualType
;
556 nconf
->level
= mode
->level
;
557 nconf
->samples
= mode
->samples
;
559 nconf
->slow_config
= (mode
->visualRating
== GLX_SLOW_CONFIG
);
561 if (mode
->transparentPixel
== GLX_TRANSPARENT_RGB
) {
562 nconf
->transparent_rgb
= TRUE
;
563 nconf
->transparent_rgb_values
[0] = mode
->transparentRed
;
564 nconf
->transparent_rgb_values
[1] = mode
->transparentGreen
;
565 nconf
->transparent_rgb_values
[2] = mode
->transparentBlue
;
571 static const struct native_config
**
572 dri2_display_get_configs(struct native_display
*ndpy
, int *num_configs
)
574 struct dri2_display
*dri2dpy
= dri2_display(ndpy
);
575 const struct native_config
**configs
;
579 if (!dri2dpy
->configs
) {
580 const __GLcontextModes
*modes
;
581 int num_modes
, count
;
583 modes
= x11_screen_get_glx_configs(dri2dpy
->xscr
);
586 num_modes
= x11_context_modes_count(modes
);
588 dri2dpy
->configs
= CALLOC(num_modes
, sizeof(*dri2dpy
->configs
));
589 if (!dri2dpy
->configs
)
593 for (i
= 0; i
< num_modes
; i
++) {
594 struct native_config
*nconf
= &dri2dpy
->configs
[count
].base
;
595 if (dri2_display_convert_config(&dri2dpy
->base
, modes
, nconf
))
600 dri2dpy
->num_configs
= count
;
603 configs
= MALLOC(dri2dpy
->num_configs
* sizeof(*configs
));
605 for (i
= 0; i
< dri2dpy
->num_configs
; i
++)
606 configs
[i
] = (const struct native_config
*) &dri2dpy
->configs
[i
];
608 *num_configs
= dri2dpy
->num_configs
;
615 dri2_display_is_pixmap_supported(struct native_display
*ndpy
,
616 EGLNativePixmapType pix
,
617 const struct native_config
*nconf
)
619 struct dri2_display
*dri2dpy
= dri2_display(ndpy
);
620 uint depth
, nconf_depth
;
622 depth
= x11_drawable_get_depth(dri2dpy
->xscr
, (Drawable
) pix
);
623 nconf_depth
= util_format_get_blocksizebits(nconf
->color_format
);
625 /* simple depth match for now */
626 return (depth
== nconf_depth
|| (depth
== 24 && depth
+ 8 == nconf_depth
));
630 dri2_display_get_param(struct native_display
*ndpy
,
631 enum native_param_type param
)
636 case NATIVE_PARAM_USE_NATIVE_BUFFER
:
637 /* DRI2GetBuffers use the native buffers */
649 dri2_display_destroy(struct native_display
*ndpy
)
651 struct dri2_display
*dri2dpy
= dri2_display(ndpy
);
653 if (dri2dpy
->configs
)
654 FREE(dri2dpy
->configs
);
656 if (dri2dpy
->base
.screen
)
657 dri2dpy
->base
.screen
->destroy(dri2dpy
->base
.screen
);
659 if (dri2dpy
->surfaces
)
660 util_hash_table_destroy(dri2dpy
->surfaces
);
663 x11_screen_destroy(dri2dpy
->xscr
);
664 if (dri2dpy
->own_dpy
)
665 XCloseDisplay(dri2dpy
->dpy
);
670 dri2_display_invalidate_buffers(struct x11_screen
*xscr
, Drawable drawable
,
673 struct native_display
*ndpy
= (struct native_display
* ) user_data
;
674 struct dri2_display
*dri2dpy
= dri2_display(ndpy
);
675 struct native_surface
*nsurf
;
676 struct dri2_surface
*dri2surf
;
678 nsurf
= (struct native_surface
*)
679 util_hash_table_get(dri2dpy
->surfaces
, (void *) drawable
);
683 dri2surf
= dri2_surface(nsurf
);
685 dri2surf
->server_stamp
++;
686 dri2dpy
->event_handler
->invalid_surface(&dri2dpy
->base
,
687 &dri2surf
->base
, dri2surf
->server_stamp
);
691 * Initialize DRI2 and pipe screen.
694 dri2_display_init_screen(struct native_display
*ndpy
)
696 struct dri2_display
*dri2dpy
= dri2_display(ndpy
);
699 if (!x11_screen_support(dri2dpy
->xscr
, X11_SCREEN_EXTENSION_DRI2
) ||
700 !x11_screen_support(dri2dpy
->xscr
, X11_SCREEN_EXTENSION_GLX
)) {
701 _eglLog(_EGL_WARNING
, "GLX/DRI2 is not supported");
705 dri2dpy
->dri_driver
= x11_screen_probe_dri2(dri2dpy
->xscr
,
706 &dri2dpy
->dri_major
, &dri2dpy
->dri_minor
);
708 fd
= x11_screen_enable_dri2(dri2dpy
->xscr
,
709 dri2_display_invalidate_buffers
, &dri2dpy
->base
);
713 dri2dpy
->base
.screen
=
714 dri2dpy
->event_handler
->new_drm_screen(&dri2dpy
->base
,
715 dri2dpy
->dri_driver
, fd
);
716 if (!dri2dpy
->base
.screen
) {
717 _eglLog(_EGL_WARNING
, "failed to create DRM screen");
725 dri2_display_hash_table_hash(void *key
)
727 XID drawable
= pointer_to_uintptr(key
);
728 return (unsigned) drawable
;
732 dri2_display_hash_table_compare(void *key1
, void *key2
)
734 return (key1
- key2
);
737 struct native_display
*
738 x11_create_dri2_display(Display
*dpy
,
739 struct native_event_handler
*event_handler
,
742 struct dri2_display
*dri2dpy
;
744 dri2dpy
= CALLOC_STRUCT(dri2_display
);
748 dri2dpy
->event_handler
= event_handler
;
749 dri2dpy
->base
.user_data
= user_data
;
753 dri2dpy
->dpy
= XOpenDisplay(NULL
);
755 dri2_display_destroy(&dri2dpy
->base
);
758 dri2dpy
->own_dpy
= TRUE
;
761 dri2dpy
->xscr_number
= DefaultScreen(dri2dpy
->dpy
);
762 dri2dpy
->xscr
= x11_screen_create(dri2dpy
->dpy
, dri2dpy
->xscr_number
);
763 if (!dri2dpy
->xscr
) {
764 dri2_display_destroy(&dri2dpy
->base
);
768 if (!dri2_display_init_screen(&dri2dpy
->base
)) {
769 dri2_display_destroy(&dri2dpy
->base
);
773 dri2dpy
->surfaces
= util_hash_table_create(dri2_display_hash_table_hash
,
774 dri2_display_hash_table_compare
);
775 if (!dri2dpy
->surfaces
) {
776 dri2_display_destroy(&dri2dpy
->base
);
780 dri2dpy
->base
.destroy
= dri2_display_destroy
;
781 dri2dpy
->base
.get_param
= dri2_display_get_param
;
782 dri2dpy
->base
.get_configs
= dri2_display_get_configs
;
783 dri2dpy
->base
.is_pixmap_supported
= dri2_display_is_pixmap_supported
;
784 dri2dpy
->base
.create_window_surface
= dri2_display_create_window_surface
;
785 dri2dpy
->base
.create_pixmap_surface
= dri2_display_create_pixmap_surface
;
787 return &dri2dpy
->base
;
790 #else /* GLX_DIRECT_RENDERING */
792 struct native_display
*
793 x11_create_dri2_display(Display
*dpy
,
794 struct native_event_handler
*event_handler
,
800 #endif /* GLX_DIRECT_RENDERING */