mirror of
https://github.com/varun-r-mallya/sysprof.git
synced 2026-02-10 07:00:53 +00:00
libsysprof: use callgraph node to categorize for icons
This commit is contained in:
@ -4,6 +4,7 @@ libsysprof_public_sources = [
|
|||||||
'sysprof-callgraph-frame.c',
|
'sysprof-callgraph-frame.c',
|
||||||
'sysprof-callgraph-symbol.c',
|
'sysprof-callgraph-symbol.c',
|
||||||
'sysprof-callgraph.c',
|
'sysprof-callgraph.c',
|
||||||
|
'sysprof-callgraph-categorize.c',
|
||||||
'sysprof-cpu-info.c',
|
'sysprof-cpu-info.c',
|
||||||
'sysprof-cpu-usage.c',
|
'sysprof-cpu-usage.c',
|
||||||
'sysprof-diagnostic.c',
|
'sysprof-diagnostic.c',
|
||||||
|
|||||||
177
src/libsysprof/sysprof-callgraph-categorize.c
Normal file
177
src/libsysprof/sysprof-callgraph-categorize.c
Normal file
@ -0,0 +1,177 @@
|
|||||||
|
/* sysprof-callgraph-categorize.c
|
||||||
|
*
|
||||||
|
* Copyright 2023 Christian Hergert <chergert@redhat.com>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#include "sysprof-callgraph-private.h"
|
||||||
|
#include "sysprof-symbol-private.h"
|
||||||
|
|
||||||
|
enum {
|
||||||
|
RULE_PREFIX = 1,
|
||||||
|
RULE_EXACT,
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct _Rule
|
||||||
|
{
|
||||||
|
guint8 kind : 2;
|
||||||
|
guint8 inherit : 1;
|
||||||
|
guint category;
|
||||||
|
const char *match;
|
||||||
|
} Rule;
|
||||||
|
|
||||||
|
typedef struct _RuleGroup
|
||||||
|
{
|
||||||
|
const char *nick;
|
||||||
|
const Rule *rules;
|
||||||
|
} RuleGroup;
|
||||||
|
|
||||||
|
static RuleGroup rule_groups[] = {
|
||||||
|
{ "EGL",
|
||||||
|
(const Rule[]) {
|
||||||
|
{ RULE_PREFIX, TRUE, SYSPROF_CALLGRAPH_CATEGORY_PAINT, "egl" },
|
||||||
|
{ 0 }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
{ "FontConfig",
|
||||||
|
(const Rule[]) {
|
||||||
|
{ RULE_PREFIX, FALSE, SYSPROF_CALLGRAPH_CATEGORY_LAYOUT, "" },
|
||||||
|
{ 0 }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
{ "GLib",
|
||||||
|
(const Rule[]) {
|
||||||
|
{ RULE_PREFIX, FALSE, SYSPROF_CALLGRAPH_CATEGORY_MAIN_LOOP, "g_main_loop_" },
|
||||||
|
{ RULE_PREFIX, FALSE, SYSPROF_CALLGRAPH_CATEGORY_MAIN_LOOP, "g_main_context_" },
|
||||||
|
{ RULE_PREFIX, FALSE, SYSPROF_CALLGRAPH_CATEGORY_MAIN_LOOP, "g_wakeup_" },
|
||||||
|
{ RULE_EXACT, FALSE, SYSPROF_CALLGRAPH_CATEGORY_MAIN_LOOP, "g_main_dispatch" },
|
||||||
|
{ 0 }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
{ "GObject",
|
||||||
|
(const Rule[]) {
|
||||||
|
{ RULE_PREFIX, FALSE, SYSPROF_CALLGRAPH_CATEGORY_SIGNALS, "g_signal_emit" },
|
||||||
|
{ RULE_PREFIX, FALSE, SYSPROF_CALLGRAPH_CATEGORY_SIGNALS, "g_signal_emit" },
|
||||||
|
{ RULE_PREFIX, FALSE, SYSPROF_CALLGRAPH_CATEGORY_SIGNALS, "g_object_notify" },
|
||||||
|
{ RULE_PREFIX, FALSE, SYSPROF_CALLGRAPH_CATEGORY_CONSTRUCTORS, "g_object_new" },
|
||||||
|
{ RULE_PREFIX, FALSE, SYSPROF_CALLGRAPH_CATEGORY_CONSTRUCTORS, "g_type_create_instance" },
|
||||||
|
{ 0 }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
{ "GTK 4",
|
||||||
|
(const Rule[]) {
|
||||||
|
{ RULE_PREFIX, TRUE, SYSPROF_CALLGRAPH_CATEGORY_LAYOUT, "gtk_css_" },
|
||||||
|
{ RULE_PREFIX, TRUE, SYSPROF_CALLGRAPH_CATEGORY_LAYOUT, "gtk_widget_measure" },
|
||||||
|
{ RULE_PREFIX, TRUE, SYSPROF_CALLGRAPH_CATEGORY_PAINT, "gdk_snapshot" },
|
||||||
|
{ RULE_PREFIX, TRUE, SYSPROF_CALLGRAPH_CATEGORY_PAINT, "gtk_snapshot" },
|
||||||
|
{ RULE_PREFIX, TRUE, SYSPROF_CALLGRAPH_CATEGORY_LAYOUT, "gtk_widget_reposition" },
|
||||||
|
{ RULE_PREFIX, TRUE, SYSPROF_CALLGRAPH_CATEGORY_WINDOWING, "gtk_window_present" },
|
||||||
|
{ RULE_PREFIX, TRUE, SYSPROF_CALLGRAPH_CATEGORY_ACTIONS, "gtk_action_muxer_" },
|
||||||
|
{ RULE_PREFIX, TRUE, SYSPROF_CALLGRAPH_CATEGORY_A11Y, "gtk_accessible_" },
|
||||||
|
{ RULE_PREFIX, TRUE, SYSPROF_CALLGRAPH_CATEGORY_A11Y, "gtk_at_" },
|
||||||
|
{ RULE_PREFIX, TRUE, SYSPROF_CALLGRAPH_CATEGORY_TEMPLATES, "gtk_builder_" },
|
||||||
|
{ RULE_PREFIX, TRUE, SYSPROF_CALLGRAPH_CATEGORY_TEMPLATES, "gtk_buildable_" },
|
||||||
|
{ RULE_PREFIX, TRUE, SYSPROF_CALLGRAPH_CATEGORY_LAYOUT, "gtk_widget_root" },
|
||||||
|
{ RULE_PREFIX, TRUE, SYSPROF_CALLGRAPH_CATEGORY_PAINT, "gdk_frame_clock_paint" },
|
||||||
|
{ RULE_PREFIX, TRUE, SYSPROF_CALLGRAPH_CATEGORY_LAYOUT, "_gdk_frame_clock_emit_layout" },
|
||||||
|
{ RULE_PREFIX, TRUE, SYSPROF_CALLGRAPH_CATEGORY_PAINT, "_gdk_frame_clock_emit_paint" },
|
||||||
|
{ RULE_PREFIX, TRUE, SYSPROF_CALLGRAPH_CATEGORY_PAINT, "_gdk_frame_clock_emit_after_paint" },
|
||||||
|
{ RULE_PREFIX, TRUE, SYSPROF_CALLGRAPH_CATEGORY_INPUT, "gdk_surface_handle_event" },
|
||||||
|
{ 0 }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
{ "libc",
|
||||||
|
(const Rule[]) {
|
||||||
|
{ RULE_EXACT, TRUE, SYSPROF_CALLGRAPH_CATEGORY_MAIN_LOOP, "poll" },
|
||||||
|
{ 0 }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
{ "Pango",
|
||||||
|
(const Rule[]) {
|
||||||
|
{ RULE_PREFIX, FALSE, SYSPROF_CALLGRAPH_CATEGORY_LAYOUT, "" },
|
||||||
|
{ 0 }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
{ "Wayland Client",
|
||||||
|
(const Rule[]) {
|
||||||
|
{ RULE_PREFIX, TRUE, SYSPROF_CALLGRAPH_CATEGORY_WINDOWING, "wl_" },
|
||||||
|
{ 0 }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
{ "Wayland Server",
|
||||||
|
(const Rule[]) {
|
||||||
|
{ RULE_PREFIX, TRUE, SYSPROF_CALLGRAPH_CATEGORY_WINDOWING, "wl_" },
|
||||||
|
{ 0 }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
SysprofCallgraphCategory
|
||||||
|
_sysprof_callgraph_node_categorize (SysprofCallgraphNode *node)
|
||||||
|
{
|
||||||
|
SysprofSymbol *symbol;
|
||||||
|
|
||||||
|
g_return_val_if_fail (node, SYSPROF_CALLGRAPH_CATEGORY_UNCATEGORIZED);
|
||||||
|
g_return_val_if_fail (node->summary, SYSPROF_CALLGRAPH_CATEGORY_UNCATEGORIZED);
|
||||||
|
g_return_val_if_fail (node->summary->symbol, SYSPROF_CALLGRAPH_CATEGORY_UNCATEGORIZED);
|
||||||
|
|
||||||
|
symbol = node->summary->symbol;
|
||||||
|
|
||||||
|
/* NOTE: We could certainly extend this to allow users to define custom
|
||||||
|
* categorization. Additionally, we might want to match more than one node so
|
||||||
|
* that you can do valgrind style function matches like:
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (symbol->kind != SYSPROF_SYMBOL_KIND_USER ||
|
||||||
|
symbol->binary_nick == NULL)
|
||||||
|
return SYSPROF_CALLGRAPH_CATEGORY_UNCATEGORIZED;
|
||||||
|
|
||||||
|
for (guint i = 0; i < G_N_ELEMENTS (rule_groups); i++)
|
||||||
|
{
|
||||||
|
if (strcmp (rule_groups[i].nick, symbol->binary_nick) != 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
for (guint j = 0; rule_groups[i].rules[j].kind; j++)
|
||||||
|
{
|
||||||
|
if (rule_groups[i].rules[j].kind == RULE_PREFIX)
|
||||||
|
{
|
||||||
|
if (g_str_has_prefix (symbol->name, rule_groups[i].rules[j].match))
|
||||||
|
return rule_groups[i].rules[j].category;
|
||||||
|
}
|
||||||
|
else if (rule_groups[i].rules[j].kind == RULE_EXACT)
|
||||||
|
{
|
||||||
|
if (strcmp (symbol->name, rule_groups[i].rules[j].match) == 0)
|
||||||
|
return rule_groups[i].rules[j].category;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return SYSPROF_CALLGRAPH_CATEGORY_UNCATEGORIZED;
|
||||||
|
}
|
||||||
@ -493,17 +493,18 @@ sysprof_callgraph_frame_is_leaf (SysprofCallgraphFrame *self)
|
|||||||
* @self: a #SysprofCallgraphFrame
|
* @self: a #SysprofCallgraphFrame
|
||||||
*
|
*
|
||||||
* Gets the category of the node if %SYSPROF_CALLGRAPH_FLAGS_CATEGORIZE_FRAMES
|
* Gets the category of the node if %SYSPROF_CALLGRAPH_FLAGS_CATEGORIZE_FRAMES
|
||||||
* was set when generating the callgraph. Otherwise 0.
|
* was set when generating the callgraph. Otherwise
|
||||||
|
* %SYSPROF_CALLGRAPH_CATEGORY_UNCATEGORIZED.
|
||||||
*
|
*
|
||||||
* Returns: 0 or a callgraph category
|
* Returns: callgraph category
|
||||||
*/
|
*/
|
||||||
SysprofCallgraphCategory
|
SysprofCallgraphCategory
|
||||||
sysprof_callgraph_frame_get_category (SysprofCallgraphFrame *self)
|
sysprof_callgraph_frame_get_category (SysprofCallgraphFrame *self)
|
||||||
{
|
{
|
||||||
g_return_val_if_fail (SYSPROF_IS_CALLGRAPH_FRAME (self), 0);
|
g_return_val_if_fail (SYSPROF_IS_CALLGRAPH_FRAME (self), 0);
|
||||||
|
|
||||||
if (self->callgraph == NULL || self->node == NULL)
|
if (self->callgraph != NULL && self->node != NULL && self->node->category)
|
||||||
return 0;
|
return self->node->category;
|
||||||
|
|
||||||
return self->node->category;
|
return SYSPROF_CALLGRAPH_CATEGORY_UNCATEGORIZED;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -68,21 +68,22 @@ struct _SysprofCallgraph
|
|||||||
SysprofCallgraphNode root;
|
SysprofCallgraphNode root;
|
||||||
};
|
};
|
||||||
|
|
||||||
void _sysprof_callgraph_new_async (SysprofDocument *document,
|
void _sysprof_callgraph_new_async (SysprofDocument *document,
|
||||||
SysprofCallgraphFlags flags,
|
SysprofCallgraphFlags flags,
|
||||||
GListModel *traceables,
|
GListModel *traceables,
|
||||||
gsize augment_size,
|
gsize augment_size,
|
||||||
SysprofAugmentationFunc augment_func,
|
SysprofAugmentationFunc augment_func,
|
||||||
gpointer augment_func_data,
|
gpointer augment_func_data,
|
||||||
GDestroyNotify augment_func_data_destroy,
|
GDestroyNotify augment_func_data_destroy,
|
||||||
GCancellable *cancellable,
|
GCancellable *cancellable,
|
||||||
GAsyncReadyCallback callback,
|
GAsyncReadyCallback callback,
|
||||||
gpointer user_data);
|
gpointer user_data);
|
||||||
SysprofCallgraph *_sysprof_callgraph_new_finish (GAsyncResult *result,
|
SysprofCallgraph *_sysprof_callgraph_new_finish (GAsyncResult *result,
|
||||||
GError **error);
|
GError **error);
|
||||||
gpointer _sysprof_callgraph_get_symbol_augment (SysprofCallgraph *self,
|
gpointer _sysprof_callgraph_get_symbol_augment (SysprofCallgraph *self,
|
||||||
SysprofSymbol *symbol);
|
SysprofSymbol *symbol);
|
||||||
void _sysprof_callgraph_node_free (SysprofCallgraphNode *self,
|
void _sysprof_callgraph_node_free (SysprofCallgraphNode *self,
|
||||||
gboolean free_self);
|
gboolean free_self);
|
||||||
|
SysprofCallgraphCategory _sysprof_callgraph_node_categorize (SysprofCallgraphNode *node);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|||||||
@ -287,15 +287,13 @@ static void
|
|||||||
sysprof_callgraph_categorize (SysprofCallgraph *self,
|
sysprof_callgraph_categorize (SysprofCallgraph *self,
|
||||||
SysprofCallgraphNode *node)
|
SysprofCallgraphNode *node)
|
||||||
{
|
{
|
||||||
SysprofSymbol *symbol = node->summary->symbol;
|
|
||||||
|
|
||||||
if (node->category)
|
if (node->category)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (node->parent && node->parent->category == 0)
|
if (node->parent && node->parent->category == 0)
|
||||||
sysprof_callgraph_categorize (self, node->parent);
|
sysprof_callgraph_categorize (self, node->parent);
|
||||||
|
|
||||||
switch (symbol->kind)
|
switch (node->summary->symbol->kind)
|
||||||
{
|
{
|
||||||
case SYSPROF_SYMBOL_KIND_ROOT:
|
case SYSPROF_SYMBOL_KIND_ROOT:
|
||||||
case SYSPROF_SYMBOL_KIND_THREAD:
|
case SYSPROF_SYMBOL_KIND_THREAD:
|
||||||
@ -316,6 +314,7 @@ sysprof_callgraph_categorize (SysprofCallgraph *self,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case SYSPROF_SYMBOL_KIND_USER:
|
case SYSPROF_SYMBOL_KIND_USER:
|
||||||
|
node->category = _sysprof_callgraph_node_categorize (node);
|
||||||
|
|
||||||
G_GNUC_FALLTHROUGH;
|
G_GNUC_FALLTHROUGH;
|
||||||
|
|
||||||
|
|||||||
@ -79,6 +79,9 @@ typedef enum _SysprofCallgraphCategory
|
|||||||
SYSPROF_CALLGRAPH_CATEGORY_TEMPLATES,
|
SYSPROF_CALLGRAPH_CATEGORY_TEMPLATES,
|
||||||
SYSPROF_CALLGRAPH_CATEGORY_UNWINDABLE,
|
SYSPROF_CALLGRAPH_CATEGORY_UNWINDABLE,
|
||||||
SYSPROF_CALLGRAPH_CATEGORY_WINDOWING,
|
SYSPROF_CALLGRAPH_CATEGORY_WINDOWING,
|
||||||
|
|
||||||
|
/* Not part of ABI */
|
||||||
|
SYSPROF_CALLGRAPH_CATEGORY_LAST,
|
||||||
} SysprofCallgraphCategory;
|
} SysprofCallgraphCategory;
|
||||||
|
|
||||||
typedef enum _SysprofCallgraphFlags
|
typedef enum _SysprofCallgraphFlags
|
||||||
|
|||||||
@ -57,6 +57,7 @@ G_BEGIN_DECLS
|
|||||||
# include "sysprof-document.h"
|
# include "sysprof-document.h"
|
||||||
# include "sysprof-elf-symbolizer.h"
|
# include "sysprof-elf-symbolizer.h"
|
||||||
# include "sysprof-energy-usage.h"
|
# include "sysprof-energy-usage.h"
|
||||||
|
# include "sysprof-enums.h"
|
||||||
# include "sysprof-instrument.h"
|
# include "sysprof-instrument.h"
|
||||||
# include "sysprof-jitmap-symbolizer.h"
|
# include "sysprof-jitmap-symbolizer.h"
|
||||||
# include "sysprof-kallsyms-symbolizer.h"
|
# include "sysprof-kallsyms-symbolizer.h"
|
||||||
|
|||||||
@ -213,8 +213,8 @@
|
|||||||
<property name="height-request">9</property>
|
<property name="height-request">9</property>
|
||||||
<property name="valign">center</property>
|
<property name="valign">center</property>
|
||||||
<property name="halign">center</property>
|
<property name="halign">center</property>
|
||||||
<binding name="symbol">
|
<binding name="category">
|
||||||
<lookup name="symbol" type="SysprofCallgraphFrame">
|
<lookup name="category" type="SysprofCallgraphFrame">
|
||||||
<lookup name="item">expander</lookup>
|
<lookup name="item">expander</lookup>
|
||||||
</lookup>
|
</lookup>
|
||||||
</binding>
|
</binding>
|
||||||
|
|||||||
@ -21,217 +21,46 @@
|
|||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
#include "sysprof-category-icon.h"
|
#include "sysprof-category-icon.h"
|
||||||
#include "sysprof-symbol-private.h"
|
|
||||||
|
|
||||||
struct _SysprofCategoryIcon
|
struct _SysprofCategoryIcon
|
||||||
{
|
{
|
||||||
GtkWidget parent_instance;
|
GtkWidget parent_instance;
|
||||||
SysprofSymbol *symbol;
|
|
||||||
guint category;
|
guint category;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
PROP_0,
|
PROP_0,
|
||||||
PROP_SYMBOL,
|
PROP_CATEGORY,
|
||||||
N_PROPS
|
N_PROPS
|
||||||
};
|
};
|
||||||
|
|
||||||
G_DEFINE_FINAL_TYPE (SysprofCategoryIcon, sysprof_category_icon, GTK_TYPE_WIDGET)
|
G_DEFINE_FINAL_TYPE (SysprofCategoryIcon, sysprof_category_icon, GTK_TYPE_WIDGET)
|
||||||
|
|
||||||
enum {
|
|
||||||
CATEGORY_0,
|
|
||||||
CATEGORY_A11Y,
|
|
||||||
CATEGORY_ACTIONS,
|
|
||||||
CATEGORY_CONSTRUCTORS,
|
|
||||||
CATEGORY_CONTEXT_SWITCH,
|
|
||||||
CATEGORY_INPUT,
|
|
||||||
CATEGORY_KERNEL,
|
|
||||||
CATEGORY_LAYOUT,
|
|
||||||
CATEGORY_MAIN_LOOP,
|
|
||||||
CATEGORY_PAINT,
|
|
||||||
CATEGORY_SIGNALS,
|
|
||||||
CATEGORY_TEMPLATES,
|
|
||||||
CATEGORY_WINDOWING,
|
|
||||||
N_CATEGORIES
|
|
||||||
};
|
|
||||||
|
|
||||||
enum {
|
|
||||||
RULE_PREFIX = 1,
|
|
||||||
RULE_EXACT,
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef struct _Rule
|
|
||||||
{
|
|
||||||
guint8 kind : 2;
|
|
||||||
guint8 inherit : 1;
|
|
||||||
guint category;
|
|
||||||
const char *match;
|
|
||||||
} Rule;
|
|
||||||
|
|
||||||
typedef struct _RuleGroup
|
|
||||||
{
|
|
||||||
const char *nick;
|
|
||||||
const Rule *rules;
|
|
||||||
} RuleGroup;
|
|
||||||
|
|
||||||
static GParamSpec *properties [N_PROPS];
|
static GParamSpec *properties [N_PROPS];
|
||||||
static GdkRGBA category_colors[N_CATEGORIES];
|
static GdkRGBA category_colors[SYSPROF_CALLGRAPH_CATEGORY_LAST];
|
||||||
static RuleGroup rule_groups[] = {
|
|
||||||
{ "EGL",
|
|
||||||
(const Rule[]) {
|
|
||||||
{ RULE_PREFIX, TRUE, CATEGORY_PAINT, "egl" },
|
|
||||||
{ 0 }
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
{ "FontConfig",
|
|
||||||
(const Rule[]) {
|
|
||||||
{ RULE_PREFIX, FALSE, CATEGORY_LAYOUT, "" },
|
|
||||||
{ 0 }
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
{ "GLib",
|
|
||||||
(const Rule[]) {
|
|
||||||
{ RULE_PREFIX, FALSE, CATEGORY_MAIN_LOOP, "g_main_loop_" },
|
|
||||||
{ RULE_PREFIX, FALSE, CATEGORY_MAIN_LOOP, "g_main_context_" },
|
|
||||||
{ RULE_PREFIX, FALSE, CATEGORY_MAIN_LOOP, "g_wakeup_" },
|
|
||||||
{ RULE_EXACT, FALSE, CATEGORY_MAIN_LOOP, "g_main_dispatch" },
|
|
||||||
{ 0 }
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
{ "GObject",
|
|
||||||
(const Rule[]) {
|
|
||||||
{ RULE_PREFIX, FALSE, CATEGORY_SIGNALS, "g_signal_emit" },
|
|
||||||
{ RULE_PREFIX, FALSE, CATEGORY_SIGNALS, "g_signal_emit" },
|
|
||||||
{ RULE_PREFIX, FALSE, CATEGORY_SIGNALS, "g_object_notify" },
|
|
||||||
{ RULE_PREFIX, FALSE, CATEGORY_CONSTRUCTORS, "g_object_new" },
|
|
||||||
{ RULE_PREFIX, FALSE, CATEGORY_CONSTRUCTORS, "g_type_create_instance" },
|
|
||||||
{ 0 }
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
{ "GTK 4",
|
|
||||||
(const Rule[]) {
|
|
||||||
{ RULE_PREFIX, TRUE, CATEGORY_LAYOUT, "gtk_css_" },
|
|
||||||
{ RULE_PREFIX, TRUE, CATEGORY_LAYOUT, "gtk_widget_measure" },
|
|
||||||
{ RULE_PREFIX, TRUE, CATEGORY_PAINT, "gdk_snapshot" },
|
|
||||||
{ RULE_PREFIX, TRUE, CATEGORY_PAINT, "gtk_snapshot" },
|
|
||||||
{ RULE_PREFIX, TRUE, CATEGORY_LAYOUT, "gtk_widget_reposition" },
|
|
||||||
{ RULE_PREFIX, TRUE, CATEGORY_WINDOWING, "gtk_window_present" },
|
|
||||||
{ RULE_PREFIX, TRUE, CATEGORY_ACTIONS, "gtk_action_muxer_" },
|
|
||||||
{ RULE_PREFIX, TRUE, CATEGORY_A11Y, "gtk_accessible_" },
|
|
||||||
{ RULE_PREFIX, TRUE, CATEGORY_A11Y, "gtk_at_" },
|
|
||||||
{ RULE_PREFIX, TRUE, CATEGORY_TEMPLATES, "gtk_builder_" },
|
|
||||||
{ RULE_PREFIX, TRUE, CATEGORY_TEMPLATES, "gtk_buildable_" },
|
|
||||||
{ RULE_PREFIX, TRUE, CATEGORY_LAYOUT, "gtk_widget_root" },
|
|
||||||
{ RULE_PREFIX, TRUE, CATEGORY_PAINT, "gdk_frame_clock_paint" },
|
|
||||||
{ RULE_PREFIX, TRUE, CATEGORY_LAYOUT, "_gdk_frame_clock_emit_layout" },
|
|
||||||
{ RULE_PREFIX, TRUE, CATEGORY_PAINT, "_gdk_frame_clock_emit_paint" },
|
|
||||||
{ RULE_PREFIX, TRUE, CATEGORY_PAINT, "_gdk_frame_clock_emit_after_paint" },
|
|
||||||
{ RULE_PREFIX, TRUE, CATEGORY_INPUT, "gdk_surface_handle_event" },
|
|
||||||
{ 0 }
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
{ "libc",
|
|
||||||
(const Rule[]) {
|
|
||||||
{ RULE_EXACT, TRUE, CATEGORY_MAIN_LOOP, "poll" },
|
|
||||||
{ 0 }
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
{ "Pango",
|
|
||||||
(const Rule[]) {
|
|
||||||
{ RULE_PREFIX, FALSE, CATEGORY_LAYOUT, "" },
|
|
||||||
{ 0 }
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
{ "Wayland Client",
|
|
||||||
(const Rule[]) {
|
|
||||||
{ RULE_PREFIX, TRUE, CATEGORY_WINDOWING, "wl_" },
|
|
||||||
{ 0 }
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
{ "Wayland Server",
|
|
||||||
(const Rule[]) {
|
|
||||||
{ RULE_PREFIX, TRUE, CATEGORY_WINDOWING, "wl_" },
|
|
||||||
{ 0 }
|
|
||||||
}
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
static guint
|
|
||||||
categorize_symbol (SysprofSymbol *symbol)
|
|
||||||
{
|
|
||||||
if (symbol->kind == SYSPROF_SYMBOL_KIND_KERNEL)
|
|
||||||
return CATEGORY_KERNEL;
|
|
||||||
else if (symbol->kind == SYSPROF_SYMBOL_KIND_CONTEXT_SWITCH)
|
|
||||||
return CATEGORY_CONTEXT_SWITCH;
|
|
||||||
else if (symbol->kind != SYSPROF_SYMBOL_KIND_USER ||
|
|
||||||
symbol->binary_nick == NULL)
|
|
||||||
return CATEGORY_0;
|
|
||||||
|
|
||||||
for (guint i = 0; i < G_N_ELEMENTS (rule_groups); i++)
|
|
||||||
{
|
|
||||||
if (strcmp (rule_groups[i].nick, symbol->binary_nick) != 0)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
for (guint j = 0; rule_groups[i].rules[j].kind; j++)
|
|
||||||
{
|
|
||||||
if (rule_groups[i].rules[j].kind == RULE_PREFIX)
|
|
||||||
{
|
|
||||||
if (g_str_has_prefix (symbol->name, rule_groups[i].rules[j].match))
|
|
||||||
return rule_groups[i].rules[j].category;
|
|
||||||
}
|
|
||||||
else if (rule_groups[i].rules[j].kind == RULE_EXACT)
|
|
||||||
{
|
|
||||||
if (strcmp (symbol->name, rule_groups[i].rules[j].match) == 0)
|
|
||||||
return rule_groups[i].rules[j].category;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return CATEGORY_0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
sysprof_category_icon_snapshot (GtkWidget *widget,
|
sysprof_category_icon_snapshot (GtkWidget *widget,
|
||||||
GtkSnapshot *snapshot)
|
GtkSnapshot *snapshot)
|
||||||
{
|
{
|
||||||
SysprofCategoryIcon *self = (SysprofCategoryIcon *)widget;
|
SysprofCategoryIcon *self = (SysprofCategoryIcon *)widget;
|
||||||
const GdkRGBA *color = NULL;
|
|
||||||
|
|
||||||
g_assert (SYSPROF_IS_CATEGORY_ICON (self));
|
g_assert (SYSPROF_IS_CATEGORY_ICON (self));
|
||||||
g_assert (GTK_IS_SNAPSHOT (snapshot));
|
g_assert (GTK_IS_SNAPSHOT (snapshot));
|
||||||
|
|
||||||
color = &category_colors[self->category];
|
if (self->category >= G_N_ELEMENTS (category_colors))
|
||||||
|
return;
|
||||||
|
|
||||||
if (color->alpha == 0)
|
if (category_colors[self->category].alpha == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
gtk_snapshot_append_color (snapshot,
|
gtk_snapshot_append_color (snapshot,
|
||||||
color,
|
&category_colors[self->category],
|
||||||
&GRAPHENE_RECT_INIT (0, 0,
|
&GRAPHENE_RECT_INIT (0, 0,
|
||||||
gtk_widget_get_width (widget),
|
gtk_widget_get_width (widget),
|
||||||
gtk_widget_get_height (widget)));
|
gtk_widget_get_height (widget)));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
sysprof_category_icon_finalize (GObject *object)
|
|
||||||
{
|
|
||||||
SysprofCategoryIcon *self = (SysprofCategoryIcon *)object;
|
|
||||||
|
|
||||||
g_clear_object (&self->symbol);
|
|
||||||
|
|
||||||
G_OBJECT_CLASS (sysprof_category_icon_parent_class)->finalize (object);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
sysprof_category_icon_get_property (GObject *object,
|
sysprof_category_icon_get_property (GObject *object,
|
||||||
guint prop_id,
|
guint prop_id,
|
||||||
@ -242,8 +71,8 @@ sysprof_category_icon_get_property (GObject *object,
|
|||||||
|
|
||||||
switch (prop_id)
|
switch (prop_id)
|
||||||
{
|
{
|
||||||
case PROP_SYMBOL:
|
case PROP_CATEGORY:
|
||||||
g_value_set_object (value, sysprof_category_icon_get_symbol (self));
|
g_value_set_enum (value, sysprof_category_icon_get_category (self));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -261,8 +90,8 @@ sysprof_category_icon_set_property (GObject *object,
|
|||||||
|
|
||||||
switch (prop_id)
|
switch (prop_id)
|
||||||
{
|
{
|
||||||
case PROP_SYMBOL:
|
case PROP_CATEGORY:
|
||||||
sysprof_category_icon_set_symbol (self, g_value_get_object (value));
|
sysprof_category_icon_set_category (self, g_value_get_enum (value));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -276,57 +105,60 @@ sysprof_category_icon_class_init (SysprofCategoryIconClass *klass)
|
|||||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||||
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
|
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
|
||||||
|
|
||||||
object_class->finalize = sysprof_category_icon_finalize;
|
|
||||||
object_class->get_property = sysprof_category_icon_get_property;
|
object_class->get_property = sysprof_category_icon_get_property;
|
||||||
object_class->set_property = sysprof_category_icon_set_property;
|
object_class->set_property = sysprof_category_icon_set_property;
|
||||||
|
|
||||||
widget_class->snapshot = sysprof_category_icon_snapshot;
|
widget_class->snapshot = sysprof_category_icon_snapshot;
|
||||||
|
|
||||||
properties[PROP_SYMBOL] =
|
properties[PROP_CATEGORY] =
|
||||||
g_param_spec_object ("symbol", NULL, NULL,
|
g_param_spec_enum ("category", NULL, NULL,
|
||||||
SYSPROF_TYPE_SYMBOL,
|
SYSPROF_TYPE_CALLGRAPH_CATEGORY,
|
||||||
(G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS));
|
SYSPROF_CALLGRAPH_CATEGORY_UNCATEGORIZED,
|
||||||
|
(G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS));
|
||||||
|
|
||||||
g_object_class_install_properties (object_class, N_PROPS, properties);
|
g_object_class_install_properties (object_class, N_PROPS, properties);
|
||||||
|
|
||||||
gdk_rgba_parse (&category_colors[CATEGORY_A11Y], "#000");
|
gdk_rgba_parse (&category_colors[SYSPROF_CALLGRAPH_CATEGORY_A11Y], "#000");
|
||||||
gdk_rgba_parse (&category_colors[CATEGORY_ACTIONS], "#f66151");
|
gdk_rgba_parse (&category_colors[SYSPROF_CALLGRAPH_CATEGORY_ACTIONS], "#f66151");
|
||||||
gdk_rgba_parse (&category_colors[CATEGORY_CONSTRUCTORS], "#613583");
|
gdk_rgba_parse (&category_colors[SYSPROF_CALLGRAPH_CATEGORY_CONSTRUCTORS], "#613583");
|
||||||
gdk_rgba_parse (&category_colors[CATEGORY_CONSTRUCTORS], "#62a0ea");
|
gdk_rgba_parse (&category_colors[SYSPROF_CALLGRAPH_CATEGORY_CONSTRUCTORS], "#62a0ea");
|
||||||
gdk_rgba_parse (&category_colors[CATEGORY_CONTEXT_SWITCH], "#ffbe6f");
|
gdk_rgba_parse (&category_colors[SYSPROF_CALLGRAPH_CATEGORY_CONTEXT_SWITCH], "#ffbe6f");
|
||||||
gdk_rgba_parse (&category_colors[CATEGORY_INPUT], "#1a5fb4");
|
gdk_rgba_parse (&category_colors[SYSPROF_CALLGRAPH_CATEGORY_INPUT], "#1a5fb4");
|
||||||
gdk_rgba_parse (&category_colors[CATEGORY_KERNEL], "#a51d2d");
|
gdk_rgba_parse (&category_colors[SYSPROF_CALLGRAPH_CATEGORY_KERNEL], "#a51d2d");
|
||||||
gdk_rgba_parse (&category_colors[CATEGORY_LAYOUT], "#9141ac");
|
gdk_rgba_parse (&category_colors[SYSPROF_CALLGRAPH_CATEGORY_LAYOUT], "#9141ac");
|
||||||
gdk_rgba_parse (&category_colors[CATEGORY_MAIN_LOOP], "#5e5c64");
|
gdk_rgba_parse (&category_colors[SYSPROF_CALLGRAPH_CATEGORY_MAIN_LOOP], "#5e5c64");
|
||||||
gdk_rgba_parse (&category_colors[CATEGORY_PAINT], "#2ec27e");
|
gdk_rgba_parse (&category_colors[SYSPROF_CALLGRAPH_CATEGORY_PAINT], "#2ec27e");
|
||||||
gdk_rgba_parse (&category_colors[CATEGORY_SIGNALS], "#e5a50a");
|
gdk_rgba_parse (&category_colors[SYSPROF_CALLGRAPH_CATEGORY_SIGNALS], "#e5a50a");
|
||||||
gdk_rgba_parse (&category_colors[CATEGORY_TEMPLATES], "#77767b");
|
gdk_rgba_parse (&category_colors[SYSPROF_CALLGRAPH_CATEGORY_TEMPLATES], "#77767b");
|
||||||
gdk_rgba_parse (&category_colors[CATEGORY_WINDOWING], "#c64600");
|
gdk_rgba_parse (&category_colors[SYSPROF_CALLGRAPH_CATEGORY_WINDOWING], "#c64600");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
sysprof_category_icon_init (SysprofCategoryIcon *self)
|
sysprof_category_icon_init (SysprofCategoryIcon *self)
|
||||||
{
|
{
|
||||||
|
self->category = SYSPROF_CALLGRAPH_CATEGORY_UNCATEGORIZED;
|
||||||
}
|
}
|
||||||
|
|
||||||
SysprofSymbol *
|
SysprofCallgraphCategory
|
||||||
sysprof_category_icon_get_symbol (SysprofCategoryIcon *self)
|
sysprof_category_icon_get_category (SysprofCategoryIcon *self)
|
||||||
{
|
{
|
||||||
g_return_val_if_fail (SYSPROF_IS_CATEGORY_ICON (self), NULL);
|
g_return_val_if_fail (SYSPROF_IS_CATEGORY_ICON (self), 0);
|
||||||
|
|
||||||
return self->symbol;
|
return self->category;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
sysprof_category_icon_set_symbol (SysprofCategoryIcon *self,
|
sysprof_category_icon_set_category (SysprofCategoryIcon *self,
|
||||||
SysprofSymbol *symbol)
|
SysprofCallgraphCategory category)
|
||||||
{
|
{
|
||||||
g_return_if_fail (SYSPROF_IS_CATEGORY_ICON (self));
|
g_return_if_fail (SYSPROF_IS_CATEGORY_ICON (self));
|
||||||
|
g_return_if_fail (category > 0);
|
||||||
|
g_return_if_fail (category < SYSPROF_CALLGRAPH_CATEGORY_LAST);
|
||||||
|
|
||||||
if (g_set_object (&self->symbol, symbol))
|
if (self->category == category)
|
||||||
{
|
return;
|
||||||
self->category = symbol ? categorize_symbol (symbol) : 0;
|
|
||||||
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_SYMBOL]);
|
self->category = category;
|
||||||
gtk_widget_queue_draw (GTK_WIDGET (self));
|
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_CATEGORY]);
|
||||||
}
|
gtk_widget_queue_draw (GTK_WIDGET (self));
|
||||||
}
|
}
|
||||||
|
|||||||
@ -30,8 +30,8 @@ G_BEGIN_DECLS
|
|||||||
|
|
||||||
G_DECLARE_FINAL_TYPE (SysprofCategoryIcon, sysprof_category_icon, SYSPROF, CATEGORY_ICON, GtkWidget)
|
G_DECLARE_FINAL_TYPE (SysprofCategoryIcon, sysprof_category_icon, SYSPROF, CATEGORY_ICON, GtkWidget)
|
||||||
|
|
||||||
SysprofSymbol *sysprof_category_icon_get_symbol (SysprofCategoryIcon *self);
|
SysprofCallgraphCategory sysprof_category_icon_get_category (SysprofCategoryIcon *self);
|
||||||
void sysprof_category_icon_set_symbol (SysprofCategoryIcon *self,
|
void sysprof_category_icon_set_category (SysprofCategoryIcon *self,
|
||||||
SysprofSymbol *symbol);
|
SysprofCallgraphCategory category);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|||||||
Reference in New Issue
Block a user