[libchamplain] Optimize ChamplainView state update
- From: Pierre-Luc Beaudoin <plbeaudoin src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [libchamplain] Optimize ChamplainView state update
- Date: Tue, 23 Mar 2010 14:43:58 +0000 (UTC)
commit 17e7937f98f686f4c8ddbf2206a20cdff495a6d7
Author: JiÅ?Ã Techet <techet gmail com>
Date: Mon Mar 22 22:48:54 2010 +0100
Optimize ChamplainView state update
When profiling with Oprofile and gprof2dot, view_update_state() consumed
nearly one half of CPU cycles (CPU used by libchamplain only without
any other libraries). This was because we were cycling through all
the tiles to determine the state and the state was updated for every
tile, which lead to quadratic complexity. This patch fixes this by
updating a counter of tiles that are being filled.
Signed-off-by: JiÅ?Ã Techet <techet gmail com>
champlain/champlain-view.c | 60 +++++++++++++++++++++++++++++++------------
1 files changed, 43 insertions(+), 17 deletions(-)
---
diff --git a/champlain/champlain-view.c b/champlain/champlain-view.c
index 7030276..0896b9b 100644
--- a/champlain/champlain-view.c
+++ b/champlain/champlain-view.c
@@ -183,6 +183,7 @@ struct _ChamplainViewPrivate
guint update_cb_id;
gboolean perform_update;
+ gint tiles_loading;
};
G_DEFINE_TYPE (ChamplainView, champlain_view, CLUTTER_TYPE_GROUP);
@@ -234,7 +235,7 @@ static void view_position_tile (ChamplainView* view,
ChamplainTile* tile);
static void view_reload_tiles_cb (ChamplainMapSource *map_source,
ChamplainView* view);
-static void view_update_state (ChamplainView *view);
+static void view_update_state (ChamplainView *view, ChamplainTile *tile);
static void view_update_anchor (ChamplainView *view,
gint x,
gint y);
@@ -255,6 +256,8 @@ static void champlain_view_go_to_with_duration (ChamplainView *view,
guint duration);
static gboolean perform_update_cb (ChamplainView *view);
static gboolean fill_tile_cb (FillTileCallbackData *data);
+static void tile_destroyed_cb (GObject *gobject,
+ gpointer data);
#define SCALE_HEIGHT 20
#define SCALE_PADDING 10
@@ -1419,6 +1422,7 @@ champlain_view_init (ChamplainView *view)
priv->scale_unit = CHAMPLAIN_UNIT_KM;
priv->max_scale_width = 100;
priv->perform_update = TRUE;
+ priv->tiles_loading = 0;
/* Setup map layer */
priv->map_layer = g_object_ref (clutter_group_new ());
@@ -2313,12 +2317,16 @@ view_load_visible_tiles (ChamplainView *view)
clutter_container_add_actor (CLUTTER_CONTAINER (priv->map_layer), CLUTTER_ACTOR (tile));
view_position_tile (view, tile);
+ /* updates champlain_view state automatically as
+ notify::state signal is connected */
champlain_tile_set_state (tile, CHAMPLAIN_STATE_LOADING);
data = g_new (FillTileCallbackData, 1);
data->tile = tile;
data->map_source = priv->map_source;
+ g_signal_connect (tile, "destroy", G_CALLBACK (tile_destroyed_cb), view);
+
g_object_add_weak_pointer (G_OBJECT (tile), (gpointer*)&data->tile);
g_object_ref (priv->map_source);
@@ -2335,8 +2343,6 @@ view_load_visible_tiles (ChamplainView *view)
}
g_free (tile_map);
-
- view_update_state (view);
}
static gboolean
@@ -2389,35 +2395,55 @@ view_reload_tiles_cb (ChamplainMapSource *map_source,
}
static void
+tile_destroyed_cb (GObject *gobject,
+ gpointer data)
+{
+ ChamplainView *view = CHAMPLAIN_VIEW (data);
+ ChamplainTile *tile = CHAMPLAIN_TILE (gobject);
+ ChamplainViewPrivate *priv = view->priv;
+
+ if (champlain_tile_get_state (tile) == CHAMPLAIN_STATE_LOADING)
+ {
+ priv->tiles_loading--;
+ if (priv->tiles_loading == 0)
+ {
+ priv->state = CHAMPLAIN_STATE_DONE;
+ g_object_notify (G_OBJECT (view), "state");
+ }
+ }
+}
+
+static void
tile_state_notify (GObject *gobject,
GParamSpec *pspec,
gpointer data)
{
- view_update_state (CHAMPLAIN_VIEW (data));
+ view_update_state (CHAMPLAIN_VIEW (data), CHAMPLAIN_TILE (gobject));
}
static void
-view_update_state (ChamplainView *view)
+view_update_state (ChamplainView *view, ChamplainTile *tile)
{
+ ChamplainState tile_state = champlain_tile_get_state (tile);
ChamplainViewPrivate *priv = view->priv;
- ChamplainState new_state = CHAMPLAIN_STATE_DONE;
- gint i;
- for (i = 0; i < clutter_group_get_n_children (CLUTTER_GROUP (priv->map_layer)); i++)
+ if (tile_state == CHAMPLAIN_STATE_LOADING)
{
- ChamplainTile *tile = CHAMPLAIN_TILE (clutter_group_get_nth_child (CLUTTER_GROUP (priv->map_layer), i));
-
- if (champlain_tile_get_state (tile) == CHAMPLAIN_STATE_LOADING)
+ if (priv->tiles_loading == 0)
{
- new_state = CHAMPLAIN_STATE_LOADING;
- break;
+ priv->state = CHAMPLAIN_STATE_LOADING;
+ g_object_notify (G_OBJECT (view), "state");
}
+ priv->tiles_loading++;
}
-
- if (priv->state != new_state)
+ else if (tile_state == CHAMPLAIN_STATE_DONE)
{
- priv->state = new_state;
- g_object_notify (G_OBJECT (view), "state");
+ priv->tiles_loading--;
+ if (priv->tiles_loading == 0)
+ {
+ priv->state = CHAMPLAIN_STATE_DONE;
+ g_object_notify (G_OBJECT (view), "state");
+ }
}
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]