17 Dec 2020

Graphics with OpenEmbedded/Yocto without X11/Weston

In a previous post I discussed graphics on the RaspberryPi and how one could use the closed binary blob + the userland library to do GLESv2 without a windowing system/compositor. This solution resulted in a system image that only required 36 packages and is 28MB in size. However, this solution is RaspberryPi-specific, 32-bit-specific, GLESv2-specific, and the quality of the binary blob graphics lags noticeably behind the quality of the fully open-source alternatives.

A better, and more generic, solution is to use DRM/KMS, GBM, and EGL directly. This allows fullscreen, "bare-metal" playback of OpenGL or OpenGL ES apps without the weight of x11 or weston/wayland.

Examples of this usage can be found with: kmscube, glmark2, mpv, and kodi. mpv and kodi are huge applications with dozens of dependencies each, so they aren't good to use for this example where I'm trying to show how small a bare-metal graphics system can be.

In this case I'm going to demonstrate on the RaspberryPi, but this solution is generic enough to work with any board whose SoC has a GPU that is supported by Mesa's DRM. I'm using the following layers:

  • bitbake: 71aaac9efa69abbf6c27d174e0862644cbf674ef
  • openembedded-core: c58fcc1379ca5755a5b670f79b75e94370d4943c
  • meta-openembedded: f03ad4971ed0b7cf34550a90ee3c0fa18f964533
  • meta-raspberrypi: 361f42e346e59f3a3fafcfa4ab7c948969d5abf4

The edits I've made to my conf/local.conf are:

1
2
3
4
5
6
7
8
MACHINE = "raspberrypi3-64"

MACHINE_FEATURES_append = " vc4graphics"
DISTRO_FEATURES += "opengl"
CORE_IMAGE_EXTRA_INSTALL += "glmark2 kmscube"
PACKAGECONFIG_append_pn-glmark2 = " drm-gl"

ENABLE_UART = "1"

Note:

  • I'm using "raspberrypi3-64" as my MACHINE, the same works for "raspberrypi3" (i.e. a 32-bit build) as well as a whole bunch of other devices/machines
  • on line 3 I'm specifically requesting the fully open-source graphics stack based on Mesa
  • notice that I'm only adding "opengl" to the DISTRO_FEATURES, and not "x11" (or "wayland")
  • on line 5 I want glmark2 and kmscube added to my image
  • by default, the way the glmark2 recipe is written, it will build drm-gles2 by default, to get drm-gl built as well I've added it to its PACKAGECONFIG
  • I like enabling the UART and using the board via the serial console

Building core-image-minimal:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
Build Configuration:
BB_VERSION           = "1.49.0"
BUILD_SYS            = "x86_64-linux"
NATIVELSBSTRING      = "opensuseleap-15.2"
TARGET_SYS           = "arm-oe-linux-gnueabi"
MACHINE              = "raspberrypi3"
DISTRO               = "nodistro"
DISTRO_VERSION       = "nodistro.0"
TUNE_FEATURES        = "arm vfp cortexa7 neon vfpv4 thumb callconvention-hard"
TARGET_FPU           = "hard"
meta-raspberrypi     = "master:361f42e346e59f3a3fafcfa4ab7c948969d5abf4"
meta                 = "master:c58fcc1379ca5755a5b670f79b75e94370d4943c"
meta-oe              = "master:f03ad4971ed0b7cf34550a90ee3c0fa18f964533"

I end up with an image that has 40 packages:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
base-files_3.0.14-r89_raspberrypi3.ipk
base-passwd_3.5.29-r0_cortexa7t2hf-neon-vfpv4.ipk
busybox_1.32.0-r0_cortexa7t2hf-neon-vfpv4.ipk
busybox-syslog_1.32.0-r0_cortexa7t2hf-neon-vfpv4.ipk
busybox-udhcpc_1.32.0-r0_cortexa7t2hf-neon-vfpv4.ipk
eudev_3.2.9-r0_cortexa7t2hf-neon-vfpv4.ipk
glmark2_20201114+0+784aca755a-r0_cortexa7t2hf-neon-vfpv4.ipk
init-ifupdown_1.0-r7_raspberrypi3.ipk
initscripts-functions_1.0-r155_cortexa7t2hf-neon-vfpv4.ipk
initscripts_1.0-r155_cortexa7t2hf-neon-vfpv4.ipk
init-system-helpers-service_1.58-r0_cortexa7t2hf-neon-vfpv4.ipk
kbd_2.3.0-r0_cortexa7t2hf-neon-vfpv4.ipk
keymaps_1.0-r31_raspberrypi3.ipk
kmscube_git-r0_cortexa7t2hf-neon-vfpv4.ipk
ldconfig_2.32-r0_cortexa7t2hf-neon-vfpv4.ipk
libblkid1_2.36-r0_cortexa7t2hf-neon-vfpv4.ipk
libc6_2.32-r0_cortexa7t2hf-neon-vfpv4.ipk
libdrm2_2.4.103-r0_cortexa7t2hf-neon-vfpv4.ipk
libegl-mesa_2:20.2.4-r0_cortexa7t2hf-neon-vfpv4.ipk
libexpat1_2.2.10-r0_cortexa7t2hf-neon-vfpv4.ipk
libgbm1_2:20.2.4-r0_cortexa7t2hf-neon-vfpv4.ipk
libgcc1_10.2.0-r0_cortexa7t2hf-neon-vfpv4.ipk
libglapi0_2:20.2.4-r0_cortexa7t2hf-neon-vfpv4.ipk
libgles2-mesa_2:20.2.4-r0_cortexa7t2hf-neon-vfpv4.ipk
libjpeg62_1:2.0.6-r0_cortexa7t2hf-neon-vfpv4.ipk
libkmod2_27-r0_cortexa7t2hf-neon-vfpv4.ipk
libpng16-16_1.6.37-r0_cortexa7t2hf-neon-vfpv4.ipk
libstdc++6_10.2.0-r0_cortexa7t2hf-neon-vfpv4.ipk
libudev1_3.2.9-r0_cortexa7t2hf-neon-vfpv4.ipk
libz1_1.2.11-r0_cortexa7t2hf-neon-vfpv4.ipk
mesa-megadriver_2:20.2.4-r0_cortexa7t2hf-neon-vfpv4.ipk
modutils-initscripts_1.0-r7_cortexa7t2hf-neon-vfpv4.ipk
netbase_1:6.2-r0_all.ipk
packagegroup-core-boot_1.0-r17_raspberrypi3.ipk
run-postinsts_1.0-r10_all.ipk
sysvinit-inittab_2.88dsf-r10_raspberrypi3.ipk
sysvinit-pidof_2.97-r0_cortexa7t2hf-neon-vfpv4.ipk
sysvinit_2.97-r0_cortexa7t2hf-neon-vfpv4.ipk
update-alternatives-opkg_0.4.3-r0_cortexa7t2hf-neon-vfpv4.ipk
update-rc.d_0.8-r0_all.ipk

and my image size is 36MB:

-rw-r--r-- 2 trevor users  36M Dec 16 23:40 tmp-glibc/deploy/images/raspberrypi3/core-image-minimal-raspberrypi3-20201217044019.rootfs.ext3

The image is super-fast to boot to a cmdline, no X11 or Wayland is started, and from the serial console I can run kmscube:


glmark2-es2-drm (OpenGL ES 2):


or glmark2-drm (OpenGL):

No comments: