[Scummvm-devel] Replacing gBitFormat, OSystem::colorToRGB etc.
max at quendi.de
Mon Apr 10 11:14:02 CEST 2006
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
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