pstats: Show hierarchical parent of collector in flame graph

Only when it's different from the nesting parent, and only if there's room.
This commit is contained in:
rdb 2022-11-29 16:55:40 +01:00
parent 1fa446e183
commit 386fe609fa
6 changed files with 53 additions and 13 deletions

View File

@ -229,7 +229,7 @@ begin_draw() {
* indicated location.
*/
void GtkStatsFlameGraph::
draw_bar(int depth, int from_x, int to_x, int collector_index) {
draw_bar(int depth, int from_x, int to_x, int collector_index, int parent_index) {
double bottom = get_ysize() - depth * _pixel_scale * 5;
double top = bottom - _pixel_scale * 5;
@ -257,18 +257,32 @@ draw_bar(int depth, int from_x, int to_x, int collector_index) {
int right = std::min(to_x, get_xsize()) - _pixel_scale / 2;
const PStatClientData *client_data = GtkStatsGraph::_monitor->get_client_data();
const std::string &name = client_data->get_collector_name(collector_index);
const PStatCollectorDef &def = client_data->get_collector_def(collector_index);
// Choose a suitable foreground color.
LRGBColor fg = get_collector_text_color(collector_index, is_highlighted);
cairo_set_source_rgb(_cr, fg[0], fg[1], fg[2]);
PangoLayout *layout = gtk_widget_create_pango_layout(_graph_window, name.c_str());
PangoLayout *layout = gtk_widget_create_pango_layout(_graph_window, def._name.c_str());
pango_layout_set_attributes(layout, _pango_attrs);
pango_layout_set_ellipsize(layout, PANGO_ELLIPSIZE_END);
pango_layout_set_width(layout, (right - left) * PANGO_SCALE);
pango_layout_set_height(layout, -1);
if (!pango_layout_is_ellipsized(layout)) {
// We have room for more. Show the collector's actual parent, if it's
// different than the block it's shown above.
if (def._parent_index > 0 && def._parent_index != parent_index) {
const PStatCollectorDef &parent_def = client_data->get_collector_def(def._parent_index);
std::string long_name = parent_def._name + ":" + def._name;
pango_layout_set_text(layout, long_name.c_str(), long_name.size());
if (pango_layout_is_ellipsized(layout)) {
// Nope, it's too long, go back.
pango_layout_set_text(layout, def._name.c_str(), def._name.size());
}
}
}
int width, height;
pango_layout_get_pixel_size(layout, &width, &height);

View File

@ -46,7 +46,8 @@ protected:
void clear_region();
virtual void begin_draw();
virtual void draw_bar(int depth, int from_x, int to_x, int collector_index);
virtual void draw_bar(int depth, int from_x, int to_x,
int collector_index, int parent_index);
virtual void end_draw();
virtual void idle();

View File

@ -347,7 +347,7 @@ begin_draw() {
* indicated location.
*/
void PStatFlameGraph::
draw_bar(int depth, int from_x, int to_x, int collector_index) {
draw_bar(int depth, int from_x, int to_x, int collector_index, int parent_index) {
}
/**
@ -572,7 +572,7 @@ r_draw_level(const StackLevel &level, int depth, double offset) {
// No need to recurse if the bars have become smaller than a pixel.
if (to_x > from_x) {
draw_bar(depth, from_x, to_x, child._collector_index);
draw_bar(depth, from_x, to_x, child._collector_index, level._collector_index);
r_draw_level(child, depth + 1, offset);
}

View File

@ -70,7 +70,8 @@ protected:
virtual void normal_guide_bars();
virtual void begin_draw();
virtual void draw_bar(int depth, int from_x, int to_x, int collector_index);
virtual void draw_bar(int depth, int from_x, int to_x,
int collector_index, int parent_index);
virtual void end_draw();
virtual void idle();

View File

@ -232,7 +232,7 @@ begin_draw() {
* indicated location.
*/
void WinStatsFlameGraph::
draw_bar(int depth, int from_x, int to_x, int collector_index) {
draw_bar(int depth, int from_x, int to_x, int collector_index, int parent_index) {
int bottom = get_ysize() - 1 - depth * _pixel_scale * 5;
int top = bottom - _pixel_scale * 5;
@ -263,11 +263,34 @@ draw_bar(int depth, int from_x, int to_x, int collector_index) {
SetTextColor(_bitmap_dc, get_collector_text_color(collector_index, is_highlighted));
const PStatClientData *client_data = WinStatsGraph::_monitor->get_client_data();
const std::string &name = client_data->get_collector_name(collector_index);
const PStatCollectorDef &def = client_data->get_collector_def(collector_index);
RECT rect = {left, top, right, bottom};
DrawText(_bitmap_dc, name.data(), name.size(),
&rect, DT_LEFT | DT_END_ELLIPSIS | DT_SINGLELINE | DT_VCENTER);
SIZE size;
GetTextExtentPoint32(_bitmap_dc, def._name.data(), def._name.size(), &size);
if (size.cx < right - left) {
// We have room for more. Show the collector's actual parent, if it's
// different than the block it's shown above.
if (def._parent_index > 0 && def._parent_index != parent_index) {
const PStatCollectorDef &parent_def = client_data->get_collector_def(def._parent_index);
std::string long_name = parent_def._name + ":" + def._name;
SIZE long_size;
GetTextExtentPoint32(_bitmap_dc, long_name.data(), long_name.size(), &long_size);
if (long_size.cx < right - left) {
TextOut(_bitmap_dc, left, top + (bottom - top - long_size.cy) / 2,
long_name.data(), long_name.length());
return;
}
}
TextOut(_bitmap_dc, left, top + (bottom - top - size.cy) / 2,
def._name.data(), def._name.length());
} else {
// Let Windows figure out how to fit it, with ellipsis if necessary.
RECT rect = {left, top, right, bottom};
DrawText(_bitmap_dc, def._name.data(), def._name.size(),
&rect, DT_LEFT | DT_END_ELLIPSIS | DT_SINGLELINE | DT_VCENTER);
}
}
}
}

View File

@ -47,7 +47,8 @@ protected:
void clear_region();
virtual void begin_draw();
virtual void draw_bar(int depth, int from_x, int to_x, int collector_index);
virtual void draw_bar(int depth, int from_x, int to_x,
int collector_index, int parent_index);
virtual void end_draw();
virtual void idle();