diff --git a/profiler_gui/blocks_graphics_view.cpp b/profiler_gui/blocks_graphics_view.cpp index cf0dab4..7405fb5 100644 --- a/profiler_gui/blocks_graphics_view.cpp +++ b/profiler_gui/blocks_graphics_view.cpp @@ -1515,6 +1515,109 @@ void EasyGraphicsView::onIdleTimeout() // Try to select one of context switches or items for (auto item : m_items) { + auto cse = item->intersectEvent(pos); + if (cse != nullptr) + { + const auto& itemBlock = cse->tree; + + auto widget = new QWidget(nullptr, Qt::FramelessWindowHint); + if (widget == nullptr) + return; + + widget->setAttribute(Qt::WA_ShowWithoutActivating, true); + widget->setFocusPolicy(Qt::NoFocus); + + auto lay = new QGridLayout(widget); + if (lay == nullptr) + return; + + int row = 0; + lay->addWidget(new EasyBoldLabel("Context switch event", widget), row, 0, 1, 3, Qt::AlignHCenter); + ++row; + + lay->addWidget(new QLabel("Thread:", widget), row, 0, Qt::AlignRight); + + const char* process_name = ""; + ::profiler::thread_id_t tid = 0; + if (EASY_GLOBALS.version < ::profiler_gui::V130) + { + tid = cse->tree.node->id(); + process_name = cse->tree.node->name(); + } + else + { + tid = cse->tree.cs->tid(); + process_name = cse->tree.cs->name(); + } + + auto it = EASY_GLOBALS.profiler_blocks.find(tid); + + if (it != EASY_GLOBALS.profiler_blocks.end()) + { + if (EASY_GLOBALS.hex_thread_id) + lay->addWidget(new QLabel(QString("0x%1 %2").arg(tid, 0, 16).arg(it->second.name()), widget), row, 1, 1, 2, Qt::AlignLeft); + else + lay->addWidget(new QLabel(QString("%1 %2").arg(tid).arg(it->second.name()), widget), row, 1, 1, 2, Qt::AlignLeft); + } + else if (EASY_GLOBALS.hex_thread_id) + lay->addWidget(new QLabel(QString("0x%1").arg(tid, 0, 16), widget), row, 1, 1, 2, Qt::AlignLeft); + else + lay->addWidget(new QLabel(QString::number(tid), widget), row, 1, 1, 2, Qt::AlignLeft); + ++row; + + lay->addWidget(new QLabel("Process:", widget), row, 0, Qt::AlignRight); + lay->addWidget(new QLabel(process_name, widget), row, 1, 1, 2, Qt::AlignLeft); + ++row; + + const auto duration = itemBlock.node->duration(); + lay->addWidget(new QLabel("Duration:", widget), row, 0, Qt::AlignRight); + lay->addWidget(new QLabel(::profiler_gui::timeStringRealNs(EASY_GLOBALS.time_units, duration, 3), widget), row, 1, 1, 2, Qt::AlignLeft); + ++row; + + if (itemBlock.per_thread_stats) + { + lay->addWidget(new QLabel("Sum:", widget), row, 0, Qt::AlignRight); + lay->addWidget(new QLabel(::profiler_gui::timeStringRealNs(EASY_GLOBALS.time_units, itemBlock.per_thread_stats->total_duration, 3), widget), row, 1, 1, 2, Qt::AlignLeft); + ++row; + + lay->addWidget(new EasyBoldLabel("-------- Statistics --------", widget), row, 0, 1, 3, Qt::AlignHCenter); + lay->addWidget(new QLabel("per ", widget), row + 1, 0, Qt::AlignRight); + lay->addWidget(new QLabel("This %:", widget), row + 2, 0, Qt::AlignRight); + lay->addWidget(new QLabel("Sum %:", widget), row + 3, 0, Qt::AlignRight); + lay->addWidget(new QLabel("N Calls:", widget), row + 4, 0, Qt::AlignRight); + + lay->addWidget(new QLabel("Thread", widget), row + 1, 1, Qt::AlignHCenter); + + auto percent = ::profiler_gui::percentReal(duration, item->root()->profiled_time); + lay->addWidget(new QLabel(0.005 < percent && percent < 0.5001 ? QString::number(percent, 'f', 2) : QString::number(static_cast(0.5 + percent)), widget), row + 2, 1, Qt::AlignHCenter); + + lay->addWidget(new QLabel(QString::number(::profiler_gui::percent(itemBlock.per_thread_stats->total_duration, item->root()->profiled_time)), widget), row + 3, 1, Qt::AlignHCenter); + + lay->addWidget(new QLabel(QString::number(itemBlock.per_thread_stats->calls_number), widget), row + 4, 1, Qt::AlignHCenter); + + if (itemBlock.per_frame_stats && !::profiler_gui::is_max(itemBlock.per_frame_stats->parent_block)) + { + int col = 2; + auto frame_duration = blocksTree(itemBlock.per_frame_stats->parent_block).node->duration(); + + lay->addWidget(new QLabel("Frame", widget), row + 1, col, Qt::AlignHCenter); + + percent = ::profiler_gui::percentReal(duration, frame_duration); + lay->addWidget(new QLabel(0.005 < percent && percent < 0.5001 ? QString::number(percent, 'f', 2) : QString::number(static_cast(0.5 + percent)), widget), row + 2, col, Qt::AlignHCenter); + + percent = ::profiler_gui::percentReal(itemBlock.per_frame_stats->total_duration, frame_duration); + lay->addWidget(new QLabel(0.005 < percent && percent < 0.5001 ? QString::number(percent, 'f', 2) : QString::number(static_cast(0.5 + percent)), widget), row + 3, col, Qt::AlignHCenter); + + lay->addWidget(new QLabel(QString::number(itemBlock.per_frame_stats->calls_number), widget), row + 4, col, Qt::AlignHCenter); + } + } + + m_popupWidget = new QGraphicsProxyWidget(); + m_popupWidget->setWidget(widget); + + break; + } + ::profiler::block_index_t i = ~0U; auto block = item->intersect(pos, i); if (block != nullptr) @@ -1736,109 +1839,6 @@ void EasyGraphicsView::onIdleTimeout() break; } - - auto cse = item->intersectEvent(pos); - if (cse != nullptr) - { - const auto& itemBlock = cse->tree; - - auto widget = new QWidget(nullptr, Qt::FramelessWindowHint); - if (widget == nullptr) - return; - - widget->setAttribute(Qt::WA_ShowWithoutActivating, true); - widget->setFocusPolicy(Qt::NoFocus); - - auto lay = new QGridLayout(widget); - if (lay == nullptr) - return; - - int row = 0; - lay->addWidget(new EasyBoldLabel("Context switch event", widget), row, 0, 1, 3, Qt::AlignHCenter); - ++row; - - lay->addWidget(new QLabel("Thread:", widget), row, 0, Qt::AlignRight); - - const char* process_name = ""; - ::profiler::thread_id_t tid = 0; - if (EASY_GLOBALS.version < ::profiler_gui::V130) - { - tid = cse->tree.node->id(); - process_name = cse->tree.node->name(); - } - else - { - tid = cse->tree.cs->tid(); - process_name = cse->tree.cs->name(); - } - - auto it = EASY_GLOBALS.profiler_blocks.find(tid); - - if (it != EASY_GLOBALS.profiler_blocks.end()) - { - if (EASY_GLOBALS.hex_thread_id) - lay->addWidget(new QLabel(QString("0x%1 %2").arg(tid, 0, 16).arg(it->second.name()), widget), row, 1, 1, 2, Qt::AlignLeft); - else - lay->addWidget(new QLabel(QString("%1 %2").arg(tid).arg(it->second.name()), widget), row, 1, 1, 2, Qt::AlignLeft); - } - else if (EASY_GLOBALS.hex_thread_id) - lay->addWidget(new QLabel(QString("0x%1").arg(tid, 0, 16), widget), row, 1, 1, 2, Qt::AlignLeft); - else - lay->addWidget(new QLabel(QString::number(tid), widget), row, 1, 1, 2, Qt::AlignLeft); - ++row; - - lay->addWidget(new QLabel("Process:", widget), row, 0, Qt::AlignRight); - lay->addWidget(new QLabel(process_name, widget), row, 1, 1, 2, Qt::AlignLeft); - ++row; - - const auto duration = itemBlock.node->duration(); - lay->addWidget(new QLabel("Duration:", widget), row, 0, Qt::AlignRight); - lay->addWidget(new QLabel(::profiler_gui::timeStringRealNs(EASY_GLOBALS.time_units, duration, 3), widget), row, 1, 1, 2, Qt::AlignLeft); - ++row; - - if (itemBlock.per_thread_stats) - { - lay->addWidget(new QLabel("Sum:", widget), row, 0, Qt::AlignRight); - lay->addWidget(new QLabel(::profiler_gui::timeStringRealNs(EASY_GLOBALS.time_units, itemBlock.per_thread_stats->total_duration, 3), widget), row, 1, 1, 2, Qt::AlignLeft); - ++row; - - lay->addWidget(new EasyBoldLabel("-------- Statistics --------", widget), row, 0, 1, 3, Qt::AlignHCenter); - lay->addWidget(new QLabel("per ", widget), row + 1, 0, Qt::AlignRight); - lay->addWidget(new QLabel("This %:", widget), row + 2, 0, Qt::AlignRight); - lay->addWidget(new QLabel("Sum %:", widget), row + 3, 0, Qt::AlignRight); - lay->addWidget(new QLabel("N Calls:", widget), row + 4, 0, Qt::AlignRight); - - lay->addWidget(new QLabel("Thread", widget), row + 1, 1, Qt::AlignHCenter); - - auto percent = ::profiler_gui::percentReal(duration, item->root()->profiled_time); - lay->addWidget(new QLabel(0.005 < percent && percent < 0.5001 ? QString::number(percent, 'f', 2) : QString::number(static_cast(0.5 + percent)), widget), row + 2, 1, Qt::AlignHCenter); - - lay->addWidget(new QLabel(QString::number(::profiler_gui::percent(itemBlock.per_thread_stats->total_duration, item->root()->profiled_time)), widget), row + 3, 1, Qt::AlignHCenter); - - lay->addWidget(new QLabel(QString::number(itemBlock.per_thread_stats->calls_number), widget), row + 4, 1, Qt::AlignHCenter); - - if (itemBlock.per_frame_stats && !::profiler_gui::is_max(itemBlock.per_frame_stats->parent_block)) - { - int col = 2; - auto frame_duration = blocksTree(itemBlock.per_frame_stats->parent_block).node->duration(); - - lay->addWidget(new QLabel("Frame", widget), row + 1, col, Qt::AlignHCenter); - - percent = ::profiler_gui::percentReal(duration, frame_duration); - lay->addWidget(new QLabel(0.005 < percent && percent < 0.5001 ? QString::number(percent, 'f', 2) : QString::number(static_cast(0.5 + percent)), widget), row + 2, col, Qt::AlignHCenter); - - percent = ::profiler_gui::percentReal(itemBlock.per_frame_stats->total_duration, frame_duration); - lay->addWidget(new QLabel(0.005 < percent && percent < 0.5001 ? QString::number(percent, 'f', 2) : QString::number(static_cast(0.5 + percent)), widget), row + 3, col, Qt::AlignHCenter); - - lay->addWidget(new QLabel(QString::number(itemBlock.per_frame_stats->calls_number), widget), row + 4, col, Qt::AlignHCenter); - } - } - - m_popupWidget = new QGraphicsProxyWidget(); - m_popupWidget->setWidget(widget); - - break; - } } if (m_popupWidget != nullptr) diff --git a/profiler_gui/descriptors_tree_widget.cpp b/profiler_gui/descriptors_tree_widget.cpp index 26ba1b8..5123cf9 100644 --- a/profiler_gui/descriptors_tree_widget.cpp +++ b/profiler_gui/descriptors_tree_widget.cpp @@ -186,7 +186,7 @@ const char* statusText(::profiler::EasyBlockStatus _status) ////////////////////////////////////////////////////////////////////////// EasyDescWidgetItem::EasyDescWidgetItem(::profiler::block_id_t _desc, Parent* _parent) - : Parent(_parent) + : Parent(_parent, QTreeWidgetItem::UserType) , m_desc(_desc) , m_type(EasyDescWidgetItem::Type::File) { diff --git a/profiler_gui/easy_graphics_item.cpp b/profiler_gui/easy_graphics_item.cpp index 6b23f55..d6291af 100644 --- a/profiler_gui/easy_graphics_item.cpp +++ b/profiler_gui/easy_graphics_item.cpp @@ -74,6 +74,7 @@ enum BlockItemState : int8_t EASY_CONSTEXPR int MIN_SYNC_SPACING = 1; EASY_CONSTEXPR int MIN_SYNC_SIZE = 3; +EASY_CONSTEXPR int EVENT_HEIGHT = 4; EASY_CONSTEXPR QRgb BORDERS_COLOR = ::profiler::colors::Grey600 & 0x00ffffff;// 0x00686868; inline QRgb selectedItemBorderColor(::profiler::color_t _color) { @@ -964,8 +965,9 @@ void EasyGraphicsItem::paint(QPainter* _painter, const QStyleOptionGraphicsItem* //firstSync = m_pRoot->sync.begin(); p.previousColor = 0; - qreal prevRight = -1e100, top = y() - 6, h = 3; - if (top + h < p.visibleBottom) + qreal prevRight = -1e100; + const qreal top = y() + 1 - EVENT_HEIGHT; + if (top + EVENT_HEIGHT < p.visibleBottom) { _painter->setPen(BORDERS_COLOR); @@ -1013,7 +1015,7 @@ void EasyGraphicsItem::paint(QPainter* _painter, const QStyleOptionGraphicsItem* _painter->setBrush(QColor::fromRgb(color)); } - p.rect.setRect(left, top, width, h); + p.rect.setRect(left, top, width, EVENT_HEIGHT); _painter->drawRect(p.rect); prevRight = left + width + MIN_SYNC_SPACING; } @@ -1041,8 +1043,9 @@ void EasyGraphicsItem::paint(QPainter* _painter, const QStyleOptionGraphicsItem* } p.previousColor = 0; - qreal prevRight = -1e100, top = y() + boundingRect().height() + 1, h = 3; - if (top + h < p.visibleBottom) + qreal prevRight = -1e100; + const qreal top = y() + boundingRect().height() - 1; + if (top + EVENT_HEIGHT < p.visibleBottom) { _painter->setPen(BORDERS_COLOR); @@ -1061,7 +1064,8 @@ void EasyGraphicsItem::paint(QPainter* _painter, const QStyleOptionGraphicsItem* left *= p.currentScale; left -= p.dx; width *= p.currentScale; - if (width < 2) width = 2; + if (width < 2) + width = 2; if (left + width <= prevRight) // This item is not visible continue; @@ -1082,7 +1086,7 @@ void EasyGraphicsItem::paint(QPainter* _painter, const QStyleOptionGraphicsItem* _painter->setBrush(QColor::fromRgb(color)); } - p.rect.setRect(left, top, width, h); + p.rect.setRect(left, top, width, EVENT_HEIGHT); _painter->drawRect(p.rect); prevRight = left + width + 2; } @@ -1340,14 +1344,13 @@ const ::profiler_gui::EasyBlock* EasyGraphicsItem::intersectEvent(const QPointF& return nullptr; } - const auto top = y() - 6; - + const auto top = y() - EVENT_HEIGHT; if (top > _pos.y()) { return nullptr; } - const auto bottom = top + 5; + const auto bottom = top + EVENT_HEIGHT + 2; if (bottom < _pos.y()) { return nullptr; diff --git a/profiler_gui/tree_widget_item.cpp b/profiler_gui/tree_widget_item.cpp index bf6572d..8ab16df 100644 --- a/profiler_gui/tree_widget_item.cpp +++ b/profiler_gui/tree_widget_item.cpp @@ -110,7 +110,7 @@ EASY_CONSTEXPR int ColumnBit[COL_COLUMNS_NUMBER] = { ////////////////////////////////////////////////////////////////////////// EasyTreeWidgetItem::EasyTreeWidgetItem(const ::profiler::block_index_t _treeBlock, Parent* _parent) - : Parent(_parent) + : Parent(_parent, QTreeWidgetItem::UserType) , m_block(_treeBlock) , m_customBGColor(0) , m_bColorized(false) diff --git a/profiler_gui/tree_widget_item.h b/profiler_gui/tree_widget_item.h index 9137e00..dddce6c 100644 --- a/profiler_gui/tree_widget_item.h +++ b/profiler_gui/tree_widget_item.h @@ -115,8 +115,8 @@ enum EasyColumnsIndexes class EasyTreeWidgetItem : public QTreeWidgetItem { - typedef QTreeWidgetItem Parent; - typedef EasyTreeWidgetItem This; + using Parent = QTreeWidgetItem; + using This = EasyTreeWidgetItem; QFont m_font; const ::profiler::block_index_t m_block;