aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDamian Hobson-Garcia <dhobsong@igel.co.jp>2021-02-04 16:13:41 +0900
committerDamian Hobson-Garcia <dhobsong@igel.co.jp>2021-03-09 17:25:21 +0900
commit3d7b404d4e6a02f05a5c1d39a16a096b37cc506a (patch)
tree0fb6e3e59a7971af0f8648de6c88b6f343ee3a47
parent92d67bf9c0385ce2513bf7bf0001f27223d750fd (diff)
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 <dhobsong@igel.co.jp>
-rw-r--r--meta-agl-drm-lease/README.md13
-rw-r--r--meta-agl-drm-lease/recipes-graphics/weston/weston/0001-backend-drm-Add-method-to-import-DRM-fd.patch205
-rw-r--r--meta-agl-drm-lease/recipes-graphics/weston/weston/0002-Add-DRM-lease-support.patch230
-rw-r--r--meta-agl-drm-lease/recipes-graphics/weston/weston_8.0.0.bbappend8
4 files changed, 454 insertions, 2 deletions
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-<output name>`
(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=<lease name>` 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 <dhobsong@igel.co.jp>
+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 <linux/vt.h>
+ #include <assert.h>
+ #include <sys/mman.h>
++#include <sys/stat.h>
+ #include <time.h>
+
+ #include <xf86drm.h>
+@@ -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 <dhobsong@igel.co.jp>
+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 <libweston/libweston.h>
++
++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 <dlmclient.h>
++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 <libweston/weston-log.h>
+ #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"