[gnome-photos/wip/rishi/misc-fixes: 19/20] base-item, item-manager: Age out the GEGL objects when unused



commit 02dd2b2cf34f06c0607f61b039adb08ac54f10c5
Author: Debarshi Ray <debarshir gnome org>
Date:   Tue Dec 15 20:35:13 2015 +0100

    base-item, item-manager: Age out the GEGL objects when unused
    
    We were never dropping the GEGL resources during the lifetime of the
    process, which is wasteful. Once a BaseItem has not been the active
    object for a certain period of time, we should drop them.

 src/photos-base-item.c    |   46 +++++++++++++++++++++++++++++++++++++++++++++
 src/photos-base-item.h    |    4 +++
 src/photos-item-manager.c |   44 +++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 94 insertions(+), 0 deletions(-)
---
diff --git a/src/photos-base-item.c b/src/photos-base-item.c
index a26957d..75926ed 100644
--- a/src/photos-base-item.c
+++ b/src/photos-base-item.c
@@ -98,6 +98,7 @@ struct _PhotosBaseItemPrivate
   gdouble iso_speed;
   gint64 date_created;
   gint64 height;
+  gint64 last_active;
   gint64 mtime;
   gint64 width;
 };
@@ -128,6 +129,11 @@ G_DEFINE_ABSTRACT_TYPE_WITH_CODE (PhotosBaseItem, photos_base_item, G_TYPE_OBJEC
 EGG_DEFINE_COUNTER (instances, "PhotosBaseItem", "Instances", "Number of PhotosBaseItem instances");
 
 
+enum
+{
+  UNLOAD_TIMEOUT = 10000000 /* us */
+};
+
 static GdkPixbuf *failed_icon;
 static GdkPixbuf *thumbnailing_icon;
 static GThreadPool *create_thumbnail_pool;
@@ -1296,6 +1302,7 @@ photos_base_item_init (PhotosBaseItem *self)
   g_mutex_init (&priv->mutex);
 
   priv->sel_cntrlr = photos_selection_controller_dup_singleton ();
+  priv->last_active = -1;
 }
 
 
@@ -1741,6 +1748,18 @@ photos_base_item_is_favorite (PhotosBaseItem *self)
 
 
 void
+photos_base_item_last_active_update (PhotosBaseItem *self)
+{
+  PhotosBaseItemPrivate *priv = self->priv;
+
+  if (priv->collection)
+    return;
+
+  priv->last_active = g_get_monotonic_time ();
+}
+
+
+void
 photos_base_item_load_async (PhotosBaseItem *self,
                              GCancellable *cancellable,
                              GAsyncReadyCallback callback,
@@ -1754,6 +1773,8 @@ photos_base_item_load_async (PhotosBaseItem *self,
   task = g_task_new (self, cancellable, callback, user_data);
   g_task_set_source_tag (task, photos_base_item_load_async);
 
+  priv->last_active = 0;
+
   if (priv->pipeline != NULL)
     {
       GeglNode *graph;
@@ -2000,3 +2021,28 @@ photos_base_item_trash (PhotosBaseItem *self)
   photos_delete_item_job_run (job, NULL, NULL);
   g_object_unref (job);
 }
+
+
+void
+photos_base_item_unload (PhotosBaseItem *self)
+{
+  PhotosBaseItemPrivate *priv = self->priv;
+  gint64 now;
+
+  if (priv->last_active <= 0)
+    return;
+
+  now = g_get_monotonic_time ();
+  if (now - priv->last_active < UNLOAD_TIMEOUT)
+    return;
+
+  priv->last_active = -1;
+
+  priv->buffer_sink = NULL;
+  priv->buffer_source = NULL;
+  priv->load = NULL;
+  g_clear_object (&priv->edit_graph);
+  g_clear_object (&priv->load_graph);
+  g_clear_object (&priv->pipeline);
+  g_clear_object (&priv->processor);
+}
diff --git a/src/photos-base-item.h b/src/photos-base-item.h
index eb067cf..4f9903e 100644
--- a/src/photos-base-item.h
+++ b/src/photos-base-item.h
@@ -167,6 +167,8 @@ gboolean            photos_base_item_is_collection           (PhotosBaseItem *se
 
 gboolean            photos_base_item_is_favorite             (PhotosBaseItem *self);
 
+void                photos_base_item_last_active_update      (PhotosBaseItem *self);
+
 void                photos_base_item_load_async              (PhotosBaseItem *self,
                                                               GCancellable *cancellable,
                                                               GAsyncReadyCallback callback,
@@ -226,6 +228,8 @@ void                photos_base_item_thumbnailing_stop       (void);
 
 void                photos_base_item_trash                   (PhotosBaseItem *self);
 
+void                photos_base_item_unload                  (PhotosBaseItem *self);
+
 G_END_DECLS
 
 #endif /* PHOTOS_BASE_ITEM_H */
diff --git a/src/photos-item-manager.c b/src/photos-item-manager.c
index fb8a8aa..8468419 100644
--- a/src/photos-item-manager.c
+++ b/src/photos-item-manager.c
@@ -262,6 +262,19 @@ photos_item_manager_item_load (GObject *source_object, GAsyncResult *res, gpoint
 
 
 static void
+photos_item_manager_last_active_update (PhotosItemManager *self)
+{
+  PhotosBaseItem *item;
+
+  item = PHOTOS_BASE_ITEM (photos_base_manager_get_active_object (PHOTOS_BASE_MANAGER (self)));
+  if (item == NULL)
+    return;
+
+  photos_base_item_last_active_update (item);
+}
+
+
+static void
 photos_item_manager_remove_object_by_id (PhotosBaseManager *mngr, const gchar *id)
 {
   PhotosItemManager *self = PHOTOS_ITEM_MANAGER (mngr);
@@ -282,6 +295,20 @@ photos_item_manager_remove_object_by_id (PhotosBaseManager *mngr, const gchar *i
 
 
 static void
+photos_item_manager_unload (PhotosItemManager *self)
+{
+  GHashTable *items;
+  GHashTableIter iter;
+  PhotosBaseItem *item;
+
+  items = photos_base_manager_get_objects (PHOTOS_BASE_MANAGER (self));
+  g_hash_table_iter_init (&iter, items);
+  while (g_hash_table_iter_next (&iter, NULL, (gpointer *) &item))
+    photos_base_item_unload (item);
+}
+
+
+static void
 photos_item_manager_update_fullscreen (PhotosItemManager *self)
 {
   /* Should be called after priv->mode has been updated. */
@@ -357,6 +384,8 @@ photos_item_manager_set_active_object (PhotosBaseManager *manager, GObject *obje
       start_loading = TRUE;
     }
 
+  photos_item_manager_last_active_update (self);
+
   ret_val = PHOTOS_BASE_MANAGER_CLASS (photos_item_manager_parent_class)->set_active_object (manager, 
object);
   /* We have already eliminated the possibility of failure. */
   g_assert (ret_val == TRUE);
@@ -393,6 +422,8 @@ photos_item_manager_set_active_object (PhotosBaseManager *manager, GObject *obje
       g_assert (active_item != (GObject *) self->active_collection);
     }
 
+  photos_item_manager_unload (self);
+
  out:
   return ret_val;
 }
@@ -566,9 +597,12 @@ photos_item_manager_activate_previous_collection (PhotosItemManager *self)
     g_object_ref (collection);
   self->active_collection = PHOTOS_BASE_ITEM (collection);
 
+  photos_item_manager_last_active_update (self);
+
   PHOTOS_BASE_MANAGER_CLASS (photos_item_manager_parent_class)
     ->set_active_object (PHOTOS_BASE_MANAGER (self), (GObject *) collection);
 
+  photos_item_manager_unload (self);
   g_signal_emit (self, signals[ACTIVE_COLLECTION_CHANGED], 0, self->active_collection);
 
   g_clear_object (&collection);
@@ -715,8 +749,12 @@ photos_mode_controller_go_back (PhotosModeController *self)
 
   if (old_mode == PHOTOS_WINDOW_MODE_PREVIEW)
     {
+      photos_item_manager_last_active_update (self);
+
       PHOTOS_BASE_MANAGER_CLASS (photos_item_manager_parent_class)
         ->set_active_object (PHOTOS_BASE_MANAGER (self), (GObject *) self->active_collection);
+
+      photos_item_manager_unload (self);
     }
   else if (old_mode != PHOTOS_WINDOW_MODE_EDIT)
     {
@@ -724,10 +762,12 @@ photos_mode_controller_go_back (PhotosModeController *self)
       self->collection_path = g_queue_new ();
 
       g_clear_object (&self->active_collection);
+      photos_item_manager_last_active_update (self);
 
       PHOTOS_BASE_MANAGER_CLASS (photos_item_manager_parent_class)
         ->set_active_object (PHOTOS_BASE_MANAGER (self), NULL);
 
+      photos_item_manager_unload (self);
       g_signal_emit (self, signals[ACTIVE_COLLECTION_CHANGED], 0, self->active_collection);
     }
 
@@ -781,9 +821,13 @@ photos_mode_controller_set_window_mode (PhotosModeController *self, PhotosWindow
           active_collection_changed = TRUE;
         }
 
+      photos_item_manager_last_active_update (self);
+
       PHOTOS_BASE_MANAGER_CLASS (photos_item_manager_parent_class)
         ->set_active_object (PHOTOS_BASE_MANAGER (self), NULL);
 
+      photos_item_manager_unload (self);
+
       if (active_collection_changed)
         g_signal_emit (self, signals[ACTIVE_COLLECTION_CHANGED], 0, self->active_collection);
     }


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