Recently I have been looking again at the issue of generating large images for a Free Pascal program at interactive display rates. There are two scenarios where I find this useful, creating a back-buffer for graphically intensive programs such as GIS mapping or procedural graphics applications. The second is for command-line, or server tools that can synthesise images in real-time for feeding into a web server response.
The bottlenecks encountered when developing high performance bitmap graphics are usually due to either the cost of access to individual pixels, or the transfer cost of a graphics buffer to screen or file. For display access, the programmer is at the mercy of both the system’s desktop shell and the hardware driver.
I have come across these hurdles repeatedly in my career. To many, the obvious solution would be to use the now ubiquitous hardware based GPU options, most likely OpenGL or OpenGLES. Whilst they are very powerful there are two capabilities I need that are not so easy to achieve with this approach: complex polygon filling and high quality vector font rendering. In addition, when targeting embedded systems or older hardware, these interfaces may not be available at all.
These days I also require code to be highly portable and ideally with very few external dependencies beyond the units supplied with Free Pascal and Lazarus. In the past I have found the best results were achieved with the Graphics32 library. Unfortunately, its development seems to have slowed of late and its support for Lazarus can be patchy. Another very useful library is which was developed specifically for Lazarus and is the rendering library behind the LazPaint image editor. This unfortunately does not compile with the current trunk compiler 3.1.1 due to changes in the UTF8 text handling, although I expect this will be fixed in due course. Also both of these libraries are a poor choice for the sever/command-line role as they depend upon the LCL desktop interface.
There are many other graphics libraries, AggPas, Vampyre, LazRGBGraphics to name a few. All of them share the same basic premise of handling memory images directly and optimise reading and writing pixels, but they are written from the ground up and so are not well integrated for use with the native image handling of Free Pascal and Lazarus.
So what are the native capabilities of Free Pascal and Lazarus and why have so many additional libraries been written? The graphics library distributed with Free Pascal is called FCL-Image and it supports all of the common image file formats and provides a a memory based drawing canvas interface. There is also the TBitmap implementation in the Lazarus Graphics unit. This is largely compatible with Delphi’s TBitmap and uses the FCL for some of its file and drawing capabilities. Unfortunately, both libraries are very slow in use compared to the third party libraries mentioned before. The fundamental reason for this is due to the FCL library abstracting pixel representation as a 64bit quantity. Whilst this provides superior colour accuracy, for more common place 32bit colour depths, it comes at the cost of requiring per pixel conversion between the two colour forms. This conversion overhead is especially noticeable for large images being transferred to files or the screen.
I have attempted to use FCL-Image on a couple of occasions but ended up rejecting the solution because I couldn’t get the performance to an acceptable level for my application. In both cases, I found myself wishing in frustration that I could use the 32bit techniques of the other libraries within the FCL. As it happens, I have now discovered that you can and that will be the subject of my next post!