diff options
author | Boyan Ding <boyan.j.ding@gmail.com> | 2015-07-21 23:44:00 +0800 |
---|---|---|
committer | Martin Peres <martin.peres@linux.intel.com> | 2015-11-17 17:26:20 +0200 |
commit | f35198badeb956a8f435727d805a47c7e42610d0 (patch) | |
tree | 055cc089ff20ad8101c632f4c2d9612f1c7684bf /src/egl/drivers/dri2/platform_x11.c | |
parent | a25df5457121d40fef86929d4c10d8058a4d5c72 (diff) | |
download | external_mesa3d-f35198badeb956a8f435727d805a47c7e42610d0.zip external_mesa3d-f35198badeb956a8f435727d805a47c7e42610d0.tar.gz external_mesa3d-f35198badeb956a8f435727d805a47c7e42610d0.tar.bz2 |
egl/x11: Implement dri3 support with loader's dri3 helper
v2: From Martin Peres
- Tell we are compiling the dri3 backend in configure.ac
- Update the Makefile.am
- get rid of the LIBDRM_HAS_RENDERNODE_SUPPORT macro
- fix some warnings related to EGLuint64KHR to int64_t conversions
- use dri2_get_dri_config to get the __DRIconfig instead of open-coding it
- replace the occasional tabs with spaces
v3: From Martin Peres
- fix and indent problem (Matt Turner)
- drop the authenticate function, use NULL in the vtable instead (Emil)
- drop some useless includes (Emil Velikov)
- mandate libdrm (Emil Velikov)
- link to xcb-dri3 (Kristian Høgsberg)
- convert to the new loader interface for drwable (Kristian)
- remove some dead code after the dropping of some vfuncs (Kristian)
- add a comment on the topic of rendering to the frontbuffer
v4: From Martin Peres
- do not expose the preserved swap behavior (Acked by Eric Anholt)
Signed-off-by: Boyan Ding <boyan.j.ding@gmail.com>
Signed-off-by: Martin Peres <martin.peres@linux.intel.com>
Reviewed-by: Kristian Høgsberg <krh@bitplanet.net>
Reviewed-by: Emil Velikov <emil.velikov@collabora.co.uk>
Diffstat (limited to 'src/egl/drivers/dri2/platform_x11.c')
-rw-r--r-- | src/egl/drivers/dri2/platform_x11.c | 117 |
1 files changed, 110 insertions, 7 deletions
diff --git a/src/egl/drivers/dri2/platform_x11.c b/src/egl/drivers/dri2/platform_x11.c index e75dcb9..d291b47 100644 --- a/src/egl/drivers/dri2/platform_x11.c +++ b/src/egl/drivers/dri2/platform_x11.c @@ -45,6 +45,10 @@ #include "egl_dri2_fallbacks.h" #include "loader.h" +#ifdef HAVE_DRI3 +#include "platform_x11_dri3.h" +#endif + static EGLBoolean dri2_x11_swap_interval(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surf, EGLint interval); @@ -703,7 +707,7 @@ dri2_x11_local_authenticate(_EGLDisplay *disp) static EGLBoolean dri2_x11_add_configs_for_visuals(struct dri2_egl_display *dri2_dpy, - _EGLDisplay *disp) + _EGLDisplay *disp, bool supports_preserved) { xcb_screen_iterator_t s; xcb_depth_iterator_t d; @@ -724,8 +728,10 @@ dri2_x11_add_configs_for_visuals(struct dri2_egl_display *dri2_dpy, surface_type = EGL_WINDOW_BIT | EGL_PIXMAP_BIT | - EGL_PBUFFER_BIT | - EGL_SWAP_BEHAVIOR_PRESERVED_BIT; + EGL_PBUFFER_BIT; + + if (supports_preserved) + surface_type |= EGL_SWAP_BEHAVIOR_PRESERVED_BIT; while (d.rem > 0) { EGLBoolean class_added[6] = { 0, }; @@ -1181,7 +1187,7 @@ dri2_initialize_x11_swrast(_EGLDriver *drv, _EGLDisplay *disp) if (!dri2_create_screen(disp)) goto cleanup_driver; - if (!dri2_x11_add_configs_for_visuals(dri2_dpy, disp)) + if (!dri2_x11_add_configs_for_visuals(dri2_dpy, disp, true)) goto cleanup_configs; /* Fill vtbl last to prevent accidentally calling virtual function during @@ -1252,6 +1258,96 @@ dri2_x11_setup_swap_interval(struct dri2_egl_display *dri2_dpy) } } +#ifdef HAVE_DRI3 +static EGLBoolean +dri2_initialize_x11_dri3(_EGLDriver *drv, _EGLDisplay *disp) +{ + struct dri2_egl_display *dri2_dpy; + + dri2_dpy = calloc(1, sizeof *dri2_dpy); + if (!dri2_dpy) + return _eglError(EGL_BAD_ALLOC, "eglInitialize"); + + disp->DriverData = (void *) dri2_dpy; + if (disp->PlatformDisplay == NULL) { + dri2_dpy->conn = xcb_connect(0, &dri2_dpy->screen); + dri2_dpy->own_device = true; + } else { + Display *dpy = disp->PlatformDisplay; + + dri2_dpy->conn = XGetXCBConnection(dpy); + dri2_dpy->screen = DefaultScreen(dpy); + } + + if (xcb_connection_has_error(dri2_dpy->conn)) { + _eglLog(_EGL_WARNING, "DRI2: xcb_connect failed"); + goto cleanup_dpy; + } + + if (dri2_dpy->conn) { + if (!dri3_x11_connect(dri2_dpy)) + goto cleanup_conn; + } + + if (!dri2_load_driver_dri3(disp)) + goto cleanup_conn; + + dri2_dpy->extensions[0] = &dri3_image_loader_extension.base; + dri2_dpy->extensions[1] = &use_invalidate.base; + dri2_dpy->extensions[2] = &image_lookup_extension.base; + dri2_dpy->extensions[3] = NULL; + + dri2_dpy->swap_available = true; + dri2_dpy->invalidate_available = true; + + if (!dri2_create_screen(disp)) + goto cleanup_fd; + + dri2_x11_setup_swap_interval(dri2_dpy); + + disp->Extensions.NOK_texture_from_pixmap = EGL_TRUE; + disp->Extensions.CHROMIUM_sync_control = EGL_TRUE; + disp->Extensions.EXT_buffer_age = EGL_TRUE; + +#ifdef HAVE_WAYLAND_PLATFORM + disp->Extensions.WL_bind_wayland_display = EGL_TRUE; +#endif + + if (dri2_dpy->conn) { + if (!dri2_x11_add_configs_for_visuals(dri2_dpy, disp, false)) + goto cleanup_configs; + } + + dri2_dpy->loader_dri3_ext.core = dri2_dpy->core; + dri2_dpy->loader_dri3_ext.image_driver = dri2_dpy->image_driver; + dri2_dpy->loader_dri3_ext.flush = dri2_dpy->flush; + dri2_dpy->loader_dri3_ext.tex_buffer = dri2_dpy->tex_buffer; + dri2_dpy->loader_dri3_ext.image = dri2_dpy->image; + dri2_dpy->loader_dri3_ext.config = dri2_dpy->config; + + /* Fill vtbl last to prevent accidentally calling virtual function during + * initialization. + */ + dri2_dpy->vtbl = &dri3_x11_display_vtbl; + + return EGL_TRUE; + + cleanup_configs: + _eglCleanupDisplay(disp); + dri2_dpy->core->destroyScreen(dri2_dpy->dri_screen); + dlclose(dri2_dpy->driver); + cleanup_fd: + close(dri2_dpy->fd); + cleanup_conn: + if (disp->PlatformDisplay == NULL) + xcb_disconnect(dri2_dpy->conn); + cleanup_dpy: + free(dri2_dpy); + + return EGL_FALSE; +} +#endif + static EGLBoolean dri2_initialize_x11_dri2(_EGLDriver *drv, _EGLDisplay *disp) { @@ -1323,7 +1419,7 @@ dri2_initialize_x11_dri2(_EGLDriver *drv, _EGLDisplay *disp) disp->Extensions.WL_bind_wayland_display = EGL_TRUE; #endif - if (!dri2_x11_add_configs_for_visuals(dri2_dpy, disp)) + if (!dri2_x11_add_configs_for_visuals(dri2_dpy, disp, true)) goto cleanup_configs; /* Fill vtbl last to prevent accidentally calling virtual function during @@ -1357,9 +1453,16 @@ dri2_initialize_x11(_EGLDriver *drv, _EGLDisplay *disp) int x11_dri2_accel = (getenv("LIBGL_ALWAYS_SOFTWARE") == NULL); if (x11_dri2_accel) { - if (!dri2_initialize_x11_dri2(drv, disp)) { - initialized = dri2_initialize_x11_swrast(drv, disp); +#ifdef HAVE_DRI3 + if (getenv("LIBGL_DRI3_DISABLE") != NULL || + !dri2_initialize_x11_dri3(drv, disp)) { +#endif + if (!dri2_initialize_x11_dri2(drv, disp)) { + initialized = dri2_initialize_x11_swrast(drv, disp); + } +#ifdef HAVE_DRI3 } +#endif } else { initialized = dri2_initialize_x11_swrast(drv, disp); } |