[gnome-software] Do not load SVG icons when parsing desktop files to speed up startup



commit 644b3222bd32a19fa274e65c111049b682749e09
Author: Richard Hughes <richard hughsie com>
Date:   Sun Oct 20 18:57:27 2013 +0100

    Do not load SVG icons when parsing desktop files to speed up startup
    
    Using the icon cache shaves 900ms off the coldstart time when getting the
    installed list.

 src/gs-plugin-loader.c               |    8 ++++
 src/gs-plugin.h                      |    1 +
 src/plugins/gs-plugin-appstream.c    |   20 +++++++++--
 src/plugins/gs-plugin-datadir-apps.c |   66 ++++++++++++++++++----------------
 4 files changed, 61 insertions(+), 34 deletions(-)
---
diff --git a/src/gs-plugin-loader.c b/src/gs-plugin-loader.c
index 4a365f8..5a430ac 100644
--- a/src/gs-plugin-loader.c
+++ b/src/gs-plugin-loader.c
@@ -43,6 +43,7 @@ struct GsPluginLoaderPrivate
 
        GMutex                   app_cache_mutex;
        GHashTable              *app_cache;
+       GHashTable              *icon_cache;
        gchar                   **compatible_projects;
 
        GList                   *queued_installs;
@@ -2327,6 +2328,7 @@ gs_plugin_loader_open_plugin (GsPluginLoader *plugin_loader,
        plugin->status_update_fn = gs_plugin_loader_status_update_cb;
        plugin->status_update_user_data = plugin_loader;
        plugin->profile = g_object_ref (plugin_loader->priv->profile);
+       plugin->icon_cache = g_hash_table_ref (plugin_loader->priv->icon_cache);
        g_debug ("opened plugin %s: %s", filename, plugin->name);
 
        /* add to array */
@@ -2448,6 +2450,7 @@ gs_plugin_loader_plugin_free (GsPlugin *plugin)
        g_free (plugin->priv);
        g_free (plugin->name);
        g_object_unref (plugin->profile);
+       g_hash_table_unref (plugin->icon_cache);
        g_module_close (plugin->module);
        g_slice_free (GsPlugin, plugin);
 }
@@ -2496,6 +2499,10 @@ gs_plugin_loader_init (GsPluginLoader *plugin_loader)
                                                                g_str_equal,
                                                                g_free,
                                                                (GFreeFunc) g_object_unref);
+       plugin_loader->priv->icon_cache = g_hash_table_new_full (g_str_hash,
+                                                                g_str_equal,
+                                                                g_free,
+                                                                g_free);
 
        g_mutex_init (&plugin_loader->priv->pending_apps_mutex);
        g_mutex_init (&plugin_loader->priv->app_cache_mutex);
@@ -2535,6 +2542,7 @@ gs_plugin_loader_finalize (GObject *object)
        g_object_unref (plugin_loader->priv->profile);
        g_strfreev (plugin_loader->priv->compatible_projects);
        g_hash_table_unref (plugin_loader->priv->app_cache);
+       g_hash_table_unref (plugin_loader->priv->icon_cache);
        g_ptr_array_unref (plugin_loader->priv->pending_apps);
        g_ptr_array_unref (plugin_loader->priv->plugins);
        g_free (plugin_loader->priv->location);
diff --git a/src/gs-plugin.h b/src/gs-plugin.h
index f278f62..4794b65 100644
--- a/src/gs-plugin.h
+++ b/src/gs-plugin.h
@@ -66,6 +66,7 @@ struct GsPlugin {
        GsPluginStatusUpdate     status_update_fn;
        gpointer                 status_update_user_data;
        GsProfile               *profile;
+       GHashTable              *icon_cache;
 };
 
 typedef enum {
diff --git a/src/plugins/gs-plugin-appstream.c b/src/plugins/gs-plugin-appstream.c
index 2af87a1..c59e3d6 100644
--- a/src/plugins/gs-plugin-appstream.c
+++ b/src/plugins/gs-plugin-appstream.c
@@ -249,16 +249,18 @@ gs_plugin_destroy (GsPlugin *plugin)
 static gboolean
 gs_plugin_startup (GsPlugin *plugin, GError **error)
 {
+       AppstreamApp *app;
+       GPtrArray *items;
        gboolean ret;
-       guint size;
+       guint i;
 
        /* Parse the XML */
        gs_profile_start (plugin->profile, "appstream::startup");
        ret = gs_plugin_parse_xml (plugin, error);
        if (!ret)
                goto out;
-       size = appstream_cache_get_size (plugin->priv->cache);
-       if (size == 0) {
+       items = appstream_cache_get_items (plugin->priv->cache);
+       if (items->len == 0) {
                g_warning ("No AppStream data, try 'make install-sample-data' in data/");
                g_set_error (error,
                             GS_PLUGIN_LOADER_ERROR,
@@ -266,6 +268,18 @@ gs_plugin_startup (GsPlugin *plugin, GError **error)
                             _("No AppStream data found"));
                goto out;
        }
+
+       /* add icons to the icon name cache */
+       for (i = 0; i < items->len; i++) {
+               app = g_ptr_array_index (items, i);
+               if (appstream_app_get_icon_kind (app) != APPSTREAM_APP_ICON_KIND_CACHED)
+                       continue;
+               g_hash_table_insert (plugin->icon_cache,
+                                    g_strdup (appstream_app_get_id (app)),
+                                    g_build_filename (appstream_app_get_userdata (app),
+                                                      appstream_app_get_icon (app),
+                                                      NULL));
+       }
 out:
        gs_profile_stop (plugin->profile, "appstream::startup");
        return ret;
diff --git a/src/plugins/gs-plugin-datadir-apps.c b/src/plugins/gs-plugin-datadir-apps.c
index 944c2f5..a3203a7 100644
--- a/src/plugins/gs-plugin-datadir-apps.c
+++ b/src/plugins/gs-plugin-datadir-apps.c
@@ -132,6 +132,7 @@ gs_plugin_datadir_apps_extract_desktop_data (GsPlugin *plugin,
                                             GError **error)
 {
        const gchar *basename_tmp = NULL;
+       const gchar *icon_tmp = NULL;
        gboolean ret = TRUE;
        gchar *basename = NULL;
        gchar *comment = NULL;
@@ -162,6 +163,15 @@ gs_plugin_datadir_apps_extract_desktop_data (GsPlugin *plugin,
        if (!ret)
                goto out;
 
+       /* set new id */
+       basename = g_path_get_basename (desktop_file);
+       dot = strrchr (basename, '.');
+       if (dot)
+               *dot = '\0';
+       basename_tmp = basename;
+       if (g_str_has_prefix (basename_tmp, "fedora-"))
+               basename_tmp += 7;
+
        /* get desktop name */
        name = g_key_file_get_locale_string (key_file,
                                             G_KEY_FILE_DESKTOP_GROUP,
@@ -180,33 +190,37 @@ gs_plugin_datadir_apps_extract_desktop_data (GsPlugin *plugin,
        if (comment == NULL || comment[0] == '\0')
                goto out;
 
-       /* get desktop icon */
-       icon = g_key_file_get_string (key_file,
-                                     G_KEY_FILE_DESKTOP_GROUP,
-                                     G_KEY_FILE_DESKTOP_KEY_ICON,
-                                     NULL);
-       if (icon == NULL)
-               goto out;
-
-       /* set pixbuf */
-       if (icon[0] == '/') {
-               pixbuf = gdk_pixbuf_new_from_file_at_size (icon,
-                                                          plugin->pixbuf_size,
+       /* do we have an icon in the cache? */
+       icon_tmp = g_hash_table_lookup (plugin->icon_cache, basename_tmp);
+       if (icon_tmp != NULL) {
+               pixbuf = gdk_pixbuf_new_from_file (icon_tmp, NULL);
+       } else {
+               icon = g_key_file_get_string (key_file,
+                                             G_KEY_FILE_DESKTOP_GROUP,
+                                             G_KEY_FILE_DESKTOP_KEY_ICON,
+                                             NULL);
+               if (icon == NULL)
+                       goto out;
+               if (icon[0] == '/') {
+                       pixbuf = gdk_pixbuf_new_from_file_at_size (icon,
+                                                                  plugin->pixbuf_size,
+                                                                  plugin->pixbuf_size,
+                                                                  NULL);
+               } else {
+                       pixbuf = gtk_icon_theme_load_icon (gtk_icon_theme_get_default (),
+                                                          icon,
                                                           plugin->pixbuf_size,
+                                                          GTK_ICON_LOOKUP_USE_BUILTIN |
+                                                          GTK_ICON_LOOKUP_FORCE_SIZE,
                                                           NULL);
-       } else {
-               pixbuf = gtk_icon_theme_load_icon (gtk_icon_theme_get_default (),
-                                                  icon,
-                                                  plugin->pixbuf_size,
-                                                  GTK_ICON_LOOKUP_USE_BUILTIN |
-                                                  GTK_ICON_LOOKUP_FORCE_SIZE,
-                                                  NULL);
+               }
+               if (pixbuf == NULL)
+                       goto out;
        }
-       if (pixbuf == NULL)
-               goto out;
 
        /* create a new cache entry */
        cache_item = g_slice_new0 (GsPluginDataDirAppsCacheItem);
+       cache_item->id = g_strdup (basename_tmp);
        cache_item->name = g_strdup (name);
        cache_item->summary = g_strdup (comment);
        cache_item->pixbuf = g_object_ref (pixbuf);
@@ -219,16 +233,6 @@ gs_plugin_datadir_apps_extract_desktop_data (GsPlugin *plugin,
        if (pkgname != NULL && pkgname[0] != '\0')
                cache_item->pkgname = g_strdup (pkgname);
 
-       /* set new id */
-       basename = g_path_get_basename (desktop_file);
-       dot = strrchr (basename, '.');
-       if (dot)
-               *dot = '\0';
-       basename_tmp = basename;
-       if (g_str_has_prefix (basename_tmp, "fedora-"))
-               basename_tmp += 7;
-       cache_item->id = g_strdup (basename_tmp);
-
        /* add to cache */
        gs_plugin_datadir_apps_set_from_cache_item (app, cache_item);
        g_mutex_lock (&plugin->priv->plugin_mutex);


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]