From eed2f8f9f5bff79ad9cfd7c248ca6c05b42f34f8 Mon Sep 17 00:00:00 2001 From: Scott Anderson Date: Thu, 19 Dec 2019 17:18:44 +1300 Subject: [PATCH 1/6] linux-dmabuf: Use designated initializer for interfaces Signed-off-by: Scott Anderson --- libweston/linux-dmabuf.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/libweston/linux-dmabuf.c b/libweston/linux-dmabuf.c index 796e98266..4084ab192 100644 --- a/libweston/linux-dmabuf.c +++ b/libweston/linux-dmabuf.c @@ -340,10 +340,10 @@ params_create_immed(struct wl_client *client, static const struct zwp_linux_buffer_params_v1_interface zwp_linux_buffer_params_implementation = { - params_destroy, - params_add, - params_create, - params_create_immed + .destroy = params_destroy, + .add = params_add, + .create = params_create, + .create_immed = params_create_immed }; static void @@ -467,8 +467,8 @@ linux_dmabuf_buffer_get_user_data(struct linux_dmabuf_buffer *buffer) } static const struct zwp_linux_dmabuf_v1_interface linux_dmabuf_implementation = { - linux_dmabuf_destroy, - linux_dmabuf_create_params + .destroy = linux_dmabuf_destroy, + .create_params = linux_dmabuf_create_params }; static void -- GitLab From bb552cff90ca7837fcb06e81fbda9e87769d7688 Mon Sep 17 00:00:00 2001 From: Scott Anderson Date: Fri, 6 Mar 2020 16:37:06 +1300 Subject: [PATCH 2/6] linux-dmabuf: Add initial support for dmabuf-hints This bumps the supported zwp_linux_dmabuf_v1 to 4. All of the protocol boilerplate has been added, but does not send any useful hints yet, instead only immediately sending a 'done' event on binding. The dmabuf-hints specification mentions that all hints are optional, so this is still properly conforms to version 4. This adds `struct weston_hints` which is a type for managing hints and some functions which should be called by the backends and renderer when they want to advertise their preference for a format. Signed-off-by: Scott Anderson --- include/libweston/libweston.h | 56 ++++++++++ libweston/compositor.c | 8 ++ libweston/linux-dmabuf.c | 205 +++++++++++++++++++++++++++++++++- 3 files changed, 266 insertions(+), 3 deletions(-) diff --git a/include/libweston/libweston.h b/include/libweston/libweston.h index d036c5bba..11397b441 100644 --- a/include/libweston/libweston.h +++ b/include/libweston/libweston.h @@ -882,6 +882,58 @@ struct weston_plane { struct wl_list link; }; +enum weston_format_preference { + /* + * The backend is capable of directly scanning out a buffer with this + * format, in some situations. + */ + WESTON_FORMAT_PREFERENCE_SCANOUT = 0x10000000, + /* + * The renderer is capable of using a texturing from a buffer with this + * format. + */ + WESTON_FORMAT_PREFERENCE_RENDERER = 0x20000000, + + WESTON_FORMAT_PREFERENCE_INVALID = 0xffffffff, +}; + +struct weston_format { + /* + * Preference the compositor has for the client to use this format. + * Reported to the client via wp_linux_dmabuf_hints. Formats with the + * same preference are reported as part of the same dmabuf tranche. + * + * Lower values mean higher preference. + */ + uint32_t preference; + uint32_t format; + uint64_t modifier; +}; + +struct weston_hints { + dev_t device; + /* struct weston_format */ + struct wl_array formats; + + struct wl_list resource_list; +}; + +void +weston_hints_init(struct weston_hints *hints); + +void +weston_hints_destroy(struct weston_hints *hints); + +void +weston_hints_set_device(struct weston_hints *hints, dev_t device); + +void +weston_hints_add_format(struct weston_hints *hints, uint32_t preference, + uint32_t format, uint64_t modifier); + +void +weston_hints_send_done(struct weston_hints *hints); + struct weston_renderer { int (*read_pixels)(struct weston_output *output, pixman_format_code_t format, void *pixels, @@ -1123,6 +1175,8 @@ struct weston_compositor { struct weston_log_scope *timeline; struct content_protection *content_protection; + + struct weston_hints default_hints; }; struct weston_buffer { @@ -1481,6 +1535,8 @@ struct weston_surface { enum weston_hdcp_protection desired_protection; enum weston_hdcp_protection current_protection; enum weston_surface_protection_mode protection_mode; + + struct weston_hints hints; }; struct weston_subsurface { diff --git a/libweston/compositor.c b/libweston/compositor.c index 5fda94328..ee1ffbc48 100644 --- a/libweston/compositor.c +++ b/libweston/compositor.c @@ -571,6 +571,8 @@ weston_surface_create(struct weston_compositor *compositor) surface->current_protection = WESTON_HDCP_DISABLE; surface->protection_mode = WESTON_SURFACE_PROTECTION_MODE_RELAXED; + weston_hints_init(&surface->hints); + return surface; } @@ -2246,6 +2248,8 @@ weston_surface_destroy(struct weston_surface *surface) fd_clear(&surface->acquire_fence_fd); + weston_hints_destroy(&surface->hints); + free(surface); } @@ -7374,6 +7378,8 @@ weston_compositor_create(struct wl_display *display, wl_list_init(&ec->plugin_api_list); + weston_hints_init(&ec->default_hints); + weston_plane_init(&ec->primary_plane, ec, 0, 0); weston_compositor_stack_plane(ec, &ec->primary_plane, NULL); @@ -7757,6 +7763,8 @@ weston_compositor_destroy(struct weston_compositor *compositor) wl_signal_emit(&compositor->destroy_signal, compositor); + weston_hints_destroy(&compositor->default_hints); + weston_compositor_xkb_destroy(compositor); if (compositor->backend) diff --git a/libweston/linux-dmabuf.c b/libweston/linux-dmabuf.c index 4084ab192..ac86c12b8 100644 --- a/libweston/linux-dmabuf.c +++ b/libweston/linux-dmabuf.c @@ -26,9 +26,14 @@ #include "config.h" #include +#include +#include #include -#include +#include +#include #include +#include +#include #include #include "linux-dmabuf.h" @@ -394,6 +399,198 @@ err_out: wl_resource_post_no_memory(linux_dmabuf_resource); } +WL_EXPORT void +weston_hints_init(struct weston_hints *hints) +{ + wl_array_init(&hints->formats); + wl_list_init(&hints->resource_list); +} + +WL_EXPORT void +weston_hints_destroy(struct weston_hints *hints) +{ + struct wl_resource *res, *tmp; + + wl_resource_for_each_safe(res, tmp, &hints->resource_list) { + wl_resource_set_user_data(res, NULL); + wl_list_init(wl_resource_get_link(res)); + } + + wl_array_release(&hints->formats); +} + +WL_EXPORT void +weston_hints_set_device(struct weston_hints *hints, dev_t device) +{ + hints->device = device; +} + +WL_EXPORT void +weston_hints_add_format(struct weston_hints *hints, uint32_t preference, + uint32_t format, uint64_t modifier) +{ + struct weston_format *fmt; + + wl_array_for_each(fmt, &hints->formats) { + if (fmt->format == format && fmt->modifier == modifier) { + fmt->preference = preference; + return; + } + } + + fmt = wl_array_add(&hints->formats, sizeof(*fmt)); + if (!fmt) + return; + + fmt->preference = preference; + fmt->format = format; + fmt->modifier = modifier; +} + +static int +compare_format(const void *arg1, const void *arg2) +{ + const struct weston_format *l = arg1, *r = arg2; + if (l->preference < r->preference) + return -1; + else if (l->preference > r->preference) + return 1; + else if (l->format < r->format) + return -1; + else if (l->format > r->format) + return 1; + else if (l->modifier < r->modifier) + return -1; + else if (l->modifier > r->modifier) + return 1; + + assert(0 && "Duplicate format"); + return 0; +} + +static void +send_hints(struct weston_hints *hints, struct wl_resource *res) +{ + struct weston_format *fmt; + uint32_t prev_pref = WESTON_FORMAT_PREFERENCE_INVALID; + + if (hints->device) + zwp_linux_dmabuf_hints_v1_send_primary_device(res, + major(hints->device), + minor(hints->device)); + + wl_array_for_each(fmt, &hints->formats) { + uint32_t mod_lo = fmt->modifier & 0xffffffff; + uint32_t mod_hi = fmt->modifier >> 32; + + if (prev_pref != WESTON_FORMAT_PREFERENCE_INVALID && + prev_pref != fmt->preference) { + assert(fmt->preference > prev_pref); + zwp_linux_dmabuf_hints_v1_send_target_device(res, + major(hints->device), + minor(hints->device)); + zwp_linux_dmabuf_hints_v1_send_tranche(res); + } + + zwp_linux_dmabuf_hints_v1_send_modifier(res, fmt->format, + mod_hi, mod_lo); + + prev_pref = fmt->preference; + } + + if (prev_pref != WESTON_FORMAT_PREFERENCE_INVALID) { + zwp_linux_dmabuf_hints_v1_send_target_device(res, + major(hints->device), + minor(hints->device)); + zwp_linux_dmabuf_hints_v1_send_tranche(res); + } + + zwp_linux_dmabuf_hints_v1_send_done(res); +} + +WL_EXPORT void +weston_hints_send_done(struct weston_hints *hints) +{ + struct wl_resource *res; + size_t memb_size = sizeof(struct weston_format); + + qsort(hints->formats.data, hints->formats.size / memb_size, + memb_size, compare_format); + + wl_resource_for_each(res, &hints->resource_list) { + send_hints(hints, res); + } +} + +static void +hints_destroy(struct wl_client *client, struct wl_resource *resource) +{ + wl_resource_destroy(resource); +} + +static const struct zwp_linux_dmabuf_hints_v1_interface +zwp_linux_dmabuf_hints_implementation = { + .destroy = hints_destroy, +}; + +static void +destroy_hints(struct wl_resource *resource) +{ + wl_list_remove(wl_resource_get_link(resource)); +} + +static void +create_hints(struct wl_client *client, + struct wl_resource *dmabuf_resource, + uint32_t hints_id, + struct weston_hints *hints) +{ + struct wl_resource *res; + uint32_t version = wl_resource_get_version(dmabuf_resource); + + res = wl_resource_create(client, + &zwp_linux_dmabuf_hints_v1_interface, + version, hints_id); + if (!res) { + wl_resource_post_no_memory(dmabuf_resource); + return; + } + + wl_resource_set_implementation(res, + &zwp_linux_dmabuf_hints_implementation, + NULL, destroy_hints); + + wl_list_insert(&hints->resource_list, wl_resource_get_link(res)); + send_hints(hints, res); +} + +static void +linux_dmabuf_get_default_hints(struct wl_client *client, + struct wl_resource *dmabuf_resource, + uint32_t hints_id) +{ + struct weston_compositor *compositor; + + compositor = wl_resource_get_user_data(dmabuf_resource); + + create_hints(client, dmabuf_resource, hints_id, + &compositor->default_hints); +} + +static void +linux_dmabuf_get_surface_hints(struct wl_client *client, + struct wl_resource *dmabuf_resource, + uint32_t hints_id, + struct wl_resource *surface_resource) +{ + struct weston_surface *surface; + + surface = wl_resource_get_user_data(surface_resource); + + create_hints(client, dmabuf_resource, hints_id, + &surface->hints); +} + /** Get the linux_dmabuf_buffer from a wl_buffer resource * * If the given wl_buffer resource was created through the linux_dmabuf @@ -468,7 +665,9 @@ linux_dmabuf_buffer_get_user_data(struct linux_dmabuf_buffer *buffer) static const struct zwp_linux_dmabuf_v1_interface linux_dmabuf_implementation = { .destroy = linux_dmabuf_destroy, - .create_params = linux_dmabuf_create_params + .create_params = linux_dmabuf_create_params, + .get_default_hints = linux_dmabuf_get_default_hints, + .get_surface_hints = linux_dmabuf_get_surface_hints, }; static void @@ -547,7 +746,7 @@ WL_EXPORT int linux_dmabuf_setup(struct weston_compositor *compositor) { if (!wl_global_create(compositor->wl_display, - &zwp_linux_dmabuf_v1_interface, 3, + &zwp_linux_dmabuf_v1_interface, 4, compositor, bind_linux_dmabuf)) return -1; -- GitLab From 4bce544d367843a6be936736e2e28d1ac3cb063c Mon Sep 17 00:00:00 2001 From: Scott Anderson Date: Fri, 20 Dec 2019 15:15:12 +1300 Subject: [PATCH 3/6] gl-renderer: Add querying for EGL_EXT_device_query We will need this to query for DRM devices for dmabuf-hints later. Signed-off-by: Scott Anderson --- libweston/renderer-gl/egl-glue.c | 8 ++++++++ libweston/renderer-gl/gl-renderer-internal.h | 4 ++++ 2 files changed, 12 insertions(+) diff --git a/libweston/renderer-gl/egl-glue.c b/libweston/renderer-gl/egl-glue.c index 28be4ffe4..354139e7c 100644 --- a/libweston/renderer-gl/egl-glue.c +++ b/libweston/renderer-gl/egl-glue.c @@ -534,6 +534,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 6e1b095c2..b9ccd40fd 100644 --- a/libweston/renderer-gl/gl-renderer-internal.h +++ b/libweston/renderer-gl/gl-renderer-internal.h @@ -118,6 +118,10 @@ struct gl_renderer { bool has_wait_sync; PFNEGLWAITSYNCKHRPROC wait_sync; + + bool has_device_query; + PFNEGLQUERYDISPLAYATTRIBEXTPROC query_display_attrib; + PFNEGLQUERYDEVICESTRINGEXTPROC query_device_string; }; static inline struct gl_renderer * -- GitLab From a688998b5e00a319406ce26253097fb799eb45d4 Mon Sep 17 00:00:00 2001 From: Scott Anderson Date: Fri, 20 Dec 2019 15:30:23 +1300 Subject: [PATCH 4/6] gl-renderer: Add querying EGL from DRM device This will be required for the dmabuf-hints protocol. Also, this logs the EGL device extensions and the DRM device if found. Signed-off-by: Scott Anderson --- libweston/renderer-gl/egl-glue.c | 45 ++++++++++++++++++++ libweston/renderer-gl/gl-renderer-internal.h | 2 + 2 files changed, 47 insertions(+) diff --git a/libweston/renderer-gl/egl-glue.c b/libweston/renderer-gl/egl-glue.c index 354139e7c..898ee1b92 100644 --- a/libweston/renderer-gl/egl-glue.c +++ b/libweston/renderer-gl/egl-glue.c @@ -455,6 +455,48 @@ gl_renderer_get_egl_config(struct gl_renderer *gr, return egl_config; } +static void +setup_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"); + goto fail; + } + + gr->egl_device = (EGLDeviceEXT) attrib; + + extensions = gr->query_device_string(gr->egl_device, EGL_EXTENSIONS); + if (!extensions) { + weston_log("querying EGL device extensions failed\n"); + goto fail; + } + + gl_renderer_log_extensions("EGL device extensions", + extensions); + + if (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("EGL DRM device: %s\n", gr->drm_device); + else + weston_log("failed to query DRM device from EGL\n"); + } + + return; +fail: + gr->has_device_query = false; +} + int gl_renderer_setup_egl_display(struct gl_renderer *gr, void *native_display) @@ -484,6 +526,9 @@ gl_renderer_setup_egl_display(struct gl_renderer *gr, goto fail; } + if (gr->has_device_query) + setup_egl_device(gr); + return 0; fail: diff --git a/libweston/renderer-gl/gl-renderer-internal.h b/libweston/renderer-gl/gl-renderer-internal.h index b9ccd40fd..70e944270 100644 --- a/libweston/renderer-gl/gl-renderer-internal.h +++ b/libweston/renderer-gl/gl-renderer-internal.h @@ -49,8 +49,10 @@ struct gl_renderer { EGLenum platform; EGLDisplay egl_display; + EGLDeviceEXT egl_device; EGLContext egl_context; EGLConfig egl_config; + const char *drm_device; EGLSurface dummy_surface; -- GitLab From 0dade5b4013428b41d549e3825c03b1a172aa730 Mon Sep 17 00:00:00 2001 From: Scott Anderson Date: Wed, 11 Mar 2020 15:52:36 +1300 Subject: [PATCH 5/6] gl-renderer: Set dmabuf hints This will set the device (if present) and formats for the default dmabuf hints, which will be reported to clients. Signed-off-by: Scott Anderson --- libweston/renderer-gl/gl-renderer.c | 55 +++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/libweston/renderer-gl/gl-renderer.c b/libweston/renderer-gl/gl-renderer.c index 4e5c6d441..f08fc110c 100644 --- a/libweston/renderer-gl/gl-renderer.c +++ b/libweston/renderer-gl/gl-renderer.c @@ -40,6 +40,8 @@ #include #include #include +#include +#include #include "linux-sync-file.h" #include "timeline.h" @@ -3366,6 +3368,55 @@ gl_renderer_create_pbuffer_surface(struct gl_renderer *gr) { return 0; } +static void +gl_renderer_set_device_hint(struct weston_compositor *ec) +{ + struct gl_renderer *gr = get_renderer(ec); + struct stat st; + + if (!gr->drm_device) + return; + + if (stat(gr->drm_device, &st) < 0) { + weston_log("failed to stat '%s': %s\n", gr->drm_device, + strerror(errno)); + return; + } + + weston_hints_set_device(&ec->default_hints, st.st_rdev); +} + +static void +gl_renderer_set_format_hints(struct weston_compositor *ec) +{ + int *formats = NULL; + int num_formats; + + gl_renderer_query_dmabuf_formats(ec, &formats, &num_formats); + + for (int i = 0; i < num_formats; ++i) { + uint64_t *mods = NULL; + int num_mods; + + gl_renderer_query_dmabuf_modifiers(ec, formats[i], + &mods, &num_mods); + + for (int j = 0; j < num_mods; ++j) + weston_hints_add_format(&ec->default_hints, + WESTON_FORMAT_PREFERENCE_RENDERER, + formats[i], mods[j]); + + if (num_mods == 0) + weston_hints_add_format(&ec->default_hints, + WESTON_FORMAT_PREFERENCE_RENDERER, + formats[i], DRM_FORMAT_MOD_INVALID); + + free(mods); + } + + free(formats); +} + static int gl_renderer_display_create(struct weston_compositor *ec, const struct gl_renderer_display_options *options) @@ -3458,6 +3509,10 @@ gl_renderer_display_create(struct weston_compositor *ec, goto fail_with_error; } + gl_renderer_set_device_hint(ec); + gl_renderer_set_format_hints(ec); + weston_hints_send_done(&ec->default_hints); + return 0; fail_with_error: -- GitLab From 6ce6be92cec7821918a39c45bb24e86a3b23441e Mon Sep 17 00:00:00 2001 From: Scott Anderson Date: Wed, 11 Mar 2020 17:34:58 +1300 Subject: [PATCH 6/6] clients/simple-dmabuf-egl: Use dmabuf-hints to select device We use the primary_device from the default hints to select which device we should open, if linux-dmabuf version 4 is supported. This allows us to not need to pass an argument or rely on hardcoding a value, but that can still be done in case the hint is not provided or if you want to override the selection. Signed-off-by: Scott Anderson --- clients/simple-dmabuf-egl.c | 86 ++++++++++++++++++++++++++++++++++++- 1 file changed, 84 insertions(+), 2 deletions(-) diff --git a/clients/simple-dmabuf-egl.c b/clients/simple-dmabuf-egl.c index 10e72a9bc..0989ef133 100644 --- a/clients/simple-dmabuf-egl.c +++ b/clients/simple-dmabuf-egl.c @@ -80,8 +80,10 @@ struct display { struct xdg_wm_base *wm_base; struct zwp_fullscreen_shell_v1 *fshell; struct zwp_linux_dmabuf_v1 *dmabuf; + struct zwp_linux_dmabuf_hints_v1 *default_hints; struct weston_direct_display_v1 *direct_display; struct zwp_linux_explicit_synchronization_v1 *explicit_sync; + char *render_node; uint64_t *modifiers; int modifiers_count; int req_dmabuf_immediate; @@ -106,6 +108,10 @@ struct display { int drm_fd; struct gbm_device *device; } gbm; + struct { + uint32_t major; + uint32_t minor; + } hints; }; struct buffer { @@ -1026,6 +1032,60 @@ static const struct zwp_linux_dmabuf_v1_listener dmabuf_listener = { dmabuf_modifiers }; +static void +hints_done(void *data, struct zwp_linux_dmabuf_hints_v1 *h) +{ + struct display *d = data; + drmDevicePtr dev; + + if (drmGetDeviceFromMajorMinor(d->hints.major, d->hints.minor, + 0, &dev) < 0) + return; + + if (dev->available_nodes & (1 << DRM_NODE_RENDER)) + d->render_node = strdup(dev->nodes[DRM_NODE_RENDER]); + + drmFreeDevice(&dev); +} + +static void +hints_primary_device(void *data, struct zwp_linux_dmabuf_hints_v1 *h, + uint32_t maj, uint32_t min) +{ + struct display *d = data; + + d->hints.major = maj; + d->hints.minor = min; +} + +static void +hints_tranche(void *data, struct zwp_linux_dmabuf_hints_v1 *h) +{ + /* TODO: Use take compositor preference into account */ +} + +static void +hints_target_device(void *data, struct zwp_linux_dmabuf_hints_v1 *h, + uint32_t maj, uint32_t min) +{ + /* TODO: Use take compositor preference into account */ +} + +static void +hints_modifier(void *data, struct zwp_linux_dmabuf_hints_v1 *h, + uint32_t format, uint32_t modifier_hi, uint32_t modifier_lo) +{ + /* TODO: Use take compositor preference into account */ +} + +static const struct zwp_linux_dmabuf_hints_v1_listener hints_listener = { + .done = hints_done, + .primary_device = hints_primary_device, + .tranche = hints_tranche, + .target_device = hints_target_device, + .modifier = hints_modifier, +}; + static void xdg_wm_base_ping(void *data, struct xdg_wm_base *wm_base, uint32_t serial) { @@ -1057,8 +1117,15 @@ registry_handle_global(void *data, struct wl_registry *registry, if (version < 3) return; d->dmabuf = wl_registry_bind(registry, - id, &zwp_linux_dmabuf_v1_interface, 3); + id, &zwp_linux_dmabuf_v1_interface, + version == 3 ? 3 : 4); zwp_linux_dmabuf_v1_add_listener(d->dmabuf, &dmabuf_listener, d); + if (version >= 4) { + d->default_hints = + zwp_linux_dmabuf_v1_get_default_hints(d->dmabuf); + zwp_linux_dmabuf_hints_v1_add_listener(d->default_hints, + &hints_listener, d); + } } else if (strcmp(interface, "zwp_linux_explicit_synchronization_v1") == 0) { d->explicit_sync = wl_registry_bind( registry, id, @@ -1116,6 +1183,7 @@ destroy_display(struct display *display) wl_display_flush(display->display); wl_display_disconnect(display->display); } + free(display->render_node); free(display); } @@ -1370,6 +1438,8 @@ create_display(char const *drm_render_node, int opts) } display->gbm.drm_fd = -1; + if (drm_render_node) + display->render_node = strdup(drm_render_node); display->display = wl_display_connect(NULL); assert(display->display); @@ -1387,11 +1457,23 @@ create_display(char const *drm_render_node, int opts) wl_display_roundtrip(display->display); + if (display->default_hints) { + zwp_linux_dmabuf_hints_v1_destroy(display->default_hints); + } + if (!display->modifiers_count) { fprintf(stderr, "format XRGB8888 is not available\n"); goto error; } + if (display->render_node) { + drm_render_node = display->render_node; + } else { + fprintf(stderr, "Warning: No render node hint or argument given\n"); + fprintf(stderr, "Defaulting to /dev/dri/renderD128\n"); + drm_render_node = "/dev/dri/renderD128"; + } + /* GBM needs to be initialized before EGL, so that we have a valid * render node gbm_device to create the EGL display from. */ if (!display_set_up_gbm(display, drm_render_node)) @@ -1484,7 +1566,7 @@ main(int argc, char **argv) struct display *display; struct window *window; int opts = 0; - char const *drm_render_node = "/dev/dri/renderD128"; + char const *drm_render_node = NULL; int c, option_index, ret = 0; int window_size = 256; -- GitLab