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: Thu, 20 Feb 2003 15:05:02 -0800
Reply-to: rt@xxxxxxxxxxxxxx

[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);
 

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