From f9787ba482467622c51ba88fc4541b9f578e1b55 Mon Sep 17 00:00:00 2001 From: Scott Anderson Date: Mon, 18 Jan 2021 18:10:58 -0300 Subject: [PATCH] gl-renderer: query DRM device given an EGLDisplay Add function to query the DRM device given an EGLDisplay. It is the device being used by the compositor to perform composition. This will be useful in the next commits of this series, where we add support for dma-buf feedback. Signed-off-by: Scott Anderson Signed-off-by: Leandro Ribeiro Reviewed-by: Daniel Stone --- libweston/renderer-gl/egl-glue.c | 50 ++++++++++++++++++++ libweston/renderer-gl/gl-renderer-internal.h | 7 +++ shared/weston-egl-ext.h | 32 +++++++++++++ 3 files changed, 89 insertions(+) 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);