[gimp/wip/init-performance-log-2-10] app: allow profiling GIMP initialization



commit 97bb9946c49666a8646a866a26fcaef72c776535
Author: Ell <ell_se yahoo com>
Date:   Thu Sep 27 01:15:01 2018 -0400

    app: allow profiling GIMP initialization
    
    This commit allows recording performance logs during startup, by
    passing a log filename through the GIMP_INIT_PERFORMANCE_LOG
    environment variable.  When the environment varaible is set, GIMP
    will record a performance log during initialization, automatically
    adding event markers for the different startup phases, and stop
    recording once initialization is complete.
    
    Since startup is relatively fast, it's also worth increasing the
    log sample rate from the default 10 samples-per-second, by
    specifying a higher rate through the
    GIMP_PERFORMANCE_LOG_SAMPLE_FREQUENCY envrionment variable.
    
    Note that this method for recording the log is a HUGE hack!  It's
    not meant to be merged.  We need to properly separate logs from the
    dashboard first.

 app/app.c                | 203 ++++++++++++++++++++++++++++++++++++++++-------
 app/gui/gui.c            |   3 +-
 app/widgets/gimpeditor.c |  22 +++--
 3 files changed, 189 insertions(+), 39 deletions(-)
---
diff --git a/app/app.c b/app/app.c
index 6e852cd513..79df47ff90 100644
--- a/app/app.c
+++ b/app/app.c
@@ -63,6 +63,15 @@
 #ifndef GIMP_CONSOLE_COMPILATION
 #include "dialogs/user-install-dialog.h"
 
+#include <gtk/gtk.h>
+
+#include "widgets/widgets-types.h"
+#include "widgets/gimpactionfactory.h"
+#include "widgets/gimpdashboard.h"
+#include "widgets/gimpmenufactory.h"
+
+#include "actions/dashboard-actions.h"
+
 #include "gui/gui.h"
 #endif
 
@@ -78,14 +87,17 @@
 
 /*  local prototypes  */
 
-static void       app_init_update_noop       (const gchar        *text1,
-                                              const gchar        *text2,
-                                              gdouble             percentage);
-static void       app_restore_after_callback (Gimp               *gimp,
-                                              GimpInitStatusFunc  status_callback);
-static gboolean   app_exit_after_callback    (Gimp               *gimp,
-                                              gboolean            kill_it,
-                                              GMainLoop         **loop);
+static void       app_init_update             (const gchar        *text1,
+                                               const gchar        *text2,
+                                               gdouble             percentage);
+#ifndef GIMP_CONSOLE_COMPILATION
+static gboolean   app_init_log_stop_recording (gpointer           data);
+#endif
+static void       app_restore_after_callback  (Gimp               *gimp,
+                                               GimpInitStatusFunc  status_callback);
+static gboolean   app_exit_after_callback     (Gimp               *gimp,
+                                               gboolean            kill_it,
+                                               GMainLoop         **loop);
 
 GType gimp_convert_dither_type_compat_get_type (void); /* compat cruft */
 GType gimp_layer_mode_effects_get_type         (void); /* compat cruft */
@@ -93,8 +105,14 @@ GType gimp_layer_mode_effects_get_type         (void); /* compat cruft */
 
 /*  local variables  */
 
-static GObject *initial_screen  = NULL;
-static gint     initial_monitor = 0;
+static GObject            *initial_screen     = NULL;
+static gint                initial_monitor    = 0;
+
+static GimpInitStatusFunc  update_status_func = NULL;
+
+#ifndef GIMP_CONSOLE_COMPILATION
+static GimpDashboard      *dashboard          = NULL;
+#endif
 
 
 /*  public functions  */
@@ -182,17 +200,19 @@ app_run (const gchar         *full_prog_name,
          GimpPDBCompatMode    pdb_compat_mode,
          const gchar         *backtrace_file)
 {
-  GimpInitStatusFunc  update_status_func = NULL;
-  Gimp               *gimp;
-  GMainLoop          *loop;
-  GMainLoop          *run_loop;
-  GFile              *default_folder = NULL;
-  GFile              *gimpdir;
-  const gchar        *abort_message;
-  GimpLangRc         *temprc;
-  gchar              *language   = NULL;
-  GError             *font_error = NULL;
-  gboolean            save_gimprc_at_exit = FALSE;
+  Gimp        *gimp;
+  GMainLoop   *loop;
+  GMainLoop   *run_loop;
+  GFile       *default_folder = NULL;
+  GFile       *gimpdir;
+  const gchar *abort_message;
+  GimpLangRc  *temprc;
+  gchar       *language   = NULL;
+  GError      *font_error = NULL;
+  gboolean     save_gimprc_at_exit = FALSE;
+  gint64       t;
+
+  t = g_get_monotonic_time ();
 
   if (filenames && filenames[0] && ! filenames[1] &&
       g_file_test (filenames[0], G_FILE_TEST_IS_DIR))
@@ -252,6 +272,53 @@ app_run (const gchar         *full_prog_name,
                    stack_trace_mode,
                    pdb_compat_mode);
 
+#ifndef GIMP_CONSOLE_COMPILATION
+  if (g_getenv ("GIMP_INIT_PERFORMANCE_LOG"))
+    {
+      GimpActionFactory *action_factory;
+      GimpMenuFactory   *menu_factory;
+      GFile             *file;
+      GError            *error = NULL;
+
+      action_factory = gimp_action_factory_new (gimp);
+
+      gimp_action_factory_group_register (action_factory,
+                                          "dashboard",
+                                          "Dashboard", "gimp-dashboard",
+                                          dashboard_actions_setup,
+                                          dashboard_actions_update);
+
+      menu_factory = gimp_menu_factory_new (gimp, action_factory);
+
+      gimp_menu_factory_manager_register (menu_factory,
+                                          "<Dashboard>", "dashboard",
+                                          NULL,
+                                          "/dashboard-popup",
+                                          "dashboard-menu.xml",
+                                          gimp_dashboard_menu_setup,
+                                          NULL);
+
+      dashboard = GIMP_DASHBOARD (gimp_dashboard_new (gimp, menu_factory));
+      g_object_ref_sink (dashboard);
+
+      g_object_unref (menu_factory);
+      g_object_unref (action_factory);
+
+      file = g_file_new_for_path (g_getenv ("GIMP_INIT_PERFORMANCE_LOG"));
+
+      if (! gimp_dashboard_log_start_recording (dashboard, file, &error))
+        {
+          g_printerr ("%s\n", error->message);
+
+          g_clear_error (&error);
+
+          g_clear_object (&dashboard);
+        }
+
+      g_object_unref (file);
+    }
+#endif
+
   if (default_folder)
     g_object_unref (default_folder);
 
@@ -325,17 +392,14 @@ app_run (const gchar         *full_prog_name,
     update_status_func = gui_init (gimp, no_splash);
 #endif
 
-  if (! update_status_func)
-    update_status_func = app_init_update_noop;
-
   /*  Create all members of the global Gimp instance which need an already
    *  parsed gimprc, e.g. the data factories
    */
-  gimp_initialize (gimp, update_status_func);
+  gimp_initialize (gimp, app_init_update);
 
   /*  Load all data files
    */
-  gimp_restore (gimp, update_status_func, &font_error);
+  gimp_restore (gimp, app_init_update, &font_error);
 
   /*  enable autosave late so we don't autosave when the
    *  monitor resolution is set in gui_init()
@@ -435,6 +499,19 @@ app_run (const gchar         *full_prog_name,
   if (run_loop)
     gimp_batch_run (gimp, batch_interpreter, batch_commands);
 
+  t = g_get_monotonic_time () - t;
+
+  g_printerr ("%g sec.\n", (gdouble) t / G_TIME_SPAN_SECOND);
+
+#ifndef GIMP_CONSOLE_COMPILATION
+  if (dashboard)
+    {
+      gimp_dashboard_log_add_marker (dashboard, "Running main loop");
+
+      g_idle_add_full (G_PRIORITY_LOW, app_init_log_stop_recording, NULL, NULL);
+    }
+#endif
+
   if (run_loop)
     {
       gimp_threads_leave (gimp);
@@ -465,13 +542,79 @@ app_run (const gchar         *full_prog_name,
 /*  private functions  */
 
 static void
-app_init_update_noop (const gchar *text1,
-                      const gchar *text2,
-                      gdouble      percentage)
+app_init_update (const gchar *text1,
+                 const gchar *text2,
+                 gdouble      percentage)
 {
-  /*  deliberately do nothing  */
+#ifndef GIMP_CONSOLE_COMPILATION
+  if (dashboard)
+    {
+      static gchar *last_text1 = NULL;
+      static gchar *last_text2 = NULL;
+
+      if ((text1 && g_strcmp0 (text1, last_text1)) ||
+          (text2 && g_strcmp0 (text2, last_text2)))
+        {
+          gchar *desc;
+
+          if (text1)
+            {
+              g_free (last_text1);
+
+              last_text1 = g_strdup (text1);
+            }
+
+          if (text2)
+            {
+              g_free (last_text2);
+
+              last_text2 = g_strdup (text2);
+            }
+
+          if (last_text2 && *last_text2)
+            desc = g_strdup_printf ("%s (%s)", last_text1, last_text2);
+          else
+            desc = g_strdup (last_text1);
+
+          gimp_dashboard_log_add_marker (dashboard, desc);
+
+          g_free (desc);
+        }
+    }
+#endif
+
+  if (update_status_func)
+    {
+      update_status_func (text1, text2, percentage);
+    }
+  else
+    {
+      /*  deliberately do nothing  */
+    }
 }
 
+#ifndef GIMP_CONSOLE_COMPILATION
+static gboolean
+app_init_log_stop_recording (gpointer data)
+{
+  if (dashboard)
+    {
+      GError *error = NULL;
+
+      if (! gimp_dashboard_log_stop_recording (dashboard, &error))
+        {
+          g_printerr ("%s\n", error->message);
+
+          g_clear_error (&error);
+        }
+
+      g_clear_object (&dashboard);
+    }
+
+  return G_SOURCE_REMOVE;
+}
+#endif
+
 static void
 app_restore_after_callback (Gimp               *gimp,
                             GimpInitStatusFunc  status_callback)
diff --git a/app/gui/gui.c b/app/gui/gui.c
index 4e8b54b274..6dcf7ded98 100644
--- a/app/gui/gui.c
+++ b/app/gui/gui.c
@@ -644,8 +644,7 @@ gui_restore_after_callback (Gimp               *gimp,
   gimp_devices_restore (gimp);
   gimp_controllers_restore (gimp, image_ui_manager);
 
-  if (status_callback == splash_update)
-    splash_destroy ();
+  splash_destroy ();
 
   if (gimp_get_show_gui (gimp))
     {
diff --git a/app/widgets/gimpeditor.c b/app/widgets/gimpeditor.c
index 01517fc80c..3ec11315d7 100644
--- a/app/widgets/gimpeditor.c
+++ b/app/widgets/gimpeditor.c
@@ -254,10 +254,14 @@ gimp_editor_constructed (GObject *object)
                                        editor->priv->menu_identifier,
                                        editor->priv->popup_data,
                                        FALSE);
-      g_signal_connect (editor->priv->ui_manager->gimp->config,
-                        "size-changed",
-                        G_CALLBACK (gimp_editor_config_size_changed),
-                        editor);
+
+      if (editor->priv->ui_manager->gimp->config)
+        {
+          g_signal_connect (editor->priv->ui_manager->gimp->config,
+                            "size-changed",
+                            G_CALLBACK (gimp_editor_config_size_changed),
+                            editor);
+        }
     }
 }
 
@@ -272,9 +276,13 @@ gimp_editor_dispose (GObject *object)
 
   if (editor->priv->ui_manager)
     {
-      g_signal_handlers_disconnect_by_func (editor->priv->ui_manager->gimp->config,
-                                            G_CALLBACK (gimp_editor_config_size_changed),
-                                            editor);
+      if (editor->priv->ui_manager->gimp->config)
+        {
+          g_signal_handlers_disconnect_by_func (editor->priv->ui_manager->gimp->config,
+                                                G_CALLBACK (gimp_editor_config_size_changed),
+                                                editor);
+        }
+
       g_clear_object (&editor->priv->ui_manager);
     }
 


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