[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