X11 With Multiple Displays

Has anyone had success attaching multiple displays to a single container? I’ve been playing with my custom version of https://github.com/balena-io/resin-electronjs as well as the stock https://github.com/balena-io-playground/x11-window-manager and I’m not sure how to get a second display to work.

I’m using an RPi 4 with the official touchscreen and an HDMI display.

I’m not too well versed in the world of x11 and Linux screens, so I’m not sure what steps to take. I’ve tried poking around the X11 config as well as tools like xrandr, but nothing I’ve done has indicated that the host or container know anything about the second monitor.

Hi, you will need to configure X11 to support dual screens. There are some references online as to how to achieve this, for example https://www.novaspirit.com/2015/12/31/low-end-tech-how-to-setup-dual-monitor-on-raspberry-pi/. It may also be worth to make this work in raspbian first and then move it to a container.

That link was pretty helpful in coming up with the correct xorg.conf. I was able to get a config that works when I boot into Raspbian without a GUI, then run startx, but putting that same xorg.conf into my container on BalenaOS still results in a single screen.

I’ve tried this on both a Pi 3 and 4. Interestingly, the 4 doesn’t seem to output via HDMI at all (it does when I boot to Raspbian), even if it is the only monitor hooked up.

Even on the 3, which does show display over HDMI when it is the only monitor, I still can’t get both the touchscreen and HDMI to display. I’m beginning to wonder if there is some driver or package that is installed on Raspbian, but not BalenaOS/the container image that is necessary to support dual displays.

Hey @csuich2 welcome to the forums!

I would personally be looking at your config.txt file under Raspbian, and comparing that to what you’re using with balenaOS. For example, when you run ls /dev/fb* on Raspbian, I’m guessing you’re seeing /dev/fb0 and /dev/fb1. Compare this to what you’re getting on balenaOS, you might need to set extra configuration variables (maybe max_framebuffers?), which you can do by setting BALENA_HOST_CONFIG_max_framebuffers under device configuration in the dashboard. Anything you prefix with BALENA_HOST_CONFIG_ will get injected into the config.txt file on the device.

I haven’t had a chance to test this yet, but I found a whole load of information here: https://www.raspberrypi.org/forums/viewtopic.php?f=63&t=216399&start=350

I hope this helps!

@chrisys That was really helpful - it got me closer, but not quite there yet. There was another link inside that thread you linked to which was really helpful: https://www.raspberrypi.org/forums/viewtopic.php?f=63&t=246384

I’ve switched to a Pi 3 for a couple of reasons. I still haven’t gotten any HDMI output to work on BalenaOS on a Pi 4, so I think there might be an issue there.

I’ve set the following config.txt values:
BALENA_HOST_CONFIG_disable_overscan=1
BALENA_HOST_CONFIG_framebuffer_priority=0
BALENA_HOST_CONFIG_hdmi_force_hotplug=1
BALENA_HOST_CONFIG_max_framebuffers=2

With those values set, I can alternate between which screen shows up by changing the screen order if the ServerLayout section of the Xorg conf.

If I additionally add:
BALENA_HOST_CONFIG_dtoverlay=vc4-fkms-v3d

Then I get output to BOTH screens at the same time, but the screens are duplicated instead of extended, despite the xorg config listing the order of the screens with ‘RightOf’. I also tried explicit dimension/locations (0 0 and 800 0).

Getting closer… :slight_smile:

So… some level of success.

With the xorg configuration below, I finally got dual screen working on the Pi 3.

I still can’t enable vc4-fkms-v3d or both displays will show the same image. I tried modifying the xorg config to no avail. It appears that setting changes the frame buffer API such that there is only one fb (/dev/fb0) and then the monitors/screens should pull the appropriate data they need from that frame buffer, but I can’t get it to work.

I still can’t get this working on the Pi 4. No matter what I do, I can’t get HDMI output working on BalenaOS on Pi 4.

The main use case for our second monitor is playing a video in our electron app. The video playback is smooth when running in Raspbian, but is quite choppy when running in Docker on BalenaOS. I’ve tried some tweaks to improve performance, such as upping the GPU memory to 256 mb, but no luck. I installed VLC into a container and ran it via startx and the video played just fine. Kinda confusing…but something I’ll have to continue looking in to. Hopefully the Pi 4 will fix that if I can get HDMI working.

Section “Device”
Identifier “fbturbo0”
Driver “fbturbo”
Option “fbdev” “/dev/fb0”
Option “SwapbuffersWait” “true”
Option “debug” “true”
EndSection

Section “Device”
Identifier “fbturbo1”
Driver “fbturbo”
Option “fbdev” “/dev/fb1”
Option “SwapbuffersWait” “true”
Option “debug” “true”
EndSection

Section “Monitor”
Identifier “Monitor0”
Option “Primary” “False”
EndSection

Section “Monitor”
Identifier “Monitor1”
Option “RightOf” “Monitor0”
Option “Primary” “False”
EndSection

Section “Screen”
Identifier “ScreenTurbo0”
Monitor “Monitor0”
Device “fbturbo0”
Subsection “Display”
EndSubSection
EndSection

Section “Screen”
Identifier “ScreenTurbo1”
Monitor “Monitor1”
Device “fbturbo1”
Subsection “Display”
EndSubSection
EndSection

Section “ServerLayout”
Identifier “Multihead”
Screen 0 “ScreenTurbo0” 0 0
Screen 1 “ScreenTurbo1” 800 0
Option “Xinerama” “true”
EndSection

Section “ServerFlags”
Option “BlankTime” “0”
Option “StandbyTime” “0”
Option “SuspendTime” “0”
Option “OffTime” “0”
Option “DefaultServerLayout” “Multihead”
EndSection

Section “InputClass”
Identifier “FT5406 memory based driver”
MatchIsTouchscreen “on”
MatchDevicePath “/dev/input/event*”
Driver “libinput”
Option “TransformationMatrix” “0.294 0 0 0 0.444 0 0 0 1”
EndSection

Hey @csuich2 good to hear you’re making progress.

I was firstly surprised to hear that you were having trouble with the HDMI output on the Pi 4 - do you mean you’re getting literally nothing (not even the balenaOS splash screen)? I wanted to check this so deployed a Pi 4 device with the latest OS and could see the splash screen on HDMI0, and then the Chromium app below is working OK (with audio).

I don’t have any other suggestions for your xorg configration, but I did want to point out that Electron is not hardware accelerated on the Pi, which will likely be the root cause of the choppiness you’re seeing. A colleague of mine is working on a hardware accelerated Chromium container, which is online here - it’s still in development and testing but if you wanted to try it and add feedback that would be great too. Of course, as you say, the Pi 4 may help with Electron since it’s more powerful CPU wise.

First off, big thanks to @chrisys and @alexgg - this is my first time working with this level of Linux display configuration & issues, so your comments & help is greatly appreciated.

Side note - really loving all of the balena ecosystem - awesome stuff!

tl;dr - I’ve got it working now. It isn’t completely ideal, but it works for this PoC that I’m working on. If we roll out further, I may need to investigate why some of this stuff works the way it is right now.

On to the technical ramble…

Interesting…so I tried a different monitor, and it works on the Pi 4. So somehow, I was able to find a monitor that works with the Pi 3 on balenaOS, but not the Pi 4 (just to clarify, this monitor works fine with Raspbian on both devices).

Just to elaborate, though. When I have the monitor hooked up to the Pi 4 and boot it, the monitor displays back-lit-black, then a few seconds later, it switches to a ‘cable not detected’ screen. If I reboot, the ‘cable not detected’ screen goes away and the monitor shows back-lit-black for a bit. At no point have I gotten the balenaOS splash on this monitor (an old Acer X233H) with a Pi 4 running balenaOS.

However, (thanks to all your help!) I finally got dual screen working on the Pi 4. For anyone who stumbles across this, here are the gory details:

Currently, balenaOS sets:

arm_64bit=1
dtoverlay=vc4-fkms-v3d

automatically for Pi 4. Disabling either of theses (currently) causes balenaOS to not boot. However, with the config that I had working on the Pi 3, attempting to run startx results in this error:

/usr/lib/xorg/Xorg: symbol lookup error: /usr/lib/xorg/modules/drivers/fbturbo_drv.so: undefined symbol: shadowUpdatePackedWeak

I ultimately decided to try disabling the

Driver "fbturbo"
Option "fbdev" "/dev/fb*"

settings in my xorg.conf due to the fbturbo_drv.so in that error. Apparently vc4-fkms-v3d is some kind of simple wrapper that leverages the standard Linux display drivers, so fbturbo is no longer necessary (working?) on the Pi 4.

Enablingvc4-fkms-v3d causes the Pi to have a single fb (/dev/fb0) which means that now, both of my monitors are displaying the same image. Luckily, the fb is sized correctly such that it’s width is correct - the width of both monitors combined.

In order to get around this, I can use a command like xrandr --output HDMI-1 --pos 800x0 to force the HDMI monitor to start displaying from position 800x0 from the framebuffer and voila, it works.

This is definitely not ideal, but it is working for now. Bonus points - the Pi 4 is plenty fast for smooth 1080 video playback through Electron/chromium. I’ll definitely look at your colleagues project though and see what is going on. Being able to use Pi 3’s would be nice too.