Render performance on Raspberry Pi

Hi all,

I am using SDL2 to develop a HUD display on a Raspberry Pi 3B. Essentially I am using PiCore distro, with a 720 x 720 TFT LCD connected to the Pi’s GPIO. I am running a simple SDL2 program in fullscreen mode.

I have set up the display and SDL2 on the Pi, that part is working fine and I can compile and run SDL2 programs with no problem.

The problem I am having is performance; by the time I draw the 720x720 background image and try and render anything over the top of it, I am struggling to get more than a couple of FPS; I did try a proof of concept previously with the same Pi on Raspberry OS and could reach framerates of 20-30, and that was unoptimised with all the usual Raspi processes running, so I hoped to get somewhere close to 60fps in an optimised/stripped down system.

My requirements are quite simple, just a 720x720 solid background bitmap with a bitmap gauge needle texture (alpha and rotation) and perhaps a few small bitmap icons drawn at each frame. My code is currently based directly on one of the image overlay/rotate SDL tutorials, and nothing I have tried makes any measureable performance improvement.

My questions are:

I’m wondering if expecting close to 60fps is realistic with the Pi 3’s graphics capability? Is drawing an entire 720x720 bitmap at each frame really that costly?

Are the some SDL tricks I can use to improve performance? I’ve tried various stuff such as SetSurfaceRLE and SetColorKey without improvement.

How can I ensure I’m running hardware accelerated in SDL? Or is this more of an OS specific thing?

Any help would be much appreciated! I’m experienced in the embedded system/graphics side, but don’t have much background in SDL2.

Thanks, Bruce.

Two main things that I can think of. Firstly you need to be using SDL_Renderer with textures rather than surfaces (and with SDL_RENDERER_ACCELERATED specified of course). Secondly, since it’s an RPi 3, you need to explicitly enable VideoCore4 hardware acceleration because it’s considered an ‘experimental’ feature:

 sudo raspi-config
 Advanced Options... GL Driver... GL (Full KMS)... Ok... Finish

This is when using standard PiOS, other distros may support this differently (if at all).

You mentioned it’s using the GPIO pins instead of HDMI. What port/protocol is the RPi communicating with the LCD over? If it’s using SPI or something it’s gonna be slower than a normal display no matter what you do.

And, as @rtrussell mentioned, using the GPU will be faster than the CPU, but only if it’s over something the GPU can output to like HDMI. If you have to use software rendering, ditch alpha blending. That’s gonna be slow even on a big beefy desktop CPU, and slow on the RPi.

When it comes to software rendering, another thing to keep in mind is that you want to redraw as little as possible. Use dirty rects, and try to avoid redrawing the entire screen every frame.

Additionally, at load time convert all your bitmaps to match the window surface’s pixel format, and then use only the converted bitmaps. Will be loads faster than converting every draw call.

SetColorKey() is only for using old fashioned on/off transparency (which you should switch to) instead of alpha blending. SetSurfaceRLE() will work in conjunction with this.

1 Like