gnome-panel r11029 - trunk/applets/clock
- From: vuntz svn gnome org
- To: svn-commits-list gnome org
- Subject: gnome-panel r11029 - trunk/applets/clock
- Date: Thu, 10 Apr 2008 05:37:14 +0100 (BST)
Author: vuntz
Date: Thu Apr 10 05:37:14 2008
New Revision: 11029
URL: http://svn.gnome.org/viewvc/gnome-panel?rev=11029&view=rev
Log:
2008-04-10 Vincent Untz <vuntz gnome org>
Implement a cache for clock face pixbufs. They're loaded from SVG, so
it can be a bit slow to read the file. With the cache, we win around
0.01s and 0.02s per face clock that can use it.
It's totally useless if you have only one location or all the locations
are in completely different timezones (always using different SVG
files), but it doesn't cost us anything, so it's a good thing in the
end.
* clock-face.c: (clock_face_finalize): don't use deprecated
gdk_pixbuf_unref(), free the cache if it's empty
(remove_pixbuf_from_cache): helper, to remove a unused pixbuf from the
cache when it's reference count reaches 0
(clock_face_load_face): initialize the cache (implemented with a
hashtable) if needed, and try to use it. If the searched pixbuf isn't
there, load it as we did before and add it to the cache.
Modified:
trunk/applets/clock/ChangeLog
trunk/applets/clock/clock-face.c
Modified: trunk/applets/clock/clock-face.c
==============================================================================
--- trunk/applets/clock/clock-face.c (original)
+++ trunk/applets/clock/clock-face.c Thu Apr 10 05:37:14 2008
@@ -20,6 +20,8 @@
#include "clock-face.h"
#include "clock-location.h"
+static GHashTable *pixbuf_cache = NULL;
+
#define CLOCK_FACE_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), INTL_TYPE_CLOCK_FACE, ClockFacePrivate))
G_DEFINE_TYPE (ClockFace, clock_face, GTK_TYPE_WIDGET);
@@ -408,7 +410,7 @@
}
if (priv->face_pixbuf) {
- gdk_pixbuf_unref (priv->face_pixbuf);
+ g_object_unref (priv->face_pixbuf);
priv->face_pixbuf = NULL;
}
@@ -418,6 +420,11 @@
}
G_OBJECT_CLASS (clock_face_parent_class)->finalize (obj);
+
+ if (g_hash_table_size (pixbuf_cache) == 0) {
+ g_hash_table_destroy (pixbuf_cache);
+ pixbuf_cache = NULL;
+ }
}
static void
@@ -430,28 +437,74 @@
GTK_WIDGET_CLASS (clock_face_parent_class)->unmap (this);
}
+/* The pixbuf is being disposed, so remove it from the cache */
+static void
+remove_pixbuf_from_cache (const char *key,
+ GObject *pixbuf)
+{
+ g_hash_table_remove (pixbuf_cache, key);
+}
+
static void
clock_face_load_face (ClockFace *this, gint width, gint height)
{
ClockFacePrivate *priv = CLOCK_FACE_GET_PRIVATE (this);
const gchar *size_string[2] = { "small", "large" };
const gchar *daytime_string[4] = { "morning", "day", "evening", "night" };
+ gchar *cache_name;
gchar *name;
+ if (!pixbuf_cache)
+ pixbuf_cache = g_hash_table_new_full (g_str_hash, g_str_equal,
+ g_free, NULL);
+
if (priv->face_pixbuf != NULL) {
- gdk_pixbuf_unref (priv->face_pixbuf);
+ /* This might empty the cache, but it's useless to destroy
+ * it since this object is still alive and might add another
+ * pixbuf in the cache later (eg, a few lines below) */
+ g_object_unref (priv->face_pixbuf);
priv->face_pixbuf = NULL;
}
- name = g_strconcat (ICONDIR, "/clock-face-", size_string[priv->size], "-", daytime_string[priv->timeofday], ".svg", NULL);
+ /* Look for the pixbuf in the process-wide cache first */
+ cache_name = g_strdup_printf ("%d-%d-%d-%d",
+ priv->size, priv->timeofday,
+ width, height);
- priv->face_pixbuf = rsvg_pixbuf_from_file_at_size (name, width, height, NULL);
+ priv->face_pixbuf = g_hash_table_lookup (pixbuf_cache, cache_name);
+ if (priv->face_pixbuf) {
+ g_object_ref (priv->face_pixbuf);
+ return;
+ }
+
+ /* The pixbuf is not cached, let's load it */
+ name = g_strconcat (ICONDIR, "/clock-face-", size_string[priv->size],
+ "-", daytime_string[priv->timeofday], ".svg",
+ NULL);
+ priv->face_pixbuf = rsvg_pixbuf_from_file_at_size (name,
+ width, height,
+ NULL);
g_free (name);
- if (priv->face_pixbuf)
- return;
+ if (!priv->face_pixbuf) {
+ name = g_strconcat (ICONDIR, "/clock-face-",
+ size_string[priv->size], ".svg", NULL);
+ priv->face_pixbuf = rsvg_pixbuf_from_file_at_size (name,
+ width,
+ height,
+ NULL);
+ g_free (name);
+ }
- name = g_strconcat (ICONDIR, "/clock-face-", size_string[priv->size], ".svg", NULL);
- priv->face_pixbuf = rsvg_pixbuf_from_file_at_size (name, width, height, NULL);
- g_free (name);
+ /* Save the found pixbuf in the cache */
+ if (priv->face_pixbuf) {
+ g_hash_table_replace (pixbuf_cache,
+ cache_name, priv->face_pixbuf);
+ /* This will handle automatic removal from the cache when
+ * the pixbuf isn't needed anymore */
+ g_object_weak_ref (G_OBJECT (priv->face_pixbuf),
+ (GWeakNotify) remove_pixbuf_from_cache,
+ cache_name);
+ } else
+ g_free (cache_name);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]