From 3d7b404d4e6a02f05a5c1d39a16a096b37cc506a Mon Sep 17 00:00:00 2001 From: Damian Hobson-Garcia Date: Thu, 4 Feb 2021 16:13:41 +0900 Subject: drm-lease: Add weston DRM lease integration Allow option for weston to use a DRM lease instead of the primary DRM device node when using the DRM backend. EGL clients will require a wayland EGL driver than can does not need DRM authentication. e.g. an implementation based on DRM render nodes. Bug-AGL: SPEC-3730 Change-Id: I12f6d5b5df62a90702431010ab685e3b0654912b Signed-off-by: Damian Hobson-Garcia --- meta-agl-drm-lease/README.md | 13 +- ...1-backend-drm-Add-method-to-import-DRM-fd.patch | 205 ++++++++++++++++++ .../weston/weston/0002-Add-DRM-lease-support.patch | 230 +++++++++++++++++++++ .../recipes-graphics/weston/weston_8.0.0.bbappend | 8 + 4 files changed, 454 insertions(+), 2 deletions(-) create mode 100644 meta-agl-drm-lease/recipes-graphics/weston/weston/0001-backend-drm-Add-method-to-import-DRM-fd.patch create mode 100644 meta-agl-drm-lease/recipes-graphics/weston/weston/0002-Add-DRM-lease-support.patch create mode 100644 meta-agl-drm-lease/recipes-graphics/weston/weston_8.0.0.bbappend diff --git a/meta-agl-drm-lease/README.md b/meta-agl-drm-lease/README.md index e397e6a3..2c5ba05d 100644 --- a/meta-agl-drm-lease/README.md +++ b/meta-agl-drm-lease/README.md @@ -14,9 +14,10 @@ Enable the `agl-drm-lease` AGL feature when setting up your build environment with aglsetup.sh. This will add the `drm-lease-manager` package to the image, and will add DRM -lease support to some packages. +lease support to the following packages: + * weston + * kmscube -Currently, only the `kmscube` sample application has support for DRM lease. `kmscube` is not included in the image by default. To add the package to the image, add the following to your local.conf @@ -37,6 +38,14 @@ This will create 1 lease for each output connection on the platform. The name of each lease will be in the form of `card0-` (eg. `card0-LVDS-1` or `card0-HDMI-A-1`) +## Running weston + +weston can be started on any available DRM lease by running with the +`--drm-lease=` option. Eg: +``` + # weston --drm-lease=card0-HDMI-A-1 +``` + ## Running kmscube sample With the `drm-lease-manager` running `kmscube` can display on any available diff --git a/meta-agl-drm-lease/recipes-graphics/weston/weston/0001-backend-drm-Add-method-to-import-DRM-fd.patch b/meta-agl-drm-lease/recipes-graphics/weston/weston/0001-backend-drm-Add-method-to-import-DRM-fd.patch new file mode 100644 index 00000000..da3a0c6f --- /dev/null +++ b/meta-agl-drm-lease/recipes-graphics/weston/weston/0001-backend-drm-Add-method-to-import-DRM-fd.patch @@ -0,0 +1,205 @@ +From e7d843e3a2af9ed04569f4ec94d3f558ab2aeede Mon Sep 17 00:00:00 2001 +From: Damian Hobson-Garcia +Date: Wed, 20 Jan 2021 16:25:39 +0900 +Subject: [PATCH 1/2] backend-drm: Add method to import DRM fd + +Allow the compositor to provide a file descriptor for a +DRM device. + +This allows the compositor to bypass the launcher backends +and to get a DRM file descriptor from an external +resource manager, such as one that can create DRM leases, +and pass it to the DRM backend for use. + +Having the DRM device management in the compositor allows for +integrating a platform specific resource manager without having +to add extra dependencies to the generic libweston code. +--- + compositor/main.c | 1 + + include/libweston/backend-drm.h | 7 +++ + libweston/backend-drm/drm.c | 76 ++++++++++++++++++++++++--------- + 3 files changed, 65 insertions(+), 19 deletions(-) + +diff --git a/compositor/main.c b/compositor/main.c +index 8eb8a470..7d5373f7 100644 +--- a/compositor/main.c ++++ b/compositor/main.c +@@ -2510,6 +2510,7 @@ load_drm_backend(struct weston_compositor *c, + config.base.struct_version = WESTON_DRM_BACKEND_CONFIG_VERSION; + config.base.struct_size = sizeof(struct weston_drm_backend_config); + config.configure_device = configure_input_device; ++ config.device_fd = -1; + + wet->heads_changed_listener.notify = drm_heads_changed; + weston_compositor_add_heads_changed_listener(c, +diff --git a/include/libweston/backend-drm.h b/include/libweston/backend-drm.h +index f6647e28..a62c8996 100644 +--- a/include/libweston/backend-drm.h ++++ b/include/libweston/backend-drm.h +@@ -223,6 +223,13 @@ struct weston_drm_backend_config { + + /** Use shadow buffer if using Pixman-renderer. */ + bool use_pixman_shadow; ++ ++ /** DRM device file descriptor to use ++ * ++ * An openeded DRM device file descriptor. If <0, open a DRM ++ * device in the backend using `specific_device` or heuristics. ++ */ ++ int device_fd; + }; + + #ifdef __cplusplus +diff --git a/libweston/backend-drm/drm.c b/libweston/backend-drm/drm.c +index e3169b6e..300c9ff6 100644 +--- a/libweston/backend-drm/drm.c ++++ b/libweston/backend-drm/drm.c +@@ -40,6 +40,7 @@ + #include + #include + #include ++#include + #include + + #include +@@ -2486,29 +2487,22 @@ drm_device_changed(struct weston_compositor *compositor, + wl_signal_emit(&compositor->session_signal, compositor); + } + +-/** +- * Determines whether or not a device is capable of modesetting. If successful, +- * sets b->drm.fd and b->drm.filename to the opened device. +- */ + static bool +-drm_device_is_kms(struct drm_backend *b, struct udev_device *device) ++drm_backend_update_kms_device(struct drm_backend *b, struct udev_device *device, ++ const char *name, int drm_fd) + { +- const char *filename = udev_device_get_devnode(device); + const char *sysnum = udev_device_get_sysnum(device); + dev_t devnum = udev_device_get_devnum(device); + drmModeRes *res; +- int id = -1, fd; ++ int id = -1; + +- if (!filename) ++ if (!name) + return false; + +- fd = weston_launcher_open(b->compositor->launcher, filename, O_RDWR); +- if (fd < 0) +- return false; + +- res = drmModeGetResources(fd); ++ res = drmModeGetResources(drm_fd); + if (!res) +- goto out_fd; ++ return false; + + if (res->count_crtcs <= 0 || res->count_connectors <= 0 || + res->count_encoders <= 0) +@@ -2517,7 +2511,7 @@ drm_device_is_kms(struct drm_backend *b, struct udev_device *device) + if (sysnum) + id = atoi(sysnum); + if (!sysnum || id < 0) { +- weston_log("couldn't get sysnum for device %s\n", filename); ++ weston_log("couldn't get sysnum for device %s\n", name); + goto out_res; + } + +@@ -2527,9 +2521,9 @@ drm_device_is_kms(struct drm_backend *b, struct udev_device *device) + weston_launcher_close(b->compositor->launcher, b->drm.fd); + free(b->drm.filename); + +- b->drm.fd = fd; ++ b->drm.fd = drm_fd; + b->drm.id = id; +- b->drm.filename = strdup(filename); ++ b->drm.filename = strdup(name); + b->drm.devnum = devnum; + + drmModeFreeResources(res); +@@ -2538,11 +2532,33 @@ drm_device_is_kms(struct drm_backend *b, struct udev_device *device) + + out_res: + drmModeFreeResources(res); +-out_fd: +- weston_launcher_close(b->compositor->launcher, fd); + return false; + } + ++/** ++ * Determines whether or not a device is capable of modesetting. If successful, ++ * sets b->drm.fd and b->drm.filename to the opened device. ++ */ ++static bool ++drm_device_is_kms(struct drm_backend *b, struct udev_device *device) ++{ ++ int fd; ++ const char *filename = udev_device_get_devnode(device); ++ if (!filename) ++ return false; ++ ++ fd = weston_launcher_open(b->compositor->launcher, filename, O_RDWR); ++ if (fd < 0) ++ return false; ++ ++ if (!drm_backend_update_kms_device(b, device, filename, fd)) { ++ weston_launcher_close(b->compositor->launcher, fd); ++ return false; ++ } ++ ++ return true; ++} ++ + /* + * Find primary GPU + * Some systems may have multiple DRM devices attached to a single seat. This +@@ -2630,6 +2646,25 @@ find_primary_gpu(struct drm_backend *b, const char *seat) + return drm_device; + } + ++static struct udev_device * ++import_drm_device_fd(struct drm_backend *b, int fd) ++{ ++ struct udev_device *device; ++ struct stat s; ++ ++ if (fstat(fd, &s) < 0 || !S_ISCHR(s.st_mode)) ++ return NULL; ++ ++ device = udev_device_new_from_devnum(b->udev, 'c', s.st_rdev); ++ if (!device) ++ return NULL; ++ ++ if (!drm_backend_update_kms_device(b, device, "imported DRM device fd", fd)) ++ return NULL; ++ ++ return device; ++} ++ + static struct udev_device * + open_specific_drm_device(struct drm_backend *b, const char *name) + { +@@ -2854,7 +2889,9 @@ drm_backend_create(struct weston_compositor *compositor, + b->session_listener.notify = session_notify; + wl_signal_add(&compositor->session_signal, &b->session_listener); + +- if (config->specific_device) ++ if (config->device_fd >= 0) ++ drm_device = import_drm_device_fd(b, config->device_fd); ++ else if (config->specific_device) + drm_device = open_specific_drm_device(b, config->specific_device); + else + drm_device = find_primary_gpu(b, seat_id); +@@ -3013,6 +3050,7 @@ static void + config_init_to_defaults(struct weston_drm_backend_config *config) + { + config->use_pixman_shadow = true; ++ config->device_fd = -1; + } + + WL_EXPORT int +-- +2.25.1 + diff --git a/meta-agl-drm-lease/recipes-graphics/weston/weston/0002-Add-DRM-lease-support.patch b/meta-agl-drm-lease/recipes-graphics/weston/weston/0002-Add-DRM-lease-support.patch new file mode 100644 index 00000000..5b2d69ae --- /dev/null +++ b/meta-agl-drm-lease/recipes-graphics/weston/weston/0002-Add-DRM-lease-support.patch @@ -0,0 +1,230 @@ +From 24ece5f73b7c9377e14d74c2b14c9ae3504edcc3 Mon Sep 17 00:00:00 2001 +From: Damian Hobson-Garcia +Date: Fri, 5 Mar 2021 19:24:35 +0900 +Subject: [PATCH 2/2] Add DRM lease support + +Add a command line option to use a DRM lease instead of a primary node for +output when using the DRM backend. +--- + compositor/drm-lease.c | 53 ++++++++++++++++++++++++++++++++++++++++++ + compositor/drm-lease.h | 40 +++++++++++++++++++++++++++++++ + compositor/main.c | 11 ++++++++- + compositor/meson.build | 5 ++++ + meson_options.txt | 7 ++++++ + 5 files changed, 115 insertions(+), 1 deletion(-) + create mode 100644 compositor/drm-lease.c + create mode 100644 compositor/drm-lease.h + +diff --git a/compositor/drm-lease.c b/compositor/drm-lease.c +new file mode 100644 +index 00000000..fdb1f5e2 +--- /dev/null ++++ b/compositor/drm-lease.c +@@ -0,0 +1,53 @@ ++/* ++ * Copyright © 2021 IGEL Co., Ltd. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining ++ * a copy of this software and associated documentation files (the ++ * "Software"), to deal in the Software without restriction, including ++ * without limitation the rights to use, copy, modify, merge, publish, ++ * distribute, sublicense, and/or sell copies of the Software, and to ++ * permit persons to whom the Software is furnished to do so, subject to ++ * the following conditions: ++ * ++ * The above copyright notice and this permission notice (including the ++ * next paragraph) shall be included in all copies or substantial ++ * portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, ++ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF ++ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND ++ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS ++ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ++ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN ++ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE ++ * SOFTWARE. ++ */ ++ ++#include "drm-lease.h" ++ ++#include ++ ++int get_drm_lease(struct dlm_lease **drm_lease, const char *drm_lease_name) { ++ if (!drm_lease_name) ++ return -1; ++ ++ int drm_fd; ++ struct dlm_lease *lease = dlm_get_lease(drm_lease_name); ++ if (lease) { ++ drm_fd = dlm_lease_fd(lease); ++ if (drm_fd < 0) ++ dlm_release_lease(lease); ++ } ++ if (drm_fd < 0) ++ weston_log("Could not get DRM lease %s\n", drm_lease_name); ++ ++ *drm_lease = lease; ++ return drm_fd; ++} ++ ++void release_drm_lease(struct dlm_lease *lease) { ++ if (lease) ++ dlm_release_lease(lease); ++} ++ ++ +diff --git a/compositor/drm-lease.h b/compositor/drm-lease.h +new file mode 100644 +index 00000000..a102e4cb +--- /dev/null ++++ b/compositor/drm-lease.h +@@ -0,0 +1,40 @@ ++/* ++ * Copyright © 2021 IGEL Co., Ltd. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining ++ * a copy of this software and associated documentation files (the ++ * "Software"), to deal in the Software without restriction, including ++ * without limitation the rights to use, copy, modify, merge, publish, ++ * distribute, sublicense, and/or sell copies of the Software, and to ++ * permit persons to whom the Software is furnished to do so, subject to ++ * the following conditions: ++ * ++ * The above copyright notice and this permission notice (including the ++ * next paragraph) shall be included in all copies or substantial ++ * portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, ++ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF ++ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND ++ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS ++ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ++ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN ++ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE ++ * SOFTWARE. ++ */ ++ ++#include "config.h" ++ ++#ifdef BUILD_DRM_LEASE_CLIENT ++#include ++int get_drm_lease(struct dlm_lease **drm_lease, const char *drm_lease_name); ++void release_drm_lease(struct dlm_lease *drm_lease); ++#else ++struct dlm_lease; ++int get_drm_lease(struct dlm_lease **drm_lease, const char *drm_lease_name) { ++ return -1; ++} ++void release_drm_lease(struct dlm_lease *drm_lease) { ++} ++ ++#endif +diff --git a/compositor/main.c b/compositor/main.c +index 7d5373f7..dae754aa 100644 +--- a/compositor/main.c ++++ b/compositor/main.c +@@ -65,6 +65,7 @@ + #include + #include "../remoting/remoting-plugin.h" + #include "../pipewire/pipewire-plugin.h" ++#include "drm-lease.h" + + #define WINDOW_TITLE "Weston Compositor" + /* flight recorder size (in bytes) */ +@@ -122,6 +123,7 @@ struct wet_compositor { + int (*simple_output_configure)(struct weston_output *output); + bool init_failed; + struct wl_list layoutput_list; /**< wet_layoutput::compositor_link */ ++ struct dlm_lease *drm_lease; + }; + + static FILE *weston_logfile = NULL; +@@ -669,6 +671,9 @@ usage(int error_code) + " --seat=SEAT\t\tThe seat that weston should run on, instead of the seat defined in XDG_SEAT\n" + " --tty=TTY\t\tThe tty to use\n" + " --drm-device=CARD\tThe DRM device to use, e.g. \"card0\".\n" ++#ifdef BUILD_DRM_LEASE_CLIENT ++ " --drm-lease=lease\tUse the specified DRM lease. e.g \"card0-HDMI-A-1\"\n" ++#endif + " --use-pixman\t\tUse the pixman (CPU) renderer\n" + " --current-mode\tPrefer current KMS mode over EDID preferred mode\n\n"); + #endif +@@ -2481,6 +2486,7 @@ load_drm_backend(struct weston_compositor *c, + struct weston_config_section *section; + struct wet_compositor *wet = to_wet_compositor(c); + int ret = 0; ++ char *drm_lease_name = NULL; + + wet->drm_use_current_mode = false; + +@@ -2492,6 +2498,7 @@ load_drm_backend(struct weston_compositor *c, + { WESTON_OPTION_STRING, "seat", 0, &config.seat_id }, + { WESTON_OPTION_INTEGER, "tty", 0, &config.tty }, + { WESTON_OPTION_STRING, "drm-device", 0, &config.specific_device }, ++ { WESTON_OPTION_STRING, "drm-lease", 0, &drm_lease_name }, + { WESTON_OPTION_BOOLEAN, "current-mode", 0, &wet->drm_use_current_mode }, + { WESTON_OPTION_BOOLEAN, "use-pixman", 0, &config.use_pixman }, + }; +@@ -2510,7 +2517,7 @@ load_drm_backend(struct weston_compositor *c, + config.base.struct_version = WESTON_DRM_BACKEND_CONFIG_VERSION; + config.base.struct_size = sizeof(struct weston_drm_backend_config); + config.configure_device = configure_input_device; +- config.device_fd = -1; ++ config.device_fd = get_drm_lease(&wet->drm_lease, drm_lease_name); + + wet->heads_changed_listener.notify = drm_heads_changed; + weston_compositor_add_heads_changed_listener(c, +@@ -2527,6 +2534,7 @@ load_drm_backend(struct weston_compositor *c, + + free(config.gbm_format); + free(config.seat_id); ++ free(drm_lease_name); + + return ret; + } +@@ -3373,6 +3381,7 @@ out: + + /* free(NULL) is valid, and it won't be NULL if it's used */ + free(wet.parsed_options); ++ release_drm_lease(wet.drm_lease); + + if (protologger) + wl_protocol_logger_destroy(protologger); +diff --git a/compositor/meson.build b/compositor/meson.build +index e1334d6a..e5b82a88 100644 +--- a/compositor/meson.build ++++ b/compositor/meson.build +@@ -25,6 +25,11 @@ if get_option('xwayland') + srcs_weston += 'xwayland.c' + config_h.set_quoted('XSERVER_PATH', get_option('xwayland-path')) + endif ++if get_option('drm-lease') ++ deps_weston += dependency('libdlmclient') ++ srcs_weston += 'drm-lease.c' ++ config_h.set('BUILD_DRM_LEASE_CLIENT', '1') ++endif + + libexec_weston = shared_library( + 'exec_weston', +diff --git a/meson_options.txt b/meson_options.txt +index 73ef2c34..9cb27536 100644 +--- a/meson_options.txt ++++ b/meson_options.txt +@@ -113,6 +113,13 @@ option( + description: 'Virtual remote output with Pipewire on DRM backend' + ) + ++option( ++ 'drm-lease', ++ type: 'boolean', ++ value: false, ++ description: 'Support for running weston with a leased DRM Master' ++) ++ + option( + 'shell-desktop', + type: 'boolean', +-- +2.25.1 + diff --git a/meta-agl-drm-lease/recipes-graphics/weston/weston_8.0.0.bbappend b/meta-agl-drm-lease/recipes-graphics/weston/weston_8.0.0.bbappend new file mode 100644 index 00000000..97de8c62 --- /dev/null +++ b/meta-agl-drm-lease/recipes-graphics/weston/weston_8.0.0.bbappend @@ -0,0 +1,8 @@ +FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:" + +SRC_URI += "file://0001-backend-drm-Add-method-to-import-DRM-fd.patch \ + file://0002-Add-DRM-lease-support.patch \ + " + +PACKAGECONFIG[drm-lease] = "-Ddrm-lease=true,-Ddrm-lease=false,drm-lease-manager" +PACKAGECONFIG_append = " drm-lease" -- cgit 1.2.3-korg