mirror of
https://github.com/brl/mutter.git
synced 2024-12-23 19:42:05 +00:00
wayland: check for egl extensions explicitly
eglGetProcAddress() returns non-null function pointers whether or not they're actually supported by the driver, since it can be used before any driver gets loaded. So we have to check if the extensions are advertised first, which requires having an initialized display, so we split the display creation code into its own function. The exception to extension-checking is EGL_MESA_drm_display, since by definition it's needed before any display is even created.
This commit is contained in:
parent
e855bc45a2
commit
20b1350614
@ -181,12 +181,43 @@ display_handle_global (struct wl_display *display,
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
try_get_display (ClutterBackendWayland *backend_wayland, GError **error)
|
||||
{
|
||||
EGLDisplay edpy = EGL_NO_DISPLAY;
|
||||
int drm_fd;
|
||||
|
||||
drm_fd = open (backend_wayland->device_name, O_RDWR);
|
||||
|
||||
backend_wayland->get_drm_display =
|
||||
(PFNEGLGETDRMDISPLAYMESA) eglGetProcAddress ("eglGetDRMDisplayMESA");
|
||||
|
||||
if (backend_wayland->get_drm_display != NULL && drm_fd >= 0)
|
||||
edpy = backend_wayland->get_drm_display (drm_fd);
|
||||
|
||||
if (edpy == EGL_NO_DISPLAY)
|
||||
edpy = eglGetDisplay(EGL_DEFAULT_DISPLAY);
|
||||
|
||||
if (edpy == EGL_NO_DISPLAY)
|
||||
{
|
||||
g_set_error (error, CLUTTER_INIT_ERROR,
|
||||
CLUTTER_INIT_ERROR_BACKEND,
|
||||
"Failed to open EGLDisplay");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
backend_wayland->edpy = edpy;
|
||||
backend_wayland->drm_fd = drm_fd;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
try_enable_drm (ClutterBackendWayland *backend_wayland, GError **error)
|
||||
{
|
||||
drm_magic_t magic;
|
||||
const gchar *exts, *glexts;
|
||||
|
||||
backend_wayland->drm_fd = open (backend_wayland->device_name, O_RDWR);
|
||||
if (backend_wayland->drm_fd < 0)
|
||||
{
|
||||
g_set_error (error, CLUTTER_INIT_ERROR,
|
||||
@ -195,6 +226,39 @@ try_enable_drm (ClutterBackendWayland *backend_wayland, GError **error)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
glexts = glGetString(GL_EXTENSIONS);
|
||||
exts = eglQueryString (backend_wayland->edpy, EGL_EXTENSIONS);
|
||||
|
||||
if (!_cogl_check_extension ("EGL_KHR_image_base", exts) ||
|
||||
!_cogl_check_extension ("EGL_MESA_drm_image", exts) ||
|
||||
!_cogl_check_extension ("GL_OES_EGL_image", glexts))
|
||||
{
|
||||
g_set_error (error, CLUTTER_INIT_ERROR,
|
||||
CLUTTER_INIT_ERROR_BACKEND,
|
||||
"Missing EGL extensions");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
backend_wayland->create_drm_image =
|
||||
(PFNEGLCREATEDRMIMAGEMESA) eglGetProcAddress ("eglCreateDRMImageMESA");
|
||||
backend_wayland->destroy_image =
|
||||
(PFNEGLDESTROYIMAGEKHRPROC) eglGetProcAddress ("eglDestroyImageKHR");
|
||||
backend_wayland->export_drm_image =
|
||||
(PFNEGLEXPORTDRMIMAGEMESA) eglGetProcAddress ("eglExportDRMImageMESA");
|
||||
backend_wayland->image_target_texture_2d =
|
||||
(PFNGLEGLIMAGETARGETTEXTURE2DOESPROC) eglGetProcAddress ("glEGLImageTargetTexture2DOES");
|
||||
|
||||
if (backend_wayland->create_drm_image == NULL ||
|
||||
backend_wayland->destroy_image == NULL ||
|
||||
backend_wayland->export_drm_image == NULL ||
|
||||
backend_wayland->image_target_texture_2d == NULL)
|
||||
{
|
||||
g_set_error (error, CLUTTER_INIT_ERROR,
|
||||
CLUTTER_INIT_ERROR_BACKEND,
|
||||
"Missing EGL extensions");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (drmGetMagic (backend_wayland->drm_fd, &magic))
|
||||
{
|
||||
g_set_error (error, CLUTTER_INIT_ERROR,
|
||||
@ -208,32 +272,6 @@ try_enable_drm (ClutterBackendWayland *backend_wayland, GError **error)
|
||||
while (!backend_wayland->authenticated)
|
||||
wl_display_iterate (backend_wayland->wayland_display, WL_DISPLAY_READABLE);
|
||||
|
||||
backend_wayland->get_drm_display =
|
||||
(PFNEGLGETDRMDISPLAYMESA) eglGetProcAddress ("eglGetDRMDisplayMESA");
|
||||
backend_wayland->create_drm_image =
|
||||
(PFNEGLCREATEDRMIMAGEMESA) eglGetProcAddress ("eglCreateDRMImageMESA");
|
||||
backend_wayland->destroy_image =
|
||||
(PFNEGLDESTROYIMAGEKHRPROC) eglGetProcAddress ("eglDestroyImageKHR");
|
||||
backend_wayland->export_drm_image =
|
||||
(PFNEGLEXPORTDRMIMAGEMESA) eglGetProcAddress ("eglExportDRMImageMESA");
|
||||
backend_wayland->image_target_texture_2d =
|
||||
(PFNGLEGLIMAGETARGETTEXTURE2DOESPROC) eglGetProcAddress ("glEGLImageTargetTexture2DOES");
|
||||
|
||||
if (backend_wayland->get_drm_display == NULL ||
|
||||
backend_wayland->create_drm_image == NULL ||
|
||||
backend_wayland->destroy_image == NULL ||
|
||||
backend_wayland->export_drm_image == NULL ||
|
||||
backend_wayland->image_target_texture_2d == NULL)
|
||||
{
|
||||
g_set_error (error, CLUTTER_INIT_ERROR,
|
||||
CLUTTER_INIT_ERROR_BACKEND,
|
||||
"Missing EGL extensions");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
backend_wayland->edpy =
|
||||
backend_wayland->get_drm_display (backend_wayland->drm_fd);
|
||||
|
||||
return TRUE;
|
||||
};
|
||||
|
||||
@ -268,17 +306,9 @@ clutter_backend_wayland_post_parse (ClutterBackend *backend,
|
||||
/* Process connection events. */
|
||||
wl_display_iterate (backend_wayland->wayland_display, WL_DISPLAY_READABLE);
|
||||
|
||||
backend_wayland->drm_enabled = try_enable_drm(backend_wayland, error);
|
||||
|
||||
if (!backend_wayland->drm_enabled) {
|
||||
if (backend_wayland->wayland_shm == NULL)
|
||||
if (!try_get_display(backend_wayland, error))
|
||||
return FALSE;
|
||||
|
||||
g_debug("Could not enable DRM buffers, falling back to SHM buffers");
|
||||
g_clear_error(error);
|
||||
backend_wayland->edpy = eglGetDisplay(EGL_DEFAULT_DISPLAY);
|
||||
}
|
||||
|
||||
status = eglInitialize (backend_wayland->edpy,
|
||||
&backend_wayland->egl_version_major,
|
||||
&backend_wayland->egl_version_minor);
|
||||
@ -294,6 +324,16 @@ clutter_backend_wayland_post_parse (ClutterBackend *backend,
|
||||
backend_wayland->egl_version_major,
|
||||
backend_wayland->egl_version_minor);
|
||||
|
||||
backend_wayland->drm_enabled = try_enable_drm(backend_wayland, error);
|
||||
|
||||
if (!backend_wayland->drm_enabled) {
|
||||
if (backend_wayland->wayland_shm == NULL)
|
||||
return FALSE;
|
||||
|
||||
g_debug("Could not enable DRM buffers, falling back to SHM buffers");
|
||||
g_clear_error(error);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@ -612,6 +652,7 @@ _clutter_backend_wayland_class_init (ClutterBackendWaylandClass *klass)
|
||||
static void
|
||||
_clutter_backend_wayland_init (ClutterBackendWayland *backend_wayland)
|
||||
{
|
||||
backend_wayland->edpy = EGL_NO_DISPLAY;
|
||||
backend_wayland->egl_context = EGL_NO_CONTEXT;
|
||||
|
||||
backend_wayland->drm_fd = -1;
|
||||
|
Loading…
Reference in New Issue
Block a user