Problems using SDL2 on raspberry pi without X11 running

I am having problems getting SDL2 to work on my raspberry pi without x11 running. The default SDL2 in the raspbian jessie repositories only supports and shows X11 as a viable video driver. If I run a test application without X11 running, that is booting straight to the terminal, SDL_GetNumVideoDisplays() returns 0 with the default SDL2 lib and I’m unable to create an SDL window.

I can however build SDL2 on my pi with RPI video driver support. When I boot to the terminal with this lib installed I can create a full screen SDL window relying on the RPI video driver, but I cannot receive any keyboard or mouse events,

Finally, I haven’t been able to build single SDL2 lib which can both create a floating window when X11 is running, and create a full screen window when X11 isn’t running. It’s either one or the other with any SDL2 lib I build, but not both.

I’ve tried many ./config options before make’ing SDL2, and I yet to create a lib which works both with the RPI driver (supporting mouse and keyboard input), and the X11 driver (capable of creating a visible floating window).

If anyone has been able to get an SDL2 lib working on raspberry pi that works as described in the prior paragraph, would you be so kind as to provide some information on how to build such an SDL lib for the pi? I think this information might be useful to others.

Thank you :slight_smile:

Seconded. I’m in the opposite position - I want to use X11 - so the default SDL2 in the Raspbian repository is suitable for me but it’s only 2.0.2 and I want to be sure that when it’s updated it continues to support X11. If it’s impossible for a single build to support both X and non-X operation, both should be provided in the repository.

Thanks Russel. I should point out I am using a raspberry pi 3 and when I build SDL2 from sources myself with X11 allowed I cannot get a window to appear. The raspbian jessie default SDL2 lib yes I can get a window to appear, but with my self built SDL2 libs no window. And again on the RPI driver without X11 I get no mouse or keyboard events.

Update below, but first with a big problem. While running an SDL2 program with the RPI video driver, all keyboard input actually is sent your terminal while you program runs. I think there is a fix to this problem, but I couldn’t find it using google. It’s a obviously very dangerous situation where running a game can cause arbitrary terminal commands to execute in the background without the users knowledge.

So here an update related to getting input working.

I was able to get a lib of SDL2-2.0.5 compiled from source working with the RPI video driver and accepting mouse and keyboard input. I had to install libudev-dev.

sudo apt-get install libudev-dev
tar xfv SDL2-2.0.5.tar.gz
cd SDL2-2.0.5
./configure --host=arm-raspberry-linux-gnueabihf --disable-video-opengl --disable-video-x11 --disable-pulseaudio --disable-esd --disable-video-mir --disable-video-wayland
make -j 4

This works for creating fullscreen SDL2 programs that do not depend on X11. Of course now the large problem is with keyboard input being passed through to the terminal while your full screen app is running.

Hi @Anthony_Walter. Looks like you figured it out, but just wanted to share a script I’ve written to compile and install SDL2, along with SDL2_image, SDL2_mixer, SDL2_ttf, and smpeg2 from source with all the appropriate config flags and dependencies for the Raspberry Pi without X and big OpenGL (preferring OpenGL ES). Check out simple2d.sh (you can run it only installing SDL2, not the Simple 2D library, with just simple2d.sh install --sdl). As for the keyboard input leaking, I think there’s a fix queued up for the next release (could be wrong).

Regarding @rtrussell’s comment, I don’t know of any way to have a single build supporing both with and without X, since all that config happends at compile time. You could build two versions of SDL, then make sure to link the right lib when compiling your app — that would add a fair amount of complexity. If someone has a solution or better approach here, would love to hear it!

I’m trying to avoid statically linking to SDL, rather I tell my users to install it from the Raspbian Jessie repository. That works well for me, because my app runs under X and uses OpenGL so the version currently available is suitable - albeit that it’s 2.0.2. But of course it would break my app if the repository version were ever to be replaced by the non-X/OpenGLES variant.

For everyone else, this page seems to document the problem with keystrokes leaking through to the underlying terminal when using the RPI video driver:

A work around posted in the link above is to build a program that then forks your SDL2 program to eat up any leaking keystrokes. I tested this work around and it works, but it seems like a hack and the I think the SDL2 devs ought to fix this issue as it could lead to serious issues for users of SDL2 programs on the raspberry pi.

Yes, what would be ideal is if we could choose whether or not we’re targeting X / OpenGL at runtime, rather than through the config flags. I wonder if that’s possible.

Edit: The following was written when I didn’t remember the VC4 driver. Things might not make sense.

For reference, there’s the README-raspberrypi.md in the SDL source that describes some of these issues. Not in very much detail, but it may give some hints on what is supported and what not.

The distribution repositories usually have the default build configuration which never includes the Raspberry Pi driver. I also think that there should be a separate package if a distribution wants to offer the rpi driver.

I’ve spotted an issue with the default GL attributes that prevents OpenGL ES contexts from being created when SDL is built with OpenGL. The version and profile get set to OpenGL 2.1 and that’s obviously problematic in an OpenGL ES environment. I currently don’t see a way to workaround this one without modifying the application or SDL (unless the developer of the application was smart and built some options into it). This may need some augmenting with environment variables or the hint system.

There’s the option to build without OpenGL. Then the attribute defaults will work for the Raspberry Pi. Sadly, SDL applications that want to use OpenGL have a bad time now, but software rendering on this slow chip is painful anyway.

The next problem you’ll see now is that the EGL driver selection is a bit stubborn. If the Raspberry Pi is detected as the host, the default library paths get set to the Raspberry Pi ones at compile time. When launching an SDL application under X11, it tries to load with the Raspberry Pi EGL library which will fail. If you get the “Could not get EGL display” error, set the SDL_VIDEO_EGL_DRIVER environment variable to libEGL.so.1 or whatever the name is on your system. This forces SDL2 to load the library that goes with X11 instead. I got my test programs to work this way.

configure command I used:

./configure --host=armv6-raspberry-linux-gnueabihf --prefix=/usr --disable-rpath --disable-video-opengl
# Some other stuff I disabled because I don't need it.
--disable-esd --disable-oss --disable-sndio --disable-pulseaudio --disable-nas --disable-video-wayland --disable-video-wayland-qt-touch --disable-wayland-shared --disable-video-mir 

Keyboard input comes from evdev. This allows for a more robust event handling instead of using the terminal stuff, but this also means that the terminal inputs don’t get consumed. I guess this is a somewhat difficult issue to solve because a library can’t just gobble up stdin. The terminal/console settings are very finicky and not a good solution in my opinion.

Like that program someone made, you can also use script to capture stdin as long as your SDL2 application runs:

script -q -c "/usr/bin/sdl2application" /dev/null

Input does not get suppressed, but the shell won’t interpret the key presses as commands.

Thank you for your considerate reply. The information you provided was very enlightening.

With regards to OpenGL support, OpenGL ES, I have settled on OpenGL ES 2 the only API I am willing to use. It’s the only API that works across every single platform.

I will look into you suggestion to use SDL_VIDEO_EGL_DRIVER and see if I can get a single SDL2 lib working on raspberry that can create and display a window on both RPI and X11.

Thanks again.

Someone just informed me about the VC4 driver for the Raspberry Pi and I have to admit that I totally forgot about it and that I only tested with the old driver (usually found in /opt/vc). I’m sorry if I caused any confusion, should you already use the new driver.

I’m going to have a look at it and check if what I said still makes any sense.

After compiling Mesa with vc4 support (took the Raspberry Pi only a few hours) I got OpenGL working with the new driver under X11.

It looks like the vc4-(f)kms-v3d overlays disable the old, firmware-side driver and this also affects the current version of the SDL2 rpi video driver, causing it to error on initialization. The upside is that the default SDL2 package from the repository works with X11 and it’s hardware accelerated.

SDL probably needs a DRM/KMS video driver to get it working without X11 in that configuration. Although I didn’t check the if the other drivers offer a solution.

@ChliHug Thanks for looking into this. I think what I’ve settled on is just compiling a version that supports the RPI driver and supports OpenGL ES 2. The pi is already limited in it’s hardware, and I think when running possibly cpu/gpu/memory intensive SDL2 programs, it’s probably best to have as little else also running such as X11 and a DE like XFCE. In other words a pi booting straight to the command line is definitely going to result in SDL2 apps running with less trouble.

Also thanks for that shell script trick to stop key presses from potentially executing commands. I haven’t tried it out yet, but I trust in you that it will work.

Indeed, which is why I use that mode for my SDL app - it makes a huge difference to performance and it’s convenient for my users. However I haven’t succeeded in making direct OpenGL calls via SDL work, for example even the trivial program listed here doesn’t run on the Raspberry Pi with the ‘GL Driver’ enabled in raspi-config. Can you suggest why?

Richard.

I have no problems using OpenGL with vc4-kms-v3d or vc4-fkms-v3d, though I’m on Arch Linux and built Mesa myself to get vc4 support. I have not used Raspbian yet but plan to do so. Perhaps there is something specific to their packages.

How do these direct calls fail? Any error messages?

I’m guessing glxinfo does report Gallium on VC4 in the OpenGL renderer string? I can’t believe they would configure their distribution otherwise. Does the application link directly with libGL.so from Mesa?

Can’t think of anything else at this moment, but there must be a hint somewhere that will point in the direction of the issue.

@rtrussell I think you need to request OpenGL ES in order to get a window and then valid context. You also have to set your SDL GL ATTRIBUTES before you call SDL_Init(SDL_INIT_VIDEO). Finally, you need to compile SDL2 from source if you want to run without X11. The libSDL2-0.so.0 in the jessie debian repos isn’t built with the RPI video driver.

SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0);
SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_ACCELERATED_VISUAL, 1);
SDL_Init(SDL_INIT_VIDEO);

then later

SDL_CreateWindow(…)
SDL_CreateContext(…)

[quote=“Anthony_Walter, post:16, topic:22621”]
I think you need to request OpenGL ES in order to get a window and then valid context. You also have to set your SDL GL ATTRIBUTES before you call SDL_Init(SDL_INIT_VIDEO). Finally, you need to compile SDL2 from source if you want to run without X11.[/quote]

But, as I’ve said, I don’t want to run without X11! My app runs perfectly well with the repo version of SDL2 and the (VC4) GL Driver enabled in raspi-config, which is what I want. But code that accesses OpenGL functions via SDL (which works perfectly in Windows, Ubuntu, Mac OS-X and Android) does not work on the Raspberry Pi.

glxinfo reports “Gallium 0.4 on VC4 V3D 2.1”

I’m not linking with anything except SDL2 and SDL2_ttf:

-L/usr/lib/ -lSDL2 -lSDL2main -lSDL2_ttf -ldl -lm

I should add that I’m getting this message in the console: “libGL error: MESA-LOADER: failed to retrieve device information”. I’ve assumed it’s not relevant because I get the same message from glxinfo and glxgears (which works), but maybe it is.

(Just hopping in here to say it’s definitely possible to build an SDL that supports both X11 and the non-X11 targets on a RPi in one library, and it should do that by default, and it should dynamically load the appropriate one…if Xlib isn’t available, or it is but there’s no X server running, SDL should move on to the next possible video target. It’s possible to misbuild the library because system headers are missing so you don’t get a target that you should, but there’s no scenario where you should ever need to build two different copies of SDL to support this.)

Note that setting of GL attributes has to happen after SDL_Init because driver initialization will reset them to the defaults.

Yeah, I don’t think the error is a problem. Seems to be a info parsing error in the DRM part and if glxgears works it should not affect SDL.

So you’re loading all GL functions with SDL_GL_GetProcAddress then? It could be that this pulls functions from the wrong library or for the wrong driver, but I have no idea how that could happen. There’s just one library around, I think.

I’m trying to get the VC4 driver to run on Raspbian and do some tests, but it’s going to take a while. Have to build Mesa again because of my old Raspberry Pi.