[…]
One way that I overcame that difficulty, though I’m positive it’s
not as good as David Olofson’s, was to create a second hardware
surface the same size as the screen, and do all of my blits to that
surface, and when I was done composing a scene, blit that one big
surface to the video surface. This gave me very good FPS, kept away
the flickering, but it is susceptible to “tearing”/not being synched
with the vertical refresh(oh yes, this technique does not use
SDL_DOUBLEBUF)… well, it probably wasn’t worth much, but that was
something I tried long ago.
I use a very similar approach to deal with the performance issues with
software alpha blending into VRAM. Basically the same thing - a
shadow surface, as I call it - except I make sure it’s a software
surface, so that it’s not in VRAM. This avoids the expensive VRAM
reads that the software alpha blitter has to do, and with some luck
(at least theoretically), the blit from the shadow surface to the
display surface can use DMA. (Or it can be made asynchronous by means
of the SDL_ASYNCBLIT flag, in case there’s an extra CPU hanging
around.)
BTW, this can be combined with SDL_DOUBLEBUF just fine. This is what I
used to call “SemiTriple” buffering in Kobo Deluxe. Again, same
setup, but with a double buffered hardware display surface (for
retrace sync’ed page flipping where available), and an SDL_Flip()
call following each shadow->display blit.
Also, both of these arrangements can be combined with dirty
rectangles!
IIRC, I do the “full deal” in Pig; double buffered hardware display
surface to eliminate tearing, software shadow buffer for fast alpha
blending (lots of AA and translucency), and dirty rectangles for
reducing the shadow->display blit bandwidth. Perhaps apart from a
better dirty rectangle manager, I think this is pretty much as
optimal as it gets for applications like this; ie “a bunch of sprites
moving over a mostly still background”.
(The Pig dirty rectangle merging algorithm can be suboptimal if you
throw certain sequences at it, because it only considers the current
full state and the new rectangle when adding a new rectangle. It
would be smarter, but probably also a lot more complex if it did all
the merging in one step, with all rectangles at hand. Microtiles
might be a simpler and better alternative - proven and used in a few
GUI toolkits and game engines.)
BTW, anyone doing full screen scrolling should probably forget about
dirty rectangles. The only situation where they’d make sense with a
full screen scroller is if moving sprites is very expensive compared
to blitting from the shadow surface to the display.
Say, you’re doing real time shadow casting and stuff. Maybe the
"sprites" are actually real time rendered structured graphics? Of
course, you want ultra smooth scrolling - but no one can tell whether
slow moving objects and shadows are animated at the full frame rate!
Then it might make sense to set up something like emulated hardware
scrolling, with a “shadow” buffer that is larger than the display
surface.
Otherwise, just repaint the whole screen every frame, using a software
shadow surface if you need alpha blending and only s/w alpha is
available.
//David Olofson - Programmer, Composer, Open Source Advocate
.- Audiality -----------------------------------------------.
| Free/Open Source audio engine for games and multimedia. |
| MIDI, modular synthesis, real time effects, scripting,… |
`-----------------------------------> http://audiality.org -’
— http://olofson.net — http://www.reologica.se —On Wednesday 24 August 2005 23.48, David Olsen wrote: