This post was converted from a page I put together several years ago. It is presented here for posterity and in the hopes that it may still be useful in some way.

The Simple Directmedia Layer (SDL) library provides several methods of displaying images, many of which may be used interchangeably. In order to help developers choose which method to use in a given set of situations, this post presents performance numbers for a variety of these display methods.

Background

Motivation

Simple Directmedia Layer (SDL) is a cross-platform multimedia library which has been used in the creation of several games, emulators, and other graphically driven applications. SDL provides low-level access to the graphics system, allowing program authors to maximize the performance of their program through precise use of the available graphics hardware. However, with this power comes a certain level of complexity as well as variability from differences in the hardware and the drivers used to control it. The benchmarks/statistics on this page are intended to clear up some of the doubt about the performance characteristics of video backends under some of the different sets of configuration options available, allowing program authors to make better informed decisions about which settings to use in their applications.

Flags

When a surface is created, the program author may specify a set of flags which change the behavior of the surface created. The image flags tested were:

SDL_HWSURFACE
Instructs SDL to create the surface in video memory. This flag means that the surface will reside in the video memory except when the surface is locked. This allows the surface to be drawn to the screen very quickly when it is also a hardware surface since it avoids the need to send as much data over the AGP (or PCI) bus to the video card. However, this option increases the overhead each time the surface needs to be modified, since it must first be locked and moved from video memory into main memory and then moved back to video memory when it is unlocked.
SDL_SRCCOLORKEY
Instructs SDL not to draw pixels matching a certain color, called the color key. This option allows an image to have transparency without requiring an alpha channel. When the image is drawn to the screen all pixels matching the color key are omitted, resulting in the underlying image showing through.
SDL_RLEACCEL
Enables RLE acceleration for the surface. RLE acceleration is a process used to decrease the time required to draw a color keyed image to the screen. As with a hardware surface, the reduction in draw time has a corresponding increase in modification time. Each time the image needs to be modified it must be locked, which causes the image to have the RLE process undone, then redone when the image is unlocked.
SDL_SRCALPHA
Enables alpha-blending for the surface. Alpha blending causes the pixels of an image to be blended with, rather than overwriting, the pixels currently on the screen according to the alpha value of the pixel. This allows for transparency effects as well as gradual blending between images. Dealing with blending and an alpha channel does allow for significantly more artistic control and effects at the cost of some processing. The exact cost is the subject of these tests.

Along with the options described above, which apply to images, there are several options which affect the behavior of the screen (drawing surface). The ones tested here are:

SDL_HWSURFACE
Causes similar behavior as when used for surfaces. The display surface will be created in video memory rather than main memory. This allows for faster drawing of images onto the screen, since the display surface does not need to be transferred to the video card after every frame.
SDL_DOUBLEBUF
Causes the display surface to be double buffered. This means that there are effectively 2 display surfaces. Screen updates will be drawn to the surface that is not being displayed, then a call to SDL_Flip will cause the updated surface to be displayed and the other surface to be set to receive future updates. This prevents tearing effects from appearing on the screen as different parts of the screen are updated. Instead it allows the entire screen to be updated in a single action, creating a more unified picture. Note: SDL_DOUBLEBUF requires a hardware surface to work, so specifying SDL_DOUBLEBUF is equivalent to SDL_DOUBLEBUF|SDL_HWSURFACE (the long form is used below for clarity).
SDL_FULLSCREEN
Causes the program to run in fullscreen mode. Although at first this may not seem like it would have any effect on the drawing speed of a program, it can actually have a great deal. Many video backends will not create a hardware surface if the program is not running fullscreen, it also may not allow the window to be double buffered. Even beyond these limitations, it does seem to have some effect on the performance (I am not exactly sure why and would rather avoid guessing...).

Test Setup

The test program takes an image and converts to the display format using the specified surface flags. For surfaces with SDL_SRCCOLORKEY set, it converts completely transparent pixels into color-keyed pixels. The test program then blits the image to the screen 1000 times, as fast as it can and records the time required to complete the blits, then calculates the framerate based on this time. The program runs at a resolution of 800x600. For the exact details, please consult the source to the test program.

Note that this is not necessarily a fair comparison, since in "real-world" conditions blits would be sent at greater intervals. However, for testing this would bring up problems with measurement errors for the timing of individual blits (requiring very high precision) or with the precision of sleep functions used to space out the blits. Given these caveats, the test results do seem to agree with the experienced performance under more practical conditions and none of the backends seem to be limiting themselves to the vertical refresh rate or any other constraint requiring greater spacing of the blits.

The image used for the tests was a scaled version of Klowner's See, Hear, Speak... wallpaper (the exact image used for testing is here). This image was chosen because it is similar to typical sprites found in 2D games (gradients with few colors, alpha around the edge of the images, rounded edges) and because it is just a really cute image.

Test Machine

  • Lenovo/IBM ThinkPad T60p
  • Intel Centrino Duo (T2500) @ 2GHz
  • ATI Mobility FireGL V5200
  • Kernel 2.6.21 with Debian patches (release 4)
  • fglrx 8.37.6
  • X.org 1.3.0 (7.2)
  • libDirectFB 0.9.25.1
  • SVGAlib 1.4.3
  • Windows XP Professional
  • Microsoft DirectX 9.0c

Results

DirectFB

Graph displaying blit speed for the DirectFB video backend

The DirectFB video backend is used to display graphics on a Linux framebuffer device (the console) using Direct FB. On the test system, DirectFB was running in the console on top of the vesa frame buffer. Although the test program runs at 800x600, DirectFB was unable to resize my display from 1024x768. This left a black border around the edges of the screen which, although not really important for a test program, may be a consideration for programs where visual appeal and use of screen space is important. Also, fullscreen hardware surfaces were only available at 16 bits (which may be a result of my vesafb configuration), so the test results for this configuration should be considered with this limitation.

During the testing of this video backend several notable characteristics of the backend appeared that may be worth considering before deploying a program using this backend. When SDL_FULLSCREEN was used for the display surface it caused the image to appear significantly off-center such that it wrapped around the edge of the monitor. On top of that, the color keyed images showed (sometimes significant) blinking or tearing for the hardware display surfaces, although the framerate is recorded as being impressively high (this needs further investigation). Finally, surfaces with the SDL_SRCALPHA flag did not render when the display surface was a hardware surface, so the numbers for this configuration are somewhat meaningless.

As one other implementation note, it may be necessary to pass video=vesafb:ywrap,mtrr to the kernel in order to enable hardware surfaces. DirectFB complained loudly before I added the line to the boot configuration. See the DirectFB documentation for details.


DirectX

Graph displaying blit speed for the DirectX video backend

The DirectX video backend provides graphics support using Microsoft DirectX® on Microsoft Windows® platforms. There were no unexpected visual effects or strangeness during the testing, although some of the results were unexpected. The first oddity was the surprisingly low framerate for surfaces with the SDL_SRCALPHA flag on a SDL_HWSURFACE display surface. In fact, the low framerate caused the test to run for a long enough time that there was debate about whether or not the test had frozen. Another oddity was the low framerate on the double-buffered display surface. My guess is that when double-buffered the render code waits for a vblank before finishing, so the framerate is capped at the refresh rate of the monitor (which would explain the 60 fps recorded for double-buffered output on the test machine). One other caveat to note is that it is not possible to allocate a hardware surface unless the display surface is fullscreen (and a hardware surface, of course).

FBCon

Graph displaying blit speed for the FBCon video backend

The FBCon video backend provides graphics support for consoles using the Linux Framebuffer. Although this driver does support hardware display surfaces, requesting a display surface with SDL_HWSURFACE caused the test machine to hard lock and prevented gathering any test data for these surfaces. (Note that this may be worth checking against before allocating a hardware display surface to prevent hard locking a client's machine).

glSDL

Graph displaying blit speed for the glSDL video backend

The glSDL video backend stands out in comparison to many of the other backends in that it works in concert with another backend to blit images using OpenGL. This backend may provide performance improvements on computers with hardware 3D acceleration where the work of blitting an image can be offloaded to the graphics processor through OpenGL. In this test, the glSDL backend was running on top of the X11 backend on Linux.

The state of this backend in the SDL community is also somewhat ambiguous. The original patches to SDL were the work of David Olofson and Stephane Marchesin, and are available as a patch providing the backend or as a wrapper around SDL. Although there has been much discussion of including the backend with SDL or in writing a different implementation of its features, neither solution has materialized and the backend remains largely unsupported. Even applying the patch to the latest libSDL requires quite a bit of work.

For this test, a reworked version of the glSDL backend patch against libSDL 1.2.11 was used. However, there is an error somewhere in the patch which results in color inversions under many of the testing conditions (whether this was introduced in the reworking or if it was present in the original patch is unknown). This appears to be the result of incorrect RGBA ordering in the DisplayFormatAlpha function (or that only manifests when this function is used). Hopefully, I will have the time to fix this in the near future...

SVGAlib

Graph displaying blit speed for the SVGAlib video backend

The SVGAlib video backend provides graphics support for Linux using SVGAlib. This video backend is not capable of dealing with hardware surfaces, so those results are omitted from the graph. Note that the version of SVGAlib used for testing (1.4.3) requires that the user be root. This likely provides a significant hurdle for potential end-users of a program using the SVGAlib backend and in addition it may affect the scheduling of the test program by the operating system and skew the test results (although I am unsure of this).

WinDIB

Graph displaying blit speed for the WinDIB video backend

The WinDIB video backend provides graphics support for Microsoft Windows® platforms using Windows® GDI. This backend does not support hardware surfaces and therefore those results are omitted from the graph.

X11

Graph displaying blit speed for the X11 video backend

The X11 video backend provides graphics support for the X Window System. This video backend does not support hardware surfaces and therefore those results have been omitted from the graph.

Notable Missing Backends

Unfortunately, the test box does not support the DGA extension, which prevents testing of the DGA video backend.

Conclusions

Across all of the graphics backends the use of RLE acceleration showed a significant speed increase for color keyed images. Interestingly, the use of color keys alone shows a highly dramatic decrease in framerate as compared to both non-color keyed surfaces and surfaces using source alpha. For surfaces where a color key is required and the surface will not be modified often, the use of RLE acceleration seems like a must.

The glSDL backend shows particularly high performance for use with hardware surfaces. If the problems with colors can be overcome, or a new implementation of an OpenGL-based backend is created, this option seems like a winner. However, given the current limitations, it does not appear to be ready for production programs.

Although hardware and double-buffered surfaces are likely to provide the highest performance, they showed a particularly high degree of strange effects and poor performance in the test environment. I strongly suggest that if the use of hardware surfaces is being considered for an SDL application that a significant amount of testing be done on a variety of systems to ensure that none of the undesired visual effects or low performance is encountered on target systems.

Beyond those observations, the best suggestion is to try a few combinations and see what works best with your program. As always, take it all with a grain of salt and go with practical experience. Best of luck!


References/More Information

  1. SDL API Documentation for SDL_Surface
  2. LinuxJournal Article: A Crash Course in SDL
  3. Linux DevCenter: Animation in SDL: Hardware Surfaces