Complete.Org: Mailing Lists: Archives: freeciv-dev: February 2003:
[Freeciv-Dev] (PR#2986) buffering the city descriptions
Home

[Freeciv-Dev] (PR#2986) buffering the city descriptions

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
To: undisclosed-recipients:;
Subject: [Freeciv-Dev] (PR#2986) buffering the city descriptions
From: "Jason Short via RT" <rt@xxxxxxxxxxxxxx>
Date: Mon, 3 Feb 2003 14:18:46 -0800
Reply-to: rt.freeciv.org@xxxxxxxxxxxxxx

As discussed previously on PR#2858...

Some ggraphics aren't buffered when they are drawn - they are drawn 
"directly" onto the screen.  In the case of city descriptions, this is 
enforced in the common code by the order of the drawing.  (Other 
graphics are drawn directly as well, but only by the GUI.)

As long as this is the case, there will be problems.  One of them is 
PR#2858.  Another is that the city descriptions will always flicker when 
they are redrawn.  And extra drawing needs to be done (with the current 
situation), since show_city_descriptions is called for every expose 
evennt (in clients for which this makes sense).

I'm convinced that the solution is to say all drawing done by the
client-common code should be buffered.  We leave the decision of how to
do the buffering up to the GUI.

Thus in update_map_canvas_visible, the current order is:

    update_map_canvas(..., TRUE); // writes to display
    show_city_descriptions(); // also writes to display

whereas it should be

    update_map_canvas(..., FALSE); //doesn't write to display
    show_city_descriptions(); // doesn't write to display
    flush_mapcanvas_full(); // writes to display

This works out well for everyone.  It cuts down on flicker and speeds up
the drawing process in normal cases.  For the SDL client, it means you
can simply draw the map widgets on top of the canvas when it is flushed.

The attached patch accomplishes this in the simplest way.  It does not
introduce a flush_mapcanvas_full, but just flushes the canvas using the
existing function (which often will give off-screen coordinates).  It
would be possible to add a write_to_screen parameter to
show_city_descriptions() and show_city_desc(), but this is probably
overkill (although it does make changes like this easier in the future).

There is one slight change since the previous version (which was 
introduced under PR#2858) - some code needs to be changed to help the 
city-descriptions-get-overwritten bugfix workaround.

It is tested under all clients other than MUI.

Although a rather short patch, this is a non-trivial design change.  Are
there any disadvantages of having the city descriptions be buffered 
(there weren't when I suggested it under PR#2858, but...)?

jason

Index: client/mapview_common.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/mapview_common.c,v
retrieving revision 1.27
diff -u -r1.27 mapview_common.c
--- client/mapview_common.c     2003/01/31 09:09:58     1.27
+++ client/mapview_common.c     2003/02/03 22:11:12
@@ -40,7 +40,7 @@
   }
 
   if (tile_visible_mapcanvas(x, y)) {
-    update_map_canvas(x, y, 1, 1, write_to_screen);
+    update_map_canvas(x, y, 1, 1, FALSE);
 
     if (write_to_screen && (draw_city_names || draw_city_productions)) {
       /* FIXME: update_map_canvas() will overwrite the city descriptions.
@@ -86,6 +86,15 @@
        }
       }
     }
+
+    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);
+    }
   }
   overview_update_tile(x, y);
 }
@@ -668,13 +677,15 @@
 
     width = height = map_tile_width + map_tile_height;
     update_map_canvas(map_view_x0, map_view_y0 - map_tile_width, width,
-                     height, TRUE);
+                     height, FALSE);
   } else {
     update_map_canvas(map_view_x0, map_view_y0, map_tile_width,
-                     map_tile_height, TRUE);
+                     map_tile_height, FALSE);
   }
 
   show_city_descriptions();
+
+  flush_mapcanvas(0, 0, map_win_width, map_win_height);
 }
 
 /**************************************************************************
Index: client/gui-gtk/mapview.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/gui-gtk/mapview.c,v
retrieving revision 1.153
diff -u -r1.153 mapview.c
--- client/gui-gtk/mapview.c    2003/02/02 00:15:52     1.153
+++ client/gui-gtk/mapview.c    2003/02/03 22:11:13
@@ -766,7 +766,6 @@
        gdk_draw_pixmap( map_canvas->window, civ_gc, map_canvas_store,
                ev->area.x, ev->area.y, ev->area.x, ev->area.y,
                ev->area.width, ev->area.height );
-       show_city_descriptions();
       }
     }
     refresh_overview_canvas();
@@ -950,14 +949,14 @@
   }
   w2 = gdk_string_width(prod_fontset, buffer2);
 
-  gtk_draw_shadowed_string(map_canvas->window, main_fontset,
+  gtk_draw_shadowed_string(map_canvas_store, main_fontset,
                           toplevel->style->black_gc,
                           toplevel->style->white_gc,
                           canvas_x - (w + w2) / 2,
                           canvas_y + ascent,
                           buffer);
   gdk_gc_set_foreground(civ_gc, colors_standard[color]);
-  gtk_draw_shadowed_string(map_canvas->window, prod_fontset,
+  gtk_draw_shadowed_string(map_canvas_store, prod_fontset,
                           toplevel->style->black_gc,
                           civ_gc,
                           canvas_x - (w + w2) / 2 + w,
@@ -972,7 +971,7 @@
     get_city_mapview_production(pcity, buffer, sizeof(buffer));
 
     gdk_string_extents(prod_fontset, buffer, NULL, NULL, &w, &ascent, NULL);
-    gtk_draw_shadowed_string(map_canvas->window, prod_fontset,
+    gtk_draw_shadowed_string(map_canvas_store, prod_fontset,
                             toplevel->style->black_gc,
                             toplevel->style->white_gc, canvas_x - w / 2,
                             canvas_y + ascent + 3, buffer);
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.41
diff -u -r1.41 mapview.c
--- client/gui-gtk-2.0/mapview.c        2003/02/02 00:15:52     1.41
+++ client/gui-gtk-2.0/mapview.c        2003/02/03 22:11:14
@@ -787,7 +787,6 @@
       gdk_draw_pixmap(map_canvas->window, civ_gc, map_canvas_store,
                ev->area.x, ev->area.y, ev->area.x, ev->area.y,
                ev->area.width, ev->area.height);
-      show_city_descriptions();
       cleared = FALSE;
     } else {
       if (!cleared) {
@@ -1003,7 +1002,7 @@
       rect2.width = 0;
     }
 
-    gtk_draw_shadowed_string(map_canvas->window,
+    gtk_draw_shadowed_string(map_canvas_store,
                             toplevel->style->black_gc,
                             toplevel->style->white_gc,
                             canvas_x - (rect.width + rect2.width) / 2,
@@ -1013,7 +1012,7 @@
       pango_layout_set_font_description(layout, city_productions_font);
       pango_layout_set_text(layout, buffer2, -1);
       gdk_gc_set_foreground(civ_gc, colors_standard[color]);
-      gtk_draw_shadowed_string(map_canvas->window,
+      gtk_draw_shadowed_string(map_canvas_store,
                               toplevel->style->black_gc,
                               civ_gc,
                               canvas_x - (rect.width + rect2.width) / 2
@@ -1033,7 +1032,7 @@
     pango_layout_set_text(layout, buffer, -1);
 
     pango_layout_get_pixel_extents(layout, &rect, NULL);
-    gtk_draw_shadowed_string(map_canvas->window,
+    gtk_draw_shadowed_string(map_canvas_store,
                             toplevel->style->black_gc,
                             toplevel->style->white_gc,
                             canvas_x - rect.width / 2,
Index: client/gui-mui/mapclass.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/gui-mui/mapclass.c,v
retrieving revision 1.90
diff -u -r1.90 mapclass.c
--- client/gui-mui/mapclass.c   2003/01/18 18:58:26     1.90
+++ client/gui-mui/mapclass.c   2003/02/03 22:11:16
@@ -455,6 +455,7 @@
 
   APTR cliphandle;
 
+  /* FIXME: this needs to draw to the backing store, not to the display. */
 
   if (!(new_font = _font(o))) return;
 
@@ -1466,8 +1467,10 @@
        }
       }
 
+#if 0 /* This is no longer needed. */
       if (!(msg->flags & MADF_DRAWUPDATE) || ((msg->flags & MADF_DRAWUPDATE) 
&& (data->update == 3)))
        show_city_descriptions();
+#endif
     }
 
     data->update = 0;
Index: client/gui-sdl/mapview.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/gui-sdl/mapview.c,v
retrieving revision 1.17
diff -u -r1.17 mapview.c
--- client/gui-sdl/mapview.c    2003/02/02 20:49:19     1.17
+++ client/gui-sdl/mapview.c    2003/02/03 22:11:17
@@ -1741,12 +1741,6 @@
 #ifdef DRAW_TIMING
   struct timer *tttt=new_timer_start(TIMER_USER,TIMER_ACTIVE);
 #endif   
-  
-#if 0  
-  /* redraw city descriptions
-     should be draw here - under map witgets */
-  show_city_descriptions();
-#endif
 
   /* redraw minimap */
   refresh_ID_background(ID_MINI_MAP_WINDOW);
Index: client/gui-win32/mapview.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/gui-win32/mapview.c,v
retrieving revision 1.53
diff -u -r1.53 mapview.c
--- client/gui-win32/mapview.c  2003/01/29 22:57:46     1.53
+++ client/gui-win32/mapview.c  2003/02/03 22:11:18
@@ -178,7 +178,6 @@
           mapstoredc, 0, 0, SRCCOPY);
     SelectObject(mapstoredc, old);
     DeleteDC(mapstoredc);
-    show_city_descriptions();
   }
 } 
 
@@ -711,9 +710,11 @@
   char buffer[500];
   int y_offset;
   HDC hdc;
+  HBITMAP old;
 
   /* TODO: hdc should be stored statically */
-  hdc = GetDC(map_window);
+  hdc = CreateCompatibleDC(NULL);
+  old = SelectObject(hdc, mapstorebitmap);
   SetBkMode(hdc,TRANSPARENT);
 
   y_offset = canvas_y + NORMAL_TILE_HEIGHT;
@@ -763,7 +764,8 @@
     DrawText(hdc, buffer, strlen(buffer), &rc, DT_NOCLIP | DT_CENTER);
   }
 
-  ReleaseDC(map_window, hdc);
+  SelectObject(hdc, old);
+  DeleteDC(hdc);
 }
 
 /**************************************************************************
Index: client/gui-xaw/mapview.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/gui-xaw/mapview.c,v
retrieving revision 1.120
diff -u -r1.120 mapview.c
--- client/gui-xaw/mapview.c    2003/02/02 00:15:52     1.120
+++ client/gui-xaw/mapview.c    2003/02/03 22:11:18
@@ -571,7 +571,6 @@
                event->xexpose.x, event->xexpose.y,
                event->xexpose.width, event->xexpose.height,
                event->xexpose.x, event->xexpose.y);
-      show_city_descriptions();
     }
   }
   refresh_overview_canvas();
@@ -674,16 +673,15 @@
                                 enum color_std shadow,
                                 int x, int y, const char *string)
 {
-  Window wndw = XtWindow(map_canvas);
   size_t len = strlen(string);
 
   y += font->ascent;
 
   XSetForeground(display, font_gc, colors_standard[shadow]);
-  XDrawString(display, wndw, font_gc, x + 1, y + 1, string, len);
+  XDrawString(display, map_canvas_store, font_gc, x + 1, y + 1, string, len);
 
   XSetForeground(display, font_gc, colors_standard[foreground]);
-  XDrawString(display, wndw, font_gc, x, y, string, len);
+  XDrawString(display, map_canvas_store, font_gc, x, y, string, len);
 }
 
 /**************************************************************************

[Prev in Thread] Current Thread [Next in Thread]
  • [Freeciv-Dev] (PR#2986) buffering the city descriptions, Jason Short via RT <=