diff options
author | Damian Hobson-Garcia <dhobsong@igel.co.jp> | 2021-01-08 17:03:00 +0900 |
---|---|---|
committer | Damian Hobson-Garcia <dhobsong@igel.co.jp> | 2021-03-05 15:21:40 +0900 |
commit | 92d67bf9c0385ce2513bf7bf0001f27223d750fd (patch) | |
tree | 851f601867ad0eaa9e65223ab835665b3529ee82 /meta-agl-drm-lease | |
parent | 3eb1a00c35bd817472067a153c793c9c7aef00a3 (diff) |
Add agl-drm-lease feature
The agl-drm-lease feature will add the DRM lease manager and client
library to the current image. DRM lease support is also added
to the kmscube test utility if it is installed.
Bug-AGL: SPEC-3729
Signed-off-by: Damian Hobson-Garcia <dhobsong@igel.co.jp>
Change-Id: I75cfbc363724916202ec15bb71813f49d6b560eb
Diffstat (limited to 'meta-agl-drm-lease')
10 files changed, 411 insertions, 0 deletions
diff --git a/meta-agl-drm-lease/README.md b/meta-agl-drm-lease/README.md new file mode 100644 index 00000000..e397e6a3 --- /dev/null +++ b/meta-agl-drm-lease/README.md @@ -0,0 +1,54 @@ +# DRM lease support layer + +This yocto layer adds support for using DRM leases to partition display +controller output resources between multiple processes. + +This layer adds a drm-lease-manager deamon (with systemd configuration) +and a client library for receiving DRM leases from the daemon. For more details +the DRM lease manager and client see the repository at +(https://gerrit.automotivelinux.org/gerrit/gitweb?p=src/drm-lease-manager.git) + +## Setup + +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. + +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 + +``` +IMAGE_INSTALL_append = " kmscube" +``` + +## Starting the DRM lease manager + +The drm-lease-manager must be the only process to directly open the DRM device. +Shut down any running window systems (eg. weston or agl-compositor) and run: + +``` + # systemctl start drm-lease-manager +``` + +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 kmscube sample + +With the `drm-lease-manager` running `kmscube` can display on any available +lease by running with the `-L -D<lease name>` options. Eg: + +``` + # kmscube -L -Dcard0-HDMI-A-1 +``` + +Multiple kmscube instances (one per DRM lease) can be started at the same time. + +## Tested targets + +This layer has been tested on the Renesas R-Car Gen3 platform. Other platforms +supporting the Linux DRM API may work as well. diff --git a/meta-agl-drm-lease/conf/include/agl-drm-lease.inc b/meta-agl-drm-lease/conf/include/agl-drm-lease.inc new file mode 100644 index 00000000..5ec51c55 --- /dev/null +++ b/meta-agl-drm-lease/conf/include/agl-drm-lease.inc @@ -0,0 +1 @@ +IMAGE_INSTALL_append = " drm-lease-manager" diff --git a/meta-agl-drm-lease/conf/layer.conf b/meta-agl-drm-lease/conf/layer.conf new file mode 100644 index 00000000..9c6d3726 --- /dev/null +++ b/meta-agl-drm-lease/conf/layer.conf @@ -0,0 +1,16 @@ +# We have a conf and classes directory, add to BBPATH +BBPATH .= ":${LAYERDIR}" + +# We have recipes-* directories, add to BBFILES +BBFILES += "${LAYERDIR}/recipes-*/*/*.bb ${LAYERDIR}/recipes-*/*/*.bbappend" + +BBFILE_COLLECTIONS += "agl-drm-lease" +BBFILE_PATTERN_agl-drm-lease = "^${LAYERDIR}/" +BBFILE_PRIORITY_agl-drm-lease = "10" + +# This should only be incremented on significant changes that will +# cause compatibility issues with other layers +LAYERVERSION_agl-drm-lease = "1" + +LAYERDEPENDS_agl-drm-lease = "core" +LAYERSERIES_COMPAT_agl-drm-lease = "dunfell" diff --git a/meta-agl-drm-lease/recipes-graphics/drm-lease-manager/drm-lease-manager/drm-lease-manager.service b/meta-agl-drm-lease/recipes-graphics/drm-lease-manager/drm-lease-manager/drm-lease-manager.service new file mode 100644 index 00000000..9984d2c5 --- /dev/null +++ b/meta-agl-drm-lease/recipes-graphics/drm-lease-manager/drm-lease-manager/drm-lease-manager.service @@ -0,0 +1,6 @@ +[Unit] +Description=DRM Lease Manager + +[Service] +ExecStart=drm-lease-manager +RuntimeDirectory=drm-lease-manager diff --git a/meta-agl-drm-lease/recipes-graphics/drm-lease-manager/drm-lease-manager/run-ptest b/meta-agl-drm-lease/recipes-graphics/drm-lease-manager/drm-lease-manager/run-ptest new file mode 100644 index 00000000..c799763c --- /dev/null +++ b/meta-agl-drm-lease/recipes-graphics/drm-lease-manager/drm-lease-manager/run-ptest @@ -0,0 +1,10 @@ +#!/bin/sh + +for i in $(ls ./*-test) ; do + $i &> /dev/null + if [ $? -eq 0 ]; then + echo "PASS: $i" + else + echo "FAIL: $i" + fi +done diff --git a/meta-agl-drm-lease/recipes-graphics/drm-lease-manager/drm-lease-manager_git.bb b/meta-agl-drm-lease/recipes-graphics/drm-lease-manager/drm-lease-manager_git.bb new file mode 100644 index 00000000..3b1f5aaf --- /dev/null +++ b/meta-agl-drm-lease/recipes-graphics/drm-lease-manager/drm-lease-manager_git.bb @@ -0,0 +1,35 @@ +LICENSE = "Apache-2.0" +LIC_FILES_CHKSUM = "file://LICENSE;md5=3b83ef96387f14655fc854ddc3c6bd57" + +SRC_URI = "git://gerrit.automotivelinux.org/gerrit/src/drm-lease-manager;protocol=https;branch=${AGL_BRANCH} \ + file://drm-lease-manager.service \ + file://run-ptest \ + " + +PV = "0.1+git${SRCPV}" +SRCREV = "f991de200799118355fd75237a740321bda7aaa7" + +S = "${WORKDIR}/git" + +inherit meson +inherit systemd +inherit ptest + +DEPENDS = "libdrm libcheck fff" + +do_install_append() { + install -d ${D}/${systemd_unitdir}/system + install -m 0644 ${WORKDIR}/drm-lease-manager.service ${D}/${systemd_unitdir}/system + rm -rf ${D}/${localstatedir} +} + +SYSTEMD_SERVICE_${PN} = "drm-lease-manager.service" + +EXTRA_OEMESON += "${@bb.utils.contains('PTEST_ENABLED', '1', '-Denable-tests=true', '', d)}" +RDEPENDS_${PN}-ptest = "libcheck" + +do_install_ptest() { + install ${B}/libdlmclient/test/libdlmclient-test ${D}${PTEST_PATH} + install ${B}/drm-lease-manager/test/lease-server-test ${D}${PTEST_PATH} + install ${B}/drm-lease-manager/test/lease-manager-test ${D}${PTEST_PATH} +} diff --git a/meta-agl-drm-lease/recipes-graphics/kmscube/kmscube/0001-texturator-Use-correct-GL-extension-header.patch b/meta-agl-drm-lease/recipes-graphics/kmscube/kmscube/0001-texturator-Use-correct-GL-extension-header.patch new file mode 100644 index 00000000..d6050778 --- /dev/null +++ b/meta-agl-drm-lease/recipes-graphics/kmscube/kmscube/0001-texturator-Use-correct-GL-extension-header.patch @@ -0,0 +1,30 @@ +From afe70b04556be4840e7fe74d7601946ade8fdbfa Mon Sep 17 00:00:00 2001 +From: Damian Hobson-Garcia <dhobsong@igel.co.jp> +Date: Wed, 16 Dec 2020 11:08:25 +0900 +Subject: [PATCH] texturator: Use correct GL extension header + +gl2ext.h is the extenstion header for OpenGL ES 2.0 and all later +versions according to the Khronos documentation [1]. gl3ext.h is either +an empty stub, or may not even exist on some platforms. + +[1]: https://www.khronos.org/registry/OpenGL/index_es.php#headers +--- + texturator.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/texturator.c b/texturator.c +index d9335d7..6d97856 100644 +--- a/texturator.c ++++ b/texturator.c +@@ -30,7 +30,7 @@ + #include <math.h> + + #include <GLES3/gl3.h> +-#include <GLES3/gl3ext.h> ++#include <GLES2/gl2ext.h> + + #ifdef HAVE_LIBPNG + #include <png.h> +-- +2.17.1 + diff --git a/meta-agl-drm-lease/recipes-graphics/kmscube/kmscube/0002-Add-DRM-lease-support.patch b/meta-agl-drm-lease/recipes-graphics/kmscube/kmscube/0002-Add-DRM-lease-support.patch new file mode 100644 index 00000000..0366bef0 --- /dev/null +++ b/meta-agl-drm-lease/recipes-graphics/kmscube/kmscube/0002-Add-DRM-lease-support.patch @@ -0,0 +1,235 @@ +From 3a766fb852b53316f4b4c0b37ec801a5b188093b Mon Sep 17 00:00:00 2001 +From: Damian Hobson-Garcia <dhobsong@igel.co.jp> +Date: Wed, 16 Dec 2020 16:21:57 +0900 +Subject: [PATCH] Add DRM lease support + +--- + drm-atomic.c | 4 ++-- + drm-common.c | 21 +++++++++++++++++++-- + drm-common.h | 9 ++++++--- + drm-legacy.c | 4 ++-- + kmscube.c | 12 +++++++++--- + meson.build | 5 +++++ + meson_options.txt | 5 +++++ + texturator.c | 2 +- + 8 files changed, 49 insertions(+), 13 deletions(-) + +diff --git a/drm-atomic.c b/drm-atomic.c +index d748772..8cb3ca5 100644 +--- a/drm-atomic.c ++++ b/drm-atomic.c +@@ -337,12 +337,12 @@ static int get_plane_id(void) + return ret; + } + +-const struct drm * init_drm_atomic(const char *device, const char *mode_str, unsigned int vrefresh) ++const struct drm * init_drm_atomic(const char *device, const char *mode_str, unsigned int vrefresh, int lease) + { + uint32_t plane_id; + int ret; + +- ret = init_drm(&drm, device, mode_str, vrefresh); ++ ret = init_drm(&drm, device, mode_str, vrefresh, lease); + if (ret) + return NULL; + +diff --git a/drm-common.c b/drm-common.c +index b9d61c1..6e7d1ce 100644 +--- a/drm-common.c ++++ b/drm-common.c +@@ -32,6 +32,10 @@ + #include "common.h" + #include "drm-common.h" + ++#ifdef HAVE_DRM_LEASE ++#include "dlmclient.h" ++#endif ++ + WEAK uint64_t + gbm_bo_get_modifier(struct gbm_bo *bo); + +@@ -169,6 +173,19 @@ static int get_resources(int fd, drmModeRes **resources) + return 0; + } + ++static int open_device(struct drm *drm, const char *device, int lease) ++{ ++ if (!lease) ++ return open(device, O_RDWR); ++ ++#ifdef HAVE_DRM_LEASE ++ drm->lease = dlm_get_lease(device); ++ if (drm->lease) ++ return dlm_lease_fd(drm->lease); ++#endif ++ return -1; ++} ++ + #define MAX_DRM_DEVICES 64 + + static int find_drm_device(drmModeRes **resources) +@@ -208,7 +225,7 @@ static int find_drm_device(drmModeRes **resources) + return fd; + } + +-int init_drm(struct drm *drm, const char *device, const char *mode_str, unsigned int vrefresh) ++int init_drm(struct drm *drm, const char *device, const char *mode_str, unsigned int vrefresh, int lease) + { + drmModeRes *resources; + drmModeConnector *connector = NULL; +@@ -216,7 +233,7 @@ int init_drm(struct drm *drm, const char *device, const char *mode_str, unsigned + int i, ret, area; + + if (device) { +- drm->fd = open(device, O_RDWR); ++ drm->fd = open_device(drm, device, lease); + ret = get_resources(drm->fd, &resources); + if (ret < 0 && errno == EOPNOTSUPP) + printf("%s does not look like a modeset device\n", device); +diff --git a/drm-common.h b/drm-common.h +index c4eb886..5119e79 100644 +--- a/drm-common.h ++++ b/drm-common.h +@@ -51,6 +51,9 @@ struct connector { + struct drm { + int fd; + ++ /* only used for DRM lease */ ++ struct dlm_lease *lease; ++ + /* only used for atomic: */ + struct plane *plane; + struct crtc *crtc; +@@ -73,8 +76,8 @@ struct drm_fb { + + struct drm_fb * drm_fb_get_from_bo(struct gbm_bo *bo); + +-int init_drm(struct drm *drm, const char *device, const char *mode_str, unsigned int vrefresh); +-const struct drm * init_drm_legacy(const char *device, const char *mode_str, unsigned int vrefresh); +-const struct drm * init_drm_atomic(const char *device, const char *mode_str, unsigned int vrefresh); ++int init_drm(struct drm *drm, const char *device, const char *mode_str, unsigned int vrefresh, int lease); ++const struct drm * init_drm_legacy(const char *device, const char *mode_str, unsigned int vrefresh, int lease); ++const struct drm * init_drm_atomic(const char *device, const char *mode_str, unsigned int vrefresh, int lease); + + #endif /* _DRM_COMMON_H */ +diff --git a/drm-legacy.c b/drm-legacy.c +index 56a0fed..03db13d 100644 +--- a/drm-legacy.c ++++ b/drm-legacy.c +@@ -122,11 +122,11 @@ static int legacy_run(const struct gbm *gbm, const struct egl *egl) + return 0; + } + +-const struct drm * init_drm_legacy(const char *device, const char *mode_str, unsigned int vrefresh) ++const struct drm * init_drm_legacy(const char *device, const char *mode_str, unsigned int vrefresh, int lease) + { + int ret; + +- ret = init_drm(&drm, device, mode_str, vrefresh); ++ ret = init_drm(&drm, device, mode_str, vrefresh, lease); + if (ret) + return NULL; + +diff --git a/kmscube.c b/kmscube.c +index f14c1d9..abb5bdd 100644 +--- a/kmscube.c ++++ b/kmscube.c +@@ -41,12 +41,13 @@ static const struct egl *egl; + static const struct gbm *gbm; + static const struct drm *drm; + +-static const char *shortopts = "AD:M:m:V:v:"; ++static const char *shortopts = "AD:LM:m:V:v:"; + + static const struct option longopts[] = { + {"atomic", no_argument, 0, 'A'}, + {"device", required_argument, 0, 'D'}, + {"format", required_argument, 0, 'f'}, ++ {"drm-lease", no_argument, 0, 'L'}, + {"mode", required_argument, 0, 'M'}, + {"modifier", required_argument, 0, 'm'}, + {"samples", required_argument, 0, 's'}, +@@ -62,6 +63,9 @@ static void usage(const char *name) + "options:\n" + " -A, --atomic use atomic modesetting and fencing\n" + " -D, --device=DEVICE use the given device\n" ++#ifdef HAVE_DRM_LEASE ++ " -L, --drm-lease the given device is the name of a DRM lease:\n" ++#endif + " -M, --mode=MODE specify mode, one of:\n" + " smooth - smooth shaded cube (default)\n" + " rgba - rgba textured cube\n" +@@ -87,6 +89,7 @@ int main(int argc, char *argv[]) + uint64_t modifier = DRM_FORMAT_MOD_LINEAR; + int samples = 0; + int atomic = 0; ++ int lease = 0; + int opt; + unsigned int len; + unsigned int vrefresh = 0; +@@ -119,6 +122,11 @@ int main(int argc, char *argv[]) + fourcc[2], fourcc[3]); + break; + } ++#ifdef HAVE_DRM_LEASE ++ case 'L': ++ lease = 1; ++ break; ++#endif + case 'M': + if (strcmp(optarg, "smooth") == 0) { + mode = SMOOTH; +@@ -164,9 +170,9 @@ int main(int argc, char *argv[]) + } + + if (atomic) +- drm = init_drm_atomic(device, mode_str, vrefresh); ++ drm = init_drm_atomic(device, mode_str, vrefresh, lease); + else +- drm = init_drm_legacy(device, mode_str, vrefresh); ++ drm = init_drm_legacy(device, mode_str, vrefresh, lease); + if (!drm) { + printf("failed to initialize %s DRM\n", atomic ? "atomic" : "legacy"); + return -1; +diff --git a/meson.build b/meson.build +index df9c315..1b47a52 100644 +--- a/meson.build ++++ b/meson.build +@@ -91,6 +91,11 @@ else + message('Building without gstreamer support') + endif + ++if get_option('drm_lease').enabled() ++ dep_common += dependency('libdlmclient') ++ add_project_arguments('-DHAVE_DRM_LEASE', language : 'c') ++endif ++ + executable('kmscube', sources, dependencies : dep_common, install : true) + + +diff --git a/meson_options.txt b/meson_options.txt +index 1ed8abc..d932a1c 100644 +--- a/meson_options.txt ++++ b/meson_options.txt +@@ -3,3 +3,8 @@ option( + type : 'feature', + description : 'Enable support for gstreamer and cube-video' + ) ++option( ++ 'drm_lease', ++ type : 'feature', ++ description : 'Enable support for running as a DRM lease client' ++) +diff --git a/texturator.c b/texturator.c +index 3d09e9e..9b87f0d 100644 +--- a/texturator.c ++++ b/texturator.c +@@ -948,7 +948,7 @@ int main(int argc, char *argv[]) + print_summary(); + + /* no real need for atomic here: */ +- drm = init_drm_legacy(device, mode_str, vrefresh); ++ drm = init_drm_legacy(device, mode_str, vrefresh, 0); + if (!drm) { + printf("failed to initialize DRM\n"); + return -1; diff --git a/meta-agl-drm-lease/recipes-graphics/kmscube/kmscube_git.bbappend b/meta-agl-drm-lease/recipes-graphics/kmscube/kmscube_git.bbappend new file mode 100644 index 00000000..fb4f9972 --- /dev/null +++ b/meta-agl-drm-lease/recipes-graphics/kmscube/kmscube_git.bbappend @@ -0,0 +1,8 @@ +FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:" + + +SRC_URI += "file://0001-texturator-Use-correct-GL-extension-header.patch \ + file://0002-Add-DRM-lease-support.patch" + +PACKAGECONFIG += "drm-lease" +PACKAGECONFIG[drm-lease] = "-Ddrm_lease=enabled,-Ddrm_lease=disabled,drm-lease-manager" diff --git a/meta-agl-drm-lease/recipes-support/fff/fff_git.bb b/meta-agl-drm-lease/recipes-support/fff/fff_git.bb new file mode 100644 index 00000000..05073561 --- /dev/null +++ b/meta-agl-drm-lease/recipes-support/fff/fff_git.bb @@ -0,0 +1,16 @@ +LICENSE = "MIT" +LIC_FILES_CHKSUM = "file://LICENSE;md5=ae0c5f671972941881237cb85e1c74b2" + +SRC_URI = "git://github.com/meekrosoft/fff.git" + +PV = "git${SRCPV}" +SRCREV = "cbe9b8b7fba14a042d2b4e008dedf0b998c35ae8" + +S = "${WORKDIR}/git" + +DEPENDS = "libdrm libcheck" + +do_install() { + install -d ${D}/${includedir} + install ${S}/fff.h ${D}/${includedir}/ +} |