[Scummvm-devel] Framebuffer
Max Horn
max at quendi.de
Sat Jun 16 13:38:49 CEST 2007
Hi folks,
this thread is now well over half a year old, but I finally want to
act on it. Mainly because I finally want to get rid of
OSystem::grabRawScreen() in its current form. It causes lots of
headaches and overhead for no good reason.
To refresh your memory, here is an (updated) version of my proposal:
-----------------
OSYSTEM FRAMEBUFFER API
The idea is to introduce the following new API to OSystem:
/**
* Lock the active screen framebuffer and return a Graphics::Surface
* representing it. The caller can then perform arbitrary graphics
* transformations on the framebuffer (blitting, scrolling, etc.).
* Must be followed by matching call to unlockScreen(). Calling code
* should make sure to only lock the framebuffer for the briefest
* periods of time possible, as the whole system is potentially
stalled
* while the lock is active.
* Returns 0 if an error occurred. Otherwise an 8bit surface is
returned.
const Graphics::Surface *OSystem::lockScreen();
/**
* Unlock the screen framebuffer, and mark it as dirty (i.e.
during the
* next updateScreen() call, the whole screen will be updated.
*/
void OSystem::unlockScreen();
The main purpose of this API will initially be to act as a
replacement for grabRawScreen(), which we will remove. Rationale: It
has a big CPU and RAM overhead, which is not at all needed for the
existing use cases. That is, creating SCUMM save game thumbnails, and
scrolling the screen content in SCUMM games. Esp. in the latter case,
a whole screenbuffer plus two full-screen blits are wasted for
nothing. This can be done much more efficiently with the new API.
Over time, I hope that we can also replace clearScreen (should be
straightforward; indeed we could simply provide a default OSystem
implementation for this which uses (un)lockScreen).
Later on, we might also ditch copyRectToScreen. This might require
the addition of a dirty rect API (think
OSystem::markFramebufferRectDirty(Rect r) ) to still allow for more
fine grained screen updates. Whether this would be necessary /
beneficial remains to be determined.
The updateScreen API would *not* be affected by all this, although it
might be renamed to flushScreen() or something similar.
-----------------
Implementation will start very soon now, with a default fallback
implementation based on grabRawScreen initially (just so that I can
make a quick prototype). I will then proceed to update backends
myself in those cases where it seems "easy" enough (most of them,
really, except for the NDS port). Since I usually can neither compile
nor test those backends, this means porters will have to put some
effort into cleaning up my changes -- but hopefully not very much,
most of the changes should be straightforward. Taking full advantage
of the new API, both in backends and frontends/engine, will probably
take some more time, but I feel that even the two existing two use
cases justify the change.
Some notes on future improvements:
* Johannes asked whether something similar could be implemented for
the overlay, to help the GUI code (reduce CPU and RAM usage there,
too). I say, why not. Feel free to have a go at it (e.g. by proposing
an API)
* A more refined API to tell the backend about "dirty" areas might be
helpful. Or not. I can't really judge whether ports would benefit.
For desktop machines, though, it seems that on modern machines, esp.
when using expensive scalers, it can be much more efficient to have a
copy of the previous frame around, then do a pixel-by-pixel check to
compute all pixels that need to be updated, and then update
everything at once. This might be totally different for low end
devices, though. I am reluctant to implement anything in this area
without knowing whether there are any benefits, though. Hence,
porters, if you can think of potential improvements (like a
'OSystem::markRectAsDirty' method), tell me, and promise to work with
me on testing the theory :-).
* Much more details on performance and implementation considerations
for dirty rect code vs. automatic dirty detection code can be found
in my initial mail on this thread:
<https://sourceforge.net/mailarchive/forum.php?
thread_name=D4F2CCFB-85E2-497F-A16A-7651D7DE3B13%
40quendi.de&forum_name=scummvm-devel>
Cheers,
Max
More information about the Scummvm-devel
mailing list