Dirty Rects and Sprig

Hey,

I’m considering implementing a toggleable dirty rect collection in Sprig’s primitives. When enabled, the rect that encloses each drawn line, circle, etc. would be added to some sort of stack or array. The array would be accessible to the programmer so his/her own dirty rects could be added to it. Then at the end of each frame, a Sprig function would be (optionally) called to combine rects appropriately. Then either you call SDL_UpdateRects or maybe that rect combining function could do it for you. I’m thinking that there should be different levels of optimization so that you can choose the level that works fastest for your application. You might even test the results to get runtime adjustment to the most efficient level.

Those a bunch of statements, so here are some questions:

Is this a good idea?
Does dirty rect compatibility seem to fit the goals of a graphics lib?
Any good reasons out there for choosing a stack, an array, or a linked list?
Is there anything I can do about single pixels, or do I have to wrap them in a rect?
Is there any code you’d like to point me to? I’ll take a look at how David Olofson handles it first, of course.
What do you think of the optimization levels idea?
Would you use this?

Thanks to everyone,
Jonny D_________________________________________________________________
Stay up to date on your PC, the Web, and your mobile phone with Windows Live.
http://clk.atdmt.com/MRT/go/msnnkwxp1020093185mrt/direct/01/

Jonathan Dearborn wrote:

I’m considering implementing a toggleable dirty rect collection in
Sprig’s primitives. When enabled, the rect that encloses each drawn
line, circle, etc. would be added to some sort of stack or array. The
array would be accessible to the programmer so his/her own dirty
rects could be added to it. Then at the end of each frame, a Sprig
function would be (optionally) called to combine rects appropriately.
Then either you call SDL_UpdateRects or maybe that rect combining
function could do it for you. I’m thinking that there should be
different levels of optimization so that you can choose the level
that works fastest for your application. You might even test the
results to get runtime adjustment to the most efficient level.

Those a bunch of statements, so here are some questions:

Is this a good idea?

for a software renderer, dirty rect optimization is often a big win.

Any good reasons out there for choosing a stack, an array, or a
linked list?

go for the latter.

Is there anything I can do about single pixels, or do I
have to wrap them in a rect?

single pixels are seldom used anyway. wrap them in a rect.

What do you think of the optimization levels idea?

in my own render engine i have implemented different screen update
strategies, each is fast in spczific use cases:

  1. immidiate update -> each blit is immidiatly updated on the screen
  2. dirty rect list -> each blit is stored in a dirty rect list and
    the list is updated after all blits are done
  3. one dirty rect -> all dirty rects are combined to one big rect
    and the screen is updated once with that
  4. whole screen -> first do all blits then update the whole screen

i want to do one more but i never came around to code it. a combination
of 2 and 3, where overlapping rects are combined to one bigger rect and
non overlapping rects are stored in the dirty rect list again. this
could be a really big improvment sometimes because it avoids updating
the same screen region multiple times without updating likly unchanged
regions.

best regards …
clemens

Thanks Clemens,I know that Fixed Rate Pig uses something like what you describe. It creates a union for dirty rects when the number of clean pixels it would add is below a certain threshold. I also found a couple other approaches when I was fishing around. The one I had already thought of breaks two overlapping rects into three, meaning that no clean pixels are updated at all. It makes me wonder how much overhead each rect update has, though. Another approach is to use spatial partitions, like a grid, that each hold a dirty rect that is a union of the dirty pixels in the grid box. I’ll probably just go with an easy approach and compare speeds between different ones when I have the time. SGE by default uses the first option you mention: Update after each blit. I wasn’t sure what advantage this gives. You don’t have to keep track of dirty rects or refresh the whole screen, but it means that overlapping blits might start flickering. Is there something else to it?Jonny D> Date: Sat, 20 Sep 2008 15:37:31 +0200> From: clemens at 1541.org> To: sdl at lists.libsdl.org> Subject: Re: [SDL] Dirty Rects and Sprig> > Jonathan Dearborn wrote:> > > I’m considering implementing a toggleable dirty rect collection in> > Sprig’s primitives. When enabled, the rect that encloses each drawn> > line, circle, etc. would be added to some sort of stack or array. The> > array would be accessible to the programmer so his/her own dirty> > rects could be added to it. Then at the end of each frame, a Sprig> > function would be (optionally) called to combine rects appropriately.> > Then either you call SDL_UpdateRects or maybe that rect combining> > function could do it for you. I’m thinking that there should be> > different levels of optimization so that you can choose the level> > that works fastest for your application. You might even test the> > results to get runtime adjustment to the most efficient level.> > > > Those a bunch of statements, so here are some questions:> > > > Is this a good idea?> > for a software renderer, dirty rect optimization is often a big win.> > > Any good reasons out there for choosing a stack, an array, or a> > linked list?> > go for the latter.> > > Is there anything I can do about single pixels, or do I> > have to wrap them in a rect?> > single pixels are seldom used anyway. wrap them in a rect.> > > What do you think of the optimization levels idea?> > in my own render engine i have implemented different screen update> strategies, each is fast in spczific use cases:> > 1. immidiate update -> each blit is immidiatly updated on the screen> 2. dirty rect list -> each blit is stored in a dirty rect list and> the list is updated after all blits are done> 3. one dirty rect -> all dirty rects are combined to one big rect> and the screen is updated once with that> 4. whole screen -> first do all blits then update the whole screen> > i want to do one more but i never came around to code it. a combination> of 2 and 3, where overlapping rects are combined to one bigger rect and> non overlapping rects are stored in the dirty rect list again. this> could be a really big improvment sometimes because it avoids updating> the same screen region multiple times without updating likly unchanged> regions.> > best regards …> clemens> > SDL mailing list> SDL at lists.libsdl.org> http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org__________________
See how Windows Mobile brings your life together?at home, work, or on the go.
http://clk.atdmt.com/MRT/go/msnnkwxp1020093182mrt/direct/01/

Jonathan Dearborn wrote:

The one I had
already thought of breaks two overlapping rects into three, meaning
that no clean pixels are updated at all.

ah, well. i didn’t think about that one yet. good idea! better than my
aproach to combine method 2 and 3. still not trivial to implement. one
has to test each rectangle against each other for an overlap. it might
help to keep them sorted though.

It makes me wonder how much
overhead each rect update has, though.

this depends on the render backend and/or on the hardware. in
SDL_UpdateRect() the software backbuffer gets transfered to the video
memory. on some plattforms this is extremly expensive (OpenMokos
Freerunner Glamo chip for example).

SGE by default uses the first option you mention:
Update after each blit. I wasn’t sure what advantage this gives.

like you say, its just extremly easy to implement and has no
disadvantage, if your blits don’t overlap.

best regards …
clemens