diff --git a/profiler_gui/blocks_graphics_view.cpp b/profiler_gui/blocks_graphics_view.cpp index b2a10ab..ed54108 100644 --- a/profiler_gui/blocks_graphics_view.cpp +++ b/profiler_gui/blocks_graphics_view.cpp @@ -244,7 +244,7 @@ void EasyTimelineIndicatorItem::paint(QPainter* _painter, const QStyleOptionGrap const auto sceneView = static_cast(scene()->parent()); const auto visibleSceneRect = sceneView->visibleSceneRect(); const auto step = sceneView->timelineStep() * sceneView->scale(); - const QString text = ::profiler_gui::timeStringInt(units2microseconds(sceneView->timelineStep())); // Displayed text + const QString text = ::profiler_gui::timeStringInt(EASY_GLOBALS.time_units, units2microseconds(sceneView->timelineStep())); // Displayed text // Draw scale indicator _painter->save(); @@ -910,6 +910,7 @@ void EasyGraphicsView::mouseReleaseEvent(QMouseEvent* _event) changedSelectedItem = true; selectedBlock = block; EASY_GLOBALS.selected_block = i; + EASY_GLOBALS.selected_block_id = easyBlock(i).tree.node->id(); break; } } @@ -918,6 +919,7 @@ void EasyGraphicsView::mouseReleaseEvent(QMouseEvent* _event) { changedSelectedItem = true; ::profiler_gui::set_max(EASY_GLOBALS.selected_block); + ::profiler_gui::set_max(EASY_GLOBALS.selected_block_id); } } } @@ -1191,7 +1193,8 @@ void EasyGraphicsView::initMode() connect(globalSignals, &::profiler_gui::EasyGlobalSignals::hierarchyFlagChanged, this, &This::onHierarchyFlagChange); connect(globalSignals, &::profiler_gui::EasyGlobalSignals::selectedThreadChanged, this, &This::onSelectedThreadChange); connect(globalSignals, &::profiler_gui::EasyGlobalSignals::selectedBlockChanged, this, &This::onSelectedBlockChange); - connect(globalSignals, &::profiler_gui::EasyGlobalSignals::itemsExpandStateChanged, this, &This::onItemsExpandStateChange); + connect(globalSignals, &::profiler_gui::EasyGlobalSignals::itemsExpandStateChanged, this, &This::onRefreshRequired); + connect(globalSignals, &::profiler_gui::EasyGlobalSignals::refreshRequired, this, &This::onRefreshRequired); } ////////////////////////////////////////////////////////////////////////// @@ -1311,7 +1314,7 @@ void EasyGraphicsView::onIdleTimeout() if (itemDesc.type() == ::profiler::BLOCK_TYPE_BLOCK) { lay->addRow("Block:", new QLabel(name)); - lay->addRow("Duration:", new QLabel(::profiler_gui::timeStringReal(PROF_MICROSECONDS(itemBlock.node->duration()), 3))); + lay->addRow("Duration:", new QLabel(::profiler_gui::timeStringRealNs(EASY_GLOBALS.time_units, itemBlock.node->duration(), 3))); } else { @@ -1357,7 +1360,7 @@ void EasyGraphicsView::onIdleTimeout() else lay->addRow("Thread:", new QLabel(QString::number(cse->tree.node->id()))); lay->addRow("Process:", new QLabel(cse->tree.node->name())); - lay->addRow("Duration:", new QLabel(::profiler_gui::timeStringReal(PROF_MICROSECONDS(cse->tree.node->duration()), 3))); + lay->addRow("Duration:", new QLabel(::profiler_gui::timeStringRealNs(EASY_GLOBALS.time_units, cse->tree.node->duration(), 3))); m_csInfoWidget = new QGraphicsProxyWidget(); m_csInfoWidget->setWidget(widget); @@ -1502,7 +1505,7 @@ void EasyGraphicsView::onSelectedBlockChange(unsigned int _block_index) ////////////////////////////////////////////////////////////////////////// -void EasyGraphicsView::onItemsExpandStateChange() +void EasyGraphicsView::onRefreshRequired() { if (!m_bUpdatingRect) { @@ -1642,7 +1645,7 @@ void EasyThreadNameItem::paint(QPainter* _painter, const QStyleOptionGraphicsIte { if (time > 0) { - const QString text = ::profiler_gui::timeStringReal(time); // Displayed text + const QString text = ::profiler_gui::autoTimeStringReal(time); // Displayed text const auto th = fm.height(); // Calculate displayed text height rect.setRect(0, y, w, th); diff --git a/profiler_gui/blocks_graphics_view.h b/profiler_gui/blocks_graphics_view.h index d39f011..db86078 100644 --- a/profiler_gui/blocks_graphics_view.h +++ b/profiler_gui/blocks_graphics_view.h @@ -199,7 +199,7 @@ private slots: void onHierarchyFlagChange(bool _value); void onSelectedThreadChange(::profiler::thread_id_t _id); void onSelectedBlockChange(unsigned int _block_index); - void onItemsExpandStateChange(); + void onRefreshRequired(); public: diff --git a/profiler_gui/blocks_tree_widget.cpp b/profiler_gui/blocks_tree_widget.cpp index 41aabd5..f7de000 100644 --- a/profiler_gui/blocks_tree_widget.cpp +++ b/profiler_gui/blocks_tree_widget.cpp @@ -102,7 +102,7 @@ EasyTreeWidget::EasyTreeWidget(QWidget* _parent) setItemsExpandable(true); setAnimated(true); setSortingEnabled(false); - setColumnCount(COL_COLUMNS_NUMBER); + setColumnCount(COL_COLUMNS_NUMBER); auto header_item = new QTreeWidgetItem(); auto f = header()->font(); @@ -639,6 +639,10 @@ void EasyTreeWidget::onJumpToItemClicked(bool) auto block_index = action->data().toUInt(); EASY_GLOBALS.selected_block = block_index; + if (block_index < EASY_GLOBALS.gui_blocks.size()) + EASY_GLOBALS.selected_block_id = easyBlock(block_index).tree.node->id(); + else + ::profiler_gui::set_max(EASY_GLOBALS.selected_block_id); emit EASY_GLOBALS.events.selectedBlockChanged(block_index); } @@ -762,12 +766,33 @@ void EasyTreeWidget::onItemCollapse(QTreeWidgetItem* _item) ////////////////////////////////////////////////////////////////////////// -void EasyTreeWidget::onCurrentItemChange(QTreeWidgetItem* _item, QTreeWidgetItem*) +void EasyTreeWidget::onCurrentItemChange(QTreeWidgetItem* _item, QTreeWidgetItem* _previous) { + if (_previous != nullptr) + { + auto f = font(); + for (int i = 0; i < COL_COLUMNS_NUMBER; ++i) + _previous->setFont(i, f); + } + if (_item == nullptr) + { ::profiler_gui::set_max(EASY_GLOBALS.selected_block); + ::profiler_gui::set_max(EASY_GLOBALS.selected_block_id); + } else + { + auto f = font(); + f.setBold(true); + for (int i = 0; i < COL_COLUMNS_NUMBER; ++i) + _item->setFont(i, f); + EASY_GLOBALS.selected_block = static_cast(_item)->block_index(); + if (EASY_GLOBALS.selected_block < EASY_GLOBALS.gui_blocks.size()) + EASY_GLOBALS.selected_block_id = easyBlock(EASY_GLOBALS.selected_block).tree.node->id(); + else + ::profiler_gui::set_max(EASY_GLOBALS.selected_block_id); + } disconnect(&EASY_GLOBALS.events, &::profiler_gui::EasyGlobalSignals::selectedBlockChanged, this, &This::onSelectedBlockChange); emit EASY_GLOBALS.events.selectedBlockChanged(EASY_GLOBALS.selected_block); @@ -826,6 +851,10 @@ void EasyTreeWidget::onSelectedBlockChange(uint32_t _block_index) if (item != nullptr) { //const QSignalBlocker b(this); + auto previous = currentItem(); + auto f = font(); + if (previous != nullptr) for (int i = 0; i < COL_COLUMNS_NUMBER; ++i) + previous->setFont(i, f); if (EASY_GLOBALS.bind_scene_and_tree_expand_status) { @@ -849,9 +878,21 @@ void EasyTreeWidget::onSelectedBlockChange(uint32_t _block_index) resizeColumnsToContents(); connect(this, &Parent::itemExpanded, this, &This::onItemExpand); } + + f.setBold(true); + for (int i = 0; i < COL_COLUMNS_NUMBER; ++i) + item->setFont(i, f); } else { + auto previous = currentItem(); + if (previous != nullptr) + { + auto f = font(); + for (int i = 0; i < COL_COLUMNS_NUMBER; ++i) + previous->setFont(i, f); + } + setCurrentItem(item); } @@ -894,11 +935,9 @@ void EasyTreeWidget::loadSettings() if (!color_rows_set.isNull()) m_bColorRows = color_rows_set.toBool(); - for (int i = 0; i < columnCount(); i++) - { - if (settings.value(QString("Column") + QString::number(i)).toBool()) - hideColumn(i); - } + auto state = settings.value("headerState").toByteArray(); + if (!state.isEmpty()) + header()->restoreState(state); settings.endGroup(); } @@ -907,14 +946,8 @@ void EasyTreeWidget::saveSettings() { QSettings settings(::profiler_gui::ORGANAZATION_NAME, ::profiler_gui::APPLICATION_NAME); settings.beginGroup("tree_widget"); - settings.setValue("color_rows", m_bColorRows); - - for (int i = 0; i < columnCount(); i++) - { - settings.setValue(QString("Column") + QString::number(i) , isColumnHidden(i)); - } - + settings.setValue("headerState", header()->saveState()); settings.endGroup(); } diff --git a/profiler_gui/common_types.h b/profiler_gui/common_types.h index 920b0cc..47a0d33 100644 --- a/profiler_gui/common_types.h +++ b/profiler_gui/common_types.h @@ -140,6 +140,11 @@ inline bool isLightColor(::profiler::color_t _color, qreal _maxSum) return sum < _maxSum || ((_color & 0xff000000) >> 24) < 0x80; } +inline ::profiler::color_t textColorForFlag(bool _is_light) +{ + return _is_light ? ::profiler::colors::Dark : ::profiler::colors::CreamWhite; +} + inline ::profiler::color_t textColorForRgb(::profiler::color_t _color) { return isLightColor(_color) ? ::profiler::colors::Dark : ::profiler::colors::CreamWhite; @@ -223,6 +228,15 @@ typedef ::std::vector TreeBlocks; ////////////////////////////////////////////////////////////////////////// +enum TimeUnits : int8_t +{ + TimeUnits_ms = 0, + TimeUnits_us, + TimeUnits_ns, + TimeUnits_auto + +}; // END of enum TimeUnits. + inline qreal timeFactor(qreal _interval) { if (_interval < 1) // interval in nanoseconds @@ -238,10 +252,10 @@ inline qreal timeFactor(qreal _interval) return 1e-6; } -inline QString timeStringReal(qreal _interval, int _precision = 1) +inline QString autoTimeStringReal(qreal _interval, int _precision = 1) { if (_interval < 1) // interval in nanoseconds - return QString("%1 ns").arg(static_cast(_interval * 1e3)); + return QString("%1 ns").arg(static_cast(_interval * 1e3)); if (_interval < 1e3) // interval in microseconds return QString("%1 us").arg(_interval, 0, 'f', _precision); @@ -250,22 +264,140 @@ inline QString timeStringReal(qreal _interval, int _precision = 1) return QString("%1 ms").arg(_interval * 1e-3, 0, 'f', _precision); // interval in seconds - return QString("%1 sec").arg(_interval * 1e-6, 0, 'f', _precision); + return QString("%1 s").arg(_interval * 1e-6, 0, 'f', _precision); } -inline QString timeStringInt(qreal _interval) +inline QString autoTimeStringInt(qreal _interval) { if (_interval < 1) // interval in nanoseconds - return QString("%1 ns").arg(static_cast(_interval * 1e3)); + return QString("%1 ns").arg(static_cast(_interval * 1e3)); if (_interval < 1e3) // interval in microseconds - return QString("%1 us").arg(static_cast(_interval)); + return QString("%1 us").arg(static_cast(_interval)); if (_interval < 1e6) // interval in milliseconds - return QString("%1 ms").arg(static_cast(_interval * 1e-3)); + return QString("%1 ms").arg(static_cast(_interval * 1e-3)); // interval in seconds - return QString("%1 sec").arg(static_cast(_interval * 1e-6)); + return QString("%1 s").arg(static_cast(_interval * 1e-6)); +} + +inline QString autoTimeStringRealNs(::profiler::timestamp_t _interval, int _precision = 1) +{ + if (_interval < 1000) // interval in nanoseconds + return QString("%1 ns").arg(_interval); + + if (_interval < 1000000) // interval in microseconds + return QString("%1 us").arg(_interval * 1e-3, 0, 'f', _precision); + + if (_interval < 1000000000U) // interval in milliseconds + return QString("%1 ms").arg(_interval * 1e-6, 0, 'f', _precision); + + // interval in seconds + return QString("%1 s").arg(_interval * 1e-9, 0, 'f', _precision); +} + +inline QString autoTimeStringIntNs(::profiler::timestamp_t _interval) +{ + if (_interval < 1000) // interval in nanoseconds + return QString("%1 ns").arg(_interval); + + if (_interval < 1000000) // interval in microseconds + return QString("%1 us").arg(static_cast(_interval * 1e-3)); + + if (_interval < 1000000000U) // interval in milliseconds + return QString("%1 ms").arg(static_cast(_interval * 1e-6)); + + // interval in seconds + return QString("%1 s").arg(static_cast(_interval * 1e-9)); +} + +inline QString timeStringReal(TimeUnits _units, qreal _interval, int _precision = 1) +{ + switch (_units) + { + case TimeUnits_ms:{ + const char fmt = _interval <= 1 ? 'g' : 'f'; + return QString("%1 ms").arg(_interval * 1e-3, 0, fmt, _precision); + } + + case TimeUnits_us: + return QString("%1 us").arg(_interval, 0, 'f', _precision); + + case TimeUnits_ns: + return QString("%1 ns").arg(static_cast(_interval * 1e3)); + + case TimeUnits_auto: + default: + return autoTimeStringReal(_interval, _precision); + } + + return QString(); +} + +inline QString timeStringRealNs(TimeUnits _units, ::profiler::timestamp_t _interval, int _precision = 1) +{ + switch (_units) + { + case TimeUnits_ms:{ + const char fmt = _interval <= 1000 ? 'g' : 'f'; + return QString("%1 ms").arg(_interval * 1e-6, 0, fmt, _precision); + } + + case TimeUnits_us: + return QString("%1 us").arg(_interval * 1e-3, 0, 'f', _precision); + + case TimeUnits_ns: + return QString("%1 ns").arg(_interval); + + case TimeUnits_auto: + default: + return autoTimeStringRealNs(_interval, _precision); + } + + return QString(); +} + +inline QString timeStringInt(TimeUnits _units, qreal _interval) +{ + switch (_units) + { + case TimeUnits_ms: + return QString("%1 ms").arg(static_cast(_interval * 1e-3)); + + case TimeUnits_us: + return QString("%1 us").arg(static_cast(_interval)); + + case TimeUnits_ns: + return QString("%1 ns").arg(static_cast(_interval * 1e3)); + + case TimeUnits_auto: + default: + return autoTimeStringInt(_interval); + } + + return QString(); +} + +inline QString timeStringIntNs(TimeUnits _units, ::profiler::timestamp_t _interval) +{ + switch (_units) + { + case TimeUnits_ms: + return QString("%1 ms").arg(static_cast(_interval * 1e-6)); + + case TimeUnits_us: + return QString("%1 us").arg(static_cast(_interval * 1e-3)); + + case TimeUnits_ns: + return QString("%1 ns").arg(_interval); + + case TimeUnits_auto: + default: + return autoTimeStringIntNs(_interval); + } + + return QString(); } ////////////////////////////////////////////////////////////////////////// @@ -282,6 +414,10 @@ template inline void set_max(T& _value) { _value = ::std::numeric_limits::max(); } +template inline bool is_max(const T& _value) { + return _value == ::std::numeric_limits::max(); +} + ////////////////////////////////////////////////////////////////////////// inline double percentReal(::profiler::timestamp_t _partial, ::profiler::timestamp_t _total) diff --git a/profiler_gui/descriptors_tree_widget.cpp b/profiler_gui/descriptors_tree_widget.cpp index da2a916..59d1827 100644 --- a/profiler_gui/descriptors_tree_widget.cpp +++ b/profiler_gui/descriptors_tree_widget.cpp @@ -226,6 +226,12 @@ EasyDescTreeWidget::EasyDescTreeWidget(QWidget* _parent) EasyDescTreeWidget::~EasyDescTreeWidget() { + if (::profiler_gui::is_max(EASY_GLOBALS.selected_block) && !::profiler_gui::is_max(EASY_GLOBALS.selected_block_id)) + { + ::profiler_gui::set_max(EASY_GLOBALS.selected_block_id); + emit EASY_GLOBALS.events.refreshRequired(); + } + saveSettings(); } @@ -466,6 +472,21 @@ void EasyDescTreeWidget::onCurrentItemChange(QTreeWidgetItem* _item, QTreeWidget f.setBold(true); for (int i = 0; i < DESC_COL_STATUS; ++i) _item->setFont(i, f); + + if (::profiler_gui::is_max(EASY_GLOBALS.selected_block) && _item->parent() != nullptr) + { + const auto id = static_cast(_item)->desc(); + if (EASY_GLOBALS.selected_block_id != id) + { + EASY_GLOBALS.selected_block_id = id; + emit EASY_GLOBALS.events.refreshRequired(); + } + } + } + else if (::profiler_gui::is_max(EASY_GLOBALS.selected_block) && !::profiler_gui::is_max(EASY_GLOBALS.selected_block_id)) + { + ::profiler_gui::set_max(EASY_GLOBALS.selected_block_id); + emit EASY_GLOBALS.events.refreshRequired(); } } diff --git a/profiler_gui/easy_chronometer_item.cpp b/profiler_gui/easy_chronometer_item.cpp index bfc1e16..6628f0c 100644 --- a/profiler_gui/easy_chronometer_item.cpp +++ b/profiler_gui/easy_chronometer_item.cpp @@ -138,7 +138,7 @@ void EasyChronometerItem::paint(QPainter* _painter, const QStyleOptionGraphicsIt QRectF rect((m_left - offset) * currentScale, visibleSceneRect.top(), ::std::max(selectedInterval * currentScale, 1.0), visibleSceneRect.height()); selectedInterval = units2microseconds(selectedInterval); - const QString text = ::profiler_gui::timeStringReal(selectedInterval); // Displayed text + const QString text = ::profiler_gui::timeStringReal(EASY_GLOBALS.time_units, selectedInterval); // Displayed text const auto textRect = QFontMetricsF(CHRONOMETER_FONT, sceneView).boundingRect(text); // Calculate displayed text boundingRect const auto rgb = m_color.rgb() & 0x00ffffff; @@ -169,7 +169,16 @@ void EasyChronometerItem::paint(QPainter* _painter, const QStyleOptionGraphicsIt // draw left and right borders _painter->setBrush(Qt::NoBrush); - _painter->setPen(QColor::fromRgba(0xd0000000 | rgb)); + if (m_bMain && !m_bReverse) + { + QPen p(QColor::fromRgba(0xd0000000 | rgb)); + p.setStyle(Qt::DotLine); + _painter->setPen(p); + } + else + { + _painter->setPen(QColor::fromRgba(0xd0000000 | rgb)); + } if (m_left > sceneLeft) _painter->drawLine(QPointF(rect.left(), rect.top()), QPointF(rect.left(), rect.bottom())); diff --git a/profiler_gui/easy_graphics_item.cpp b/profiler_gui/easy_graphics_item.cpp index e3b6026..9f17b2c 100644 --- a/profiler_gui/easy_graphics_item.cpp +++ b/profiler_gui/easy_graphics_item.cpp @@ -63,13 +63,19 @@ enum BlockItemState : int8_t ////////////////////////////////////////////////////////////////////////// const int MIN_SYNC_SPACING = 1; -const QRgb BORDERS_COLOR = ::profiler::colors::Grey700 & 0x00ffffff;// 0x00686868; +const QRgb BORDERS_COLOR = ::profiler::colors::Grey600 & 0x00ffffff;// 0x00686868; inline QRgb selectedItemBorderColor(::profiler::color_t _color) { return ::profiler_gui::isLightColor(_color, 192) ? ::profiler::colors::Black : ::profiler::colors::RichRed; - //return ::profiler::colors::Black; } +inline QRgb highlightItemColor(bool _is_light) { + return _is_light ? ::profiler::colors::RichRed : ::profiler::colors::White; +} + +#define HIGHLIGHT_COLOR(_is_light) ::profiler::colors::White +//#define HIGHLIGHT_COLOR(_is_light) highlightItemColor(_is_light) + const auto ITEMS_FONT = ::profiler_gui::EFont("Helvetica", 10, QFont::Medium); const auto SELECTED_ITEM_FONT = ::profiler_gui::EFont("Helvetica", 10, QFont::Bold); @@ -142,6 +148,7 @@ void EasyGraphicsItem::paint(QPainter* _painter, const QStyleOptionGraphicsItem* QBrush brush; QRgb previousColor = 0, inverseColor = 0xffffffff, textColor = 0; Qt::PenStyle previousPenStyle = Qt::NoPen; + bool is_light = false; brush.setStyle(Qt::SolidPattern); _painter->save(); @@ -343,16 +350,33 @@ void EasyGraphicsItem::paint(QPainter* _painter, const QStyleOptionGraphicsItem* // Set background color brush for rectangle previousColor = itemDesc.color(); inverseColor = 0xffffffff - previousColor; - textColor = ::profiler_gui::textColorForRgb(previousColor); + is_light = ::profiler_gui::isLightColor(previousColor); + textColor = ::profiler_gui::textColorForFlag(is_light); brush.setColor(previousColor); _painter->setBrush(brush); } - if (EASY_GLOBALS.draw_graphics_items_borders && (previousPenStyle != Qt::SolidLine || colorChange)) + if (EASY_GLOBALS.highlight_blocks_with_same_id && EASY_GLOBALS.selected_block_id == itemDesc.id()) { - // Restore pen for item which is wide enough to paint borders - previousPenStyle = Qt::SolidLine; - _painter->setPen(BORDERS_COLOR & inverseColor);// BORDERS_COLOR); + if (previousPenStyle != Qt::DotLine) + { + previousPenStyle = Qt::DotLine; + _painter->setPen(HIGHLIGHT_COLOR(is_light)); + } + } + else if (EASY_GLOBALS.draw_graphics_items_borders) + { + if (previousPenStyle != Qt::SolidLine)// || colorChange) + { + // Restore pen for item which is wide enough to paint borders + previousPenStyle = Qt::SolidLine; + _painter->setPen(BORDERS_COLOR);//BORDERS_COLOR & inverseColor); + } + } + else if (previousPenStyle != Qt::NoPen) + { + previousPenStyle = Qt::NoPen; + _painter->setPen(Qt::NoPen); } if (w < EASY_GLOBALS.blocks_size_min) @@ -383,16 +407,33 @@ void EasyGraphicsItem::paint(QPainter* _painter, const QStyleOptionGraphicsItem* // Set background color brush for rectangle previousColor = itemDesc.color(); inverseColor = 0xffffffff - previousColor; - textColor = ::profiler_gui::textColorForRgb(previousColor); + is_light = ::profiler_gui::isLightColor(previousColor); + textColor = ::profiler_gui::textColorForFlag(is_light); brush.setColor(previousColor); _painter->setBrush(brush); } - if (EASY_GLOBALS.draw_graphics_items_borders && (previousPenStyle != Qt::SolidLine || colorChange)) + if (EASY_GLOBALS.highlight_blocks_with_same_id && EASY_GLOBALS.selected_block_id == itemDesc.id()) { - // Restore pen for item which is wide enough to paint borders - previousPenStyle = Qt::SolidLine; - _painter->setPen(BORDERS_COLOR & inverseColor);// BORDERS_COLOR); + if (previousPenStyle != Qt::DotLine) + { + previousPenStyle = Qt::DotLine; + _painter->setPen(HIGHLIGHT_COLOR(is_light)); + } + } + else if (EASY_GLOBALS.draw_graphics_items_borders) + { + if (previousPenStyle != Qt::SolidLine)// || colorChange) + { + // Restore pen for item which is wide enough to paint borders + previousPenStyle = Qt::SolidLine; + _painter->setPen(BORDERS_COLOR);// BORDERS_COLOR & inverseColor); + } + } + else if (previousPenStyle != Qt::NoPen) + { + previousPenStyle = Qt::NoPen; + _painter->setPen(Qt::NoPen); } // Draw rectangle @@ -441,7 +482,7 @@ void EasyGraphicsItem::paint(QPainter* _painter, const QStyleOptionGraphicsItem* // text will be painted with inverse color //auto textColor = inverseColor < 0x00808080 ? profiler::colors::Black : profiler::colors::White; //if (textColor == previousColor) textColor = 0; - _painter->setPen(QColor::fromRgb(textColor)); + _painter->setPen(textColor); if (item.block == EASY_GLOBALS.selected_block) _painter->setFont(SELECTED_ITEM_FONT); @@ -453,8 +494,12 @@ void EasyGraphicsItem::paint(QPainter* _painter, const QStyleOptionGraphicsItem* // restore previous pen color if (previousPenStyle == Qt::NoPen) _painter->setPen(Qt::NoPen); + else if (previousPenStyle == Qt::DotLine) + { + _painter->setPen(HIGHLIGHT_COLOR(is_light)); + } else - _painter->setPen(BORDERS_COLOR & inverseColor);// BORDERS_COLOR); // restore pen for rectangle painting + _painter->setPen(BORDERS_COLOR);// BORDERS_COLOR & inverseColor); // restore pen for rectangle painting // restore font if (item.block == EASY_GLOBALS.selected_block) diff --git a/profiler_gui/globals.cpp b/profiler_gui/globals.cpp index 4425f2d..cfab6bf 100644 --- a/profiler_gui/globals.cpp +++ b/profiler_gui/globals.cpp @@ -60,11 +60,13 @@ namespace profiler_gui { EasyGlobals::EasyGlobals() : selected_thread(0U) , selected_block(::profiler_gui::numeric_max()) - , chrono_text_position(ChronoTextPosition_Center) + , selected_block_id(::profiler_gui::numeric_max()) , frame_time(4e4f) , blocks_spacing(2) , blocks_size_min(3) , blocks_narrow_size(20) + , chrono_text_position(ChronoTextPosition_Center) + , time_units(TimeUnits_auto) , connected(false) , enable_event_indicators(true) , enable_statistics(true) @@ -76,6 +78,7 @@ namespace profiler_gui { , collapse_items_on_tree_close(false) , all_items_expanded_by_default(true) , only_current_thread_hierarchy(false) + , highlight_blocks_with_same_id(true) , bind_scene_and_tree_expand_status(true) { diff --git a/profiler_gui/globals.h b/profiler_gui/globals.h index 9e6ea82..1dc1fc0 100644 --- a/profiler_gui/globals.h +++ b/profiler_gui/globals.h @@ -90,7 +90,7 @@ namespace profiler_gui { ////////////////////////////////////////////////////////////////////////// - enum ChronometerTextPosition + enum ChronometerTextPosition : int8_t { ChronoTextPosition_Center = 0, ChronoTextPosition_Top, @@ -110,11 +110,13 @@ namespace profiler_gui { EasyBlocks gui_blocks; ///< Profiler graphics blocks builded by GUI ::profiler::thread_id_t selected_thread; ///< Current selected thread id ::profiler::block_index_t selected_block; ///< Current selected profiler block index - ChronometerTextPosition chrono_text_position; ///< Selected interval text position + ::profiler::block_id_t selected_block_id; ///< Current selected profiler block id float frame_time; ///< Value in microseconds to be displayed at minimap on graphics scrollbar int blocks_spacing; ///< Minimum blocks spacing on diagram int blocks_size_min; ///< Minimum blocks size on diagram int blocks_narrow_size; ///< Width indicating narrow blocks + ChronometerTextPosition chrono_text_position; ///< Selected interval text position + TimeUnits time_units; ///< Units type for time (milliseconds, microseconds, nanoseconds or auto-definition) bool connected; ///< Is connected to source (to be able to capture profiling information) bool enable_event_indicators; ///< Enable event indicators painting (These are narrow rectangles at the bottom of each thread) bool enable_statistics; ///< Enable gathering and using statistics (Disable if you want to consume less memory) @@ -126,6 +128,7 @@ namespace profiler_gui { bool collapse_items_on_tree_close; ///< Collapse all items which were displayed in the hierarchy tree after tree close/reset bool all_items_expanded_by_default; ///< Expand all items after file is opened bool only_current_thread_hierarchy; ///< Build hierarchy tree for current thread only + bool highlight_blocks_with_same_id; ///< Highlight all blocks with same id on diagram bool bind_scene_and_tree_expand_status; /** \brief If true then items on graphics scene and in the tree (blocks hierarchy) are binded on each other so expanding/collapsing items on scene also expands/collapse items in the tree. */ diff --git a/profiler_gui/globals_qobjects.h b/profiler_gui/globals_qobjects.h index f83085d..a5b2792 100644 --- a/profiler_gui/globals_qobjects.h +++ b/profiler_gui/globals_qobjects.h @@ -55,6 +55,7 @@ namespace profiler_gui { void blocksRefreshRequired(bool); void timelineMarkerChanged(); void hierarchyFlagChanged(bool); + void refreshRequired(); }; // END of class EasyGlobalSignals. diff --git a/profiler_gui/main_window.cpp b/profiler_gui/main_window.cpp index 15bd9f4..31c58a9 100644 --- a/profiler_gui/main_window.cpp +++ b/profiler_gui/main_window.cpp @@ -275,6 +275,11 @@ EasyMainWindow::EasyMainWindow() : Parent(), m_lastAddress("127.0.0.1"), m_lastP action->setChecked(EASY_GLOBALS.enable_zero_length); connect(action, &QAction::triggered, [this](bool _checked){ EASY_GLOBALS.enable_zero_length = _checked; refreshDiagram(); }); + action = submenu->addAction("Highlight similar blocks"); + action->setCheckable(true); + action->setChecked(EASY_GLOBALS.highlight_blocks_with_same_id); + connect(action, &QAction::triggered, [this](bool _checked){ EASY_GLOBALS.highlight_blocks_with_same_id = _checked; refreshDiagram(); }); + action = submenu->addAction("Collapse items on tree reset"); action->setCheckable(true); action->setChecked(EASY_GLOBALS.collapse_items_on_tree_close); @@ -370,6 +375,42 @@ EasyMainWindow::EasyMainWindow() : Parent(), m_lastAddress("127.0.0.1"), m_lastP submenu->addAction(waction); + submenu = menu->addMenu("Units"); + actionGroup = new QActionGroup(this); + actionGroup->setExclusive(true); + action = new QAction("Auto", actionGroup); + action->setCheckable(true); + action->setData(static_cast(::profiler_gui::TimeUnits_auto)); + if (EASY_GLOBALS.time_units == ::profiler_gui::TimeUnits_auto) + action->setChecked(true); + submenu->addAction(action); + connect(action, &QAction::triggered, this, &This::onUnitsChanged); + + action = new QAction("Milliseconds", actionGroup); + action->setCheckable(true); + action->setData(static_cast(::profiler_gui::TimeUnits_ms)); + if (EASY_GLOBALS.time_units == ::profiler_gui::TimeUnits_ms) + action->setChecked(true); + submenu->addAction(action); + connect(action, &QAction::triggered, this, &This::onUnitsChanged); + + action = new QAction("Microseconds", actionGroup); + action->setCheckable(true); + action->setData(static_cast(::profiler_gui::TimeUnits_us)); + if (EASY_GLOBALS.time_units == ::profiler_gui::TimeUnits_us) + action->setChecked(true); + submenu->addAction(action); + connect(action, &QAction::triggered, this, &This::onUnitsChanged); + + action = new QAction("Nanoseconds", actionGroup); + action->setCheckable(true); + action->setData(static_cast(::profiler_gui::TimeUnits_ns)); + if (EASY_GLOBALS.time_units == ::profiler_gui::TimeUnits_ns) + action->setChecked(true); + submenu->addAction(action); + connect(action, &QAction::triggered, this, &This::onUnitsChanged); + + submenu = menu->addMenu("Remote"); m_eventTracingEnableAction = submenu->addAction("Event tracing enabled"); m_eventTracingEnableAction->setCheckable(true); @@ -609,6 +650,7 @@ void EasyMainWindow::clear() EASY_GLOBALS.selected_thread = 0; ::profiler_gui::set_max(EASY_GLOBALS.selected_block); + ::profiler_gui::set_max(EASY_GLOBALS.selected_block_id); EASY_GLOBALS.profiler_blocks.clear(); EASY_GLOBALS.descriptors.clear(); EASY_GLOBALS.gui_blocks.clear(); @@ -662,6 +704,12 @@ void EasyMainWindow::onChronoTextPosChanged(bool) refreshDiagram(); } +void EasyMainWindow::onUnitsChanged(bool) +{ + auto _sender = qobject_cast(sender()); + EASY_GLOBALS.time_units = static_cast<::profiler_gui::TimeUnits>(_sender->data().toInt()); +} + void EasyMainWindow::onEventIndicatorsChange(bool _checked) { EASY_GLOBALS.enable_event_indicators = _checked; @@ -843,6 +891,10 @@ void EasyMainWindow::loadSettings() if (!val.isNull()) EASY_GLOBALS.chrono_text_position = static_cast<::profiler_gui::ChronometerTextPosition>(val.toInt()); + val = settings.value("time_units"); + if (!val.isNull()) + EASY_GLOBALS.time_units = static_cast<::profiler_gui::TimeUnits>(val.toInt()); + val = settings.value("frame_time"); if (!val.isNull()) @@ -889,6 +941,11 @@ void EasyMainWindow::loadSettings() if (!flag.isNull()) EASY_GLOBALS.add_zero_blocks_to_hierarchy = flag.toBool(); + + flag = settings.value("highlight_blocks_with_same_id"); + if (!flag.isNull()) + EASY_GLOBALS.highlight_blocks_with_same_id = flag.toBool(); + flag = settings.value("bind_scene_and_tree_expand_status"); if (!flag.isNull()) EASY_GLOBALS.bind_scene_and_tree_expand_status = flag.toBool(); @@ -936,6 +993,7 @@ void EasyMainWindow::saveSettingsAndGeometry() settings.setValue("ip_address", m_lastAddress); settings.setValue("port", (quint32)m_lastPort); settings.setValue("chrono_text_position", static_cast(EASY_GLOBALS.chrono_text_position)); + settings.setValue("time_units", static_cast(EASY_GLOBALS.time_units)); settings.setValue("frame_time", EASY_GLOBALS.frame_time); settings.setValue("blocks_spacing", EASY_GLOBALS.blocks_spacing); settings.setValue("blocks_size_min", EASY_GLOBALS.blocks_size_min); @@ -947,6 +1005,7 @@ void EasyMainWindow::saveSettingsAndGeometry() settings.setValue("only_current_thread_hierarchy", EASY_GLOBALS.only_current_thread_hierarchy); settings.setValue("enable_zero_length", EASY_GLOBALS.enable_zero_length); settings.setValue("add_zero_blocks_to_hierarchy", EASY_GLOBALS.add_zero_blocks_to_hierarchy); + settings.setValue("highlight_blocks_with_same_id", EASY_GLOBALS.highlight_blocks_with_same_id); settings.setValue("bind_scene_and_tree_expand_status", EASY_GLOBALS.bind_scene_and_tree_expand_status); settings.setValue("enable_event_indicators", EASY_GLOBALS.enable_event_indicators); settings.setValue("enable_statistics", EASY_GLOBALS.enable_statistics); @@ -1058,6 +1117,7 @@ void EasyMainWindow::onFileReaderTimeout() m_descriptorsNumberInFile = descriptorsNumberInFile; EASY_GLOBALS.selected_thread = 0; ::profiler_gui::set_max(EASY_GLOBALS.selected_block); + ::profiler_gui::set_max(EASY_GLOBALS.selected_block_id); EASY_GLOBALS.profiler_blocks.swap(threads_map); EASY_GLOBALS.descriptors.swap(descriptors); diff --git a/profiler_gui/main_window.h b/profiler_gui/main_window.h index c9e8abe..5e7220b 100644 --- a/profiler_gui/main_window.h +++ b/profiler_gui/main_window.h @@ -230,6 +230,7 @@ protected slots: void onExitClicked(bool); void onEncodingChanged(bool); void onChronoTextPosChanged(bool); + void onUnitsChanged(bool); void onEventIndicatorsChange(bool); void onEnableDisableStatistics(bool); void onDrawBordersChanged(bool); diff --git a/profiler_gui/tree_widget_item.cpp b/profiler_gui/tree_widget_item.cpp index e5394c9..9d6003c 100644 --- a/profiler_gui/tree_widget_item.cpp +++ b/profiler_gui/tree_widget_item.cpp @@ -129,30 +129,39 @@ const ::profiler::BlocksTree& EasyTreeWidgetItem::block() const return data(COL_SELF_DURATION, Qt::UserRole).toULongLong(); } -void EasyTreeWidgetItem::setTimeSmart(int _column, const ::profiler::timestamp_t& _time, const QString& _prefix) +void EasyTreeWidgetItem::setTimeSmart(int _column, ::profiler_gui::TimeUnits _units, const ::profiler::timestamp_t& _time, const QString& _prefix) { const ::profiler::timestamp_t nanosecondsTime = PROF_NANOSECONDS(_time); setData(_column, Qt::UserRole, (quint64)nanosecondsTime); - setToolTip(_column, QString("%1 ns").arg(nanosecondsTime)); + setText(_column, QString("%1%2").arg(_prefix).arg(::profiler_gui::timeStringRealNs(_units, nanosecondsTime, 3))); - if (_time < 1e3) - { - setText(_column, QString("%1%2 ns").arg(_prefix).arg(nanosecondsTime)); - } - else if (_time < 1e6) - { - setText(_column, QString("%1%2 us").arg(_prefix).arg(double(nanosecondsTime) * 1e-3, 0, 'f', 3)); - } - else if (_time < 1e9) - { - setText(_column, QString("%1%2 ms").arg(_prefix).arg(double(nanosecondsTime) * 1e-6, 0, 'f', 3)); - } - else - { - setText(_column, QString("%1%2 s").arg(_prefix).arg(double(nanosecondsTime) * 1e-9, 0, 'f', 3)); - } +// if (_time < 1e3) +// { +// setText(_column, QString("%1%2 ns").arg(_prefix).arg(nanosecondsTime)); +// } +// else if (_time < 1e6) +// { +// setText(_column, QString("%1%2 us").arg(_prefix).arg(double(nanosecondsTime) * 1e-3, 0, 'f', 3)); +// } +// else if (_time < 1e9) +// { +// setText(_column, QString("%1%2 ms").arg(_prefix).arg(double(nanosecondsTime) * 1e-6, 0, 'f', 3)); +// } +// else +// { +// setText(_column, QString("%1%2 s").arg(_prefix).arg(double(nanosecondsTime) * 1e-9, 0, 'f', 3)); +// } +} + +void EasyTreeWidgetItem::setTimeSmart(int _column, ::profiler_gui::TimeUnits _units, const ::profiler::timestamp_t& _time) +{ + const ::profiler::timestamp_t nanosecondsTime = PROF_NANOSECONDS(_time); + + setData(_column, Qt::UserRole, (quint64)nanosecondsTime); + setToolTip(_column, QString("%1 ns").arg(nanosecondsTime)); + setText(_column, ::profiler_gui::timeStringRealNs(_units, nanosecondsTime, 3)); } void EasyTreeWidgetItem::setTimeMs(int _column, const ::profiler::timestamp_t& _time) diff --git a/profiler_gui/tree_widget_item.h b/profiler_gui/tree_widget_item.h index 1bbd118..15ebc43 100644 --- a/profiler_gui/tree_widget_item.h +++ b/profiler_gui/tree_widget_item.h @@ -125,7 +125,8 @@ public: ::profiler::timestamp_t duration() const; ::profiler::timestamp_t selfDuration() const; - void setTimeSmart(int _column, const ::profiler::timestamp_t& _time, const QString& _prefix = ""); + void setTimeSmart(int _column, ::profiler_gui::TimeUnits _units, const ::profiler::timestamp_t& _time, const QString& _prefix); + void setTimeSmart(int _column, ::profiler_gui::TimeUnits _units, const ::profiler::timestamp_t& _time); void setTimeMs(int _column, const ::profiler::timestamp_t& _time); void setTimeMs(int _column, const ::profiler::timestamp_t& _time, const QString& _prefix); diff --git a/profiler_gui/tree_widget_loader.cpp b/profiler_gui/tree_widget_loader.cpp index ca7f0be..73cd0a1 100644 --- a/profiler_gui/tree_widget_loader.cpp +++ b/profiler_gui/tree_widget_loader.cpp @@ -153,7 +153,7 @@ void EasyTreeWidgetLoader::fillTree(::profiler::timestamp_t& _beginTime, const u interrupt(); m_thread = ::std::move(::std::thread(&FillTreeClass::setTreeInternal1, ::std::ref(*this), ::std::ref(m_items), ::std::ref(m_topLevelItems), ::std::ref(_beginTime), - _blocksNumber, ::std::ref(_blocksTree), _colorizeRows, EASY_GLOBALS.add_zero_blocks_to_hierarchy)); + _blocksNumber, ::std::ref(_blocksTree), _colorizeRows, EASY_GLOBALS.add_zero_blocks_to_hierarchy, EASY_GLOBALS.time_units)); } void EasyTreeWidgetLoader::fillTreeBlocks(const::profiler_gui::TreeBlocks& _blocks, ::profiler::timestamp_t _beginTime, ::profiler::timestamp_t _left, ::profiler::timestamp_t _right, bool _strict, bool _colorizeRows) @@ -161,13 +161,13 @@ void EasyTreeWidgetLoader::fillTreeBlocks(const::profiler_gui::TreeBlocks& _bloc interrupt(); m_thread = ::std::move(::std::thread(&FillTreeClass::setTreeInternal2, ::std::ref(*this), ::std::ref(m_items), ::std::ref(m_topLevelItems), _beginTime, ::std::ref(_blocks), - _left, _right, _strict, _colorizeRows, EASY_GLOBALS.add_zero_blocks_to_hierarchy)); + _left, _right, _strict, _colorizeRows, EASY_GLOBALS.add_zero_blocks_to_hierarchy, EASY_GLOBALS.time_units)); } ////////////////////////////////////////////////////////////////////////// template -void FillTreeClass::setTreeInternal1(T& _safelocker, Items& _items, ThreadedItems& _topLevelItems, ::profiler::timestamp_t& _beginTime, const unsigned int _blocksNumber, const ::profiler::thread_blocks_tree_t& _blocksTree, bool _colorizeRows, bool _addZeroBlocks) +void FillTreeClass::setTreeInternal1(T& _safelocker, Items& _items, ThreadedItems& _topLevelItems, ::profiler::timestamp_t& _beginTime, const unsigned int _blocksNumber, const ::profiler::thread_blocks_tree_t& _blocksTree, bool _colorizeRows, bool _addZeroBlocks, ::profiler_gui::TimeUnits _units) { _items.reserve(_blocksNumber + _blocksTree.size()); // _blocksNumber does not include Thread root blocks @@ -217,16 +217,16 @@ void FillTreeClass::setTreeInternal1(T& _safelocker, Items& _items, ThreadedI if (!root.children.empty()) duration = blocksTree(root.children.back()).node->end() - blocksTree(root.children.front()).node->begin(); - item->setTimeSmart(COL_DURATION, duration); + item->setTimeSmart(COL_DURATION, _units, duration); item->setBackgroundColor(::profiler_gui::SELECTED_THREAD_BACKGROUND); item->setTextColor(::profiler_gui::SELECTED_THREAD_FOREGROUND); //_items.push_back(item); - item->setTimeSmart(COL_SELF_DURATION, root.active_time); + item->setTimeSmart(COL_SELF_DURATION, _units, root.active_time); ::profiler::timestamp_t children_duration = 0; - const auto children_items_number = FillTreeClass::setTreeInternal(_safelocker, _items, _beginTime, root.children, item, nullptr, item, _beginTime, finishtime + 1000000000ULL, false, children_duration, _colorizeRows, _addZeroBlocks); + const auto children_items_number = FillTreeClass::setTreeInternal(_safelocker, _items, _beginTime, root.children, item, nullptr, item, _beginTime, finishtime + 1000000000ULL, false, children_duration, _colorizeRows, _addZeroBlocks, _units); if (children_items_number > 0) { @@ -259,7 +259,7 @@ auto calculateTotalChildrenNumber(const ::profiler::BlocksTree& _tree) -> declty } template -void FillTreeClass::setTreeInternal2(T& _safelocker, Items& _items, ThreadedItems& _topLevelItems, const ::profiler::timestamp_t& _beginTime, const ::profiler_gui::TreeBlocks& _blocks, ::profiler::timestamp_t _left, ::profiler::timestamp_t _right, bool _strict, bool _colorizeRows, bool _addZeroBlocks) +void FillTreeClass::setTreeInternal2(T& _safelocker, Items& _items, ThreadedItems& _topLevelItems, const ::profiler::timestamp_t& _beginTime, const ::profiler_gui::TreeBlocks& _blocks, ::profiler::timestamp_t _left, ::profiler::timestamp_t _right, bool _strict, bool _colorizeRows, bool _addZeroBlocks, ::profiler_gui::TimeUnits _units) { //size_t blocksNumber = 0; //for (const auto& block : _blocks) @@ -316,12 +316,12 @@ void FillTreeClass::setTreeInternal2(T& _safelocker, Items& _items, ThreadedI if (!block.root->children.empty()) duration = blocksTree(block.root->children.back()).node->end() - blocksTree(block.root->children.front()).node->begin(); - thread_item->setTimeSmart(COL_DURATION, duration); + thread_item->setTimeSmart(COL_DURATION, _units, duration); thread_item->setBackgroundColor(::profiler_gui::SELECTED_THREAD_BACKGROUND); thread_item->setTextColor(::profiler_gui::SELECTED_THREAD_FOREGROUND); // Sum of all children durations: - thread_item->setTimeSmart(COL_SELF_DURATION, block.root->active_time); + thread_item->setTimeSmart(COL_SELF_DURATION, _units, block.root->active_time); threadsMap.insert(::std::make_pair(block.root->thread_id, thread_item)); } @@ -331,7 +331,7 @@ void FillTreeClass::setTreeInternal2(T& _safelocker, Items& _items, ThreadedI auto name = *gui_block.tree.node->name() != 0 ? gui_block.tree.node->name() : easyDescriptor(gui_block.tree.node->id()).name(); item->setText(COL_NAME, ::profiler_gui::toUnicode(name)); - item->setTimeSmart(COL_DURATION, duration); + item->setTimeSmart(COL_DURATION, _units, duration); item->setTimeMs(COL_BEGIN, startTime - _beginTime); item->setTimeMs(COL_END, endTime - _beginTime); @@ -350,10 +350,10 @@ void FillTreeClass::setTreeInternal2(T& _safelocker, Items& _items, ThreadedI if (per_thread_stats->calls_number > 1 || !EASY_GLOBALS.display_only_relevant_stats) { - item->setTimeSmart(COL_MIN_PER_THREAD, per_thread_stats->min_duration, "min "); - item->setTimeSmart(COL_MAX_PER_THREAD, per_thread_stats->max_duration, "max "); - item->setTimeSmart(COL_AVERAGE_PER_THREAD, per_thread_stats->average_duration()); - item->setTimeSmart(COL_DURATION_SUM_PER_THREAD, per_thread_stats->total_duration); + item->setTimeSmart(COL_MIN_PER_THREAD, _units, per_thread_stats->min_duration, "min "); + item->setTimeSmart(COL_MAX_PER_THREAD, _units, per_thread_stats->max_duration, "max "); + item->setTimeSmart(COL_AVERAGE_PER_THREAD, _units, per_thread_stats->average_duration()); + item->setTimeSmart(COL_DURATION_SUM_PER_THREAD, _units, per_thread_stats->total_duration); } item->setData(COL_NCALLS_PER_THREAD, Qt::UserRole, per_thread_stats->calls_number); @@ -366,10 +366,10 @@ void FillTreeClass::setTreeInternal2(T& _safelocker, Items& _items, ThreadedI if (per_parent_stats->calls_number > 1 || !EASY_GLOBALS.display_only_relevant_stats) { - item->setTimeSmart(COL_MIN_PER_PARENT, per_parent_stats->min_duration, "min "); - item->setTimeSmart(COL_MAX_PER_PARENT, per_parent_stats->max_duration, "max "); - item->setTimeSmart(COL_AVERAGE_PER_PARENT, per_parent_stats->average_duration()); - item->setTimeSmart(COL_DURATION_SUM_PER_PARENT, per_parent_stats->total_duration); + item->setTimeSmart(COL_MIN_PER_PARENT, _units, per_parent_stats->min_duration, "min "); + item->setTimeSmart(COL_MAX_PER_PARENT, _units, per_parent_stats->max_duration, "max "); + item->setTimeSmart(COL_AVERAGE_PER_PARENT, _units, per_parent_stats->average_duration()); + item->setTimeSmart(COL_DURATION_SUM_PER_PARENT, _units, per_parent_stats->total_duration); } item->setData(COL_NCALLS_PER_PARENT, Qt::UserRole, per_parent_stats->calls_number); @@ -378,10 +378,10 @@ void FillTreeClass::setTreeInternal2(T& _safelocker, Items& _items, ThreadedI if (per_frame_stats->calls_number > 1 || !EASY_GLOBALS.display_only_relevant_stats) { - item->setTimeSmart(COL_MIN_PER_FRAME, per_frame_stats->min_duration, "min "); - item->setTimeSmart(COL_MAX_PER_FRAME, per_frame_stats->max_duration, "max "); - item->setTimeSmart(COL_AVERAGE_PER_FRAME, per_frame_stats->average_duration()); - item->setTimeSmart(COL_DURATION_SUM_PER_FRAME, per_frame_stats->total_duration); + item->setTimeSmart(COL_MIN_PER_FRAME, _units, per_frame_stats->min_duration, "min "); + item->setTimeSmart(COL_MAX_PER_FRAME, _units, per_frame_stats->max_duration, "max "); + item->setTimeSmart(COL_AVERAGE_PER_FRAME, _units, per_frame_stats->average_duration()); + item->setTimeSmart(COL_DURATION_SUM_PER_FRAME, _units, per_frame_stats->total_duration); } item->setData(COL_NCALLS_PER_FRAME, Qt::UserRole, per_frame_stats->calls_number); @@ -406,7 +406,7 @@ void FillTreeClass::setTreeInternal2(T& _safelocker, Items& _items, ThreadedI ::profiler::timestamp_t children_duration = 0; if (!gui_block.tree.children.empty()) { - children_items_number = FillTreeClass::setTreeInternal(_safelocker, _items, _beginTime, gui_block.tree.children, item, item, thread_item, _left, _right, _strict, children_duration, _colorizeRows, _addZeroBlocks); + children_items_number = FillTreeClass::setTreeInternal(_safelocker, _items, _beginTime, gui_block.tree.children, item, item, thread_item, _left, _right, _strict, children_duration, _colorizeRows, _addZeroBlocks, _units); if (_safelocker.interrupted()) break; } @@ -418,7 +418,7 @@ void FillTreeClass::setTreeInternal2(T& _safelocker, Items& _items, ThreadedI percentage = static_cast(0.5 + 100. * static_cast(self_duration) / static_cast(duration)); } - item->setTimeSmart(COL_SELF_DURATION, self_duration); + item->setTimeSmart(COL_SELF_DURATION, _units, self_duration); item->setData(COL_SELF_DURATION_PERCENT, Qt::UserRole, percentage); item->setText(COL_SELF_DURATION_PERCENT, QString::number(percentage)); @@ -472,7 +472,7 @@ void FillTreeClass::setTreeInternal2(T& _safelocker, Items& _items, ThreadedI } template -size_t FillTreeClass::setTreeInternal(T& _safelocker, Items& _items, const ::profiler::timestamp_t& _beginTime, const ::profiler::BlocksTree::children_t& _children, EasyTreeWidgetItem* _parent, EasyTreeWidgetItem* _frame, EasyTreeWidgetItem* _thread, ::profiler::timestamp_t _left, ::profiler::timestamp_t _right, bool _strict, ::profiler::timestamp_t& _duration, bool _colorizeRows, bool _addZeroBlocks) +size_t FillTreeClass::setTreeInternal(T& _safelocker, Items& _items, const ::profiler::timestamp_t& _beginTime, const ::profiler::BlocksTree::children_t& _children, EasyTreeWidgetItem* _parent, EasyTreeWidgetItem* _frame, EasyTreeWidgetItem* _thread, ::profiler::timestamp_t _left, ::profiler::timestamp_t _right, bool _strict, ::profiler::timestamp_t& _duration, bool _colorizeRows, bool _addZeroBlocks, ::profiler_gui::TimeUnits _units) { size_t total_items = 0; for (auto child_index : _children) @@ -498,7 +498,7 @@ size_t FillTreeClass::setTreeInternal(T& _safelocker, Items& _items, const :: auto name = *child.node->name() != 0 ? child.node->name() : easyDescriptor(child.node->id()).name(); item->setText(COL_NAME, ::profiler_gui::toUnicode(name)); - item->setTimeSmart(COL_DURATION, duration); + item->setTimeSmart(COL_DURATION, _units, duration); item->setTimeMs(COL_BEGIN, startTime - _beginTime); item->setTimeMs(COL_END, endTime - _beginTime); item->setData(COL_PERCENT_SUM_PER_THREAD, Qt::UserRole, 0); @@ -549,10 +549,10 @@ size_t FillTreeClass::setTreeInternal(T& _safelocker, Items& _items, const :: if (per_thread_stats->calls_number > 1 || !EASY_GLOBALS.display_only_relevant_stats) { - item->setTimeSmart(COL_MIN_PER_THREAD, per_thread_stats->min_duration, "min "); - item->setTimeSmart(COL_MAX_PER_THREAD, per_thread_stats->max_duration, "max "); - item->setTimeSmart(COL_AVERAGE_PER_THREAD, per_thread_stats->average_duration()); - item->setTimeSmart(COL_DURATION_SUM_PER_THREAD, per_thread_stats->total_duration); + item->setTimeSmart(COL_MIN_PER_THREAD, _units, per_thread_stats->min_duration, "min "); + item->setTimeSmart(COL_MAX_PER_THREAD, _units, per_thread_stats->max_duration, "max "); + item->setTimeSmart(COL_AVERAGE_PER_THREAD, _units, per_thread_stats->average_duration()); + item->setTimeSmart(COL_DURATION_SUM_PER_THREAD, _units, per_thread_stats->total_duration); } item->setData(COL_NCALLS_PER_THREAD, Qt::UserRole, per_thread_stats->calls_number); @@ -568,10 +568,10 @@ size_t FillTreeClass::setTreeInternal(T& _safelocker, Items& _items, const :: if (per_parent_stats->calls_number > 1 || !EASY_GLOBALS.display_only_relevant_stats) { - item->setTimeSmart(COL_MIN_PER_PARENT, per_parent_stats->min_duration, "min "); - item->setTimeSmart(COL_MAX_PER_PARENT, per_parent_stats->max_duration, "max "); - item->setTimeSmart(COL_AVERAGE_PER_PARENT, per_parent_stats->average_duration()); - item->setTimeSmart(COL_DURATION_SUM_PER_PARENT, per_parent_stats->total_duration); + item->setTimeSmart(COL_MIN_PER_PARENT, _units, per_parent_stats->min_duration, "min "); + item->setTimeSmart(COL_MAX_PER_PARENT, _units, per_parent_stats->max_duration, "max "); + item->setTimeSmart(COL_AVERAGE_PER_PARENT, _units, per_parent_stats->average_duration()); + item->setTimeSmart(COL_DURATION_SUM_PER_PARENT, _units, per_parent_stats->total_duration); } item->setData(COL_NCALLS_PER_PARENT, Qt::UserRole, per_parent_stats->calls_number); @@ -580,10 +580,10 @@ size_t FillTreeClass::setTreeInternal(T& _safelocker, Items& _items, const :: if (per_frame_stats->calls_number > 1 || !EASY_GLOBALS.display_only_relevant_stats) { - item->setTimeSmart(COL_MIN_PER_FRAME, per_frame_stats->min_duration, "min "); - item->setTimeSmart(COL_MAX_PER_FRAME, per_frame_stats->max_duration, "max "); - item->setTimeSmart(COL_AVERAGE_PER_FRAME, per_frame_stats->average_duration()); - item->setTimeSmart(COL_DURATION_SUM_PER_FRAME, per_frame_stats->total_duration); + item->setTimeSmart(COL_MIN_PER_FRAME, _units, per_frame_stats->min_duration, "min "); + item->setTimeSmart(COL_MAX_PER_FRAME, _units, per_frame_stats->max_duration, "max "); + item->setTimeSmart(COL_AVERAGE_PER_FRAME, _units, per_frame_stats->average_duration()); + item->setTimeSmart(COL_DURATION_SUM_PER_FRAME, _units, per_frame_stats->total_duration); } item->setData(COL_NCALLS_PER_FRAME, Qt::UserRole, per_frame_stats->calls_number); @@ -619,7 +619,7 @@ size_t FillTreeClass::setTreeInternal(T& _safelocker, Items& _items, const :: ::profiler::timestamp_t children_duration = 0; if (!child.children.empty()) { - children_items_number = FillTreeClass::setTreeInternal(_safelocker, _items, _beginTime, child.children, item, _frame ? _frame : item, _thread, _left, _right, _strict, children_duration, _colorizeRows, _addZeroBlocks); + children_items_number = FillTreeClass::setTreeInternal(_safelocker, _items, _beginTime, child.children, item, _frame ? _frame : item, _thread, _left, _right, _strict, children_duration, _colorizeRows, _addZeroBlocks, _units); if (_safelocker.interrupted()) break; } @@ -631,7 +631,7 @@ size_t FillTreeClass::setTreeInternal(T& _safelocker, Items& _items, const :: percentage = ::profiler_gui::percent(self_duration, duration); } - item->setTimeSmart(COL_SELF_DURATION, self_duration); + item->setTimeSmart(COL_SELF_DURATION, _units, self_duration); item->setData(COL_SELF_DURATION_PERCENT, Qt::UserRole, percentage); item->setText(COL_SELF_DURATION_PERCENT, QString::number(percentage)); diff --git a/profiler_gui/tree_widget_loader.h b/profiler_gui/tree_widget_loader.h index 1297533..c5b9e7d 100644 --- a/profiler_gui/tree_widget_loader.h +++ b/profiler_gui/tree_widget_loader.h @@ -98,9 +98,9 @@ public: template struct FillTreeClass Q_DECL_FINAL { - static void setTreeInternal1(T& _safelocker, Items& _items, ThreadedItems& _topLevelItems, ::profiler::timestamp_t& _beginTime, const unsigned int _blocksNumber, const ::profiler::thread_blocks_tree_t& _blocksTree, bool _colorizeRows, bool _addZeroBlocks); - static void setTreeInternal2(T& _safelocker, Items& _items, ThreadedItems& _topLevelItems, const ::profiler::timestamp_t& _beginTime, const ::profiler_gui::TreeBlocks& _blocks, ::profiler::timestamp_t _left, ::profiler::timestamp_t _right, bool _strict, bool _colorizeRows, bool _addZeroBlocks); - static size_t setTreeInternal(T& _safelocker, Items& _items, const ::profiler::timestamp_t& _beginTime, const ::profiler::BlocksTree::children_t& _children, EasyTreeWidgetItem* _parent, EasyTreeWidgetItem* _frame, EasyTreeWidgetItem* _thread, ::profiler::timestamp_t _left, ::profiler::timestamp_t _right, bool _strict, ::profiler::timestamp_t& _duration, bool _colorizeRows, bool _addZeroBlocks); + static void setTreeInternal1(T& _safelocker, Items& _items, ThreadedItems& _topLevelItems, ::profiler::timestamp_t& _beginTime, const unsigned int _blocksNumber, const ::profiler::thread_blocks_tree_t& _blocksTree, bool _colorizeRows, bool _addZeroBlocks, ::profiler_gui::TimeUnits _units); + static void setTreeInternal2(T& _safelocker, Items& _items, ThreadedItems& _topLevelItems, const ::profiler::timestamp_t& _beginTime, const ::profiler_gui::TreeBlocks& _blocks, ::profiler::timestamp_t _left, ::profiler::timestamp_t _right, bool _strict, bool _colorizeRows, bool _addZeroBlocks, ::profiler_gui::TimeUnits _units); + static size_t setTreeInternal(T& _safelocker, Items& _items, const ::profiler::timestamp_t& _beginTime, const ::profiler::BlocksTree::children_t& _children, EasyTreeWidgetItem* _parent, EasyTreeWidgetItem* _frame, EasyTreeWidgetItem* _thread, ::profiler::timestamp_t _left, ::profiler::timestamp_t _right, bool _strict, ::profiler::timestamp_t& _duration, bool _colorizeRows, bool _addZeroBlocks, ::profiler_gui::TimeUnits _units); }; //////////////////////////////////////////////////////////////////////////