[Freeciv-Dev] (PR#12032) canvas_set_clip_rect function
[Top] [All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
<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 <=
|
|