2 * Copyright © 2011 Intel Corporation
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
19 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
20 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
25 * Kristian Høgsberg <krh@bitplanet.net>
37 #include <sys/types.h>
43 * Called via eglCreateWindowSurface(), drv->API.CreateWindowSurface().
46 dri2_create_surface(_EGLDriver
*drv
, _EGLDisplay
*disp
, EGLint type
,
47 _EGLConfig
*conf
, EGLNativeWindowType window
,
48 const EGLint
*attrib_list
)
50 struct dri2_egl_display
*dri2_dpy
= dri2_egl_display(disp
);
51 struct dri2_egl_config
*dri2_conf
= dri2_egl_config(conf
);
52 struct dri2_egl_surface
*dri2_surf
;
53 xcb_get_geometry_cookie_t cookie
;
54 xcb_get_geometry_reply_t
*reply
;
55 xcb_screen_iterator_t s
;
56 xcb_generic_error_t
*error
;
60 dri2_surf
= malloc(sizeof *dri2_surf
);
62 _eglError(EGL_BAD_ALLOC
, "dri2_create_surface");
66 if (!_eglInitSurface(&dri2_surf
->base
, disp
, type
, conf
, attrib_list
))
69 dri2_surf
->region
= XCB_NONE
;
70 if (type
== EGL_PBUFFER_BIT
) {
71 dri2_surf
->drawable
= xcb_generate_id(dri2_dpy
->conn
);
72 s
= xcb_setup_roots_iterator(xcb_get_setup(dri2_dpy
->conn
));
73 xcb_create_pixmap(dri2_dpy
->conn
, conf
->BufferSize
,
74 dri2_surf
->drawable
, s
.data
->root
,
75 dri2_surf
->base
.Width
, dri2_surf
->base
.Height
);
77 dri2_surf
->drawable
= window
;
80 dri2_surf
->dri_drawable
=
81 (*dri2_dpy
->dri2
->createNewDrawable
) (dri2_dpy
->dri_screen
,
82 type
== EGL_WINDOW_BIT
?
83 dri2_conf
->dri_double_config
:
84 dri2_conf
->dri_single_config
,
86 if (dri2_surf
->dri_drawable
== NULL
) {
87 _eglError(EGL_BAD_ALLOC
, "dri2->createNewDrawable");
91 xcb_dri2_create_drawable (dri2_dpy
->conn
, dri2_surf
->drawable
);
93 if (type
!= EGL_PBUFFER_BIT
) {
94 cookie
= xcb_get_geometry (dri2_dpy
->conn
, dri2_surf
->drawable
);
95 reply
= xcb_get_geometry_reply (dri2_dpy
->conn
, cookie
, &error
);
96 if (reply
== NULL
|| error
!= NULL
) {
97 _eglError(EGL_BAD_ALLOC
, "xcb_get_geometry");
99 goto cleanup_dri_drawable
;
102 dri2_surf
->base
.Width
= reply
->width
;
103 dri2_surf
->base
.Height
= reply
->height
;
107 return &dri2_surf
->base
;
109 cleanup_dri_drawable
:
110 dri2_dpy
->core
->destroyDrawable(dri2_surf
->dri_drawable
);
112 if (type
== EGL_PBUFFER_BIT
)
113 xcb_free_pixmap(dri2_dpy
->conn
, dri2_surf
->drawable
);
121 * Called via eglCreateWindowSurface(), drv->API.CreateWindowSurface().
124 dri2_create_window_surface(_EGLDriver
*drv
, _EGLDisplay
*disp
,
125 _EGLConfig
*conf
, EGLNativeWindowType window
,
126 const EGLint
*attrib_list
)
128 return dri2_create_surface(drv
, disp
, EGL_WINDOW_BIT
, conf
,
129 window
, attrib_list
);
133 dri2_create_pixmap_surface(_EGLDriver
*drv
, _EGLDisplay
*disp
,
134 _EGLConfig
*conf
, EGLNativePixmapType pixmap
,
135 const EGLint
*attrib_list
)
137 return dri2_create_surface(drv
, disp
, EGL_PIXMAP_BIT
, conf
,
138 pixmap
, attrib_list
);
142 dri2_create_pbuffer_surface(_EGLDriver
*drv
, _EGLDisplay
*disp
,
143 _EGLConfig
*conf
, const EGLint
*attrib_list
)
145 return dri2_create_surface(drv
, disp
, EGL_PBUFFER_BIT
, conf
,
146 XCB_WINDOW_NONE
, attrib_list
);
150 dri2_destroy_surface(_EGLDriver
*drv
, _EGLDisplay
*disp
, _EGLSurface
*surf
)
152 struct dri2_egl_display
*dri2_dpy
= dri2_egl_display(disp
);
153 struct dri2_egl_surface
*dri2_surf
= dri2_egl_surface(surf
);
157 if (!_eglPutSurface(surf
))
160 (*dri2_dpy
->core
->destroyDrawable
)(dri2_surf
->dri_drawable
);
162 xcb_dri2_destroy_drawable (dri2_dpy
->conn
, dri2_surf
->drawable
);
164 if (surf
->Type
== EGL_PBUFFER_BIT
)
165 xcb_free_pixmap (dri2_dpy
->conn
, dri2_surf
->drawable
);
173 * Process list of buffer received from the server
175 * Processes the list of buffers received in a reply from the server to either
176 * \c DRI2GetBuffers or \c DRI2GetBuffersWithFormat.
179 dri2_process_buffers(struct dri2_egl_surface
*dri2_surf
,
180 xcb_dri2_dri2_buffer_t
*buffers
, unsigned count
)
182 struct dri2_egl_display
*dri2_dpy
=
183 dri2_egl_display(dri2_surf
->base
.Resource
.Display
);
184 xcb_rectangle_t rectangle
;
187 dri2_surf
->buffer_count
= count
;
188 dri2_surf
->have_fake_front
= 0;
190 /* This assumes the DRI2 buffer attachment tokens matches the
191 * __DRIbuffer tokens. */
192 for (i
= 0; i
< count
; i
++) {
193 dri2_surf
->buffers
[i
].attachment
= buffers
[i
].attachment
;
194 dri2_surf
->buffers
[i
].name
= buffers
[i
].name
;
195 dri2_surf
->buffers
[i
].pitch
= buffers
[i
].pitch
;
196 dri2_surf
->buffers
[i
].cpp
= buffers
[i
].cpp
;
197 dri2_surf
->buffers
[i
].flags
= buffers
[i
].flags
;
199 /* We only use the DRI drivers single buffer configs. This
200 * means that if we try to render to a window, DRI2 will give us
201 * the fake front buffer, which we'll use as a back buffer.
202 * Note that EGL doesn't require that several clients rendering
203 * to the same window must see the same aux buffers. */
204 if (dri2_surf
->buffers
[i
].attachment
== __DRI_BUFFER_FAKE_FRONT_LEFT
)
205 dri2_surf
->have_fake_front
= 1;
208 if (dri2_surf
->region
!= XCB_NONE
)
209 xcb_xfixes_destroy_region(dri2_dpy
->conn
, dri2_surf
->region
);
213 rectangle
.width
= dri2_surf
->base
.Width
;
214 rectangle
.height
= dri2_surf
->base
.Height
;
215 dri2_surf
->region
= xcb_generate_id(dri2_dpy
->conn
);
216 xcb_xfixes_create_region(dri2_dpy
->conn
, dri2_surf
->region
, 1, &rectangle
);
220 dri2_get_buffers(__DRIdrawable
* driDrawable
,
221 int *width
, int *height
,
222 unsigned int *attachments
, int count
,
223 int *out_count
, void *loaderPrivate
)
225 struct dri2_egl_surface
*dri2_surf
= loaderPrivate
;
226 struct dri2_egl_display
*dri2_dpy
=
227 dri2_egl_display(dri2_surf
->base
.Resource
.Display
);
228 xcb_dri2_dri2_buffer_t
*buffers
;
229 xcb_dri2_get_buffers_reply_t
*reply
;
230 xcb_dri2_get_buffers_cookie_t cookie
;
234 cookie
= xcb_dri2_get_buffers_unchecked (dri2_dpy
->conn
,
236 count
, count
, attachments
);
237 reply
= xcb_dri2_get_buffers_reply (dri2_dpy
->conn
, cookie
, NULL
);
238 buffers
= xcb_dri2_get_buffers_buffers (reply
);
242 *out_count
= reply
->count
;
243 dri2_surf
->base
.Width
= *width
= reply
->width
;
244 dri2_surf
->base
.Height
= *height
= reply
->height
;
245 dri2_process_buffers(dri2_surf
, buffers
, *out_count
);
249 return dri2_surf
->buffers
;
253 dri2_get_buffers_with_format(__DRIdrawable
* driDrawable
,
254 int *width
, int *height
,
255 unsigned int *attachments
, int count
,
256 int *out_count
, void *loaderPrivate
)
258 struct dri2_egl_surface
*dri2_surf
= loaderPrivate
;
259 struct dri2_egl_display
*dri2_dpy
=
260 dri2_egl_display(dri2_surf
->base
.Resource
.Display
);
261 xcb_dri2_dri2_buffer_t
*buffers
;
262 xcb_dri2_get_buffers_with_format_reply_t
*reply
;
263 xcb_dri2_get_buffers_with_format_cookie_t cookie
;
264 xcb_dri2_attach_format_t
*format_attachments
;
268 format_attachments
= (xcb_dri2_attach_format_t
*) attachments
;
269 cookie
= xcb_dri2_get_buffers_with_format_unchecked (dri2_dpy
->conn
,
274 reply
= xcb_dri2_get_buffers_with_format_reply (dri2_dpy
->conn
,
279 buffers
= xcb_dri2_get_buffers_with_format_buffers (reply
);
280 dri2_surf
->base
.Width
= *width
= reply
->width
;
281 dri2_surf
->base
.Height
= *height
= reply
->height
;
282 *out_count
= reply
->count
;
283 dri2_process_buffers(dri2_surf
, buffers
, *out_count
);
287 return dri2_surf
->buffers
;
291 dri2_flush_front_buffer(__DRIdrawable
* driDrawable
, void *loaderPrivate
)
295 /* FIXME: Does EGL support front buffer rendering at all? */
298 struct dri2_egl_surface
*dri2_surf
= loaderPrivate
;
300 dri2WaitGL(dri2_surf
);
302 (void) loaderPrivate
;
307 dri2_strndup(const char *s
, int length
)
311 d
= malloc(length
+ 1);
315 memcpy(d
, s
, length
);
322 dri2_connect(struct dri2_egl_display
*dri2_dpy
)
324 xcb_xfixes_query_version_reply_t
*xfixes_query
;
325 xcb_xfixes_query_version_cookie_t xfixes_query_cookie
;
326 xcb_dri2_query_version_reply_t
*dri2_query
;
327 xcb_dri2_query_version_cookie_t dri2_query_cookie
;
328 xcb_dri2_connect_reply_t
*connect
;
329 xcb_dri2_connect_cookie_t connect_cookie
;
330 xcb_generic_error_t
*error
;
331 xcb_screen_iterator_t s
;
333 xcb_prefetch_extension_data (dri2_dpy
->conn
, &xcb_xfixes_id
);
334 xcb_prefetch_extension_data (dri2_dpy
->conn
, &xcb_dri2_id
);
336 xfixes_query_cookie
= xcb_xfixes_query_version(dri2_dpy
->conn
,
337 XCB_XFIXES_MAJOR_VERSION
,
338 XCB_XFIXES_MINOR_VERSION
);
340 dri2_query_cookie
= xcb_dri2_query_version (dri2_dpy
->conn
,
341 XCB_DRI2_MAJOR_VERSION
,
342 XCB_DRI2_MINOR_VERSION
);
344 s
= xcb_setup_roots_iterator(xcb_get_setup(dri2_dpy
->conn
));
345 connect_cookie
= xcb_dri2_connect_unchecked (dri2_dpy
->conn
,
347 XCB_DRI2_DRIVER_TYPE_DRI
);
350 xcb_xfixes_query_version_reply (dri2_dpy
->conn
,
351 xfixes_query_cookie
, &error
);
352 if (xfixes_query
== NULL
||
353 error
!= NULL
|| xfixes_query
->major_version
< 2) {
354 _eglLog(_EGL_FATAL
, "DRI2: failed to query xfixes version");
361 xcb_dri2_query_version_reply (dri2_dpy
->conn
, dri2_query_cookie
, &error
);
362 if (dri2_query
== NULL
|| error
!= NULL
) {
363 _eglLog(_EGL_FATAL
, "DRI2: failed to query version");
367 dri2_dpy
->dri2_major
= dri2_query
->major_version
;
368 dri2_dpy
->dri2_minor
= dri2_query
->minor_version
;
371 connect
= xcb_dri2_connect_reply (dri2_dpy
->conn
, connect_cookie
, NULL
);
372 if (connect
== NULL
||
373 connect
->driver_name_length
+ connect
->device_name_length
== 0) {
374 _eglLog(_EGL_FATAL
, "DRI2: failed to authenticate");
378 dri2_dpy
->device_name
=
379 dri2_strndup(xcb_dri2_connect_device_name (connect
),
380 xcb_dri2_connect_device_name_length (connect
));
382 dri2_dpy
->driver_name
=
383 dri2_strndup(xcb_dri2_connect_driver_name (connect
),
384 xcb_dri2_connect_driver_name_length (connect
));
386 if (dri2_dpy
->device_name
== NULL
|| dri2_dpy
->driver_name
== NULL
) {
387 free(dri2_dpy
->device_name
);
388 free(dri2_dpy
->driver_name
);
398 dri2_authenticate(struct dri2_egl_display
*dri2_dpy
)
400 xcb_dri2_authenticate_reply_t
*authenticate
;
401 xcb_dri2_authenticate_cookie_t authenticate_cookie
;
402 xcb_screen_iterator_t s
;
405 if (drmGetMagic(dri2_dpy
->fd
, &magic
)) {
406 _eglLog(_EGL_FATAL
, "DRI2: failed to get drm magic");
410 s
= xcb_setup_roots_iterator(xcb_get_setup(dri2_dpy
->conn
));
411 authenticate_cookie
=
412 xcb_dri2_authenticate_unchecked(dri2_dpy
->conn
, s
.data
->root
, magic
);
414 xcb_dri2_authenticate_reply(dri2_dpy
->conn
, authenticate_cookie
, NULL
);
415 if (authenticate
== NULL
|| !authenticate
->authenticated
) {
416 _eglLog(_EGL_FATAL
, "DRI2: failed to authenticate");
427 dri2_add_configs_for_visuals(struct dri2_egl_display
*dri2_dpy
,
430 xcb_screen_iterator_t s
;
431 xcb_depth_iterator_t d
;
432 xcb_visualtype_t
*visuals
;
435 EGLint config_attrs
[] = {
436 EGL_NATIVE_VISUAL_ID
, 0,
437 EGL_NATIVE_VISUAL_TYPE
, 0,
441 s
= xcb_setup_roots_iterator(xcb_get_setup(dri2_dpy
->conn
));
442 d
= xcb_screen_allowed_depths_iterator(s
.data
);
449 EGL_SWAP_BEHAVIOR_PRESERVED_BIT
;
452 EGLBoolean class_added
[6] = { 0, };
454 visuals
= xcb_depth_visuals(d
.data
);
455 for (i
= 0; i
< xcb_depth_visuals_length(d
.data
); i
++) {
456 if (class_added
[visuals
[i
]._class
])
459 class_added
[visuals
[i
]._class
] = EGL_TRUE
;
460 for (j
= 0; dri2_dpy
->driver_configs
[j
]; j
++) {
461 config_attrs
[1] = visuals
[i
].visual_id
;
462 config_attrs
[3] = visuals
[i
]._class
;
464 dri2_add_config(disp
, dri2_dpy
->driver_configs
[j
], id
++,
465 d
.data
->depth
, surface_type
, config_attrs
);
472 if (!_eglGetArraySize(disp
->Configs
)) {
473 _eglLog(_EGL_WARNING
, "DRI2: failed to create any config");
481 dri2_copy_region(_EGLDriver
*drv
, _EGLDisplay
*disp
,
482 _EGLSurface
*draw
, xcb_xfixes_region_t region
)
484 struct dri2_egl_driver
*dri2_drv
= dri2_egl_driver(drv
);
485 struct dri2_egl_display
*dri2_dpy
= dri2_egl_display(disp
);
486 struct dri2_egl_surface
*dri2_surf
= dri2_egl_surface(draw
);
488 enum xcb_dri2_attachment_t render_attachment
;
489 xcb_dri2_copy_region_cookie_t cookie
;
491 if (dri2_drv
->glFlush
) {
492 ctx
= _eglGetCurrentContext();
493 if (ctx
&& ctx
->DrawSurface
== &dri2_surf
->base
)
497 (*dri2_dpy
->flush
->flush
)(dri2_surf
->dri_drawable
);
500 /* FIXME: Add support for dri swapbuffers, that'll give us swap
501 * interval and page flipping (at least for fullscreen windows) as
502 * well as the page flip event. Unless surface->SwapBehavior is
503 * EGL_BUFFER_PRESERVED. */
504 #if __DRI2_FLUSH_VERSION >= 2
506 (*pdraw
->psc
->f
->flushInvalidate
)(pdraw
->driDrawable
);
510 if (dri2_surf
->have_fake_front
)
511 render_attachment
= XCB_DRI2_ATTACHMENT_BUFFER_FAKE_FRONT_LEFT
;
513 render_attachment
= XCB_DRI2_ATTACHMENT_BUFFER_BACK_LEFT
;
515 cookie
= xcb_dri2_copy_region_unchecked(dri2_dpy
->conn
,
518 XCB_DRI2_ATTACHMENT_BUFFER_FRONT_LEFT
,
520 free(xcb_dri2_copy_region_reply(dri2_dpy
->conn
, cookie
, NULL
));
526 dri2_swap_buffers(_EGLDriver
*drv
, _EGLDisplay
*disp
, _EGLSurface
*draw
)
528 struct dri2_egl_surface
*dri2_surf
= dri2_egl_surface(draw
);
530 return dri2_copy_region(drv
, disp
, draw
, dri2_surf
->region
);
534 dri2_swap_buffers_region(_EGLDriver
*drv
, _EGLDisplay
*disp
, _EGLSurface
*draw
,
535 EGLint numRects
, const EGLint
*rects
)
537 struct dri2_egl_display
*dri2_dpy
= dri2_egl_display(disp
);
538 struct dri2_egl_surface
*dri2_surf
= dri2_egl_surface(draw
);
540 xcb_xfixes_region_t region
;
541 xcb_rectangle_t rectangles
[16];
544 if (numRects
> (int)ARRAY_SIZE(rectangles
))
545 return dri2_copy_region(drv
, disp
, draw
, dri2_surf
->region
);
547 /* FIXME: Invert y here? */
548 for (i
= 0; i
< numRects
; i
++) {
549 rectangles
[i
].x
= rects
[i
* 4];
550 rectangles
[i
].y
= rects
[i
* 4 + 1];
551 rectangles
[i
].width
= rects
[i
* 4 + 2];
552 rectangles
[i
].height
= rects
[i
* 4 + 3];
555 region
= xcb_generate_id(dri2_dpy
->conn
);
556 xcb_xfixes_create_region(dri2_dpy
->conn
, region
, numRects
, rectangles
);
557 ret
= dri2_copy_region(drv
, disp
, draw
, region
);
558 xcb_xfixes_destroy_region(dri2_dpy
->conn
, region
);
564 dri2_copy_buffers(_EGLDriver
*drv
, _EGLDisplay
*disp
, _EGLSurface
*surf
,
565 EGLNativePixmapType target
)
567 struct dri2_egl_display
*dri2_dpy
= dri2_egl_display(disp
);
568 struct dri2_egl_surface
*dri2_surf
= dri2_egl_surface(surf
);
573 (*dri2_dpy
->flush
->flush
)(dri2_surf
->dri_drawable
);
575 gc
= xcb_generate_id(dri2_dpy
->conn
);
576 xcb_create_gc(dri2_dpy
->conn
, gc
, target
, 0, NULL
);
577 xcb_copy_area(dri2_dpy
->conn
,
583 dri2_surf
->base
.Width
,
584 dri2_surf
->base
.Height
);
585 xcb_free_gc(dri2_dpy
->conn
, gc
);
591 dri2_create_image_khr_pixmap(_EGLDisplay
*disp
, _EGLContext
*ctx
,
592 EGLClientBuffer buffer
, const EGLint
*attr_list
)
594 struct dri2_egl_display
*dri2_dpy
= dri2_egl_display(disp
);
595 struct dri2_egl_image
*dri2_img
;
596 unsigned int attachments
[1];
597 xcb_drawable_t drawable
;
598 xcb_dri2_get_buffers_cookie_t buffers_cookie
;
599 xcb_dri2_get_buffers_reply_t
*buffers_reply
;
600 xcb_dri2_dri2_buffer_t
*buffers
;
601 xcb_get_geometry_cookie_t geometry_cookie
;
602 xcb_get_geometry_reply_t
*geometry_reply
;
603 xcb_generic_error_t
*error
;
608 drawable
= (xcb_drawable_t
) buffer
;
609 xcb_dri2_create_drawable (dri2_dpy
->conn
, drawable
);
610 attachments
[0] = XCB_DRI2_ATTACHMENT_BUFFER_FRONT_LEFT
;
612 xcb_dri2_get_buffers_unchecked (dri2_dpy
->conn
,
613 drawable
, 1, 1, attachments
);
614 geometry_cookie
= xcb_get_geometry (dri2_dpy
->conn
, drawable
);
615 buffers_reply
= xcb_dri2_get_buffers_reply (dri2_dpy
->conn
,
616 buffers_cookie
, NULL
);
617 buffers
= xcb_dri2_get_buffers_buffers (buffers_reply
);
618 if (buffers
== NULL
) {
622 geometry_reply
= xcb_get_geometry_reply (dri2_dpy
->conn
,
623 geometry_cookie
, &error
);
624 if (geometry_reply
== NULL
|| error
!= NULL
) {
625 _eglError(EGL_BAD_ALLOC
, "xcb_get_geometry");
630 switch (geometry_reply
->depth
) {
632 format
= __DRI_IMAGE_FORMAT_RGB565
;
635 format
= __DRI_IMAGE_FORMAT_XRGB8888
;
638 format
= __DRI_IMAGE_FORMAT_ARGB8888
;
641 _eglError(EGL_BAD_PARAMETER
,
642 "dri2_create_image_khr: unsupported pixmap depth");
644 free(geometry_reply
);
648 dri2_img
= malloc(sizeof *dri2_img
);
651 free(geometry_reply
);
652 _eglError(EGL_BAD_ALLOC
, "dri2_create_image_khr");
653 return EGL_NO_IMAGE_KHR
;
656 if (!_eglInitImage(&dri2_img
->base
, disp
)) {
658 free(geometry_reply
);
659 return EGL_NO_IMAGE_KHR
;
662 stride
= buffers
[0].pitch
/ buffers
[0].cpp
;
663 dri2_img
->dri_image
=
664 dri2_dpy
->image
->createImageFromName(dri2_dpy
->dri_screen
,
665 buffers_reply
->width
,
666 buffers_reply
->height
,
673 free(geometry_reply
);
675 return &dri2_img
->base
;
679 dri2_x11_create_image_khr(_EGLDriver
*drv
, _EGLDisplay
*disp
,
680 _EGLContext
*ctx
, EGLenum target
,
681 EGLClientBuffer buffer
, const EGLint
*attr_list
)
686 case EGL_NATIVE_PIXMAP_KHR
:
687 return dri2_create_image_khr_pixmap(disp
, ctx
, buffer
, attr_list
);
689 return dri2_create_image_khr(drv
, disp
, ctx
, target
, buffer
, attr_list
);
694 dri2_initialize_x11(_EGLDriver
*drv
, _EGLDisplay
*disp
)
696 struct dri2_egl_display
*dri2_dpy
;
698 drv
->API
.CreateWindowSurface
= dri2_create_window_surface
;
699 drv
->API
.CreatePixmapSurface
= dri2_create_pixmap_surface
;
700 drv
->API
.CreatePbufferSurface
= dri2_create_pbuffer_surface
;
701 drv
->API
.DestroySurface
= dri2_destroy_surface
;
702 drv
->API
.SwapBuffers
= dri2_swap_buffers
;
703 drv
->API
.CopyBuffers
= dri2_copy_buffers
;
704 drv
->API
.CreateImageKHR
= dri2_x11_create_image_khr
;
705 drv
->API
.SwapBuffersRegionNOK
= dri2_swap_buffers_region
;
707 dri2_dpy
= malloc(sizeof *dri2_dpy
);
709 return _eglError(EGL_BAD_ALLOC
, "eglInitialize");
711 disp
->DriverData
= (void *) dri2_dpy
;
712 if (disp
->PlatformDisplay
== NULL
) {
713 dri2_dpy
->conn
= xcb_connect(0, 0);
715 dri2_dpy
->conn
= XGetXCBConnection((Display
*) disp
->PlatformDisplay
);
718 if (xcb_connection_has_error(dri2_dpy
->conn
)) {
719 _eglLog(_EGL_WARNING
, "DRI2: xcb_connect failed");
723 if (dri2_dpy
->conn
) {
724 if (!dri2_connect(dri2_dpy
))
728 if (!dri2_load_driver(disp
))
731 dri2_dpy
->fd
= open(dri2_dpy
->device_name
, O_RDWR
);
732 if (dri2_dpy
->fd
== -1) {
733 _eglLog(_EGL_WARNING
,
734 "DRI2: could not open %s (%s)", dri2_dpy
->device_name
,
739 if (dri2_dpy
->conn
) {
740 if (!dri2_authenticate(dri2_dpy
))
744 if (dri2_dpy
->dri2_minor
>= 1) {
745 dri2_dpy
->dri2_loader_extension
.base
.name
= __DRI_DRI2_LOADER
;
746 dri2_dpy
->dri2_loader_extension
.base
.version
= 3;
747 dri2_dpy
->dri2_loader_extension
.getBuffers
= dri2_get_buffers
;
748 dri2_dpy
->dri2_loader_extension
.flushFrontBuffer
= dri2_flush_front_buffer
;
749 dri2_dpy
->dri2_loader_extension
.getBuffersWithFormat
=
750 dri2_get_buffers_with_format
;
752 dri2_dpy
->dri2_loader_extension
.base
.name
= __DRI_DRI2_LOADER
;
753 dri2_dpy
->dri2_loader_extension
.base
.version
= 2;
754 dri2_dpy
->dri2_loader_extension
.getBuffers
= dri2_get_buffers
;
755 dri2_dpy
->dri2_loader_extension
.flushFrontBuffer
= dri2_flush_front_buffer
;
756 dri2_dpy
->dri2_loader_extension
.getBuffersWithFormat
= NULL
;
759 dri2_dpy
->extensions
[0] = &dri2_dpy
->dri2_loader_extension
.base
;
760 dri2_dpy
->extensions
[1] = &image_lookup_extension
.base
;
761 dri2_dpy
->extensions
[2] = NULL
;
763 if (!dri2_create_screen(disp
))
766 if (dri2_dpy
->conn
) {
767 if (!dri2_add_configs_for_visuals(dri2_dpy
, disp
))
768 goto cleanup_configs
;
771 disp
->Extensions
.MESA_drm_image
= EGL_TRUE
;
772 disp
->Extensions
.KHR_image_base
= EGL_TRUE
;
773 disp
->Extensions
.KHR_image_pixmap
= EGL_TRUE
;
774 disp
->Extensions
.KHR_gl_renderbuffer_image
= EGL_TRUE
;
775 disp
->Extensions
.KHR_gl_texture_2D_image
= EGL_TRUE
;
776 disp
->Extensions
.NOK_swap_region
= EGL_TRUE
;
777 disp
->Extensions
.NOK_texture_from_pixmap
= EGL_TRUE
;
779 /* we're supporting EGL 1.4 */
780 disp
->VersionMajor
= 1;
781 disp
->VersionMinor
= 4;
786 _eglCleanupDisplay(disp
);
787 dri2_dpy
->core
->destroyScreen(dri2_dpy
->dri_screen
);
791 dlclose(dri2_dpy
->driver
);
793 if (disp
->PlatformDisplay
== NULL
)
794 xcb_disconnect(dri2_dpy
->conn
);