Time to wonder?

Hi all :slight_smile:

First of all I want to thank Sam and Martin for their help with my
"fullscreen" problem (didn’t want to post a “thank-you-only-message”,
for not making the traffic to much / big ?)
Anes - thank you, too, but it seems there is no “SDL_VIDEO” as a setting
for SDL_SetVideoMode with my version :slight_smile:

Again there is a question I have: “Is there a special way to calculate
the time an update-rect” needs (without reffering to the architecture of
the hardware…)

My problem is the following. Lets say I draw a Line on a SDL_Surface
wich goes from (0,0) to (100,100). I could update the whole rect like
graph-1 shows, or i could update it in 2 (graph 2) and so on up to
100x100 (=10.000) seperated rects (updating every pixel as a rect of 1x1
pixel), but i guess, it would be usesless updating 100rects, cos I think
it would take more time, but the use of 2 or 4 updaterects could be
optimizing performance here, so i need this calculation to find out,
where the “critical point” might be.

Hope this isn’t a stupid question :slight_smile:

Greetings,

Sascha

±---------------------+ ±---------------------+
|\ | |\ | |
| \ | | \ | |
| \ 1 | | \ | |
| \ | | 1 \ | 2 |
| \ | | \ | |
| \ | |----------X-----------|
| \ | | | \ |
| \ | | | \ |
| \ | | | \ |
| \ | | 4 | 3 \ |
| \ | | | \ |
±---------------------+ ±---------------------+
(graph-01 100x100 update) (graph-02 2x50x50 update)
(2 and 4 don’t need an update)±---------------------+
|\ | o | o | o | o | o |
|–X-------±–±--±–|
| o| \ | o | o | o | o |
|------X—±–±--±–|
| o| o | \ | o | o | o |
|----------X—±–±--|
| o| o | o | \ | o | o |
|--------------X—±–|
| o| o | o | o | \ | o |
|------------------X—|
| o| o | o | o | o | \ |
±---------------------+
(graph-01 10x10x10 update)
(areas marked with o don’t need an update)

Generally, of course, you shouldn’t be updating for 1 line unless you
really need to.

We have a “dirty rectangles” scheme. Currently it’s a fairly complex
span-line scheme, but I recently tried something extremely simple that
seemed to work just as well, and it’s kinda similar to your 10x10 grid.

The idea is to make a mxn grid of simple chars, choosing the grid size is a
trade off, as you describe, between wasted updates and lots of little rects.

Whenever something needs updating, just mark a ‘1’ in any grid square touched.

Then “periodically” (for example, if the time since the last update is
greater than some threshold), flush out the dirty rects and clear the grid

I had also added a simple scheme to grow the update rects as far as
possible (I just grew right then down then repeat as long as it’s still
working)

Our scheme is somewhat complicated by not drawing to the backbuffer until
the dirty regions are flushed (avoids any duplicate or unnecessary
drawing). We do this by testing each update rect against an object hierarchy.

The only catch is SDL will toss rather than clip any update rect which is
partially out of the surface, so some care is needed with the right column
and bottom row, if the grid isn’t a perfect multiple of the screen size.

Anyway, that’s one approach for a really simple scheme that does
generically and automatically what you seem to be after.

–Manny

Generally, of course, you shouldn’t be updating for 1 line unless you
really need to.

We have a “dirty rectangles” scheme. Currently it’s a fairly complex
span-line scheme, but I recently tried something extremely simple that
seemed to work just as well, and it’s kinda similar to your 10x10 grid.

The idea is to make a mxn grid of simple chars, choosing the grid size is
a
trade off, as you describe, between wasted updates and lots of little
rects.

I experimented with a scheme like you describe years ago
(Hercules grafics, at that time). At that time, with a 386SX
20 MHz CPU, i achieved optimum performance at 32x32
pixel, as far as i recall. (Blitting from memory to screen,
hand-optimized assembler blitting routines) (with loads and
loads of special cases for the borders)

Making the rectangles smaller resulted in management
overhead, making the whole thing slower and more memory-
consuming.

What optimum do you achieve with todays machines?

Whenever something needs updating, just mark a ‘1’ in any grid square
touched.

Then “periodically” (for example, if the time since the last update is
greater than some threshold), flush out the dirty rects and clear the grid

I had also added a simple scheme to grow the update rects as far as
possible (I just grew right then down then repeat as long as it’s still
working)

Our scheme is somewhat complicated by not drawing to the backbuffer until
the dirty regions are flushed (avoids any duplicate or unnecessary
drawing). We do this by testing each update rect against an object
hierarchy.

I didn’t understand that one. Could you explain some more?

Dipl.Inform. Dirk-Ulrich Heise
@Dirk-Ulrich_Heise
dheise at debitel.netVon: “Manny”

Sascha G?nther wrote:

Hi all :slight_smile:

First of all I want to thank Sam and Martin for their help with my
"fullscreen" problem (didn’t want to post a “thank-you-only-message”,
for not making the traffic to much / big ?)
Anes - thank you, too, but it seems there is no “SDL_VIDEO” as a setting
for SDL_SetVideoMode with my version :slight_smile:

Ups …

Sorry, i meant something like
screen=SDL_SetVideoMode(width,height,depth,SDL_HWSURFACE|SDL_FULLSCREEN);

Regards

My problem is the following. Lets say I draw a Line on a SDL_Surface
wich goes from (0,0) to (100,100). I could update the whole rect like
graph-1 shows, or i could update it in 2 (graph 2) and so on up to
100x100 (=10.000) seperated rects […]

This is a very artificial problem; you will rarely update the screen after
having drawn a single line. For a general line-vector graphics application,
I’d use a simple bounding-box scheme or a fixed grid of dirty rectangles,
with coalescing to bigger rectangles as needed.

If this is important, do a small runtime test when initialising your game
to select the best method or rectangle size

I experimented with a scheme like you describe years ago
(Hercules grafics, at that time). At that time, with a 386SX
20 MHz CPU, i achieved optimum performance at 32x32
pixel, as far as i recall. (Blitting from memory to screen,
hand-optimized assembler blitting routines) (with loads and
loads of special cases for the borders)

Making the rectangles smaller resulted in management
overhead, making the whole thing slower and more memory-
consuming.

What optimum do you achieve with todays machines?

As I mentioned, we’re actually using a span-line based system. It’s the
same basic idea in that it generates a list of dirty rectangles. I only
spent an evening experimenting with the simpler method, but the more I
think about it, the more I think the span-line scheme isn’t giving any real
benefits for the added complexity (it gets a tighter fit on update regions,
but that doesn’t seem important). I also ended up at 32x32, but I haven’t
done any proper measurements yet. Growing out the rectangles takes away a
lot of the concern about small rectangles. A grid of 32x32 rectangles on a
1024x768 screen is only 32x24 or 768 bytes.

Whenever something needs updating, just mark a ‘1’ in any grid square
touched.

Then “periodically” (for example, if the time since the last update is
greater than some threshold), flush out the dirty rects and clear the grid

I had also added a simple scheme to grow the update rects as far as
possible (I just grew right then down then repeat as long as it’s still
working)

Our scheme is somewhat complicated by not drawing to the backbuffer until
the dirty regions are flushed (avoids any duplicate or unnecessary
drawing). We do this by testing each update rect against an object
hierarchy.

I didn’t understand that one. Could you explain some more?

Our loop is basically:

  1. Process all pending events (stops early if it’s taking to long)
  2. Get the current time, update & process timers
    (steps 1 & 2 generally create dirty regions)
    (2 1/2: back to 1 if very little time has passed, but I think I’ll take
    this out)
  3. Redraw dirty regions to back buffer
  4. Update drawn regions to front buffer

We have a “Game Tree”, sort of a simple 2d scene graph. When something
needs updating it just marks that part of the screen as dirty. If more
than one thing marks the same region, the area is only drawn once. When
the dirty areas are flushed, each rectangle is tested against the
GameTree. It’s hierarchical, so if an object is outside the rectangle, so
are all of it’s children. Objects that overlap the dirty region are
clipped to the region and drawn.

We also had an occlusion test that wouldn’t draw an object if something was
covering it up, but that took just as long as doing the extra drawing.

-----Urspr?ngliche Nachricht-----

Our loop is basically:

  1. Process all pending events (stops early if it’s taking to long)
  2. Get the current time, update & process timers
    (steps 1 & 2 generally create dirty regions)
    (2 1/2: back to 1 if very little time has passed, but I think I’ll take
    this out)
  3. Redraw dirty regions to back buffer
  4. Update drawn regions to front buffer

Thanks, now i got it.

It’s really funny that you say the new approach is simpler.
At the time i wrote it (and i’m about to revive that project,
it fell into coma 5 years ago, it was written in PASCAL, and now
i’m rewriting it in Python), i wondered whether a span-line
system would be better :slight_smile: So this encourages me to keep
the old logic i already had. Thanks!

BTW, it’s not a game but a sort of grafical front end
to a database, where objects move randomly towards
their neighbours. Made for nice self-organizing data
associations.

Dipl.Inform. Dirk-Ulrich Heise
@Dirk-Ulrich_Heise
dheise at debitel.netVon: “Manny”