#!/bin/sh
# Imprion OS — which renderer the kiosk compositor draws with, decided per start.
#
# `cage` renders with GLES2 by default. On a graphics card with no 3D driver
# Mesa falls back to `kms_swrast`, and on that path the last frame of a burst
# never reaches the scanout: the page and the compositor both hold the join
# code, and the screen keeps the frame before it — "Contacting server" over a
# blank hostname and serial — until something else redraws. Measured on a
# virtio-gpu terminal, 11 stale screens out of 11 page loads (README decision
# 263). wlroots' pixman renderer draws into the scanout buffer on the CPU,
# synchronously, and has 0 out of 18 on the same terminal.
#
# So a card whose driver has no 3D engine gets pixman, and every other card
# keeps GLES2: a till with a real GPU is not moved to CPU compositing.
#
# The answer is an environment file the kiosk units read after this runs
# (`EnvironmentFile=-/run/imprion-kiosk/renderer.env`). It is rewritten on every
# start, so a card swapped between two boots is decided again.
#
#   IMPRION_DRM_SYSFS  the DRM class directory (tests point it at a fake tree)
#   IMPRION_KIOSK_ENV  the file written
set -u

SYSFS="${IMPRION_DRM_SYSFS:-/sys/class/drm}"
OUT="${IMPRION_KIOSK_ENV:-/run/imprion-kiosk/renderer.env}"

# The DRM drivers with no 3D engine a terminal or a virtual machine can boot
# on. A virtio device's own driver is `virtio-pci`; the DRM driver is the one
# bound to its virtio child, which is what `driver_of` reads.
is_software_driver() {
	case "$1" in
		virtio_gpu|simpledrm|bochs-drm|bochs|cirrus|cirrus-qemu|qxl|vmwgfx|hyperv_drm|vboxvideo) return 0 ;;
		*) return 1 ;;
	esac
}

driver_of() {
	driver="$(readlink "$1/device/driver" 2>/dev/null)"
	driver="${driver##*/}"

	if [ "$driver" = "virtio-pci" ]; then
		for child in "$1"/device/virtio*; do
			[ -e "$child/driver" ] || continue

			driver="$(readlink "$child/driver" 2>/dev/null)"
			driver="${driver##*/}"

			break
		done
	fi

	echo "$driver"
}

software=""

for path in "$SYSFS"/card*; do
	name="${path##*/}"

	case "$name" in
		card*-*) continue ;;
		card*) ;;
		*) continue ;;
	esac

	driver="$(driver_of "$path")"

	if is_software_driver "$driver"; then
		software="$name $driver"
	fi
done

mkdir -p "${OUT%/*}"

if [ -n "$software" ]; then
	printf 'WLR_RENDERER=pixman\n' > "$OUT"
	echo "kiosk-renderer: $software, pixman"
else
	: > "$OUT"
	echo "kiosk-renderer: gles2"
fi

exit 0
