[Scummvm-devel] Scummvm-devel Digest, Vol 13, Issue 11
Neil Millstone
neil at millstone.demon.co.uk
Sun Jun 17 02:06:28 CEST 2007
Hi Max,
For the DS port, this change isn't really useful. At the moment, I'm
using copyRectToScreen() to copy data directly into the hardware
framebuffer. This memory is awkward, because it doesn't allow 8-bit
writes. So if you want to write directly to a single pixel in an 8-bit
mode you have to do a read-modify-write. This would mean I couldn't
just wrap this buffer and return it as a Graphics::Surface. I would
have to make a copy in system memory and return that, which would make
it similar to the existing grabRawScreen() method.
Although it's not a lot of work to implement, so if it helps others it's
fine by me.
- Neil
Max Horn wrote:
> 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