[Scummvm-devel] Replacing gBitFormat, OSystem::colorToRGB etc.

Max Horn max at quendi.de
Mon Apr 10 11:14:02 CEST 2006

Hi folks,

I meant to write about this a week ago, but apparently forgot and  
only updated the TODO (see also <http://wiki.scummvm.org/index.php/ 
TODO>). Seems age is getting at me :-).

Anyway, here's the deal: We currently have a hack that is called  
gBitFormat and which is used by the scaler code and the new GUI code  
for optimized drawing. This has posed some problems in the past for  
porters (Hi Marcus :-), and is generally a bit hackish (it doesn't  
support anything but 565 and 555 mode -- no alpha channels, no 4444,  
and of course no palette modes).

Parallel to this, we have the OSystem::colorToRGB etc. API, which was  
introduced for the old GUI code (or should I call it "old new gui",  
as opposed to the "real old gui" code back from the ScummVM stoneage?  
But I digress *g*). It converts between (A/)R/G/B tuples and  
"OverlayColors", thus providing an abstraction layer, which deals  
with precisely the issues gBitFormat is troubled by.

This API has a big disadvantage, too: It's slow by design. If you  
need to use it for color fades, for example, you have to (1) call  
OSystem::colorToRGB (a virtual method call, thus extremely slow), (2)  
play with the RGB data, (3) call OSystem::RGBToColor (another virtual  
method call). Ouch. Operations that ordinary could run in a few  
cycles in a few registers suddenly have to do indirect branches,  
possibly involving stack manipulations and more. Yuck.

This issue so far was pretty unimportant, but with the new GUI code,  
we actually *want* to do pixel operations, like dimming or color  
gradients. Due to the slow nature of colorToRGB etc., the new GUI  
code was forced to introduce a color cache. But this causes new  
problems: It takes lots of memory (a couple hundred kb), which is bad  
for low end devices. And it takes some time to compute it -- which  
forced LordHoto to introduce a file cache for the color cache. Ouch  

Hence, my desire to finally get rid of both in favor of a new  
approach: We introduce an OSystem API that allows querying the  
pixelformat of the screen surface (and possibly another for the  
overlay). Similar in spirt to <http://www.libsdl.org/cgi/docwiki.cgi/ 
SDL_5fPixelFormat>. This way, client code can properly be optimized.  
Dealing with alpha channels becomes trivial, too (and  
kFeatureOverlaySupportsAlpha, currently only used by the DC port, can  
go away).

Using a pixelformat makes it possible to write both "generic but  
slow" functions that always work (well, possibly with another special  
case for palette based systems), as well as "special but fast"  
functions (i.e. we could provide optimized code for 555 and 565  
systems, just like we do now).

If nobody objects (in particular porters), I would like to implement  
this pretty soon. The exact details are not yet fully hashed out, but  
basically it's about adding a PixelFormat struct similar to the SDL  
one, two methods to OSystem for querying the screen / overlay pixel  
formats, and a couple of helper functions that demonstrate how to get/ 
set pixels based on the pixelformat info.

In the future, beyond what we need now, I would like to change our  
backends to allow direct access to the screen /overlay surfaces, *if  
that's possible (not sure*), and also change our struct Surface to  
use a pixelformat, too. But that's even sketchier in my mind ;-).


More information about the Scummvm-devel mailing list