Commit 126002c5 authored by Ell's avatar Ell

app: allow controlling performance-log parameters through the UI

When recording a performance log, allow setting the log parametrs
through the file dialog.  Currently, this includes the sample
frequency, and the option to include backtraces.

These options are still controllable through the
GIMP_PERFORMANCE_LOG_SAMPLE_FREQUENCY and
GIMP_PERFORMANCE_LOG_BACKTRACE environment variables.  When set,
the variables override the values entered through the UI.
parent 95b69dd7
...@@ -37,15 +37,25 @@ ...@@ -37,15 +37,25 @@
#include "gimp-intl.h" #include "gimp-intl.h"
typedef struct
{
GFile *folder;
GimpDashboardLogParams params;
} DashboardLogDialogInfo;
/* local function prototypes */ /* local function prototypes */
static void dashboard_log_record_response (GtkWidget *dialog, static void dashboard_log_record_response (GtkWidget *dialog,
int response_id, int response_id,
GimpDashboard *dashboard); 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, static DashboardLogDialogInfo * dashboard_log_dialog_info_new (GimpDashboard *dashboard);
const gchar *description, static void dashboard_log_dialog_info_free (DashboardLogDialogInfo *info);
GimpDashboard *dashboard);
/* public functions */ /* public functions */
...@@ -94,8 +104,13 @@ dashboard_log_record_cmd_callback (GimpAction *action, ...@@ -94,8 +104,13 @@ dashboard_log_record_cmd_callback (GimpAction *action,
if (! dialog) if (! dialog)
{ {
GtkFileFilter *filter; GtkFileFilter *filter;
GFile *folder; DashboardLogDialogInfo *info;
GtkWidget *hbox;
GtkWidget *hbox2;
GtkWidget *label;
GtkWidget *spinbutton;
GtkWidget *toggle;
dialog = gtk_file_chooser_dialog_new ( dialog = gtk_file_chooser_dialog_new (
"Record Performance Log", NULL, GTK_FILE_CHOOSER_ACTION_SAVE, "Record Performance Log", NULL, GTK_FILE_CHOOSER_ACTION_SAVE,
...@@ -134,18 +149,69 @@ dashboard_log_record_cmd_callback (GimpAction *action, ...@@ -134,18 +149,69 @@ dashboard_log_record_cmd_callback (GimpAction *action,
gtk_file_chooser_set_filter (GTK_FILE_CHOOSER (dialog), filter); gtk_file_chooser_set_filter (GTK_FILE_CHOOSER (dialog), filter);
folder = g_object_get_data (G_OBJECT (dashboard), info = g_object_get_data (G_OBJECT (dashboard),
"gimp-dashboard-log-record-folder"); "gimp-dashboard-log-dialog-info");
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 (folder) if (info->folder)
{ {
gtk_file_chooser_set_current_folder_file ( 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), gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (dialog),
"gimp-performance.log"); "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_signal_connect (dialog, "response",
G_CALLBACK (dashboard_log_record_response), G_CALLBACK (dashboard_log_record_response),
dashboard); dashboard);
...@@ -253,15 +319,22 @@ dashboard_log_record_response (GtkWidget *dialog, ...@@ -253,15 +319,22 @@ dashboard_log_record_response (GtkWidget *dialog,
{ {
if (response_id == GTK_RESPONSE_OK) if (response_id == GTK_RESPONSE_OK)
{ {
GFile *file = gtk_file_chooser_get_file (GTK_FILE_CHOOSER (dialog)); GFile *file;
GError *error = NULL; DashboardLogDialogInfo *info;
GError *error = NULL;
file = gtk_file_chooser_get_file (GTK_FILE_CHOOSER (dialog));
g_object_set_data_full (G_OBJECT (dashboard), info = g_object_get_data (G_OBJECT (dashboard),
"gimp-dashboard-log-record-folder", "gimp-dashboard-log-dialog-info");
g_file_get_parent (file),
g_object_unref);
if (! gimp_dashboard_log_start_recording (dashboard, file, &error)) 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_message_literal (
gimp_editor_get_ui_manager (GIMP_EDITOR (dashboard))->gimp, gimp_editor_get_ui_manager (GIMP_EDITOR (dashboard))->gimp,
...@@ -283,3 +356,22 @@ dashboard_log_add_marker_response (GtkWidget *dialog, ...@@ -283,3 +356,22 @@ dashboard_log_add_marker_response (GtkWidget *dialog,
{ {
gimp_dashboard_log_add_marker (dashboard, description); 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);
}
...@@ -94,7 +94,10 @@ ...@@ -94,7 +94,10 @@
#define CPU_ACTIVE_OFF /* individual cpu usage is below */ 0.25 #define CPU_ACTIVE_OFF /* individual cpu usage is below */ 0.25
#define LOG_VERSION 1 #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 typedef enum
...@@ -311,12 +314,11 @@ struct _GimpDashboardPrivate ...@@ -311,12 +314,11 @@ struct _GimpDashboardPrivate
GOutputStream *log_output; GOutputStream *log_output;
GError *log_error; GError *log_error;
GimpDashboardLogParams log_params;
gint64 log_start_time; gint64 log_start_time;
gint log_sample_frequency;
gint log_n_samples; gint log_n_samples;
gint log_n_markers; gint log_n_markers;
VariableData log_variables[N_VARIABLES]; VariableData log_variables[N_VARIABLES];
gboolean log_include_backtrace;
GimpBacktrace *log_backtrace; GimpBacktrace *log_backtrace;
GHashTable *log_addresses; GHashTable *log_addresses;
...@@ -1757,9 +1759,14 @@ gimp_dashboard_sample (GimpDashboard *dashboard) ...@@ -1757,9 +1759,14 @@ gimp_dashboard_sample (GimpDashboard *dashboard)
update_interval = priv->update_interval * G_TIME_SPAN_SECOND / 1000; update_interval = priv->update_interval * G_TIME_SPAN_SECOND / 1000;
if (priv->log_output) 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 else
sample_interval = update_interval; {
sample_interval = update_interval;
}
end_time = last_sample_time + sample_interval; end_time = last_sample_time + sample_interval;
...@@ -3650,7 +3657,7 @@ gimp_dashboard_log_sample (GimpDashboard *dashboard, ...@@ -3650,7 +3657,7 @@ gimp_dashboard_log_sample (GimpDashboard *dashboard,
"</vars>\n"); "</vars>\n");
} }
if (priv->log_include_backtrace) if (priv->log_params.backtrace)
backtrace = gimp_backtrace_new (FALSE); backtrace = gimp_backtrace_new (FALSE);
if (backtrace) if (backtrace)
...@@ -4257,9 +4264,10 @@ gimp_dashboard_new (Gimp *gimp, ...@@ -4257,9 +4264,10 @@ gimp_dashboard_new (Gimp *gimp,
} }
gboolean gboolean
gimp_dashboard_log_start_recording (GimpDashboard *dashboard, gimp_dashboard_log_start_recording (GimpDashboard *dashboard,
GFile *file, GFile *file,
GError **error) const GimpDashboardLogParams *params,
GError **error)
{ {
GimpDashboardPrivate *priv; GimpDashboardPrivate *priv;
GimpUIManager *ui_manager; GimpUIManager *ui_manager;
...@@ -4281,6 +4289,27 @@ gimp_dashboard_log_start_recording (GimpDashboard *dashboard, ...@@ -4281,6 +4289,27 @@ gimp_dashboard_log_start_recording (GimpDashboard *dashboard,
g_return_val_if_fail (! gimp_dashboard_log_is_recording (dashboard), FALSE); 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); g_mutex_lock (&priv->mutex);
priv->log_output = G_OUTPUT_STREAM (g_file_replace (file, priv->log_output = G_OUTPUT_STREAM (g_file_replace (file,
...@@ -4294,28 +4323,14 @@ gimp_dashboard_log_start_recording (GimpDashboard *dashboard, ...@@ -4294,28 +4323,14 @@ gimp_dashboard_log_start_recording (GimpDashboard *dashboard,
return FALSE; return FALSE;
} }
priv->log_error = NULL; priv->log_error = NULL;
priv->log_start_time = g_get_monotonic_time (); priv->log_start_time = g_get_monotonic_time ();
priv->log_sample_frequency = LOG_SAMPLE_FREQUENCY; priv->log_n_samples = 0;
priv->log_n_samples = 0; priv->log_n_markers = 0;
priv->log_n_markers = 0; priv->log_backtrace = NULL;
priv->log_include_backtrace = TRUE; priv->log_addresses = g_hash_table_new (NULL, NULL);
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 (); has_backtrace = gimp_backtrace_start ();
else else
has_backtrace = FALSE; has_backtrace = FALSE;
...@@ -4331,7 +4346,7 @@ gimp_dashboard_log_start_recording (GimpDashboard *dashboard, ...@@ -4331,7 +4346,7 @@ gimp_dashboard_log_start_recording (GimpDashboard *dashboard,
"<sample-frequency>%d</sample-frequency>\n" "<sample-frequency>%d</sample-frequency>\n"
"<backtrace>%d</backtrace>\n" "<backtrace>%d</backtrace>\n"
"</params>\n", "</params>\n",
priv->log_sample_frequency, priv->log_params.sample_frequency,
has_backtrace); has_backtrace);
gimp_dashboard_log_printf (dashboard, gimp_dashboard_log_printf (dashboard,
...@@ -4558,7 +4573,7 @@ gimp_dashboard_log_stop_recording (GimpDashboard *dashboard, ...@@ -4558,7 +4573,7 @@ gimp_dashboard_log_stop_recording (GimpDashboard *dashboard,
"\n" "\n"
"</gimp-performance-log>\n"); "</gimp-performance-log>\n");
if (priv->log_include_backtrace) if (priv->log_params.backtrace)
gimp_backtrace_stop (); gimp_backtrace_stop ();
if (! priv->log_error) if (! priv->log_error)
...@@ -4612,6 +4627,20 @@ gimp_dashboard_log_is_recording (GimpDashboard *dashboard) ...@@ -4612,6 +4627,20 @@ gimp_dashboard_log_is_recording (GimpDashboard *dashboard)
return priv->log_output != NULL; 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 void
gimp_dashboard_log_add_marker (GimpDashboard *dashboard, gimp_dashboard_log_add_marker (GimpDashboard *dashboard,
const gchar *description) const gchar *description)
......
...@@ -25,6 +25,13 @@ ...@@ -25,6 +25,13 @@
#include "gimpeditor.h" #include "gimpeditor.h"
struct _GimpDashboardLogParams
{
gint sample_frequency;
gboolean backtrace;
};
#define GIMP_TYPE_DASHBOARD (gimp_dashboard_get_type ()) #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(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)) #define GIMP_DASHBOARD_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_DASHBOARD, GimpDashboardClass))
...@@ -56,10 +63,12 @@ GtkWidget * gimp_dashboard_new (Gimp ...@@ -56,10 +63,12 @@ GtkWidget * gimp_dashboard_new (Gimp
gboolean gimp_dashboard_log_start_recording (GimpDashboard *dashboard, gboolean gimp_dashboard_log_start_recording (GimpDashboard *dashboard,
GFile *file, GFile *file,
const GimpDashboardLogParams *params,
GError **error); GError **error);
gboolean gimp_dashboard_log_stop_recording (GimpDashboard *dashboard, gboolean gimp_dashboard_log_stop_recording (GimpDashboard *dashboard,
GError **error); GError **error);
gboolean gimp_dashboard_log_is_recording (GimpDashboard *dashboard); 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, void gimp_dashboard_log_add_marker (GimpDashboard *dashboard,
const gchar *description); const gchar *description);
......
...@@ -292,6 +292,8 @@ typedef struct _GimpToggleActionEntry GimpToggleActionEntry; ...@@ -292,6 +292,8 @@ typedef struct _GimpToggleActionEntry GimpToggleActionEntry;
typedef struct _GimpDialogFactoryEntry GimpDialogFactoryEntry; typedef struct _GimpDialogFactoryEntry GimpDialogFactoryEntry;
typedef struct _GimpDashboardLogParams GimpDashboardLogParams;
/* function types */ /* function types */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment