diff options
12 files changed, 416 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}/ +} diff --git a/templates/feature/agl-drm-lease/50_bblayers.conf.inc b/templates/feature/agl-drm-lease/50_bblayers.conf.inc new file mode 100644 index 00000000..9977bba4 --- /dev/null +++ b/templates/feature/agl-drm-lease/50_bblayers.conf.inc @@ -0,0 +1,3 @@ +BBLAYERS =+ " \ + ${METADIR}/meta-agl-devel/meta-agl-drm-lease \ +" diff --git a/templates/feature/agl-drm-lease/50_local.conf.inc b/templates/feature/agl-drm-lease/50_local.conf.inc new file mode 100644 index 00000000..fe32a6ed --- /dev/null +++ b/templates/feature/agl-drm-lease/50_local.conf.inc @@ -0,0 +1,2 @@ +#see meta-agl-devel/meta-agl-drm-lease/conf/include/agl-drm-lease.inc +require conf/include/agl-drm-lease.inc |