diff --git a/app/actions/dashboard-commands.c b/app/actions/dashboard-commands.c index e54c242f49..8906489a0e 100644 --- a/app/actions/dashboard-commands.c +++ b/app/actions/dashboard-commands.c @@ -37,15 +37,25 @@ #include "gimp-intl.h" +typedef struct +{ + GFile *folder; + GimpDashboardLogParams params; +} DashboardLogDialogInfo; + + /* local function prototypes */ -static void dashboard_log_record_response (GtkWidget *dialog, - int response_id, - GimpDashboard *dashboard); +static void dashboard_log_record_response (GtkWidget *dialog, + int response_id, + GimpDashboard *dashboard); -static void dashboard_log_add_marker_response (GtkWidget *dialog, - const gchar *description, - GimpDashboard *dashboard); +static void dashboard_log_add_marker_response (GtkWidget *dialog, + const gchar *description, + GimpDashboard *dashboard); + +static DashboardLogDialogInfo * dashboard_log_dialog_info_new (GimpDashboard *dashboard); +static void dashboard_log_dialog_info_free (DashboardLogDialogInfo *info); /* public functions */ @@ -94,8 +104,13 @@ dashboard_log_record_cmd_callback (GimpAction *action, if (! dialog) { - GtkFileFilter *filter; - GFile *folder; + GtkFileFilter *filter; + DashboardLogDialogInfo *info; + GtkWidget *hbox; + GtkWidget *hbox2; + GtkWidget *label; + GtkWidget *spinbutton; + GtkWidget *toggle; dialog = gtk_file_chooser_dialog_new ( "Record Performance Log", NULL, GTK_FILE_CHOOSER_ACTION_SAVE, @@ -134,18 +149,69 @@ dashboard_log_record_cmd_callback (GimpAction *action, gtk_file_chooser_set_filter (GTK_FILE_CHOOSER (dialog), filter); - folder = g_object_get_data (G_OBJECT (dashboard), - "gimp-dashboard-log-record-folder"); + info = g_object_get_data (G_OBJECT (dashboard), + "gimp-dashboard-log-dialog-info"); - if (folder) + if (! info) + { + info = dashboard_log_dialog_info_new (dashboard); + + g_object_set_data_full ( + G_OBJECT (dashboard), + "gimp-dashboard-log-dialog-info", info, + (GDestroyNotify) dashboard_log_dialog_info_free); + } + + if (info->folder) { gtk_file_chooser_set_current_folder_file ( - GTK_FILE_CHOOSER (dialog), folder, NULL); + GTK_FILE_CHOOSER (dialog), info->folder, NULL); } gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (dialog), "gimp-performance.log"); + hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 16); + gtk_file_chooser_set_extra_widget (GTK_FILE_CHOOSER (dialog), hbox); + gtk_widget_show (hbox); + + hbox2 = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 8); + gimp_help_set_help_data (hbox2, _("Log samples per second"), NULL); + gtk_box_pack_start (GTK_BOX (hbox), hbox2, FALSE, FALSE, 0); + gtk_widget_show (hbox2); + + label = gtk_label_new_with_mnemonic (_("Sample fre_quency:")); + gtk_box_pack_start (GTK_BOX (hbox2), label, FALSE, FALSE, 0); + gtk_widget_show (label); + + spinbutton = gimp_spin_button_new_with_range (1, 1000, 1); + gtk_box_pack_start (GTK_BOX (hbox2), spinbutton, FALSE, FALSE, 0); + gtk_widget_show (spinbutton); + + gtk_spin_button_set_value (GTK_SPIN_BUTTON (spinbutton), + info->params.sample_frequency); + + g_signal_connect (gtk_spin_button_get_adjustment ( + GTK_SPIN_BUTTON (spinbutton)), + "value-changed", + G_CALLBACK (gimp_int_adjustment_update), + &info->params.sample_frequency); + + gtk_label_set_mnemonic_widget (GTK_LABEL (label), spinbutton); + + toggle = gtk_check_button_new_with_mnemonic (_("_Backtrace")); + gimp_help_set_help_data (toggle, _("Include backtraces in log"), + NULL); + gtk_box_pack_start (GTK_BOX (hbox), toggle, FALSE, FALSE, 0); + gtk_widget_show (toggle); + + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle), + info->params.backtrace); + + g_signal_connect (toggle, "toggled", + G_CALLBACK (gimp_toggle_button_update), + &info->params.backtrace); + g_signal_connect (dialog, "response", G_CALLBACK (dashboard_log_record_response), dashboard); @@ -253,15 +319,22 @@ dashboard_log_record_response (GtkWidget *dialog, { if (response_id == GTK_RESPONSE_OK) { - GFile *file = gtk_file_chooser_get_file (GTK_FILE_CHOOSER (dialog)); - GError *error = NULL; + GFile *file; + DashboardLogDialogInfo *info; + GError *error = NULL; - g_object_set_data_full (G_OBJECT (dashboard), - "gimp-dashboard-log-record-folder", - g_file_get_parent (file), - g_object_unref); + file = gtk_file_chooser_get_file (GTK_FILE_CHOOSER (dialog)); - if (! gimp_dashboard_log_start_recording (dashboard, file, &error)) + info = g_object_get_data (G_OBJECT (dashboard), + "gimp-dashboard-log-dialog-info"); + + g_return_if_fail (info != NULL); + + g_set_object (&info->folder, g_file_get_parent (file)); + + if (! gimp_dashboard_log_start_recording (dashboard, + file, &info->params, + &error)) { gimp_message_literal ( gimp_editor_get_ui_manager (GIMP_EDITOR (dashboard))->gimp, @@ -283,3 +356,22 @@ dashboard_log_add_marker_response (GtkWidget *dialog, { gimp_dashboard_log_add_marker (dashboard, description); } + +static DashboardLogDialogInfo * +dashboard_log_dialog_info_new (GimpDashboard *dashboard) +{ + DashboardLogDialogInfo *info = g_slice_new (DashboardLogDialogInfo); + + info->folder = NULL; + info->params = *gimp_dashboard_log_get_default_params (dashboard); + + return info; +} + +static void +dashboard_log_dialog_info_free (DashboardLogDialogInfo *info) +{ + g_clear_object (&info->folder); + + g_slice_free (DashboardLogDialogInfo, info); +} diff --git a/app/widgets/gimpdashboard.c b/app/widgets/gimpdashboard.c index 2f3f13dc91..46305922f2 100644 --- a/app/widgets/gimpdashboard.c +++ b/app/widgets/gimpdashboard.c @@ -94,7 +94,10 @@ #define CPU_ACTIVE_OFF /* individual cpu usage is below */ 0.25 #define LOG_VERSION 1 -#define LOG_SAMPLE_FREQUENCY 10 /* samples per second */ +#define LOG_SAMPLE_FREQUENCY_MIN 1 /* samples per second */ +#define LOG_SAMPLE_FREQUENCY_MAX 1000 /* samples per second */ +#define LOG_DEFAULT_SAMPLE_FREQUENCY 10 /* samples per second */ +#define LOG_DEFAULT_BACKTRACE TRUE typedef enum @@ -311,12 +314,11 @@ struct _GimpDashboardPrivate GOutputStream *log_output; GError *log_error; + GimpDashboardLogParams log_params; gint64 log_start_time; - gint log_sample_frequency; gint log_n_samples; gint log_n_markers; VariableData log_variables[N_VARIABLES]; - gboolean log_include_backtrace; GimpBacktrace *log_backtrace; GHashTable *log_addresses; @@ -1757,9 +1759,14 @@ gimp_dashboard_sample (GimpDashboard *dashboard) update_interval = priv->update_interval * G_TIME_SPAN_SECOND / 1000; if (priv->log_output) - sample_interval = G_TIME_SPAN_SECOND / priv->log_sample_frequency; + { + sample_interval = G_TIME_SPAN_SECOND / + priv->log_params.sample_frequency; + } else - sample_interval = update_interval; + { + sample_interval = update_interval; + } end_time = last_sample_time + sample_interval; @@ -3650,7 +3657,7 @@ gimp_dashboard_log_sample (GimpDashboard *dashboard, "\n"); } - if (priv->log_include_backtrace) + if (priv->log_params.backtrace) backtrace = gimp_backtrace_new (FALSE); if (backtrace) @@ -4257,9 +4264,10 @@ gimp_dashboard_new (Gimp *gimp, } gboolean -gimp_dashboard_log_start_recording (GimpDashboard *dashboard, - GFile *file, - GError **error) +gimp_dashboard_log_start_recording (GimpDashboard *dashboard, + GFile *file, + const GimpDashboardLogParams *params, + GError **error) { GimpDashboardPrivate *priv; GimpUIManager *ui_manager; @@ -4281,6 +4289,27 @@ gimp_dashboard_log_start_recording (GimpDashboard *dashboard, g_return_val_if_fail (! gimp_dashboard_log_is_recording (dashboard), FALSE); + if (! params) + params = gimp_dashboard_log_get_default_params (dashboard); + + priv->log_params = *params; + + if (g_getenv ("GIMP_PERFORMANCE_LOG_SAMPLE_FREQUENCY")) + { + priv->log_params.sample_frequency = + atoi (g_getenv ("GIMP_PERFORMANCE_LOG_SAMPLE_FREQUENCY")); + } + + if (g_getenv ("GIMP_PERFORMANCE_LOG_BACKTRACE")) + { + priv->log_params.backtrace = + atoi (g_getenv ("GIMP_PERFORMANCE_LOG_BACKTRACE")) ? 1 : 0; + } + + priv->log_params.sample_frequency = CLAMP (priv->log_params.sample_frequency, + LOG_SAMPLE_FREQUENCY_MIN, + LOG_SAMPLE_FREQUENCY_MAX); + g_mutex_lock (&priv->mutex); priv->log_output = G_OUTPUT_STREAM (g_file_replace (file, @@ -4294,28 +4323,14 @@ gimp_dashboard_log_start_recording (GimpDashboard *dashboard, return FALSE; } - priv->log_error = NULL; - priv->log_start_time = g_get_monotonic_time (); - priv->log_sample_frequency = LOG_SAMPLE_FREQUENCY; - priv->log_n_samples = 0; - priv->log_n_markers = 0; - priv->log_include_backtrace = TRUE; - priv->log_backtrace = NULL; - priv->log_addresses = g_hash_table_new (NULL, NULL); + priv->log_error = NULL; + priv->log_start_time = g_get_monotonic_time (); + priv->log_n_samples = 0; + priv->log_n_markers = 0; + priv->log_backtrace = NULL; + priv->log_addresses = g_hash_table_new (NULL, NULL); - if (g_getenv ("GIMP_PERFORMANCE_LOG_SAMPLE_FREQUENCY")) - { - priv->log_sample_frequency = - atoi (g_getenv ("GIMP_PERFORMANCE_LOG_SAMPLE_FREQUENCY")); - - priv->log_sample_frequency = CLAMP (priv->log_sample_frequency, - 1, 1000); - } - - if (g_getenv ("GIMP_PERFORMANCE_LOG_NO_BACKTRACE")) - priv->log_include_backtrace = FALSE; - - if (priv->log_include_backtrace) + if (priv->log_params.backtrace) has_backtrace = gimp_backtrace_start (); else has_backtrace = FALSE; @@ -4331,7 +4346,7 @@ gimp_dashboard_log_start_recording (GimpDashboard *dashboard, "%d\n" "%d\n" "\n", - priv->log_sample_frequency, + priv->log_params.sample_frequency, has_backtrace); gimp_dashboard_log_printf (dashboard, @@ -4558,7 +4573,7 @@ gimp_dashboard_log_stop_recording (GimpDashboard *dashboard, "\n" "\n"); - if (priv->log_include_backtrace) + if (priv->log_params.backtrace) gimp_backtrace_stop (); if (! priv->log_error) @@ -4612,6 +4627,20 @@ gimp_dashboard_log_is_recording (GimpDashboard *dashboard) return priv->log_output != NULL; } +const GimpDashboardLogParams * +gimp_dashboard_log_get_default_params (GimpDashboard *dashboard) +{ + static const GimpDashboardLogParams default_params = + { + .sample_frequency = LOG_DEFAULT_SAMPLE_FREQUENCY, + .backtrace = LOG_DEFAULT_BACKTRACE, + }; + + g_return_val_if_fail (GIMP_IS_DASHBOARD (dashboard), NULL); + + return &default_params; +} + void gimp_dashboard_log_add_marker (GimpDashboard *dashboard, const gchar *description) diff --git a/app/widgets/gimpdashboard.h b/app/widgets/gimpdashboard.h index 3255775cd0..3a5b639aa4 100644 --- a/app/widgets/gimpdashboard.h +++ b/app/widgets/gimpdashboard.h @@ -25,6 +25,13 @@ #include "gimpeditor.h" +struct _GimpDashboardLogParams +{ + gint sample_frequency; + gboolean backtrace; +}; + + #define GIMP_TYPE_DASHBOARD (gimp_dashboard_get_type ()) #define GIMP_DASHBOARD(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_DASHBOARD, GimpDashboard)) #define GIMP_DASHBOARD_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_DASHBOARD, GimpDashboardClass)) @@ -56,10 +63,12 @@ GtkWidget * gimp_dashboard_new (Gimp gboolean gimp_dashboard_log_start_recording (GimpDashboard *dashboard, GFile *file, + const GimpDashboardLogParams *params, GError **error); gboolean gimp_dashboard_log_stop_recording (GimpDashboard *dashboard, GError **error); gboolean gimp_dashboard_log_is_recording (GimpDashboard *dashboard); +const GimpDashboardLogParams * gimp_dashboard_log_get_default_params (GimpDashboard *dashboard); void gimp_dashboard_log_add_marker (GimpDashboard *dashboard, const gchar *description); diff --git a/app/widgets/widgets-types.h b/app/widgets/widgets-types.h index 852e2fdf1d..e7272cc97f 100644 --- a/app/widgets/widgets-types.h +++ b/app/widgets/widgets-types.h @@ -292,6 +292,8 @@ typedef struct _GimpToggleActionEntry GimpToggleActionEntry; typedef struct _GimpDialogFactoryEntry GimpDialogFactoryEntry; +typedef struct _GimpDashboardLogParams GimpDashboardLogParams; + /* function types */