From 451e79a84cb899a024d494ba8bc4477e690abc80 Mon Sep 17 00:00:00 2001 From: Christian Hergert Date: Mon, 12 Jun 2023 11:16:41 -0700 Subject: [PATCH] libsysprof-gtk: add augmented functions list This provides an area to have augmented functions listing like we have in the 3-part sysprof view in our current release. The weighed callgrpah view uses this to show self/total sortable columns similar to the descendants view. --- .../sysprof-callgraph-view-private.h | 4 +- src/libsysprof-gtk/sysprof-callgraph-view.c | 17 ++- src/libsysprof-gtk/sysprof-callgraph-view.ui | 78 +++++++++--- .../sysprof-weighted-callgraph-view.c | 119 ++++++++++++++++-- .../sysprof-weighted-callgraph-view.ui | 67 ++++++++++ 5 files changed, 259 insertions(+), 26 deletions(-) diff --git a/src/libsysprof-gtk/sysprof-callgraph-view-private.h b/src/libsysprof-gtk/sysprof-callgraph-view-private.h index 3521c094..031cb32d 100644 --- a/src/libsysprof-gtk/sysprof-callgraph-view-private.h +++ b/src/libsysprof-gtk/sysprof-callgraph-view-private.h @@ -34,7 +34,9 @@ struct _SysprofCallgraphView GListModel *traceables; GtkColumnView *column_view; - GtkWidget *scrolled_window; + GtkColumnView *functions_column_view; + GtkScrolledWindow *scrolled_window; + GtkWidget *paned; GCancellable *cancellable; diff --git a/src/libsysprof-gtk/sysprof-callgraph-view.c b/src/libsysprof-gtk/sysprof-callgraph-view.c index 83974b5c..fd31dfd8 100644 --- a/src/libsysprof-gtk/sysprof-callgraph-view.c +++ b/src/libsysprof-gtk/sysprof-callgraph-view.c @@ -71,7 +71,7 @@ sysprof_callgraph_view_dispose (GObject *object) g_clear_handle_id (&self->reload_source, g_source_remove); - g_clear_pointer ((GtkWidget **)&self->scrolled_window, gtk_widget_unparent); + g_clear_pointer (&self->paned, gtk_widget_unparent); g_cancellable_cancel (self->cancellable); g_clear_object (&self->cancellable); @@ -153,6 +153,8 @@ sysprof_callgraph_view_class_init (SysprofCallgraphViewClass *klass) gtk_widget_class_set_template_from_resource (widget_class, "/libsysprof-gtk/sysprof-callgraph-view.ui"); gtk_widget_class_set_layout_manager_type (widget_class, GTK_TYPE_BIN_LAYOUT); gtk_widget_class_bind_template_child (widget_class, SysprofCallgraphView, column_view); + gtk_widget_class_bind_template_child (widget_class, SysprofCallgraphView, functions_column_view); + gtk_widget_class_bind_template_child (widget_class, SysprofCallgraphView, paned); gtk_widget_class_bind_template_child (widget_class, SysprofCallgraphView, scrolled_window); gtk_widget_class_bind_template_callback (widget_class, sysprof_callgraph_view_key_pressed_cb); @@ -187,7 +189,10 @@ sysprof_callgraph_view_reload_cb (GObject *object, g_autoptr(SysprofCallgraph) callgraph = NULL; g_autoptr(GtkTreeListRowSorter) sorter = NULL; g_autoptr(GtkMultiSelection) model = NULL; + g_autoptr(GtkSingleSelection) functions_selection = NULL; g_autoptr(GtkSortListModel) sort_model = NULL; + g_autoptr(GtkSortListModel) functions_sort_model = NULL; + g_autoptr(GListModel) functions_model = NULL; g_autoptr(GtkTreeListModel) tree = NULL; g_autoptr(GtkTreeListRow) first = NULL; g_autoptr(GError) error = NULL; @@ -216,6 +221,14 @@ sysprof_callgraph_view_reload_cb (GObject *object, model = gtk_multi_selection_new (g_object_ref (G_LIST_MODEL (sort_model))); gtk_column_view_set_model (self->column_view, GTK_SELECTION_MODEL (model)); + column_sorter = gtk_column_view_get_sorter (self->functions_column_view); + functions_model = sysprof_callgraph_list_symbols (callgraph); + functions_sort_model = gtk_sort_list_model_new (g_object_ref (functions_model), + g_object_ref (column_sorter)); + functions_selection = gtk_single_selection_new (g_object_ref (G_LIST_MODEL (functions_sort_model))); + gtk_column_view_set_model (self->functions_column_view, + GTK_SELECTION_MODEL (functions_selection)); + if (SYSPROF_CALLGRAPH_VIEW_GET_CLASS (self)->load) SYSPROF_CALLGRAPH_VIEW_GET_CLASS (self)->load (self, callgraph); @@ -329,6 +342,8 @@ sysprof_callgraph_view_get_internal_child (GtkBuildable *buildable, { if (g_strcmp0 (name, "column_view") == 0) return G_OBJECT (SYSPROF_CALLGRAPH_VIEW (buildable)->column_view); + else if (g_strcmp0 (name, "functions_column_view") == 0) + return G_OBJECT (SYSPROF_CALLGRAPH_VIEW (buildable)->functions_column_view); return NULL; } diff --git a/src/libsysprof-gtk/sysprof-callgraph-view.ui b/src/libsysprof-gtk/sysprof-callgraph-view.ui index f85a9d9e..6b7e0469 100644 --- a/src/libsysprof-gtk/sysprof-callgraph-view.ui +++ b/src/libsysprof-gtk/sysprof-callgraph-view.ui @@ -2,19 +2,67 @@ diff --git a/src/libsysprof-gtk/sysprof-weighted-callgraph-view.c b/src/libsysprof-gtk/sysprof-weighted-callgraph-view.c index 35d035ed..74cc5e26 100644 --- a/src/libsysprof-gtk/sysprof-weighted-callgraph-view.c +++ b/src/libsysprof-gtk/sysprof-weighted-callgraph-view.c @@ -30,9 +30,13 @@ struct _SysprofWeightedCallgraphView GtkColumnViewColumn *self_column; GtkColumnViewColumn *total_column; - GtkCustomSorter *self_sorter; GtkCustomSorter *total_sorter; + + GtkColumnViewColumn *functions_self_column; + GtkColumnViewColumn *functions_total_column; + GtkCustomSorter *functions_self_sorter; + GtkCustomSorter *functions_total_sorter; }; struct _SysprofWeightedCallgraphViewClass @@ -97,7 +101,7 @@ get_total_fraction (GObject *item) AugmentWeight *sum = sysprof_callgraph_frame_get_augment (frame); AugmentWeight *root = sysprof_callgraph_get_augment (callgraph, NULL); - return (double)sum->total / (double)root->total; + return sum->total / (double)root->total; } return 0; @@ -124,10 +128,48 @@ get_self_fraction (GObject *item) return .0; } +static double +functions_get_total_fraction (GObject *item) +{ + g_autoptr(SysprofCallgraphSymbol) sym = NULL; + + g_object_get (item, "item", &sym, NULL); + + if (SYSPROF_IS_CALLGRAPH_SYMBOL (sym)) + { + SysprofCallgraph *callgraph = sysprof_callgraph_symbol_get_callgraph (sym); + AugmentWeight *sum = sysprof_callgraph_symbol_get_summary_augment (sym); + AugmentWeight *root = sysprof_callgraph_get_augment (callgraph, NULL); + + return sum->total / (double)root->total; + } + + return 0; +} + +static double +functions_get_self_fraction (GObject *item) +{ + g_autoptr(SysprofCallgraphSymbol) sym = NULL; + + g_object_get (item, "item", &sym, NULL); + + if (SYSPROF_IS_CALLGRAPH_SYMBOL (sym)) + { + SysprofCallgraph *callgraph = sysprof_callgraph_symbol_get_callgraph (sym); + AugmentWeight *sum = sysprof_callgraph_symbol_get_summary_augment (sym); + AugmentWeight *root = sysprof_callgraph_get_augment (callgraph, NULL); + + return sum->size / (double)root->total; + } + + return 0; +} + static int -sort_by_self (gconstpointer a, - gconstpointer b, - gpointer user_data) +descendants_sort_by_self (gconstpointer a, + gconstpointer b, + gpointer user_data) { SysprofCallgraphFrame *frame_a = (SysprofCallgraphFrame *)a; SysprofCallgraphFrame *frame_b = (SysprofCallgraphFrame *)b; @@ -146,9 +188,9 @@ sort_by_self (gconstpointer a, } static int -sort_by_total (gconstpointer a, - gconstpointer b, - gpointer user_data) +descendants_sort_by_total (gconstpointer a, + gconstpointer b, + gpointer user_data) { SysprofCallgraphFrame *frame_a = (SysprofCallgraphFrame *)a; SysprofCallgraphFrame *frame_b = (SysprofCallgraphFrame *)b; @@ -166,6 +208,48 @@ sort_by_total (gconstpointer a, return 0; } +static int +functions_sort_by_self (gconstpointer a, + gconstpointer b, + gpointer user_data) +{ + SysprofCallgraphSymbol *sym_a = (SysprofCallgraphSymbol *)a; + SysprofCallgraphSymbol *sym_b = (SysprofCallgraphSymbol *)b; + AugmentWeight *aug_a = sysprof_callgraph_symbol_get_summary_augment (sym_a); + AugmentWeight *aug_b = sysprof_callgraph_symbol_get_summary_augment (sym_b); + AugmentWeight *root = user_data; + double self_a = aug_a->size / (double)root->total; + double self_b = aug_b->size / (double)root->total; + + if (self_a < self_b) + return -1; + else if (self_a > self_b) + return 1; + else + return 0; +} + +static int +functions_sort_by_total (gconstpointer a, + gconstpointer b, + gpointer user_data) +{ + SysprofCallgraphSymbol *sym_a = (SysprofCallgraphSymbol *)a; + SysprofCallgraphSymbol *sym_b = (SysprofCallgraphSymbol *)b; + AugmentWeight *aug_a = sysprof_callgraph_symbol_get_summary_augment (sym_a); + AugmentWeight *aug_b = sysprof_callgraph_symbol_get_summary_augment (sym_b); + AugmentWeight *root = user_data; + double total_a = aug_a->total / (double)root->total; + double total_b = aug_b->total / (double)root->total; + + if (total_a < total_b) + return -1; + else if (total_a > total_b) + return 1; + else + return 0; +} + static void sysprof_weighted_callgraph_view_load (SysprofCallgraphView *view, SysprofCallgraph *callgraph) @@ -178,12 +262,18 @@ sysprof_weighted_callgraph_view_load (SysprofCallgraphView *view, root = sysprof_callgraph_get_augment (callgraph, NULL); - gtk_custom_sorter_set_sort_func (self->self_sorter, sort_by_self, root, NULL); - gtk_custom_sorter_set_sort_func (self->total_sorter, sort_by_total, root, NULL); + gtk_custom_sorter_set_sort_func (self->self_sorter, descendants_sort_by_self, root, NULL); + gtk_custom_sorter_set_sort_func (self->total_sorter, descendants_sort_by_total, root, NULL); + + gtk_custom_sorter_set_sort_func (self->functions_self_sorter, functions_sort_by_self, root, NULL); + gtk_custom_sorter_set_sort_func (self->functions_total_sorter, functions_sort_by_total, root, NULL); gtk_column_view_sort_by_column (SYSPROF_CALLGRAPH_VIEW (self)->column_view, self->total_column, GTK_SORT_DESCENDING); + gtk_column_view_sort_by_column (SYSPROF_CALLGRAPH_VIEW (self)->functions_column_view, + self->functions_total_column, + GTK_SORT_DESCENDING); } static void @@ -197,12 +287,21 @@ sysprof_weighted_callgraph_view_class_init (SysprofWeightedCallgraphViewClass *k callgraph_view_class->load = sysprof_weighted_callgraph_view_load; gtk_widget_class_set_template_from_resource (widget_class, "/libsysprof-gtk/sysprof-weighted-callgraph-view.ui"); + gtk_widget_class_bind_template_child (widget_class, SysprofWeightedCallgraphView, self_column); gtk_widget_class_bind_template_child (widget_class, SysprofWeightedCallgraphView, total_column); gtk_widget_class_bind_template_child (widget_class, SysprofWeightedCallgraphView, self_sorter); gtk_widget_class_bind_template_child (widget_class, SysprofWeightedCallgraphView, total_sorter); + + gtk_widget_class_bind_template_child (widget_class, SysprofWeightedCallgraphView, functions_self_column); + gtk_widget_class_bind_template_child (widget_class, SysprofWeightedCallgraphView, functions_total_column); + gtk_widget_class_bind_template_child (widget_class, SysprofWeightedCallgraphView, functions_self_sorter); + gtk_widget_class_bind_template_child (widget_class, SysprofWeightedCallgraphView, functions_total_sorter); + gtk_widget_class_bind_template_callback (widget_class, get_self_fraction); gtk_widget_class_bind_template_callback (widget_class, get_total_fraction); + gtk_widget_class_bind_template_callback (widget_class, functions_get_self_fraction); + gtk_widget_class_bind_template_callback (widget_class, functions_get_total_fraction); g_type_ensure (SYSPROF_TYPE_PROGRESS_CELL); } diff --git a/src/libsysprof-gtk/sysprof-weighted-callgraph-view.ui b/src/libsysprof-gtk/sysprof-weighted-callgraph-view.ui index 56260171..087ee6c0 100644 --- a/src/libsysprof-gtk/sysprof-weighted-callgraph-view.ui +++ b/src/libsysprof-gtk/sysprof-weighted-callgraph-view.ui @@ -65,5 +65,72 @@ + + + + + + Self + + + + + + +]]> + + + + + + + + + + + + Total + + + + + + +]]> + + + + + + + + + + +