Effectively using a single-buffered hardware surface

Hello;

I’m trying to optimise a game that runs at a non-negotiable 800x600 which, up
until now has used a fullscreen software display surface, and used
SDL_UpdateRects to update dirty rectangles on screen, since there’s not very
much moving on screen at once. This is proving too slow in some
circumstances (when larger animations are required basically), so I’m looking
for ways to get all the blits happening to and from hardware surfaces.

I assume I cannot use double-buffering because I don’t know whether all the
graphics will fit into the graphics card memory, and the speed penalty if
they don’t will be horrendous.

What I’d like to do is allocate a shadow hardware surface, use that to blit
to when graphics are updating in the course of the game loop, and blit all
the dirty rectangles to the display surface at the vsync. However there’s no
SDL_WaitForVSync() call for me to time this on.

By my reckoning this optimisation should be a well-trodden path, or at least
a possible one, but given that I can’t seem to do it in SDL, is there a
better way?–
Matthew > http://www.soup-kitchen.net/
> ICQ 19482073

Hello;

I’m trying to optimise a game that runs at a non-negotiable 800x600
which, up until now has used a fullscreen software display surface, and
used SDL_UpdateRects to update dirty rectangles on screen, since
there’s not very much moving on screen at once. This is proving too
slow in some circumstances (when larger animations are required
basically), so I’m looking for ways to get all the blits happening to
and from hardware surfaces.

I assume I cannot use double-buffering because I don’t know whether all
the graphics will fit into the graphics card memory, and the speed
penalty if they don’t will be horrendous.

What I’d like to do is allocate a shadow hardware surface, use that to
blit to when graphics are updating in the course of the game loop, and
blit all the dirty rectangles to the display surface at the vsync.

Why would the h/w shadow surface be smaller than a real back buffer…?

However there’s no SDL_WaitForVSync() call for me to time this on.

Right - and it’s not even possible to implement one on some platforms, as
it’s part of the “flip” operation. (Oh, and a bunch of platforms don’t
have retrace sync, at all, except with a few drivers.)

By my reckoning this optimisation should be a well-trodden path, or at
least a possible one, but given that I can’t seem to do it in SDL, is
there a better way?

It’s possible with SDL all right, but you have to keep in mind that many
targets only get slower when you force h/w surfaces, since they lack
h/w accelerated blits. Also keep in mind that no SDL targets support h/w
accelerated alpha so far. (glSDL will be first, it seems.)

Better way? Not really. If there’s no acceleration, you’re out of luck.
Your s/w shadow buffer + SDL_UpdateRects() solution seems to be as
optimal as it gets, provided you optimize the rectangles. Make sure
you’re only updating what has actually changed, and that you minimize
overlapping update rects.

//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 22 May 2002 10:58, Matthew Bloch wrote:

Speaking of which: anyone have a good general algorithm/sample code for
doing this that they’d like to share?On Wed, May 22, 2002 at 04:28:06PM +0200, David Olofson wrote:

optimal as it gets, provided you optimize the rectangles. Make sure
you’re only updating what has actually changed, and that you minimize
overlapping update rects.


Matthew Miller @Matthew_Miller http://www.mattdm.org/
Boston University Linux ------> http://linux.bu.edu/

Haven’t played much with this kind of stuff so far (since I’m usually
hacking stuff that needs to update the whole screen every frame anyway
:-), but this might be what you’re looking for:

http://www.levien.com/libart/uta.html

Note that on some platforms, where the per rectangle overhead is
significant, it might be a good idea to add some fuzziness to the
microtile concatenation stage, so that microtiles that are almost the
same width or height can be merged as well. One has to find a good
area/count tradeoff for maximum speed.

I used a much simpler variant in the original Project Spitire/DOS. That
game used hardware scrolling, and thus didn’t need to repaint the whole
background every frame. I simply created a “dirty map” for each buffer,
covering the screen with tiles of the same size as the background map.
(16x16 tiles.) Before rendering all sprites of a frame, the "dirty map"
would be filled with invalid tile indices, meaning “no change here”. The
sprite blitter would then copy tile indices from the background map for
each tile that it touched. To remove all sprites quickly, I just scanned
the “dirty map” for valid tile indices, and painted the indicated tile in
the corresponding position on the screen whenever one was found. (The
tile blitter was optimized for 16x16 tiles on VGA Mode-X, so there wasn’t
much point in trying to keep a rectangle for each tile.)

Basically UTA, but with a tile index (or a boolean - you can look at the
real map instead) instead of the rect for each “microtile”.

//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 22 May 2002 16:42, Matthew Miller wrote:

On Wed, May 22, 2002 at 04:28:06PM +0200, David Olofson wrote:

optimal as it gets, provided you optimize the rectangles. Make sure
you’re only updating what has actually changed, and that you minimize
overlapping update rects.

Speaking of which: anyone have a good general algorithm/sample code for
doing this that they’d like to share?

Matthew,

It would be a large scale change to the application, but have you considered
using OpenGL? You would just operate with an orthographic projection set to
your screen resolution and do all your blits as 32 bit quads. (32 bit
graphics meaning RGB8 and an 8 bit alpha channel, giving you nice
anitaliasing if you want.) You would have to redesign your graphics low
level, but you would gain quite a bit in performance and you would be able
to have neato special effects via alpha channel operations that blend
graphic overlays over other graphics.

Plus, when you’re done you’d have a nice initial training in OpenGL without
any of the 3D logic that makes it more difficult for many people in their
first time exposure to OpenGL.

Just a suggestion (from someone what doesn’t understand why everything is
not done in OpenGL.)
-Blake

p.s. did you read where the next Mac OS will have OpenGL as the lowest level
graphics interface for everything?> ----- Original Message -----

From: mattbee-sdl@soup-kitchen.net (Matthew Bloch)
To:
Sent: Wednesday, May 22, 2002 1:58 AM
Subject: [SDL] Effectively using a single-buffered hardware surface

Hello;

I’m trying to optimise a game that runs at a non-negotiable 800x600 which,
up
until now has used a fullscreen software display surface, and used
SDL_UpdateRects to update dirty rectangles on screen, since there’s not
very
much moving on screen at once. This is proving too slow in some
circumstances (when larger animations are required basically), so I’m
looking
for ways to get all the blits happening to and from hardware surfaces.

I assume I cannot use double-buffering because I don’t know whether all
the
graphics will fit into the graphics card memory, and the speed penalty if
they don’t will be horrendous.

What I’d like to do is allocate a shadow hardware surface, use that to
blit
to when graphics are updating in the course of the game loop, and blit all
the dirty rectangles to the display surface at the vsync. However there’s
no
SDL_WaitForVSync() call for me to time this on.

By my reckoning this optimisation should be a well-trodden path, or at
least
a possible one, but given that I can’t seem to do it in SDL, is there a
better way?


Matthew > http://www.soup-kitchen.net/
> ICQ 19482073


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

[…2D on OpenGL…]

Just a suggestion (from someone what doesn’t understand why everything
is not done in OpenGL.)

Well… There are cards without 3D acceleration, and it’s more work
implementing both SDL and OpenGL backends than SDL only. I’m definitely
not saying it’s a bad idea; just that it’s more work. …and that
supporting only OpenGL is a bad idea in most cases.

That said, glSDL will hopefully eliminate this problem for the majority
of users, when it comes to games written by 2D die-hards. No fancy OpenGL
features (at least not with the current SDL API), but that’s not the
point. Portable h/w acceleration of the 2D API is.

-Blake

p.s. did you read where the next Mac OS will have OpenGL as the lowest
level graphics interface for everything?

Looks like they’ll beat me to it. Damn! :wink:

Anyway, Microsoft seems to be doing the same thing with the new GDI. Not
sure whether this is done on the Direct3D/DirectGraphics level, but at
least, it’ll use the same drivers, rather than the old GDI driver crap
where “Windows accelerator” cards used to plug in.

//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 22 May 2002 17:38, Blake Senftner wrote:

Plus there are cards with crappy OpenGL support. I’ve got a SiS chipset in my
laptop, and glSubTexImage is broken - even with the latest driver. And no, I
got no response from the support people.

cu,
NicolaiAm Mittwoch, 22. Mai 2002 19:48 schrieb David Olofson:

On Wednesday 22 May 2002 17:38, Blake Senftner wrote:
[…2D on OpenGL…]

Just a suggestion (from someone what doesn’t understand why everything
is not done in OpenGL.)

Well… There are cards without 3D acceleration, and it’s more work
implementing both SDL and OpenGL backends than SDL only. I’m definitely
not saying it’s a bad idea; just that it’s more work. …and that
supporting only OpenGL is a bad idea in most cases.

Oh my yes. Especially on Linux – it’s much more rare to see a system set up
nicely with OpenGL than the reverse.On Wed, May 22, 2002 at 07:48:42PM +0200, David Olofson wrote:

Just a suggestion (from someone what doesn’t understand why everything
is not done in OpenGL.)
Well… There are cards without 3D acceleration, and it’s more work
implementing both SDL and OpenGL backends than SDL only. I’m definitely


Matthew Miller @Matthew_Miller http://www.mattdm.org/
Boston University Linux ------> http://linux.bu.edu/

Just a suggestion (from someone what doesn’t understand why everything
is not done in OpenGL.)
Well… There are cards without 3D acceleration, and it’s more work
implementing both SDL and OpenGL backends than SDL only. I’m definitely

Oh my yes. Especially on Linux – it’s much more rare to see a system set
up
nicely with OpenGL than the reverse.

That is sad to learn. Is it expected to change anytime in the near future?

-Blake

One would hope so - but as long as all serious 3D cards have only closed
source drivers, I don’t see how the driver quality and motivation among
hackers will ever reach the required level.

/me hopes that Matrox won’t become like all the others when they release
the Parhelia 512.

//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 22 May 2002 20:59, Blake Senftner wrote:

Just a suggestion (from someone what doesn’t understand why
everything is not done in OpenGL.)

Well… There are cards without 3D acceleration, and it’s more
work implementing both SDL and OpenGL backends than SDL only. I’m
definitely

Oh my yes. Especially on Linux – it’s much more rare to see a system
set

up

nicely with OpenGL than the reverse.

That is sad to learn. Is it expected to change anytime in the near
future?

I think Alan Cox summed it up best when he was asked something following this:

“With free versions of software such as Open Office constantly improving, what
place do you perceive commercial software to have in the free software world as
free alternatives mature to an acceptable and usable state?”

Alan Cox:
“It really comes down to people having a business model that justifies the extra
cost of their proprietary product, both in convenience to the user and
development cost to them. Sometimes that equation makes real sense…”

and:

"I’ve talked to Nvidia folks about why they do it. The bottom line is that I
can’t make a good case for them to open source it. Their worries about what it
might do to their performance relative to competitors are quite well founded. "On Wed, May 22, 2002 at 09:41:52PM +0200, David Olofson wrote:

On Wednesday 22 May 2002 20:59, Blake Senftner wrote:

Just a suggestion (from someone what doesn’t understand why
everything is not done in OpenGL.)

Well… There are cards without 3D acceleration, and it’s more
work implementing both SDL and OpenGL backends than SDL only. I’m
definitely

Oh my yes. Especially on Linux – it’s much more rare to see a system
set

up

nicely with OpenGL than the reverse.

That is sad to learn. Is it expected to change anytime in the near
future?

One would hope so - but as long as all serious 3D cards have only closed
source drivers, I don’t see how the driver quality and motivation among
hackers will ever reach the required level.

/me hopes that Matrox won’t become like all the others when they release
the Parhelia 512.

============================

So I personally don’t hold much against them…

-EvilTypeGuy

One would hope so - but as long as all serious 3D cards have only
closed source drivers, I don’t see how the driver quality and
motivation among hackers will ever reach the required level.
[…]
"I’ve talked to Nvidia folks about why they do it. The bottom line is
that I can’t make a good case for them to open source it. Their worries
about what it might do to their performance relative to competitors are
quite well founded. "

Well, that’s a good point. Besides, binary drivers should be capable of
working rather well, provided the interface is solid and well defined.

Meanwhile, XFree86 seems to be the single most common reason for “loosing
the interface” as well as real crashes - and that’s not just with these
binary drivers everyone’s bashing. In my experience, XFree86 has been
(is?) very unstable, at least compared to the Linux kernel, especially
when messing with OpenGL, DGA or any other “advanced” features.

So, blaming the 3D h/w people isn’t going to help. Nor is whining about
all this…

I’m getting the feeling that XFree86 is just to big and messy, and needs
to be split up and partially rewritten. Considering the very different
ways platforms handle the low level stuff, it might even be a good idea
to fork off a Linux-only project.

How about ripping only the parts needed for local OpenGL to get a clean,
simple and solid “direct OpenGL layer”, and then implementing
(independent) X servers and other stuff on top of that? (Would at least
result in a very portable, accelerater X server. :slight_smile: Is any fbdev related
project working on that, perhaps?

Then again, it might be that there are already too many projects, and not
enough developers to have both quality and features in any of those
projects. Or maybe XFree86 has been pushed too far without a major
redesign, and is now about to collapse as a result…?

Oh well, time to take this thread off the list.

//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 22 May 2002 21:51, EvilTypeGuy wrote:

I know the API is sane, and you can rely on acceleration, but the game is
being deployed on machines with basically 2D graphics cards so it’s not an
option. Plus I’d need a Ruby binding for the SDL-specific OpenGL stuff.

cheers,On Wednesday 22 May 2002 16:38, you wrote:

Matthew,

It would be a large scale change to the application, but have you
considered using OpenGL? You would just operate with an orthographic
projection set to your screen resolution and do all your blits as 32 bit
quads.


Matthew > http://www.soup-kitchen.net/
> ICQ 19482073

Matthew Miller wrote:

David Olofson wrote:

Make sure you’re only updating what has actually changed, and that
you minimize overlapping update rects.

Speaking of which: anyone have a good general algorithm/sample code
for doing this that they’d like to share?

You can check out the “Desktop” class in the project below.

It basically checks to see if a new dirty rectangle intersects with a
rectangle in the dirty list. If there is an intersection, it compares the
area of the union against the sum of the two individual areas. If the area
of the union is smaller, it replaces the two rectangles with the union. When
the update occurs, the dirty list is sent to the screen and the list is
cleared.

There is a lot of room for improvement but it seems to work pretty good.

  • Randi

Regimental Command
Generic Armored Combat System
http://regcom.sourceforge.net