SDL_UpdateRect() question

I’m a newbie to SDL…pretty much the only thing I need clarification on
though is the following:
Is it better to just call SDL_UpdateRect() once on the entire screen to
update it, or should I be calling it for every single
little image that I write to the screen? I’m used to graphics programming
where I’ve got a separate in memory surface that I do all my initial drawing
to, and then I just call a flip() sort of method to swap the screen’s
contents with my buffer. I assume the method though in SDL is to use
UpdateRect? Thanks for your help.--------------------------------------------------------
Jeff W.
ICQ: #17989474


http://8bitavatar.org

“Jeff W.” wrote:

Is it better to just call SDL_UpdateRect() once on the entire screen to
update it, or should I be calling it for every single
little image that I write to the screen?

if you have more than one changed region, use SDL_UpdateRects(), not
SDL_UpdateRect(). Don’t call either more than once per frame

so it’s more efficient to call UpdateRects, with a rectangle for every item
that needs to be updated, than to just call UpdateRect on the entire screen?
I guess my problem is that I don’t fully understand how SDL is actually
doing it’s blitting. It would just seem to me that UpdateRects is less
efficient than an UpdateRect on the entire screen. Is it because an
UpdateRect on the entire screen has to update the WHOLE screen, whereas
UpdateRects will only update those rectangular regions passed into it?> “Jeff W.” <@Jeff_W> wrote:

Is it better to just call SDL_UpdateRect() once on the entire screen to
update it, or should I be calling it for every single
little image that I write to the screen?

if you have more than one changed region, use SDL_UpdateRects(), not
SDL_UpdateRect(). Don’t call either more than once per frame


SDL mailing list
SDL at libsdl.org
http://www.libsdl.org/mailman/listinfo/sdl

Jeff W. wrote:

so it’s more efficient to call UpdateRects, with a rectangle for every item
that needs to be updated, than to just call UpdateRect on the entire screen?
I guess my problem is that I don’t fully understand how SDL is actually
doing it’s blitting. It would just seem to me that UpdateRects is less
efficient than an UpdateRect on the entire screen. Is it because an
UpdateRect on the entire screen has to update the WHOLE screen, whereas
UpdateRects will only update those rectangular regions passed into it?

when using software surfaces with SDL, blitting to the display surface
doesn’t really blit to the screen. you can think of it as an internal
double buffer. when you make the call to update, the contents of this
software backbuffer are then sent to the screen. now you can update the
entire display, it just copies the entire surface to the screen. if your
game only has sprites moving around it can be a big timesaver to only
"flip" / “update” the areas of the screen that changed. even if half the
screen is moving around, you can see a noticeable speedup by only
updating the changed areas.

of course, if your game has a fullscrolling background, or some
situation where the entire screen changed every frame, there’s nothing
to be gained with specific updates :]

Pete Shinners wrote:

when using software surfaces with SDL, blitting to the display surface
doesn’t really blit to the screen. you can think of it as an internal
double buffer.

it *is’ an internal double buffer :slight_smile:

I’m a newbie to SDL…pretty much the only thing I need
clarification on though is the following:
Is it better to just call SDL_UpdateRect() once on the entire
screen to update it, or should I be calling it for every single
little image that I write to the screen? I’m used to graphics
programming where I’ve got a separate in memory surface that I do
all my initial drawing to, and then I just call a flip() sort of
method to swap the screen’s contents with my buffer. I assume the
method though in SDL is to use UpdateRect? Thanks for your help.

If you update large portions of the screen it’s probably better to
use SDL_Flip(screen). Just be sure to pass SDL_DOUBLEBUF as a flag to
SDL_SetVideoMode first. If double buffering is supported at the
current diplay target, SDL_Flip flips the screen buffers, if it
isn’t, SDL_Flip is equivalent to SDL_UpdateRect on the whole screen.
So, it works either way =) .–
Trick


Linux User #229006 * http://counter.li.org

Actually, if you care about performance don’t do that. Check whether or
not you get a hardware back surface when asking for
SDL_DOUBLEBUF|SDL_HWSURFACE, and if not, use SDL_UpdateRects() instead of
SDL_Flip().

//David Olofson — Programmer, Reologica Instruments AB

.- M A I A -------------------------------------------------.
| Multimedia Application Integration Architecture |
| A Free/Open Source Plugin API for Professional Multimedia |
----------------------------> http://www.linuxdj.com/maia -' .- David Olofson -------------------------------------------. | Audio Hacker - Open Source Advocate - Singer - Songwriter |-------------------------------------> http://olofson.net -'On Wednesday 10 October 2001 16:32, Trick wrote:

I’m a newbie to SDL…pretty much the only thing I need
clarification on though is the following:
Is it better to just call SDL_UpdateRect() once on the entire
screen to update it, or should I be calling it for every single
little image that I write to the screen? I’m used to graphics
programming where I’ve got a separate in memory surface that I do
all my initial drawing to, and then I just call a flip() sort of
method to swap the screen’s contents with my buffer. I assume the
method though in SDL is to use UpdateRect? Thanks for your help.

If you update large portions of the screen it’s probably better to
use SDL_Flip(screen). Just be sure to pass SDL_DOUBLEBUF as a flag to
SDL_SetVideoMode first. If double buffering is supported at the
current diplay target, SDL_Flip flips the screen buffers, if it
isn’t, SDL_Flip is equivalent to SDL_UpdateRect on the whole screen.
So, it works either way =) .

It seems like SDL_UpdateRects() is a NOP in h/w pageflipping setups, you
you have to use SDL_Flip() instead. Did I get that right?

BTW, the Kobo Deluxe engine has a buffering mode called “SemiTriple”, in
which rendering is done in a software buffer, and where flip() first
blits the current list of dirty rectangles [one list per buffer] into the
VRAM back buffer, and then performs SDL_Flip(). If the back buffer turns
out to be a software buffer, the engine automatically eliminates the
rendering buffer, and switches to the SDL_UpdateRects() method.

//David Olofson — Programmer, Reologica Instruments AB

.- M A I A -------------------------------------------------.
| Multimedia Application Integration Architecture |
| A Free/Open Source Plugin API for Professional Multimedia |
----------------------------> http://www.linuxdj.com/maia -' .- David Olofson -------------------------------------------. | Audio Hacker - Open Source Advocate - Singer - Songwriter |-------------------------------------> http://olofson.net -’

Why?On Wed, Oct 10, 2001 at 10:28:06AM +0200, Mattias Engdegard wrote:

“Jeff W.” wrote:

if you have more than one changed region, use SDL_UpdateRects(), not
SDL_UpdateRect().

If you update large portions of the screen it’s probably better
to use SDL_Flip(screen). Just be sure to pass SDL_DOUBLEBUF as a
flag to SDL_SetVideoMode first. If double buffering is supported
at the current diplay target, SDL_Flip flips the screen buffers,
if it isn’t, SDL_Flip is equivalent to SDL_UpdateRect on the
whole screen. So, it works either way =) .

Actually, if you care about performance don’t do that. Check
whether or not you get a hardware back surface when asking for
SDL_DOUBLEBUF|SDL_HWSURFACE, and if not, use SDL_UpdateRects()
instead of SDL_Flip().

Why ? Isn’t pageflipping supposed to just flip the pointers to the
pages beeing flipped ? I understand that performance may suffer if
SDL_Flip flips one hardware and one software surface, if it needs to
READ from the video ram to get the current front buffer, but i don’t
see why SDL should be stupid enough to do that… In those cases it’s
way better to just do a SW-SW flip, and then transfer the front
buffer to VRAM. This way no performace is lost.

So, i guess your point is that SDL doesn’t do it this way. Since i
answered that first “why” for you, here’s another: Why ? =)

Why doesn’t SDL do it this way ? IMHO the extra memory needed for
this is far less inconvenient than a broken flipping function.–
Trick


Linux User #229006 * http://counter.li.org

If you update large portions of the screen it’s probably better
to use SDL_Flip(screen). Just be sure to pass SDL_DOUBLEBUF as a
flag to SDL_SetVideoMode first. If double buffering is supported
at the current diplay target, SDL_Flip flips the screen buffers,
if it isn’t, SDL_Flip is equivalent to SDL_UpdateRect on the
whole screen. So, it works either way =) .

Actually, if you care about performance don’t do that. Check
whether or not you get a hardware back surface when asking for
SDL_DOUBLEBUF|SDL_HWSURFACE, and if not, use SDL_UpdateRects()
instead of SDL_Flip().

Why ? Isn’t pageflipping supposed to just flip the pointers to the
pages beeing flipped ?

Yes, but if that isn’t supported, you end up with a full screen
sysRAM->VRAM blit on every flip… If you use SDL_UpdateRects(), at least
you get speed similar to what you’d get on a target that supports
hardware pageflipping.

I understand that performance may suffer if
SDL_Flip flips one hardware and one software surface, if it needs to
READ from the video ram to get the current front buffer, but i don’t
see why SDL should be stupid enough to do that…

It isn’t, but it’s bad enough that it’ll end up copying the whole
buffer, although you may only have changed a few percent of the pixels.
SDL can’t help it as it doesn’t have the necessary information - but you
can provide that by using SDL_UpdateRects() instead.

In those cases it’s
way better to just do a SW-SW flip, and then transfer the front
buffer to VRAM. This way no performace is lost.

On the contrary, performance is lost, compared to updating only parts
of the back buffer and the performing a hardware flip.

So, i guess your point is that SDL doesn’t do it this way. Since i
answered that first “why” for you, here’s another: Why ? =)

Why doesn’t SDL do it this way ? IMHO the extra memory needed for
this is far less inconvenient than a broken flipping function.

Sure, but I’m talking about performance here - and unless you need to
update the whole screen every frame, using SDL_Flip() may result in a
significant performance loss if there’s no h/w pageflipping.

It may not look like a big deal if you manage to avoid blitting 30% of
the screen area, but keep in mind that sysRAM->VRAM blitting without
busmaster DMA is THE major performance killer in 2D rendering - and
it’s the only options for some (possible the majority) of SDL targets.

A game that runs at several hundred fps when rendering into a sysRAM
buffer can drop to 20-30 fps as soon as you try to display it’s output.
Yes, it really is that bad.

//David Olofson — Programmer, Reologica Instruments AB

.- M A I A -------------------------------------------------.
| Multimedia Application Integration Architecture |
| A Free/Open Source Plugin API for Professional Multimedia |
----------------------------> http://www.linuxdj.com/maia -' .- David Olofson -------------------------------------------. | Audio Hacker - Open Source Advocate - Singer - Songwriter |-------------------------------------> http://olofson.net -'On Wednesday 10 October 2001 23:17, Trick wrote:

Why ? Isn’t pageflipping supposed to just flip the pointers to
the pages beeing flipped ?

Yes, but if that isn’t supported, you end up with a full screen
sysRAM->VRAM blit on every flip… If you use SDL_UpdateRects(), at
least you get speed similar to what you’d get on a target that
supports hardware pageflipping.

Ok. I got the impression that doing UpdateRect() on the whole screen
was faster than SDL_Flip() on most targets, but obviously i
misunderstood =) (or maybe not, see below).

I understand that performance may suffer if
SDL_Flip flips one hardware and one software surface, if it needs
to READ from the video ram to get the current front buffer, but i
don’t see why SDL should be stupid enough to do that…

It isn’t, but it’s bad enough that it’ll end up copying the whole
buffer, although you may only have changed a few percent of the
pixels. SDL can’t help it as it doesn’t have the necessary
information - but you can provide that by using SDL_UpdateRects()
instead.

So, in other words, use SDL_Flip() only when updating the whole
screen (fx. in a scrolling game), or when wanting vsync (which isn’t
supported on most targets, i know).

In those cases it’s
way better to just do a SW-SW flip, and then transfer the front
buffer to VRAM. This way no performace is lost.

On the contrary, performance is lost, compared to updating only
parts of the back buffer and the performing a hardware flip.

Yep, but not if the whole screen actually is updated… The whole
screen needs to be transferred anyway.

So, i guess your point is that SDL doesn’t do it this way. Since
i answered that first “why” for you, here’s another: Why ? =)

Why doesn’t SDL do it this way ? IMHO the extra memory needed for
this is far less inconvenient than a broken flipping function.

Sure, but I’m talking about performance here - and unless you need
to update the whole screen every frame, using SDL_Flip() may
result in a significant performance loss if there’s no h/w
pageflipping.

Hm. So, in a scrolling game which fx. scrolls when the player is
within 20% of the left or right border, but our hero is free to kill
Evil, moving windows™ logos in the remaining 60%, it would
actually be better to avoid using SDL_Flip() at all, and use
UpdateRect() on the whole screen when scrolling.

IOW, SDL_Flip() is mostly only good for attempting to vsync, which
mostly aren’t supported ? …

It may not look like a big deal if you manage to avoid blitting 30%
of the screen area, but keep in mind that sysRAM->VRAM blitting
without busmaster DMA is THE major performance killer in 2D
rendering - and it’s the only options for some (possible the
majority) of SDL targets.

A game that runs at several hundred fps when rendering into a
sysRAM buffer can drop to 20-30 fps as soon as you try to display
it’s output. Yes, it really is that bad.

Ouch. It would be nice if SDL could tell when this is the case (ie.
if hardware page flipping and/or DMA is available), so that a
performance-wanting game could check for it and use SDL_Flip() only
in the best cases, to attempt to avoid tearing through vsync…–
Trick


Linux User #229006 * http://counter.li.org

Why ? Isn’t pageflipping supposed to just flip the pointers to
the pages beeing flipped ?

Yes, but if that isn’t supported, you end up with a full screen
sysRAM->VRAM blit on every flip… If you use SDL_UpdateRects(), at
least you get speed similar to what you’d get on a target that
supports hardware pageflipping.

Ok. I got the impression that doing UpdateRect() on the whole screen
was faster than SDL_Flip() on most targets, but obviously i
misunderstood =) (or maybe not, see below).

Uhm, well, if there is h/w pageflipping, SDL_Flip() call a driver
function that does little by flip some pointers around. If there isn’t,
the entire screen will have to be copied.

SDL_UpdateRects() (which works only with a software back/shadow buffer
and a single front buffer, AFAIK) always copies data, but only in the
areas you tell it to update.

I understand that performance may suffer if
SDL_Flip flips one hardware and one software surface, if it needs
to READ from the video ram to get the current front buffer, but i
don’t see why SDL should be stupid enough to do that…

It isn’t, but it’s bad enough that it’ll end up copying the whole
buffer, although you may only have changed a few percent of the
pixels. SDL can’t help it as it doesn’t have the necessary
information - but you can provide that by using SDL_UpdateRects()
instead.

So, in other words, use SDL_Flip() only when updating the whole
screen (fx. in a scrolling game), or when wanting vsync (which isn’t
supported on most targets, i know).

Something like that… Except that when you do have h/w pageflipping, you
really do want to use it, even if you’re just bouncing a tiny ball
around the screen.

(That’s why Kobo Deluxe adds it’s own, third buffer in the default
"SemiTriple" buffering mode. Every frame, it does it’s own
"UpdateRects()" on the scrolling area, and occasionally some displays, or
the radar screen, into the back buffer, and the calls SDL_Flip().)

In those cases it’s
way better to just do a SW-SW flip, and then transfer the front
buffer to VRAM. This way no performace is lost.

On the contrary, performance is lost, compared to updating only
parts of the back buffer and the performing a hardware flip.

Yep, but not if the whole screen actually is updated… The whole
screen needs to be transferred anyway.

Correct. :slight_smile:

So, i guess your point is that SDL doesn’t do it this way. Since
i answered that first “why” for you, here’s another: Why ? =)

Why doesn’t SDL do it this way ? IMHO the extra memory needed for
this is far less inconvenient than a broken flipping function.

Sure, but I’m talking about performance here - and unless you need
to update the whole screen every frame, using SDL_Flip() may
result in a significant performance loss if there’s no h/w
pageflipping.

Hm. So, in a scrolling game which fx. scrolls when the player is
within 20% of the left or right border, but our hero is free to kill
Evil, moving windows™ logos in the remaining 60%, it would
actually be better to avoid using SDL_Flip() at all, and use
UpdateRect() on the whole screen when scrolling.

If there’s no h/w pageflipping; yes.

If there is; no, use SDL_Flip() (and perhaps something like Kobo’s
SemiTriple buffering mode) instead, to reduce distortion, and (possibly)
gain retrace sync.

IOW, SDL_Flip() is mostly only good for attempting to vsync, which
mostly aren’t supported ? …

Kind of, but don’t rule it out - even if there are targets that can’t
implement SDL_Flip() “properly”, there are some targets (even on Linux)
which can perform h/w pageflipping, even if it’s not retracy sync’ed.

Even if it isn’t retrace sync’ed, it usually eliminates tearing, as video
cards latch new display window position only during retrace. That is,
even if you don’t get your game to sync with the refresh rate, you
can’t get tearing, as there’s no way you can flip while the CRT is
rendering the front buffer. (If flipping is properly implemented, that
is…)

It may not look like a big deal if you manage to avoid blitting 30%
of the screen area, but keep in mind that sysRAM->VRAM blitting
without busmaster DMA is THE major performance killer in 2D
rendering - and it’s the only options for some (possible the
majority) of SDL targets.

A game that runs at several hundred fps when rendering into a
sysRAM buffer can drop to 20-30 fps as soon as you try to display
it’s output. Yes, it really is that bad.

Ouch. It would be nice if SDL could tell when this is the case (ie.
if hardware page flipping and/or DMA is available), so that a
performance-wanting game could check for it and use SDL_Flip() only
in the best cases, to attempt to avoid tearing through vsync…

It can, and Kobo Deluxe makes use of it to detect whether it should use
single buffering + software shadow buffer with SDL_UpdateRects() or
"SemiTriple" buffering.

I’m not sure about checking for DMA blitting (Kobo can’t use it anyway
because of the alpha blending), but SDL should be able to tell you about
that too.

//David Olofson — Programmer, Reologica Instruments AB

.- M A I A -------------------------------------------------.
| Multimedia Application Integration Architecture |
| A Free/Open Source Plugin API for Professional Multimedia |
----------------------------> http://www.linuxdj.com/maia -' .- David Olofson -------------------------------------------. | Audio Hacker - Open Source Advocate - Singer - Songwriter |-------------------------------------> http://olofson.net -'On Thursday 11 October 2001 12:33, Trick wrote:

Ouch. It would be nice if SDL could tell when this is the case
(ie. if hardware page flipping and/or DMA is available), so that
a performance-wanting game could check for it and use SDL_Flip()
only in the best cases, to attempt to avoid tearing through
vsync…

It can, and Kobo Deluxe makes use of it to detect whether it should
use single buffering + software shadow buffer with
SDL_UpdateRects() or “SemiTriple” buffering.

How ? I thought SDL always emulate that kind of stuff in software
when it can’t do it in hardware ? Any flag i should check ? (ok,
beeing lazy now, sorry =)–
Trick


Linux User #229006 * http://counter.li.org

Ouch. It would be nice if SDL could tell when this is the case
(ie. if hardware page flipping and/or DMA is available), so that
a performance-wanting game could check for it and use SDL_Flip()
only in the best cases, to attempt to avoid tearing through
vsync…

It can, and Kobo Deluxe makes use of it to detect whether it should
use single buffering + software shadow buffer with
SDL_UpdateRects() or “SemiTriple” buffering.

How ? I thought SDL always emulate that kind of stuff in software
when it can’t do it in hardware ?

Yep, but…

Any flag i should check ?

…that can be detected by checking whether or not you really get a
hardware screen surface (hint) and that kind of stuff.

(ok, beeing lazy now, sorry =)

Yeah! :wink:

//David Olofson — Programmer, Reologica Instruments AB

.- M A I A -------------------------------------------------.
| Multimedia Application Integration Architecture |
| A Free/Open Source Plugin API for Professional Multimedia |
----------------------------> http://www.linuxdj.com/maia -' .- David Olofson -------------------------------------------. | Audio Hacker - Open Source Advocate - Singer - Songwriter |-------------------------------------> http://olofson.net -'On Thursday 11 October 2001 18:11, Trick wrote:

  • David Olofson <david.olofson at reologica.se> [011011 11:51]:> On Thursday 11 October 2001 18:11, Trick wrote:

Ouch. It would be nice if SDL could tell when this is the case
(ie. if hardware page flipping and/or DMA is available), so that
a performance-wanting game could check for it and use SDL_Flip()
only in the best cases, to attempt to avoid tearing through
vsync…

It can, and Kobo Deluxe makes use of it to detect whether it should
use single buffering + software shadow buffer with
SDL_UpdateRects() or “SemiTriple” buffering.

How ? I thought SDL always emulate that kind of stuff in software
when it can’t do it in hardware ?

Yep, but…

Any flag i should check ?

…that can be detected by checking whether or not you really get a
hardware screen surface (hint) and that kind of stuff.

I believe SDL_Surface->flags will tell you what you need to know…but I am
new to all this so that might be incorrect.

create a SDL_Surface w/ SDL_SetVideoMode and print some debugging on
it…you can get something like this.

SDL_Surface - flags: 0
SDL_Surface - pitch: 1280
Available Surface Flags:
SDL_SWSURFACE: 0
SDL_HWSURFACE: 1
SDL_DOUBLEBUF: 1073741824
SDL_FULLSCREEN: 2147483648
SDL_OPENGL: 2
SDL_OPENGLBLIT: 10
SDL_Surface - refcount: 1

with these print statements (screen is simply an SDL_Surface *screen):

fprintf ( stderr,“SDL_Surface - flags: %d\n”, screen->flags);
fprintf ( stderr,“SDL_Surface - pitch: %d\n”, screen->pitch);
fprintf ( stderr,“Available Surface Flags:\n”);
fprintf ( stderr,"\tSDL_SWSURFACE: %u\n",SDL_SWSURFACE);
fprintf ( stderr,"\tSDL_HWSURFACE: %u\n",SDL_HWSURFACE);
fprintf ( stderr,"\tSDL_DOUBLEBUF: %u\n",SDL_DOUBLEBUF);
fprintf ( stderr,"\tSDL_FULLSCREEN: %u\n",SDL_FULLSCREEN);
fprintf ( stderr,"\tSDL_OPENGL: %u\n",SDL_OPENGL);
fprintf ( stderr,"\tSDL_OPENGLBLIT: %u\n",SDL_OPENGLBLIT);
fprintf ( stderr,“SDL_Surface - refcount: %d\n”, screen->refcount);

I am sure there is a better way but that might point you in the right
direction.

-Nick

SDL_UpdateRects() batches the updates into a single call to the underlying
API (X11, hardware command FIFO, whatever)

-Sam Lantinga, Software Engineer, Blizzard Entertainment> On Wed, Oct 10, 2001 at 10:28:06AM +0200, Mattias Engdegard wrote:

“Jeff W.” wrote:

if you have more than one changed region, use SDL_UpdateRects(), not
SDL_UpdateRect().

Why?