diff --git a/libweston/renderer-gl/egl-glue.c b/libweston/renderer-gl/egl-glue.c index 28be4ffe..013172af 100644 --- a/libweston/renderer-gl/egl-glue.c +++ b/libweston/renderer-gl/egl-glue.c @@ -455,6 +455,45 @@ gl_renderer_get_egl_config(struct gl_renderer *gr, return egl_config; } +static void +gl_renderer_set_egl_device(struct gl_renderer *gr) +{ + EGLAttrib attrib; + const char *extensions; + + assert(gr->has_device_query); + + if (!gr->query_display_attrib(gr->egl_display, EGL_DEVICE_EXT, &attrib)) { + weston_log("failed to get EGL device\n"); + gl_renderer_print_egl_error_state(); + return; + } + + gr->egl_device = (EGLDeviceEXT) attrib; + + extensions = gr->query_device_string(gr->egl_device, EGL_EXTENSIONS); + if (!extensions) { + weston_log("failed to get EGL extensions\n"); + return; + } + + gl_renderer_log_extensions("EGL device extensions", extensions); + + /* Try to query the render node using EGL_DRM_RENDER_NODE_FILE_EXT */ + if (weston_check_egl_extension(extensions, "EGL_EXT_device_drm_render_node")) + gr->drm_device = gr->query_device_string(gr->egl_device, + EGL_DRM_RENDER_NODE_FILE_EXT); + + /* The extension is not supported by the Mesa version of the system or + * the query failed. Fallback to EGL_DRM_DEVICE_FILE_EXT */ + if (!gr->drm_device && weston_check_egl_extension(extensions, "EGL_EXT_device_drm")) + gr->drm_device = gr->query_device_string(gr->egl_device, + EGL_DRM_DEVICE_FILE_EXT); + + if (!gr->drm_device) + weston_log("failed to query DRM device from EGL\n"); +} + int gl_renderer_setup_egl_display(struct gl_renderer *gr, void *native_display) @@ -484,6 +523,9 @@ gl_renderer_setup_egl_display(struct gl_renderer *gr, goto fail; } + if (gr->has_device_query) + gl_renderer_set_egl_device(gr); + return 0; fail: @@ -534,6 +576,14 @@ gl_renderer_setup_egl_client_extensions(struct gl_renderer *gr) gl_renderer_log_extensions("EGL client extensions", extensions); + if (weston_check_egl_extension(extensions, "EGL_EXT_device_query")) { + gr->query_display_attrib = + (void *) eglGetProcAddress("eglQueryDisplayAttribEXT"); + gr->query_device_string = + (void *) eglGetProcAddress("eglQueryDeviceStringEXT"); + gr->has_device_query = true; + } + if (weston_check_egl_extension(extensions, "EGL_EXT_platform_base")) { gr->get_platform_display = (void *) eglGetProcAddress("eglGetPlatformDisplayEXT"); diff --git a/libweston/renderer-gl/gl-renderer-internal.h b/libweston/renderer-gl/gl-renderer-internal.h index 8dfdc9bf..72101b47 100644 --- a/libweston/renderer-gl/gl-renderer-internal.h +++ b/libweston/renderer-gl/gl-renderer-internal.h @@ -119,6 +119,9 @@ struct gl_renderer { struct wl_array vertices; struct wl_array vtxcnt; + EGLDeviceEXT egl_device; + const char *drm_device; + struct weston_drm_format_array supported_formats; PFNGLEGLIMAGETARGETTEXTURE2DOESPROC image_target_texture_2d; @@ -163,6 +166,10 @@ struct gl_renderer { PFNEGLQUERYDMABUFFORMATSEXTPROC query_dmabuf_formats; PFNEGLQUERYDMABUFMODIFIERSEXTPROC query_dmabuf_modifiers; + bool has_device_query; + PFNEGLQUERYDISPLAYATTRIBEXTPROC query_display_attrib; + PFNEGLQUERYDEVICESTRINGEXTPROC query_device_string; + bool has_native_fence_sync; PFNEGLCREATESYNCKHRPROC create_sync; PFNEGLDESTROYSYNCKHRPROC destroy_sync; diff --git a/shared/weston-egl-ext.h b/shared/weston-egl-ext.h index ac308ba4..822810f4 100644 --- a/shared/weston-egl-ext.h +++ b/shared/weston-egl-ext.h @@ -143,6 +143,38 @@ typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYDMABUFFORMATSEXTPROC) (EGLDisplay dp typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYDMABUFMODIFIERSEXTPROC) (EGLDisplay dpy, EGLint format, EGLint max_modifiers, EGLuint64KHR *modifiers, EGLBoolean *external_only, EGLint *num_modifiers); #endif +/* Define tokens from EGL_EXT_device_base */ +#ifndef EGL_EXT_device_base +#define EGL_EXT_device_base 1 +typedef void *EGLDeviceEXT; +#define EGL_NO_DEVICE_EXT EGL_CAST(EGLDeviceEXT,0) +#define EGL_BAD_DEVICE_EXT 0x322B +#define EGL_DEVICE_EXT 0x322C +typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYDEVICEATTRIBEXTPROC) (EGLDeviceEXT device, EGLint attribute, EGLAttrib *value); +typedef const char *(EGLAPIENTRYP PFNEGLQUERYDEVICESTRINGEXTPROC) (EGLDeviceEXT device, EGLint name); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYDEVICESEXTPROC) (EGLint max_devices, EGLDeviceEXT *devices, EGLint *num_devices); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYDISPLAYATTRIBEXTPROC) (EGLDisplay dpy, EGLint attribute, EGLAttrib *value); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglQueryDeviceAttribEXT (EGLDeviceEXT device, EGLint attribute, EGLAttrib *value); +EGLAPI const char *EGLAPIENTRY eglQueryDeviceStringEXT (EGLDeviceEXT device, EGLint name); +EGLAPI EGLBoolean EGLAPIENTRY eglQueryDevicesEXT (EGLint max_devices, EGLDeviceEXT *devices, EGLint *num_devices); +EGLAPI EGLBoolean EGLAPIENTRY eglQueryDisplayAttribEXT (EGLDisplay dpy, EGLint attribute, EGLAttrib *value); +#endif +#endif /* EGL_EXT_device_base */ + +/* Define tokens from EGL_EXT_device_drm */ +#ifndef EGL_EXT_device_drm +#define EGL_EXT_device_drm 1 +#define EGL_DRM_DEVICE_FILE_EXT 0x3233 +#define EGL_DRM_MASTER_FD_EXT 0x333C +#endif /* EGL_EXT_device_drm */ + +/* Define tokens from EGL_EXT_device_drm_render_node */ +#ifndef EGL_EXT_device_drm_render_node +#define EGL_EXT_device_drm_render_node 1 +#define EGL_DRM_RENDER_NODE_FILE_EXT 0x3377 +#endif /* EGL_EXT_device_drm_render_node */ + #ifndef EGL_EXT_swap_buffers_with_damage #define EGL_EXT_swap_buffers_with_damage 1 typedef EGLBoolean (EGLAPIENTRYP PFNEGLSWAPBUFFERSWITHDAMAGEEXTPROC) (EGLDisplay dpy, EGLSurface surface, EGLint *rects, EGLint n_rects);