UpdateRects VS Flip

Hi all,

I was wondering about performance comparison between UpdateRects and Flip.
I’m aware that Flip() has a special behavior when double buffering is activated,
and is reduced to UpdateRect(0,0,screen->w,screen->h) when it is not activated.

My question to you is, don’t you think that from a certain number of dirty rectangles,
it’s quicker to use SDL_Flip() than using SDL_UpdateRects() ?

Cheers_____________________________________________________________________________
Envoyez avec Yahoo! Mail. Une boite mail plus intelligente http://mail.yahoo.fr

Hello !

My question to you is, don’t you think that from a certain number of
dirty rectangles,
it’s quicker to use SDL_Flip() than using SDL_UpdateRects() ?

It is, but it is hard to guess at what Nr. the first is better than
the second. It depends a lot on what machine you are using, what gfx card
and so on.

Also if your app or game is scrolling for example SDL_Flip is
most of the time quicker and easier to use.

CU

Torsten Giebl <wizard syntheticsw.com> writes:

Hello !

My question to you is, don’t you think that from a certain number of
dirty rectangles,
it’s quicker to use SDL_Flip() than using SDL_UpdateRects() ?

Yes it is.
But I can’t almost find an SDL engine that is made in this way.
Everyone just say “I have accelerated hardware or opengl so I don’t care”.

It is, but it is hard to guess at what Nr. the first is better than
the second. It depends a lot on what machine you are using, what gfx card
and so on.

Also if your app or game is scrolling for example SDL_Flip is
most of the time quicker and easier to use.

I agree about easier… but most of time quicker?
I don’t think so!
As you said before… it depends!
On old machines and without full screen mode SDL_Flip is a mess for performance.

The is an old (never finished) Ultima Online client based on SDL called
"Aracnide" that don’t use Flip and implements a lot of code in order to redraw
only what is needed (with updaterects, bitmasks etc) and is a lot of faster than
Flip.

Obviously it has its limits: no alpha and only 16 bit depth.

Guido

My “Mad Bomber” game is, admittedly, one of the few games where I did
dirty-rectangle updates to the screen. (I wrote it on a 133MHz Pentium,
mind you.)

I didn’t bother in “Defendguin” because most of the time, lots of stuff
was being scrolled on the screen, so I just wiped it all and drew it
over again each frame. (I wrote it on a 133MHz Pentium, too, and it worked
pretty well, so it’s not awful :^) )On Fri, Jul 11, 2008 at 03:32:18PM +0000, Guido wrote:

Yes it is.
But I can’t almost find an SDL engine that is made in this way.
Everyone just say “I have accelerated hardware or opengl so I don’t care”.


-bill!
“Tux Paint” - free children’s drawing software for Windows / Mac OS X / Linux!
Download it today! http://www.tuxpaint.org/

This is just me doing wild guessing, but since each check against
rectangles is, say, around a half-dozen logic operations (at most),
throw in a few others for loops, etc… and then estimating that a
logic operation takes a similar amount of time as a memory copy to
perform (or even maybe twice as long? 3x? I’m not a CS major, so…

.>), then you’ve got a lot of extra rectangles you can check with
the time it would take to draw all those extra pixels to the buffer
for a full redraw. I would guess that unless you’re going to have to
redraw everything anyway, or you’re checking a number of rectangles on
an order of magnitude similar to the number of pixels in your buffer
(640 * 480 = 307,200 pixels * number of color channels for memory
copying) then you may well be saving a LOT of time doing dirty-
rectangle checks.

No promises on this, and ALL of these numbers were basically guesses,
so I’m willing to accept that my answer is way off, but I think it’s
probably not so far off as to no longer be applicable. :slight_smile: Admittedly
I’m not including the creation of union dirty rectangles, or the time
taken to draw out the new pixels or anything, so that throws the
direct usage of my numbers out the window, but still I think unless
your sprites take up (and move across) a significant portion of your
screen and/or you’re dealing with, around half or more sprites as the
number of pixels, you are probably saving significant amounts of time.

Probably.

My < $.02. :slight_smile:

– ScottOn Jul 11, 2008, at 6:20 PM, julien CLEMENT wrote:

Hi all,

I was wondering about performance comparison between UpdateRects and
Flip.
I’m aware that Flip() has a special behavior when double buffering
is activated,
and is reduced to UpdateRect(0,0,screen->w,screen->h) when it is not
activated.

My question to you is, don’t you think that from a certain number of
dirty rectangles,
it’s quicker to use SDL_Flip() than using SDL_UpdateRects() ?

Cheers

???
…as a man’s knowledge widens, ever the way he can follow grows
narrower; until at last he chooses nothing, but does only and wholely
what he must do…
? Ursula K. Le Guin “A Wizard of Earthsea”

copying) then you may well be saving a LOT of time doing dirty-rectangle
checks.

In a non-SDL project of mine with a dirty rects implementation, each
dirty rect update increments a pixel count and a rect count. When it
comes time to render the dirty rects, it checks both counts against
some randomly-guessed-pre-determined values (been a while, i believe
they’re set to 16 rects / half the number of pixels of the screen)…
and if either condition is beyond the ‘punt’ value, it just does a
complete reblit from the offscreen source. It seemed to do pretty
good at deciding when to do one or the other.

-Will

Torsten Giebl <wizard syntheticsw.com> writes:

Hello !

My question to you is, don’t you think that from a certain
number of dirty rectangles,
it’s quicker to use SDL_Flip() than using SDL_UpdateRects() ?

Yes it is.
But I can’t almost find an SDL engine that is made in this way.
Everyone just say “I have accelerated hardware or opengl so I don’t
care”.

Well, if you have some 2D backend with actual page flipping,
SDL_Flip() is the way to go, as that’s basically a no cost operation,
involving no copying of VRAM data.

Now, OpenGL isn’t really an excuse, as it may well be using
back-to-front copy blits for “swapping”. You’ll see this in windowed
mode on most platforms, and in some cases (xf86, xorg, …) even in
fullscreen mode. Even though it’s hardware accelerated, it’s not
free, and will actually bring less powerful video cards to their
knees in high resolution.

Basically, always consider “smart” refresh methods if your application
normally only animates part of the display area - especially if it
can run in high resolutions. Even with full acceleration, a slower
video card may not even be able to do full screen/full window "flips"
by copying without dropping to annoyingly low frame rates.

Also, it’s generally bad manners wasting CPU and/or GPU power doing
essentially nothing. It generates heat (my quad core dual video card
monster keeps my room warm quite well as it is, thank you!) and
consumes power, which is particularly annoying if you’re using some
mobile device on battery power.

It is, but it is hard to guess at what Nr. the first is better
than

the second. It depends a lot on what machine you are using, what
gfx card

and so on.

Also if your app or game is scrolling for example SDL_Flip is
most of the time quicker and easier to use.

I agree about easier… but most of time quicker?
I don’t think so!
As you said before… it depends!
On old machines and without full screen mode SDL_Flip is a mess for
performance.

Well… I was going to say that if you’re actually scrolling the
whole screen at all times, SDL_Flip() is the way to go - but it’s not
quite that simple!

Say you have a scrolling shooter; ie a constantly scrolling background
with some sprites over it. You could just do the na?ve thing and
repaint the whole screen and then calling SDL_Flip() every frame.

That’s optimal if you have hardware page flipping, and allows you to
take advantage of retrace sync where available.

However, if you don’t have hardware page flipping, you’ll end up
blitting more than two full screen’s worth of data for every frame!
First you render the background, then the sprites… and then you
copy it all to the frame buffer.

Obviously, you can’t (usually) avoid that by simply rendering directly
to the display buffer, as that would result in flickering sprites and
whatnot. (Well, you can avoid that by doing “halv buffering”, but I
wouldn’t recommend that on any normal operating system.)

So, what you do is emulate hardware scrolling. That is, drop the SDL
shadow surface (ie use a single buffered display surface) and replace
it with some constellation of custom back buffers, arranged so that
you can get away with only moving the sprites and rendering a small
fraction of new background graphics every frame. This way, a
quiescent scene takes only ever so sligthly more than one full screen
blit (the “flip” blit) per frame, whereas the na?ve “repaint all,
then flip” method would take two full screen blits per frame.

Of course, if you don’t mind rolling your own blitters, you could come
up with some sort of method of rendering the screen progressively as
a one step blit with no intermediate buffers. S-buffering springs to
mind… This may also have the advantage of eliminating overdraw,
which can matter a great deal if you have lots of sprites, parallax
layers or other things that would impact “painter’s algorithm” a lot.

The is an old (never finished) Ultima Online client based on SDL
called “Aracnide” that don’t use Flip and implements a lot of code
in order to redraw only what is needed (with updaterects, bitmasks
etc) and is a lot of faster than Flip.

Obviously it has its limits: no alpha and only 16 bit depth.

Well, that’s the downside of custom blitters, I suppose… :slight_smile:

//David Olofson - Programmer, Composer, Open Source Advocate

.------- http://olofson.net - Games, SDL examples -------.
| http://zeespace.net - 2.5D rendering engine |
| http://audiality.org - Music/audio engine |
| http://eel.olofson.net - Real time scripting |
’-- http://www.reologica.se - Rheology instrumentation --'On Friday 11 July 2008, Guido wrote:

hi,

pygame(SDL in python) has a sprite module (pygame.sprite.DirtySprite,
and pygame.sprite.LayeredDirty) which compares the approach (flip vs
dirty) and chooses the better one. It depends on what you’re drawing,
and the computer. So choosing that at runtime is best.

cheers.On Fri, Jul 11, 2008 at 7:20 PM, julien CLEMENT wrote:

Hi all,

I was wondering about performance comparison between UpdateRects and Flip.
I’m aware that Flip() has a special behavior when double buffering is
activated,
and is reduced to UpdateRect(0,0,screen->w,screen->h) when it is not
activated.

My question to you is, don’t you think that from a certain number of dirty
rectangles,
it’s quicker to use SDL_Flip() than using SDL_UpdateRects() ?

Cheers


Envoy? avec Yahoo! Mail.
Une boite mail plus intelligente.


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

pygame(SDL in python) has a sprite module (pygame.sprite.DirtySprite,
and pygame.sprite.LayeredDirty) which compares the approach (flip vs
dirty) and chooses the better one. It depends on what you’re drawing,
and the computer. So choosing that at runtime is best.

I wanted to do something like that, but one thing to remember is that
when there is actual page flipping happening, the blits you do to one
page has to be done to the others…

So if you’re doing something like just one sprite moving across a
background efficiently, by putting back the piece of background where
it used to be, then blitting just the sprite itself at the new
location, it will be incorrect, because the old location on the
alternate page will be the one before that.

If your game redraws the whole screen every time (very common for
software 3D renderers, for example, and possibly some other types of
games), then flipping is fine, and there’s not even a point of
selecting at runtime between flipping and updating, since you’d do a
full screen update anyway, and that’s what SDL_Flip does when it can’t
really do page flipping…On Sat, Jul 12, 2008 at 3:12 AM, Ren? Dudfield wrote:


http://pphaneuf.livejournal.com/

Agreed. If you’re able to use double-buffering, dirty rects are more trouble than they’re worth, and you can generally draw the whole screen fast enough to not need them.>----- Original Message ----

From: Pierre Phaneuf
Subject: Re: [SDL] UpdateRects VS Flip

On Sat, Jul 12, 2008 at 3:12 AM, Ren? Dudfield wrote:

I wanted to do something like that, but one thing to remember is that
when there is actual page flipping happening, the blits you do to one
page has to be done to the others…

[…]On Saturday 12 July 2008, Pierre Phaneuf wrote:

On Sat, Jul 12, 2008 at 3:12 AM, Ren? Dudfield wrote:

pygame(SDL in python) has a sprite
module(pygame.sprite.DirtySprite,
and pygame.sprite.LayeredDirty) which compares the approach (flip
vs dirty) and chooses the better one. It depends on what you’re
drawing, and the computer. So choosing that at runtime is best.

I wanted to do something like that, but one thing to remember is
that when there is actual page flipping happening, the blits you do
to one page has to be done to the others…

You just keep one set of “dirtyrects” for each page, so you can remove
the sprites from the page at hand, however old it may be. :slight_smile:

This is what I do in Fixed Rate Pig:
http://olofson.net/mixed.html

Kobo Deluxe also does this, though it’s only really used for the
displays and bar graphs, as the playfield is scrolling constantly.

The tricky part is finding out how manny pages there actually are, and
how flipping is performed; ie if you can trust that the contents of
old pages are preserved when flipping. There is no official, safe
method of doing this.

For Kobo Deluxe, I’m considering a hack that literally checks it
during initialization, by rendering “counter patterns”, flipping and
reading back, to see if/when previous pages come back. (As it is, you
have to configure it manually if your system doesn’t behave as Kobo
Deluxe expects.)

//David Olofson - Programmer, Composer, Open Source Advocate

.------- http://olofson.net - Games, SDL examples -------.
| http://zeespace.net - 2.5D rendering engine |
| http://audiality.org - Music/audio engine |
| http://eel.olofson.net - Real time scripting |
’-- http://www.reologica.se - Rheology instrumentation --’

Well, “generally” is the keyword here. This may be true for your
average (ie overkill) PC in reasonable resolutions, and/or with
proper hardware acceleration - but does availability of true double
buffering (ie hardware page flipping) automatically imply that you’re
on a “fast enough” machine? :slight_smile:

Of course, you also have to be realistic about scalability. Making
games run really well on “anything” is a great deal of extra work.

//David Olofson - Programmer, Composer, Open Source Advocate

.------- http://olofson.net - Games, SDL examples -------.
| http://zeespace.net - 2.5D rendering engine |
| http://audiality.org - Music/audio engine |
| http://eel.olofson.net - Real time scripting |
’-- http://www.reologica.se - Rheology instrumentation --'On Saturday 12 July 2008, Mason Wheeler wrote:

Agreed. If you’re able to use double-buffering, dirty rects are more
trouble than they’re worth, and you can generally draw the whole
screen fast enough to not need them.

Well, “generally” is the keyword here. This may be true for your
average (ie overkill) PC in reasonable resolutions, and/or with
proper hardware acceleration - but does availability of true double
buffering (ie hardware page flipping) automatically imply that you’re
on a “fast enough” machine? :slight_smile:

Actually, on faster machines, there seems to be less and less
availability of true double buffering based on page flipping! More
often than not, there’s an offscreen buffer that is just blitted to
the screen, which is okay when you’ve got a good enough video
card/hardware. Page flipping is kind of a hack that is useful mostly
for those lower end platforms, especially for something like the
original Doom, which blew away 97% of the screen on every frame, so
there was just no point in trying to do update rectangles.

Of course, you also have to be realistic about scalability. Making
games run really well on “anything” is a great deal of extra work.

The problem is that with SDL_Flip, there is a semantic difference
between having hardware page flipping and not having it.

For example, someone clever could make a two-frame flashing animation
by simply blitting one frame, flipping, blitting the other frame, then
flipping from one to the other without blitting anything to keep on
animating it. This would be valid and work correctly with hardware
page flipping, and would not update correctly when SDL_Flip would be
transformed into a fullscreen SDL_UpdateRect.

Likewise, simulating SDL_UpdateRects with SDL_Flip when you have
hardware page flipping is a little bit tricky (although I guess it
would be possible, by saving the content of the blits for the previous
frame and replaying them?), due to SDL_Flip giving you the screen as
it was two frames ago (you blit image A, then flip, blit image B,
then flip, what you are working with now if you want to do a partial
update is image A, not image B, as would be the case without page
flipping, but you could fake it by replaying the blit of image B).

So, in conclusion, a pain in the ass, yes.On Sat, Jul 12, 2008 at 3:44 PM, David Olofson wrote:


http://pphaneuf.livejournal.com/

[…]

Well, “generally” is the keyword here. This may be true for your
average (ie overkill) PC in reasonable resolutions, and/or with
proper hardware acceleration - but does availability of true
double buffering (ie hardware page flipping) automatically imply
that you’re on a “fast enough” machine? :slight_smile:

Actually, on faster machines, there seems to be less and less
availability of true double buffering based on page flipping! More
often than not, there’s an offscreen buffer that is just blitted to
the screen, which is okay when you’ve got a good enough video
card/hardware.
[…]

Yes, I’ve noticed this is pretty common, at least in OpenGL drivers.

And of course, most non workstation video cards (still?) lack hardware
windowing support, so whenever you’re in windowed mode, it’s either
flipping the whole desktop (which no widely used desktop environment
does, AFAIK), or back-to-front blits…

[…]

Likewise, simulating SDL_UpdateRects with SDL_Flip when you have
hardware page flipping is a little bit tricky (although I guess it
would be possible, by saving the content of the blits for the
previous frame and replaying them?),

Either that, or as I do it in Kobo Deluxe; callbacks. Each window
object has a “render” method that the engine calls whenever it needs
the area refreshed - that is, twice after each change, when running
on a true page flipped display.

due to SDL_Flip giving you the screen as
it was two frames ago (you blit image A, then flip, blit image B,
then flip, what you are working with now if you want to do a partial
update is image A, not image B, as would be the case without page
flipping, but you could fake it by replaying the blit of image B).

Yeah, I deal with this to some extent in the Fixed Rate Pig example -
but I don’t bother detecting what kind of “flipping” is used.
Instead, I abuse the “dirtyrect optimizer” a little, and hand it the
dirtyrect sets for both pages. That way, I cover the full area two
frames back, avoiding glitches regardless of whether the screen is
flipped or copied.

So, in conclusion, a pain in the ass, yes.

Yep - but Fixed Rate Pig will pump out hundreds or even thousands of
FPS on pretty much anything. :wink:

What I’m saying is, unless you really are animating essentially the
entire screen at the full frame rate, there is a lot of speed to gain
here - or, a let of battery power to save. :slight_smile:

//David Olofson - Programmer, Composer, Open Source Advocate

.------- http://olofson.net - Games, SDL examples -------.
| http://zeespace.net - 2.5D rendering engine |
| http://audiality.org - Music/audio engine |
| http://eel.olofson.net - Real time scripting |
’-- http://www.reologica.se - Rheology instrumentation --'On Saturday 12 July 2008, Pierre Phaneuf wrote:

On Sat, Jul 12, 2008 at 3:44 PM, David Olofson <@David_Olofson> wrote: