Complete.Org: Mailing Lists: Archives: freeciv-dev: January 2005:
[Freeciv-Dev] (PR#12032) canvas_set_clip_rect function
Home

[Freeciv-Dev] (PR#12032) canvas_set_clip_rect function

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
Subject: [Freeciv-Dev] (PR#12032) canvas_set_clip_rect function
From: "Jason Short" <jdorje@xxxxxxxxxxxxxxxxxxxxx>
Date: Thu, 27 Jan 2005 14:43:20 -0800
Reply-to: bugs@xxxxxxxxxxx

<URL: http://bugs.freeciv.org/Ticket/Display.html?id=12032 >

Currently in update_map_canvas when only redrawing part of the canvas, 
we enforce a "clip rectangle".  This is done by double-buffering 
(really, triple-buffering since there's already one layer of buffer) the 
drawing.  We draw to a tmp store then copy the rectangle being update to 
the main backing store.

However X (and gdk) has a mechanism for doing this: cliprects.  I 
thought it should be faster to use a clip-rect than to do an extra blit. 
  So I implemented this (for gui-xaw).  However I was surprised to find 
it was actually much slower: I dropped from 40 to 32 FPS.  It's also 
less reliable (since it only affects the civ_gc, while some canvas 
operations use other GCs).

Nonetheless I'll store the patch here.  Maybe someone will have a use 
for it someday.

-jason

Index: client/mapview_common.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/mapview_common.c,v
retrieving revision 1.171
diff -u -r1.171 mapview_common.c
--- client/mapview_common.c     5 Jan 2005 23:24:24 -0000       1.171
+++ client/mapview_common.c     27 Jan 2005 22:39:10 -0000
@@ -522,7 +522,7 @@
     } while (mytime < timing_sec);
 
     mytime = read_timer_seconds(anim_timer);
-    freelog(LOG_DEBUG, "Got %d frames in %f seconds: %f FPS.",
+    freelog(LOG_NORMAL, "Got %d frames in %f seconds: %f FPS.",
            frames, mytime, (double)frames / mytime);
   } else {
     base_set_mapview_origin(gui_x0, gui_y0);
@@ -1469,7 +1469,6 @@
 {
   int gui_x0, gui_y0;
   bool full;
-  struct canvas *tmp;
 
   canvas_x = MAX(canvas_x, 0);
   canvas_y = MAX(canvas_y, 0);
@@ -1490,10 +1489,7 @@
    * However if a partial redraw is done we draw everything onto the
    * tmp_canvas then copy *just* the area of update onto the canvas. */
   if (!full) {
-    /* Swap store and tmp_store. */
-    tmp = mapview_canvas.store;
-    mapview_canvas.store = mapview_canvas.tmp_store;
-    mapview_canvas.tmp_store = tmp;
+    canvas_set_clip_rectangle(canvas_x, canvas_y, width, height);
   }
 
   /* Clear the area.  This is necessary since some parts of the rectangle
@@ -1573,14 +1569,7 @@
   show_city_descriptions(canvas_x, canvas_y, width, height);
 
   if (!full) {
-    /* Swap store and tmp_store back. */
-    tmp = mapview_canvas.store;
-    mapview_canvas.store = mapview_canvas.tmp_store;
-    mapview_canvas.tmp_store = tmp;
-
-    /* And copy store to tmp_store. */
-    canvas_copy(mapview_canvas.store, mapview_canvas.tmp_store,
-               canvas_x, canvas_y, canvas_x, canvas_y, width, height);
+    canvas_clear_clip_rectangle();
   }
 
   dirty_rect(canvas_x, canvas_y, width, height);
Index: client/gui-xaw/mapview.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/gui-xaw/mapview.c,v
retrieving revision 1.186
diff -u -r1.186 mapview.c
--- client/gui-xaw/mapview.c    1 Dec 2004 18:56:53 -0000       1.186
+++ client/gui-xaw/mapview.c    27 Jan 2005 22:39:13 -0000
@@ -95,6 +95,28 @@
 }
 
 /**************************************************************************
+  Set the clipping rectangle.  Nothing outside of this rectangle should be
+  drawn by ANY of the canvas functions.  The clip rect doesn't apply to
+  any particular canvas (the caller will make sure the right canvases are
+  used when the rectangle is set).
+**************************************************************************/
+void canvas_set_clip_rectangle(int x0, int y0, int w, int h)
+{
+  XRectangle rects[1] = {{.x = x0, .y = y0, .width = w, .height = h}};
+
+  XSetClipRectangles(display, civ_gc, 0, 0, rects, 1, Unsorted);
+}
+
+/**************************************************************************
+  Clear any existing clipping rectangle.
+**************************************************************************/
+void canvas_clear_clip_rectangle(void)
+{
+
+  XSetClipMask(display, civ_gc, None);
+}
+
+/**************************************************************************
 ...
 **************************************************************************/
 void canvas_free(struct canvas *store)
Index: client/include/mapview_g.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/include/mapview_g.h,v
retrieving revision 1.58
diff -u -r1.58 mapview_g.h
--- client/include/mapview_g.h  29 Sep 2004 02:24:22 -0000      1.58
+++ client/include/mapview_g.h  27 Jan 2005 22:39:13 -0000
@@ -37,6 +37,8 @@
                    struct city *pcity, int *width, int *height);
 void prepare_show_city_descriptions(void);
 
+void canvas_set_clip_rectangle(int x0, int y0, int w, int h);
+void canvas_clear_clip_rectangle(void);
 void canvas_put_sprite(struct canvas *pcanvas,
                       int canvas_x, int canvas_y, struct Sprite *sprite,
                       int offset_x, int offset_y, int width, int height);

[Prev in Thread] Current Thread [Next in Thread]
  • [Freeciv-Dev] (PR#12032) canvas_set_clip_rect function, Jason Short <=