[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]
[jdorje - Tue Feb 18 10:06:31 2003]:
> 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.
Here's my current version of the patch. This is still a work in
progress - finding the correct places to call flush_dirty requires a
fair amount of work (both auditing and testing). It currently works
very well for the GTK2 client; the GTK, XAW, and Win32 client still need
some work.
It has, unfortunately, grown significantly.
jason
? client/automation.c
? client/automation.h
? client/scratch
? client/gui-sdl/diff
Index: client/climisc.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/climisc.c,v
retrieving revision 1.112
diff -u -r1.112 climisc.c
--- client/climisc.c 2003/02/15 20:26:17 1.112
+++ client/climisc.c 2003/02/20 00:31:15
@@ -111,7 +111,7 @@
get_nation_name(city_owner(pcity)->nation), pcity->x, pcity->y);
}
- refresh_tile_mapcanvas(x, y, TRUE);
+ refresh_tile_mapcanvas(x, y, FALSE);
}
/**************************************************************************
@@ -142,7 +142,7 @@
popdown_city_dialog(pcity);
game_remove_city(pcity);
city_report_dialog_update();
- refresh_tile_mapcanvas(x, y, TRUE);
+ refresh_tile_mapcanvas(x, y, FALSE);
}
/**************************************************************************
@@ -368,6 +368,7 @@
OUT:
; /* do nothing */
}
+ flush_dirty();
}
/**************************************************************************
Index: client/control.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/control.c,v
retrieving revision 1.94
diff -u -r1.94 control.c
--- client/control.c 2003/02/10 21:43:40 1.94
+++ client/control.c 2003/02/20 00:31:16
@@ -110,7 +110,7 @@
auto_center_on_focus_unit();
punit->focus_status=FOCUS_AVAIL;
- refresh_tile_mapcanvas(punit->x, punit->y, TRUE);
+ refresh_tile_mapcanvas(punit->x, punit->y, FALSE);
if (punit->activity != ACTIVITY_IDLE || punit->ai.control) {
punit->activity = ACTIVITY_IDLE;
@@ -123,7 +123,7 @@
if (punit_old_focus
&& (!punit || !same_pos(punit_old_focus->x, punit_old_focus->y,
punit->x, punit->y))) {
- refresh_tile_mapcanvas(punit_old_focus->x, punit_old_focus->y, TRUE);
+ refresh_tile_mapcanvas(punit_old_focus->x, punit_old_focus->y, FALSE);
}
update_unit_info_label(punit);
@@ -141,7 +141,7 @@
punit_focus=punit;
if(punit) {
- refresh_tile_mapcanvas(punit->x, punit->y, TRUE);
+ refresh_tile_mapcanvas(punit->x, punit->y, FALSE);
punit->focus_status=FOCUS_AVAIL;
}
}
@@ -214,7 +214,7 @@
* because above we change punit_focus directly.
*/
if(punit_old_focus && punit_old_focus!=punit_focus)
- refresh_tile_mapcanvas(punit_old_focus->x, punit_old_focus->y, TRUE);
+ refresh_tile_mapcanvas(punit_old_focus->x, punit_old_focus->y, FALSE);
set_unit_focus(punit_focus);
@@ -915,6 +915,7 @@
draw_map_grid^=1;
update_map_canvas_visible();
+ flush_dirty();
}
/**************************************************************************
@@ -928,6 +929,7 @@
draw_city_names ^= 1;
update_map_canvas_visible();
+ flush_dirty();
}
/**************************************************************************
@@ -941,6 +943,7 @@
draw_city_growth = !draw_city_growth;
update_map_canvas_visible();
+ flush_dirty();
}
/**************************************************************************
@@ -954,6 +957,7 @@
draw_city_productions ^= 1;
update_map_canvas_visible();
+ flush_dirty();
}
/**************************************************************************
@@ -967,6 +971,7 @@
draw_terrain ^= 1;
update_map_canvas_visible();
+ flush_dirty();
}
/**************************************************************************
@@ -980,6 +985,7 @@
draw_coastline ^= 1;
update_map_canvas_visible();
+ flush_dirty();
}
/**************************************************************************
@@ -993,6 +999,7 @@
draw_roads_rails ^= 1;
update_map_canvas_visible();
+ flush_dirty();
}
/**************************************************************************
@@ -1006,6 +1013,7 @@
draw_irrigation ^= 1;
update_map_canvas_visible();
+ flush_dirty();
}
/**************************************************************************
@@ -1019,6 +1027,7 @@
draw_mines ^= 1;
update_map_canvas_visible();
+ flush_dirty();
}
/**************************************************************************
@@ -1032,6 +1041,7 @@
draw_fortress_airbase ^= 1;
update_map_canvas_visible();
+ flush_dirty();
}
/**************************************************************************
@@ -1045,6 +1055,7 @@
draw_specials ^= 1;
update_map_canvas_visible();
+ flush_dirty();
}
/**************************************************************************
@@ -1058,6 +1069,7 @@
draw_pollution ^= 1;
update_map_canvas_visible();
+ flush_dirty();
}
/**************************************************************************
@@ -1071,6 +1083,7 @@
draw_cities ^= 1;
update_map_canvas_visible();
+ flush_dirty();
}
/**************************************************************************
@@ -1084,6 +1097,7 @@
draw_units ^= 1;
update_map_canvas_visible();
+ flush_dirty();
}
/**************************************************************************
@@ -1097,6 +1111,7 @@
draw_focus_unit ^= 1;
update_map_canvas_visible();
+ flush_dirty();
}
/**************************************************************************
@@ -1112,6 +1127,7 @@
update_map_canvas_visible();
refresh_overview_canvas();
refresh_overview_viewrect();
+ flush_dirty();
}
/**************************************************************************
@@ -1119,10 +1135,12 @@
**************************************************************************/
void request_center_focus_unit(void)
{
- struct unit *punit;
+ struct unit *punit = get_unit_in_focus();
- if((punit=get_unit_in_focus()))
+ if (punit) {
center_tile_mapcanvas(punit->x, punit->y);
+ flush_dirty();
+ }
}
/**************************************************************************
@@ -1168,6 +1186,9 @@
unit_list_unlink(&map_get_tile(x, y)->units, punit);
+ /* We need to update the canvas if the unit has moved. But unless it
+ * teleported we shouldn't flush this yet (that is handled by
+ * move_unit_map_canvas. */
if(!pinfo->carried)
refresh_tile_mapcanvas(x, y, was_teleported);
@@ -1183,7 +1204,7 @@
dx=1;
if(smooth_move_units)
move_unit_map_canvas(punit, x, y, dx, pinfo->y - punit->y);
- refresh_tile_mapcanvas(x, y, TRUE);
+ refresh_tile_mapcanvas(x, y, FALSE);
}
punit->x=pinfo->x;
@@ -1202,12 +1223,12 @@
} unit_list_iterate_end;
out:
if (refresh) {
- refresh_tile_mapcanvas(x, y, TRUE);
+ refresh_tile_mapcanvas(x, y, FALSE);
}
} square_iterate_end;
if(!pinfo->carried && tile_get_known(punit->x,punit->y) == TILE_KNOWN)
- refresh_tile_mapcanvas(punit->x, punit->y, TRUE);
+ refresh_tile_mapcanvas(punit->x, punit->y, FALSE);
if(get_unit_in_focus()==punit) update_menus();
}
@@ -1348,6 +1369,7 @@
} else {
append_output_window(_("Game: Didn't find a route to the destination!"));
}
+ flush_dirty();
}
set_hover_state(NULL, HOVER_NONE);
Index: client/mapctrl_common.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/mapctrl_common.c,v
retrieving revision 1.5
diff -u -r1.5 mapctrl_common.c
--- client/mapctrl_common.c 2003/01/09 19:21:17 1.5
+++ client/mapctrl_common.c 2003/02/20 00:31:16
@@ -94,6 +94,7 @@
get_line_dest(&old_x, &old_y);
if (!same_pos(old_x, old_y, x, y)) {
draw_line(x, y);
+ flush_dirty();
}
}
}
Index: client/mapview_common.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/mapview_common.c,v
retrieving revision 1.30
diff -u -r1.30 mapview_common.c
--- client/mapview_common.c 2003/02/17 02:11:25 1.30
+++ client/mapview_common.c 2003/02/20 00:31:16
@@ -42,7 +42,7 @@
if (tile_visible_mapcanvas(x, y)) {
update_map_canvas(x, y, 1, 1, FALSE);
- if (write_to_screen && (draw_city_names || draw_city_productions)) {
+ if (draw_city_names || draw_city_productions) {
/* FIXME: update_map_canvas() will overwrite the city descriptions.
* This is a workaround that redraws the city descriptions (most of
* the time). Although it seems inefficient to redraw the
@@ -88,12 +88,7 @@
}
if (write_to_screen) {
- int canvas_start_x, canvas_start_y;
-
- get_canvas_xy(x, y, &canvas_start_x, &canvas_start_y);
- canvas_start_y += NORMAL_TILE_HEIGHT - UNIT_TILE_HEIGHT;
- flush_mapcanvas(canvas_start_x, canvas_start_y,
- UNIT_TILE_WIDTH, UNIT_TILE_HEIGHT);
+ flush_dirty();
}
}
overview_update_tile(x, y);
@@ -528,6 +523,8 @@
void update_map_canvas(int x, int y, int width, int height,
bool write_to_screen)
{
+ int canvas_start_x, canvas_start_y;
+
freelog(LOG_DEBUG,
"update_map_canvas(pos=(%d,%d), size=(%d,%d), write_to_screen=%d)",
x, y, width, height, write_to_screen);
@@ -602,31 +599,26 @@
/* Lastly draw our changes to the screen. */
- if (write_to_screen) {
- int canvas_start_x, canvas_start_y;
+ /* top left corner */
+ get_canvas_xy(x, y, &canvas_start_x, &canvas_start_y);
- /* top left corner */
- get_canvas_xy(x, y, &canvas_start_x, &canvas_start_y);
+ /* top left corner in isometric view */
+ canvas_start_x -= height * NORMAL_TILE_WIDTH / 2;
- /* top left corner in isometric view */
- canvas_start_x -= height * NORMAL_TILE_WIDTH / 2;
+ /* because of where get_canvas_xy() sets canvas_x */
+ canvas_start_x += NORMAL_TILE_WIDTH / 2;
- /* because of where get_canvas_xy() sets canvas_x */
- canvas_start_x += NORMAL_TILE_WIDTH / 2;
-
- /* And because units fill a little extra */
- canvas_start_y -= NORMAL_TILE_HEIGHT / 2;
-
- /* Here we draw a rectangle that includes the updated tiles. This
- * method can fail if the area wraps off one side of the screen and
- * back to the other (although this will not be a problem for
- * update_map_canvas_visible(). */
- flush_mapcanvas(canvas_start_x, canvas_start_y,
- (height + width) * NORMAL_TILE_WIDTH / 2,
- (height + width) * NORMAL_TILE_HEIGHT / 2
- + NORMAL_TILE_HEIGHT / 2);
- }
-
+ /* And because units fill a little extra */
+ canvas_start_y += NORMAL_TILE_HEIGHT - UNIT_TILE_HEIGHT;
+
+ /* Here we draw a rectangle that includes the updated tiles. This
+ * method can fail if the area wraps off one side of the screen and
+ * back to the other (although this will not be a problem for
+ * update_map_canvas_visible(). */
+ dirty_rect(canvas_start_x, canvas_start_y,
+ (height + width) * NORMAL_TILE_WIDTH / 2,
+ (height + width) * NORMAL_TILE_HEIGHT / 2
+ + NORMAL_TILE_HEIGHT / 2);
} else {
/* not isometric */
int map_x, map_y;
@@ -641,18 +633,22 @@
}
}
- if (write_to_screen) {
- int canvas_x, canvas_y;
-
- /* Here we draw a rectangle that includes the updated tiles. This
- * method can fail if the area wraps off one side of the screen and
- * back to the other (although this will not be a problem for
- * update_map_canvas_visible(). */
- get_canvas_xy(x, y, &canvas_x, &canvas_y);
- flush_mapcanvas(canvas_x, canvas_y,
- width * NORMAL_TILE_WIDTH,
- height * NORMAL_TILE_HEIGHT);
- }
+ get_canvas_xy(x, y, &canvas_start_x, &canvas_start_y);
+ /* Here we draw a rectangle that includes the updated tiles. This
+ * method can fail if the area wraps off one side of the screen and
+ * back to the other (although this will not be a problem for
+ * update_map_canvas_visible(). */
+ dirty_rect(canvas_start_x, canvas_start_y,
+ width * NORMAL_TILE_WIDTH,
+ height * NORMAL_TILE_HEIGHT);
+ }
+
+ if (write_to_screen) {
+ /* We never want a partial flush; that would leave the screen in an
+ * inconsistent state. If the caller tells us to write_to_screen we
+ * simply flush everything immediately. Note that this makes it pretty
+ * expensive to spuriously write_to_screen. */
+ flush_dirty();
}
}
@@ -684,7 +680,7 @@
show_city_descriptions();
- flush_mapcanvas(0, 0, map_win_width, map_win_height);
+ dirty_all();
}
/**************************************************************************
@@ -757,16 +753,10 @@
assert(0);
}
- if (is_isometric) {
- /* somewhat inefficient */
- update_map_canvas(MIN(src_x, dest_x), MIN(src_y, dest_y),
- src_x == dest_x ? 1 : 2,
- src_y == dest_y ? 1 : 2,
- TRUE);
- } else {
- refresh_tile_mapcanvas(src_x, src_y, TRUE);
- refresh_tile_mapcanvas(dest_x, dest_y, TRUE);
+ refresh_tile_mapcanvas(src_x, src_y, FALSE);
+ refresh_tile_mapcanvas(dest_x, dest_y, FALSE);
+ if (!is_isometric) {
if (NORMAL_TILE_WIDTH % 2 == 0 || NORMAL_TILE_HEIGHT % 2 == 0) {
if (dir == DIR8_NORTHEAST) {
/* Since the tile doesn't have a middle we draw an extra pixel
@@ -774,12 +764,12 @@
if (!MAPSTEP(dest_x, dest_y, src_x, src_y, DIR8_EAST)) {
assert(0);
}
- refresh_tile_mapcanvas(dest_x, dest_y, TRUE);
+ refresh_tile_mapcanvas(dest_x, dest_y, FALSE);
} else if (dir == DIR8_SOUTHWEST) { /* the same */
if (!MAPSTEP(dest_x, dest_y, src_x, src_y, DIR8_SOUTH)) {
assert(0);
}
- refresh_tile_mapcanvas(dest_x, dest_y, TRUE);
+ refresh_tile_mapcanvas(dest_x, dest_y, FALSE);
}
}
}
@@ -810,6 +800,8 @@
if (!normalize_map_pos(&dest_x, &dest_y)) {
assert(0);
}
+
+ flush_dirty();
if (player_can_see_unit(game.player_ptr, punit) &&
(tile_visible_mapcanvas(map_x, map_y) ||
Index: client/messagewin_common.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/messagewin_common.c,v
retrieving revision 1.11
diff -u -r1.11 messagewin_common.c
--- client/messagewin_common.c 2003/02/19 23:46:16 1.11
+++ client/messagewin_common.c 2003/02/20 00:31:16
@@ -209,6 +209,10 @@
* highlighted at all - this is left up to the GUI. */
popup_city_dialog(pcity, FALSE);
}
+
+ if (center_when_popup_city || pcity) {
+ flush_dirty();
+ }
}
}
@@ -222,6 +226,7 @@
if (messages[message_index].location_ok) {
center_tile_mapcanvas(messages[message_index].x,
messages[message_index].y);
+ flush_dirty();
}
}
Index: client/packhand.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/packhand.c,v
retrieving revision 1.291
diff -u -r1.291 packhand.c
--- client/packhand.c 2003/02/17 22:49:27 1.291
+++ client/packhand.c 2003/02/20 00:31:17
@@ -190,6 +190,7 @@
**************************************************************************/
void handle_nuke_tile(struct packet_nuke_tile *packet)
{
+ flush_dirty();
put_nuke_mushroom_pixmaps(packet->x, packet->y);
}
@@ -223,14 +224,15 @@
unit_type(punit1)->sound_fight_alt);
if (do_combat_animation) {
+ flush_dirty();
decrease_unit_hp_smooth(punit0, hp0, punit1, hp1);
} else {
punit0->hp = hp0;
punit1->hp = hp1;
set_units_in_combat(NULL, NULL);
- refresh_tile_mapcanvas(punit0->x, punit0->y, TRUE);
- refresh_tile_mapcanvas(punit1->x, punit1->y, TRUE);
+ refresh_tile_mapcanvas(punit0->x, punit0->y, FALSE);
+ refresh_tile_mapcanvas(punit1->x, punit1->y, FALSE);
}
}
}
@@ -503,7 +505,7 @@
CITY_MAP_SIZE, CITY_MAP_SIZE, FALSE);
queue_mapview_update(UPDATE_CITY_DESCRIPTIONS);
} else {
- refresh_tile_mapcanvas(pcity->x, pcity->y, TRUE);
+ refresh_tile_mapcanvas(pcity->x, pcity->y, FALSE);
}
if (city_workers_display==pcity) {
@@ -914,7 +916,7 @@
if(punit->owner==game.player_idx)
refresh_unit_city_dialogs(punit);
- /* refresh_tile_mapcanvas(punit->x, punit->y, TRUE);
+ /* refresh_tile_mapcanvas(punit->x, punit->y, FALSE);
* update_unit_pix_label(punit);
* update_unit_focus();
*/
@@ -982,7 +984,7 @@
else {
do_move_unit(punit, packet); /* nice to see where a unit is going */
client_remove_unit(punit);
- refresh_tile_mapcanvas(packet->x, packet->y, TRUE);
+ refresh_tile_mapcanvas(packet->x, packet->y, FALSE);
return;
}
if(pcity) {
@@ -1052,7 +1054,7 @@
/*fog of war*/
if (!(tile_get_known(punit->x,punit->y) == TILE_KNOWN)) {
client_remove_unit(punit);
- refresh_tile_mapcanvas(dest_x, dest_y, TRUE);
+ refresh_tile_mapcanvas(dest_x, dest_y, FALSE);
}
agents_unit_changed(punit);
}
@@ -1089,7 +1091,7 @@
}
if(repaint_unit)
- refresh_tile_mapcanvas(punit->x, punit->y, TRUE);
+ refresh_tile_mapcanvas(punit->x, punit->y, FALSE);
if (check_focus || get_unit_in_focus() == NULL)
update_unit_focus();
@@ -1697,14 +1699,14 @@
/* the tile itself */
if (tile_changed || old_known!=ptile->known)
- refresh_tile_mapcanvas(x, y, TRUE);
+ refresh_tile_mapcanvas(x, y, FALSE);
/* if the terrain or the specials of the tile
have changed it affects the adjacent tiles */
if (tile_changed) {
adjc_iterate(x, y, x1, y1) {
if (tile_get_known(x1, y1) >= TILE_KNOWN_FOGGED)
- refresh_tile_mapcanvas(x1, y1, TRUE);
+ refresh_tile_mapcanvas(x1, y1, FALSE);
}
adjc_iterate_end;
return;
@@ -1715,7 +1717,7 @@
if (old_known == TILE_UNKNOWN && packet->known >= TILE_KNOWN_FOGGED) {
cartesian_adjacent_iterate(x, y, x1, y1) {
if (tile_get_known(x1, y1) >= TILE_KNOWN_FOGGED)
- refresh_tile_mapcanvas(x1, y1, TRUE);
+ refresh_tile_mapcanvas(x1, y1, FALSE);
}
cartesian_adjacent_iterate_end;
}
@@ -2478,6 +2480,7 @@
}
agents_processing_finished();
+ flush_dirty();
}
/**************************************************************************
@@ -2548,4 +2551,5 @@
reports_thaw();
agents_thaw_hint();
+ flush_dirty();
}
Index: client/tilespec.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/tilespec.c,v
retrieving revision 1.110
diff -u -r1.110 tilespec.c
--- client/tilespec.c 2003/02/05 07:19:43 1.110
+++ client/tilespec.c 2003/02/20 00:31:19
@@ -361,6 +361,7 @@
}
tileset_changed();
center_tile_mapcanvas(center_x, center_y);
+ flush_dirty();
}
/**************************************************************************
Index: client/gui-gtk/mapctrl.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/gui-gtk/mapctrl.c,v
retrieving revision 1.76
diff -u -r1.76 mapctrl.c
--- client/gui-gtk/mapctrl.c 2003/02/17 22:49:27 1.76
+++ client/gui-gtk/mapctrl.c 2003/02/20 00:31:19
@@ -335,6 +335,7 @@
} else if (ev->button == 3) {
center_tile_mapcanvas(xtile, ytile);
}
+ flush_dirty();
return TRUE;
}
@@ -428,6 +429,8 @@
} else if (can_client_issue_orders() && ev->button == 1) {
do_unit_goto(xtile, ytile);
}
+
+ flush_dirty();
return TRUE;
}
Index: client/gui-gtk/mapview.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/gui-gtk/mapview.c,v
retrieving revision 1.156
diff -u -r1.156 mapview.c
--- client/gui-gtk/mapview.c 2003/02/17 02:11:25 1.156
+++ client/gui-gtk/mapview.c 2003/02/20 00:31:20
@@ -241,10 +241,10 @@
else
punit0->hp--;
- refresh_tile_mapcanvas(punit0->x, punit0->y, TRUE);
- refresh_tile_mapcanvas(punit1->x, punit1->y, TRUE);
+ refresh_tile_mapcanvas(punit0->x, punit0->y, FALSE);
+ refresh_tile_mapcanvas(punit1->x, punit1->y, FALSE);
+ flush_dirty();
- gdk_flush();
usleep_since_timer_start(anim_timer, 10000);
} while (punit0->hp > hp0 || punit1->hp > hp1);
@@ -286,8 +286,9 @@
}
set_units_in_combat(NULL, NULL);
- refresh_tile_mapcanvas(punit0->x, punit0->y, TRUE);
- refresh_tile_mapcanvas(punit1->x, punit1->y, TRUE);
+ refresh_tile_mapcanvas(punit0->x, punit0->y, FALSE);
+ refresh_tile_mapcanvas(punit1->x, punit1->y, FALSE);
+ flush_dirty();
}
/**************************************************************************
@@ -905,9 +906,60 @@
gdk_draw_pixmap(map_canvas->window, civ_gc, map_canvas_store,
canvas_x, canvas_y, canvas_x, canvas_y,
pixel_width, pixel_height);
+
+}
+
+#define MAX_DIRTY_RECTS 10
+static int num_dirty_rects = 0;
+static GdkRectangle dirty_rects[MAX_DIRTY_RECTS];
+
+/**************************************************************************
+ Mark the rectangular region as 'dirty' so that we know to flush it
+ later.
+**************************************************************************/
+void dirty_rect(int canvas_x, int canvas_y,
+ int pixel_width, int pixel_height)
+{
+ if (num_dirty_rects < MAX_DIRTY_RECTS) {
+ dirty_rects[num_dirty_rects].x = canvas_x;
+ dirty_rects[num_dirty_rects].y = canvas_y;
+ dirty_rects[num_dirty_rects].width = pixel_width;
+ dirty_rects[num_dirty_rects].height = pixel_height;
+ num_dirty_rects++;
+ }
+}
+
+/**************************************************************************
+ Mark the entire screen area as "dirty" so that we can flush it later.
+**************************************************************************/
+void dirty_all(void)
+{
+ num_dirty_rects = MAX_DIRTY_RECTS;
}
/**************************************************************************
+ Flush all regions that have been previously marked as dirty. See
+ dirty_rect and dirty_all. This function is generally called after we've
+ processed a batch of drawing operations.
+**************************************************************************/
+void flush_dirty(void)
+{
+ if (num_dirty_rects == MAX_DIRTY_RECTS) {
+ flush_mapcanvas(0, 0, map_canvas->allocation.width,
+ map_canvas->allocation.height);
+ } else {
+ int i;
+
+ for (i = 0; i < num_dirty_rects; i++) {
+ flush_mapcanvas(dirty_rects[i].x, dirty_rects[i].y,
+ dirty_rects[i].width, dirty_rects[i].height);
+ }
+ }
+ num_dirty_rects = 0;
+ gdk_flush();
+}
+
+/**************************************************************************
Update display of descriptions associated with cities on the main map.
**************************************************************************/
void update_city_descriptions(void)
@@ -1407,9 +1459,14 @@
/* draw it! */
gdk_draw_line(map_canvas_store, thick_line_gc,
canvas_start_x, canvas_start_y, canvas_end_x, canvas_end_y);
+
+ dirty_rect(MIN(canvas_start_x, canvas_end_x) - 1,
+ MIN(canvas_start_y, canvas_end_y) - 1,
+ ABS(canvas_end_x - canvas_start_x) + 2,
+ ABS(canvas_end_y - canvas_start_y) + 2);
+
if (write_to_screen)
- gdk_draw_line(map_canvas->window, thick_line_gc,
- canvas_start_x, canvas_start_y, canvas_end_x, canvas_end_y);
+ flush_dirty();
return;
}
@@ -1421,7 +1478,7 @@
assert(get_drawn(src_x, src_y, dir) > 0);
if (is_isometric) {
- really_draw_segment(src_x, src_y, dir, TRUE, FALSE);
+ really_draw_segment(src_x, src_y, dir, FALSE, FALSE);
} else {
int dest_x, dest_y, is_real;
@@ -1430,11 +1487,9 @@
if (tile_visible_mapcanvas(src_x, src_y)) {
put_line(map_canvas_store, src_x, src_y, dir);
- put_line(map_canvas->window, src_x, src_y, dir);
}
if (tile_visible_mapcanvas(dest_x, dest_y)) {
put_line(map_canvas_store, dest_x, dest_y, DIR_REVERSE(dir));
- put_line(map_canvas->window, dest_x, dest_y, DIR_REVERSE(dir));
}
}
}
@@ -1446,6 +1501,8 @@
{
int canvas_src_x, canvas_src_y, canvas_dest_x, canvas_dest_y;
get_canvas_xy(x, y, &canvas_src_x, &canvas_src_y);
+ dirty_rect(canvas_src_x, canvas_src_y,
+ NORMAL_TILE_WIDTH, NORMAL_TILE_HEIGHT);
canvas_src_x += NORMAL_TILE_WIDTH/2;
canvas_src_y += NORMAL_TILE_HEIGHT/2;
DIRSTEP(canvas_dest_x, canvas_dest_y, dir);
Index: client/gui-gtk-2.0/mapview.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/gui-gtk-2.0/mapview.c,v
retrieving revision 1.44
diff -u -r1.44 mapview.c
--- client/gui-gtk-2.0/mapview.c 2003/02/17 02:11:25 1.44
+++ client/gui-gtk-2.0/mapview.c 2003/02/20 00:31:21
@@ -240,10 +240,10 @@
else
punit0->hp--;
- refresh_tile_mapcanvas(punit0->x, punit0->y, TRUE);
- refresh_tile_mapcanvas(punit1->x, punit1->y, TRUE);
+ refresh_tile_mapcanvas(punit0->x, punit0->y, FALSE);
+ refresh_tile_mapcanvas(punit1->x, punit1->y, FALSE);
+ flush_dirty();
- gdk_flush();
usleep_since_timer_start(anim_timer, 10000);
} while (punit0->hp > hp0 || punit1->hp > hp1);
@@ -285,8 +285,9 @@
}
set_units_in_combat(NULL, NULL);
- refresh_tile_mapcanvas(punit0->x, punit0->y, TRUE);
- refresh_tile_mapcanvas(punit1->x, punit1->y, TRUE);
+ refresh_tile_mapcanvas(punit0->x, punit0->y, FALSE);
+ refresh_tile_mapcanvas(punit1->x, punit1->y, FALSE);
+ flush_dirty();
}
/**************************************************************************
@@ -937,6 +938,46 @@
}
/**************************************************************************
+ Mark the rectangular region as "dirty" so that we know to flush it
+ later.
+**************************************************************************/
+void dirty_rect(int canvas_x, int canvas_y,
+ int pixel_width, int pixel_height)
+{
+ /* GDK gives an error if we invalidate out-of-bounds parts of the
+ window. */
+ GdkRectangle rect = {MAX(canvas_x, 0), MAX(canvas_y, 0),
+ MIN(pixel_width,
+ map_canvas->allocation.width - canvas_x),
+ MIN(pixel_height,
+ map_canvas->allocation.height - canvas_y)};
+
+ gdk_window_invalidate_rect(map_canvas->window, &rect, FALSE);
+}
+
+/**************************************************************************
+ Mark the entire screen area as "dirty" so that we can flush it later.
+**************************************************************************/
+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);
+}
+
+/**************************************************************************
+ Flush all regions that have been previously marked as dirty. See
+ dirty_rect and dirty_all. This function is generally called after we've
+ processed a batch of drawing operations.
+**************************************************************************/
+void flush_dirty(void)
+{
+ gdk_window_process_updates(map_canvas->window, FALSE);
+ gdk_flush();
+}
+
+/**************************************************************************
Update display of descriptions associated with cities on the main map.
**************************************************************************/
void update_city_descriptions(void)
@@ -1480,9 +1521,14 @@
/* draw it! */
gdk_draw_line(map_canvas_store, thick_line_gc,
canvas_start_x, canvas_start_y, canvas_end_x, canvas_end_y);
+
+ dirty_rect(MIN(canvas_start_x, canvas_end_x) - 1,
+ MIN(canvas_start_y, canvas_end_y) - 1,
+ ABS(canvas_end_x - canvas_start_x) + 2,
+ ABS(canvas_end_y - canvas_start_y) + 2);
+
if (write_to_screen)
- gdk_draw_line(map_canvas->window, thick_line_gc,
- canvas_start_x, canvas_start_y, canvas_end_x, canvas_end_y);
+ flush_dirty();
return;
}
@@ -1494,7 +1540,7 @@
assert(get_drawn(src_x, src_y, dir) > 0);
if (is_isometric) {
- really_draw_segment(src_x, src_y, dir, TRUE, FALSE);
+ really_draw_segment(src_x, src_y, dir, FALSE, FALSE);
} else {
int dest_x, dest_y, is_real;
@@ -1503,11 +1549,9 @@
if (tile_visible_mapcanvas(src_x, src_y)) {
put_line(map_canvas_store, src_x, src_y, dir);
- put_line(map_canvas->window, src_x, src_y, dir);
}
if (tile_visible_mapcanvas(dest_x, dest_y)) {
put_line(map_canvas_store, dest_x, dest_y, DIR_REVERSE(dir));
- put_line(map_canvas->window, dest_x, dest_y, DIR_REVERSE(dir));
}
}
}
@@ -1519,6 +1563,8 @@
{
int canvas_src_x, canvas_src_y, canvas_dest_x, canvas_dest_y;
get_canvas_xy(x, y, &canvas_src_x, &canvas_src_y);
+ dirty_rect(canvas_src_x, canvas_src_y,
+ NORMAL_TILE_WIDTH, NORMAL_TILE_HEIGHT);
canvas_src_x += NORMAL_TILE_WIDTH/2;
canvas_src_y += NORMAL_TILE_HEIGHT/2;
DIRSTEP(canvas_dest_x, canvas_dest_y, dir);
Index: client/gui-sdl/mapview.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/gui-sdl/mapview.c,v
retrieving revision 1.22
diff -u -r1.22 mapview.c
--- client/gui-sdl/mapview.c 2003/02/19 23:03:39 1.22
+++ client/gui-sdl/mapview.c 2003/02/20 00:31:22
@@ -330,6 +330,34 @@
}
/**************************************************************************
+ Mark the rectangular region as "dirty" so that we know to flush it
+ later.
+**************************************************************************/
+void dirty_rect(int canvas_x, int canvas_y,
+ int pixel_width, int pixel_height)
+{
+ add_refresh_region(canvas_x, canvas_y, pixel_width, pixel_height);
+}
+
+/**************************************************************************
+ Mark the entire screen area as "dirty" so that we can flush it later.
+**************************************************************************/
+void dirty_all(void)
+{
+ Main.rects_count = RECT_LIMIT;
+}
+
+/**************************************************************************
+ Flush all regions that have been previously marked as dirty. See
+ dirty_rect and dirty_all. This function is generally called after we've
+ processed a batch of drawing operations.
+**************************************************************************/
+void flush_dirty(void)
+{
+ refresh_rects();
+}
+
+/**************************************************************************
Finds the pixel coordinates of a tile. Save setting of the results in
(pX, pY). Function returns TRUE whether the tile is inside the pDest
surface.
Index: client/gui-stub/mapview.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/gui-stub/mapview.c,v
retrieving revision 1.26
diff -u -r1.26 mapview.c
--- client/gui-stub/mapview.c 2003/02/07 08:35:03 1.26
+++ client/gui-stub/mapview.c 2003/02/20 00:31:22
@@ -224,6 +224,33 @@
/* PORTME */
}
+/**************************************************************************
+ Mark the rectangular region as 'dirty' so that we know to flush it
+ later.
+**************************************************************************/
+void dirty_rect(int canvas_x, int canvas_y,
+ int pixel_width, int pixel_height)
+{
+ /* PORTME */
+}
+
+/**************************************************************************
+ Mark the entire screen area as "dirty" so that we can flush it later.
+**************************************************************************/
+void dirty_all(void)
+{
+ /* PORTME */
+}
+
+/**************************************************************************
+ Flush all regions that have been previously marked as dirty. See
+ dirty_rect and dirty_all. This function is generally called after we've
+ processed a batch of drawing operations.
+**************************************************************************/
+void flush_dirty(void)
+{
+ /* PORTME */
+}
/**************************************************************************
Update (refresh) the locations of the mapview scrollbars (if it uses
Index: client/gui-win32/mapctrl.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/gui-win32/mapctrl.c,v
retrieving revision 1.20
diff -u -r1.20 mapctrl.c
--- client/gui-win32/mapctrl.c 2003/02/17 22:49:27 1.20
+++ client/gui-win32/mapctrl.c 2003/02/20 00:31:22
@@ -302,6 +302,7 @@
} else {
center_tile_mapcanvas(xtile,ytile);
}
+ flush_dirty();
}
break;
case WM_SETFOCUS:
@@ -371,7 +372,7 @@
return;
}
center_tile_mapcanvas(xtile,ytile);
-
+ flush_dirty();
}
/**************************************************************************
Index: client/gui-win32/mapview.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/gui-win32/mapview.c,v
retrieving revision 1.56
diff -u -r1.56 mapview.c
--- client/gui-win32/mapview.c 2003/02/17 02:11:26 1.56
+++ client/gui-win32/mapview.c 2003/02/20 00:31:23
@@ -673,7 +673,58 @@
DeleteDC(mapstoredc);
}
+#define MAX_DIRTY_RECTS 10
+static int num_dirty_rects = 0;
+static struct {
+ int x, y, w, h;
+} dirty_rects[MAX_DIRTY_RECTS];
+
+/**************************************************************************
+ Mark the rectangular region as 'dirty' so that we know to flush it
+ later.
+**************************************************************************/
+void dirty_rect(int canvas_x, int canvas_y,
+ int pixel_width, int pixel_height)
+{
+ if (num_dirty_rects < MAX_DIRTY_RECTS) {
+ dirty_rects[num_dirty_rects].x = canvas_x;
+ dirty_rects[num_dirty_rects].y = canvas_y;
+ dirty_rects[num_dirty_rects].w = pixel_width;
+ dirty_rects[num_dirty_rects].h = pixel_height;
+ num_dirty_rects++;
+ }
+}
+
+/**************************************************************************
+ Mark the entire screen area as "dirty" so that we can flush it later.
+**************************************************************************/
+void dirty_all(void)
+{
+ num_dirty_rects = MAX_DIRTY_RECTS;
+}
+
/**************************************************************************
+ Flush all regions that have been previously marked as dirty. See
+ dirty_rect and dirty_all. This function is generally called after we've
+ processed a batch of drawing operations.
+**************************************************************************/
+void flush_dirty(void)
+{
+ if (num_dirty_rects == MAX_DIRTY_RECTS) {
+ flush_mapcanvas(0, 0, map_win_width, map_win_height);
+ } else {
+ int i;
+
+ for (i = 0; i < num_dirty_rects; i++) {
+ flush_mapcanvas(dirty_rects[i].x, dirty_rects[i].y,
+ dirty_rects[i].w, dirty_rects[i].h);
+ }
+ }
+ num_dirty_rects = 0;
+ GdiFlush();
+}
+
+/**************************************************************************
**************************************************************************/
void update_map_canvas_scrollbars_size(void)
@@ -867,9 +918,9 @@
else
punit0->hp--;
- refresh_tile_mapcanvas(punit0->x, punit0->y, TRUE);
- refresh_tile_mapcanvas(punit1->x, punit1->y, TRUE);
- GdiFlush();
+ refresh_tile_mapcanvas(punit0->x, punit0->y, FALSE);
+ refresh_tile_mapcanvas(punit1->x, punit1->y, FALSE);
+ flush_dirty();
usleep_since_timer_start(anim_timer, 10000);
@@ -912,9 +963,9 @@
SelectObject(mapstoredc,old_mapbmp);
DeleteDC(mapstoredc);
set_units_in_combat(NULL, NULL);
- refresh_tile_mapcanvas(punit0->x, punit0->y, TRUE);
- refresh_tile_mapcanvas(punit1->x, punit1->y, TRUE);
-
+ refresh_tile_mapcanvas(punit0->x, punit0->y, FALSE);
+ refresh_tile_mapcanvas(punit1->x, punit1->y, FALSE);
+ flush_dirty();
}
/**************************************************************************
Index: client/gui-xaw/mapctrl.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/gui-xaw/mapctrl.c,v
retrieving revision 1.64
diff -u -r1.64 mapctrl.c
--- client/gui-xaw/mapctrl.c 2003/02/17 22:49:27 1.64
+++ client/gui-xaw/mapctrl.c 2003/02/20 00:31:23
@@ -273,6 +273,7 @@
else if (ev->button == Button3) {
center_tile_mapcanvas(x, y);
}
+ flush_dirty();
}
/**************************************************************************
@@ -386,6 +387,8 @@
do_unit_goto(xtile,ytile);
else if(ev->button==Button3)
center_tile_mapcanvas(xtile, ytile);
+
+ flush_dirty();
}
/**************************************************************************
Index: client/gui-xaw/mapview.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/gui-xaw/mapview.c,v
retrieving revision 1.123
diff -u -r1.123 mapview.c
--- client/gui-xaw/mapview.c 2003/02/17 02:11:26 1.123
+++ client/gui-xaw/mapview.c 2003/02/20 00:31:24
@@ -108,10 +108,10 @@
else
punit0->hp--;
- refresh_tile_mapcanvas(punit0->x, punit0->y, TRUE);
- refresh_tile_mapcanvas(punit1->x, punit1->y, TRUE);
+ refresh_tile_mapcanvas(punit0->x, punit0->y, FALSE);
+ refresh_tile_mapcanvas(punit1->x, punit1->y, FALSE);
+ flush_dirty();
- XSync(display, 0);
usleep_since_timer_start(anim_timer, 10000);
} while (punit0->hp > hp0 || punit1->hp > hp1);
@@ -670,6 +670,58 @@
canvas_x, canvas_y);
}
+#define MAX_DIRTY_RECTS 10
+static int num_dirty_rects = 0;
+static XRectangle dirty_rects[MAX_DIRTY_RECTS];
+
+/**************************************************************************
+ Mark the rectangular region as 'dirty' so that we know to flush it
+ later.
+**************************************************************************/
+void dirty_rect(int canvas_x, int canvas_y,
+ int pixel_width, int pixel_height)
+{
+ if (num_dirty_rects < MAX_DIRTY_RECTS) {
+ dirty_rects[num_dirty_rects].x = canvas_x;
+ dirty_rects[num_dirty_rects].y = canvas_y;
+ dirty_rects[num_dirty_rects].width = pixel_width;
+ dirty_rects[num_dirty_rects].height = pixel_height;
+ num_dirty_rects++;
+ }
+}
+
+/**************************************************************************
+ Mark the entire screen area as "dirty" so that we can flush it later.
+**************************************************************************/
+void dirty_all(void)
+{
+ num_dirty_rects = MAX_DIRTY_RECTS;
+}
+
+/**************************************************************************
+ Flush all regions that have been previously marked as dirty. See
+ dirty_rect and dirty_all. This function is generally called after we've
+ processed a batch of drawing operations.
+**************************************************************************/
+void flush_dirty(void)
+{
+ if (num_dirty_rects == MAX_DIRTY_RECTS) {
+ Dimension width, height;
+
+ XtVaGetValues(map_canvas, XtNwidth, &width, XtNheight, &height, NULL);
+ flush_mapcanvas(0, 0, width, height);
+ } else {
+ int i;
+
+ for (i = 0; i < num_dirty_rects; i++) {
+ flush_mapcanvas(dirty_rects[i].x, dirty_rects[i].y,
+ dirty_rects[i].width, dirty_rects[i].height);
+ }
+ }
+ num_dirty_rects = 0;
+ XSync(display, 0);
+}
+
/**************************************************************************
...
**************************************************************************/
@@ -1146,6 +1198,8 @@
{
int canvas_src_x, canvas_src_y, canvas_dest_x, canvas_dest_y;
get_canvas_xy(x, y, &canvas_src_x, &canvas_src_y);
+ dirty_rect(canvas_src_x, canvas_src_y,
+ NORMAL_TILE_WIDTH, NORMAL_TILE_HEIGHT);
canvas_src_x += NORMAL_TILE_WIDTH/2;
canvas_src_y += NORMAL_TILE_HEIGHT/2;
canvas_dest_x = canvas_src_x + (NORMAL_TILE_WIDTH * DIR_DX[dir])/2;
@@ -1171,12 +1225,10 @@
if (tile_visible_mapcanvas(src_x, src_y)) {
put_line(map_canvas_store, src_x, src_y, dir);
- put_line(XtWindow(map_canvas), src_x, src_y, dir);
}
if (tile_visible_mapcanvas(dest_x, dest_y)) {
put_line(map_canvas_store, dest_x, dest_y, DIR_REVERSE(dir));
- put_line(XtWindow(map_canvas), dest_x, dest_y, DIR_REVERSE(dir));
}
}
Index: client/include/mapview_g.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/include/mapview_g.h,v
retrieving revision 1.31
diff -u -r1.31 mapview_g.h
--- client/include/mapview_g.h 2003/02/07 08:35:03 1.31
+++ client/include/mapview_g.h 2003/02/20 00:31:24
@@ -51,6 +51,10 @@
int width, int height);
void flush_mapcanvas(int canvas_x, int canvas_y,
int pixel_width, int pixel_height);
+void dirty_rect(int canvas_x, int canvas_y,
+ int pixel_width, int pixel_height);
+void dirty_all(void);
+void flush_dirty(void);
void update_map_canvas_scrollbars(void);
- [Freeciv-Dev] Re: (PR#3424) New flush code soplited in 2 parts, (continued)
- Message not available
- [Freeciv-Dev] Re: (PR#3424) New flush code soplited in 2 parts, Raimar Falke, 2003/02/15
- Message not available
- [Freeciv-Dev] Re: (PR#3424) New flush code soplited in 2 parts, Rafał Bursig, 2003/02/15
- Message not available
- [Freeciv-Dev] Re: (PR#3424) New flush code soplited in 2 parts, Raimar Falke, 2003/02/15
- Message not available
- [Freeciv-Dev] Re: (PR#3424) New flush code soplited in 2 parts, Jason Short, 2003/02/15
- Message not available
- [Freeciv-Dev] Re: (PR#3424) New flush code soplited in 2 parts, Raimar Falke, 2003/02/15
- Message not available
- [Freeciv-Dev] Re: (PR#3424) New flush code splited in 2 parts, Rafał Bursig, 2003/02/16
Message not available
[Freeciv-Dev] (PR#3424) New flush code soplited in 2 parts, Jason Short, 2003/02/18
[Freeciv-Dev] (PR#3424) New flush code soplited in 2 parts,
Jason Short <=
|
|