Complete.Org: Mailing Lists: Archives: freeciv-dev: February 2003:
[Freeciv-Dev] (PR#3424) New flush code soplited in 2 parts
Home

[Freeciv-Dev] (PR#3424) New flush code soplited in 2 parts

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
To: bursig@xxxxxxxxx
Subject: [Freeciv-Dev] (PR#3424) New flush code soplited in 2 parts
From: "Jason Short" <jdorje@xxxxxxxxxxxxxxxxxxxxx>
Date: Tue, 18 Feb 2003 02:06:32 -0800
Reply-to: rt@xxxxxxxxxxxxxx

[rfalke - Mon Feb 17 20:11:36 2003]:

> On Mon, Feb 17, 2003 at 11:53:33AM -0800, Jason Short wrote:
> > Raimar Falke wrote:
> > > On Thu, Feb 13, 2003 at 04:50:59PM -0800, Rafa? Bursig wrote:
> > > 
> > > why can't the non-sdl guis also do the deferred flushing? I.e. save
> > > the info and only flush at flush_rects just like gui-sdl? This would
> > > make the code more homogeneous.
> > 
> > Works for me.  However there are some drawing bugs (see 2982) that may 
> > cause problems for the flushing method. Also it takes a lot of code to 
> > do in independently for each GUI; I had thought to introduce a set of 
> > common functions to do this in a second patch (if it is done at all).
> > 
> > However, the situation with update_map_canvas_visible (where we don't 
> > call dirty_all even though it seems we should) makes me think 
> 
> > that all clients should do the flush-buffering
> 
> Pro:
>  - since the flushs get defered this adds the _possibility_ to merge
>  flushs
>  - makes it the same for all clients (and gui-sdl needs it, so we
>  can't do it the other way around)
> 
> Con:
>  - ??
> 
> Seems pretty clear to me.

SDL and other GUI libraries do optimizations of this code.  For instance
in gui-gtk-2.0 the code will end up as something like:

  void dirty_rect(int canvas_x, int canvas_y,
                 int pixel_width, int pixel_height)
  {
    GdkRectangle rect = {canvas_x, canvas_y, pixel_width, pixel_height};
    gdk_window_invalidate_rect(map_canvas->window, &rect, FALSE);
  }

  void dirty_all(void)
  {
    GdkRectangle rect = {0, 0, map_canvas->allocation.width,
                        map_canvas->allocation.height};
    gdk_window_invalidate_rect(map_canvas->window, &rect, FALSE);
  }

  void flush_dirty(void)
  {
    gdk_window_process_updates(map_canvas->window, FALSE);
  }

which is much easier to write by leaving these functions in the GUI.  I
suspect that other libraries (GTK-1.2 and XAW, at least) will support
similar functionality.

> > My next question, then, is: does this flush-buffering code need to
> > go into the GUI, or can there just be one implementation in
> > mapview_common?
> 
> dirty_rectangle
> dirty_all
> flush_dirty
> 
> can all be done with in common code. The hook here would be
> flush_region with the same parameter as the current flush_mapcanvas.

In SDL the call is SDL_FlushRects which takes an array of rectangles
that are to be flushed.  This means to be most efficient the GUI needs
to have all rectangles at once.  So at best we could have
flush_regions() which takes a list of rectangles.  But this is slower
for SDL (extra memcpy needed) and makes the gtk2 implementation uglier.
 So I think it is best to leave all three functions at the GUI end.

I'm working on a patch to implement this properly for other GUIs.  So
far the gtk2 implementation (as above) is about the same speed as the
original code, but gives smoother drawing.  We'll see how it works out
for the other GUIs.

jason



[Prev in Thread] Current Thread [Next in Thread]