From 386fe609fa8d232c8965cbf5a3b478c8d475a8de Mon Sep 17 00:00:00 2001 From: rdb Date: Tue, 29 Nov 2022 16:55:40 +0100 Subject: [PATCH] pstats: Show hierarchical parent of collector in flame graph Only when it's different from the nesting parent, and only if there's room. --- .../src/gtk-stats/gtkStatsFlameGraph.cxx | 20 +++++++++-- pandatool/src/gtk-stats/gtkStatsFlameGraph.h | 3 +- pandatool/src/pstatserver/pStatFlameGraph.cxx | 4 +-- pandatool/src/pstatserver/pStatFlameGraph.h | 3 +- .../src/win-stats/winStatsFlameGraph.cxx | 33 ++++++++++++++++--- pandatool/src/win-stats/winStatsFlameGraph.h | 3 +- 6 files changed, 53 insertions(+), 13 deletions(-) diff --git a/pandatool/src/gtk-stats/gtkStatsFlameGraph.cxx b/pandatool/src/gtk-stats/gtkStatsFlameGraph.cxx index 2e9476262e..08291038b8 100644 --- a/pandatool/src/gtk-stats/gtkStatsFlameGraph.cxx +++ b/pandatool/src/gtk-stats/gtkStatsFlameGraph.cxx @@ -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); diff --git a/pandatool/src/gtk-stats/gtkStatsFlameGraph.h b/pandatool/src/gtk-stats/gtkStatsFlameGraph.h index 9227e1ab45..7e29ac6bcc 100644 --- a/pandatool/src/gtk-stats/gtkStatsFlameGraph.h +++ b/pandatool/src/gtk-stats/gtkStatsFlameGraph.h @@ -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(); diff --git a/pandatool/src/pstatserver/pStatFlameGraph.cxx b/pandatool/src/pstatserver/pStatFlameGraph.cxx index e91c037a07..14274f28dc 100644 --- a/pandatool/src/pstatserver/pStatFlameGraph.cxx +++ b/pandatool/src/pstatserver/pStatFlameGraph.cxx @@ -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); } diff --git a/pandatool/src/pstatserver/pStatFlameGraph.h b/pandatool/src/pstatserver/pStatFlameGraph.h index 611f285ac5..f1efd96e11 100644 --- a/pandatool/src/pstatserver/pStatFlameGraph.h +++ b/pandatool/src/pstatserver/pStatFlameGraph.h @@ -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(); diff --git a/pandatool/src/win-stats/winStatsFlameGraph.cxx b/pandatool/src/win-stats/winStatsFlameGraph.cxx index e67da41eee..3b1f991dba 100644 --- a/pandatool/src/win-stats/winStatsFlameGraph.cxx +++ b/pandatool/src/win-stats/winStatsFlameGraph.cxx @@ -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); + } } } } diff --git a/pandatool/src/win-stats/winStatsFlameGraph.h b/pandatool/src/win-stats/winStatsFlameGraph.h index 5a7224bd87..950f046b17 100644 --- a/pandatool/src/win-stats/winStatsFlameGraph.h +++ b/pandatool/src/win-stats/winStatsFlameGraph.h @@ -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();