mirror of
https://github.com/yse/easy_profiler.git
synced 2024-12-26 16:11:02 +08:00
(GUI) Added an option to display thread ids in HEX mode;
* (GUI) Fixed problem with searching selected blocks in histogram when selecting block from BlocksList widget
This commit is contained in:
parent
65ac892e32
commit
089fcf1e31
@ -1368,21 +1368,8 @@ void EasyGraphicsView::initMode()
|
||||
onRefreshRequired();
|
||||
});
|
||||
|
||||
connect(globalSignals, &::profiler_gui::EasyGlobalSignals::threadNameDecorationChanged, [this]()
|
||||
{
|
||||
if (m_bEmpty)
|
||||
return;
|
||||
|
||||
for (auto item : m_items)
|
||||
item->validateName();
|
||||
|
||||
emit treeChanged();
|
||||
|
||||
updateVisibleSceneRect();
|
||||
onHierarchyFlagChange(EASY_GLOBALS.only_current_thread_hierarchy);
|
||||
|
||||
repaintScene();
|
||||
});
|
||||
connect(globalSignals, &::profiler_gui::EasyGlobalSignals::threadNameDecorationChanged, this, &This::onThreadViewChanged);
|
||||
connect(globalSignals, &::profiler_gui::EasyGlobalSignals::hexThreadIdChanged, this, &This::onThreadViewChanged);
|
||||
|
||||
connect(globalSignals, &::profiler_gui::EasyGlobalSignals::blocksTreeModeChanged, [this]()
|
||||
{
|
||||
@ -1393,6 +1380,24 @@ void EasyGraphicsView::initMode()
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void EasyGraphicsView::onThreadViewChanged()
|
||||
{
|
||||
if (m_bEmpty)
|
||||
return;
|
||||
|
||||
for (auto item : m_items)
|
||||
item->validateName();
|
||||
|
||||
emit treeChanged();
|
||||
|
||||
updateVisibleSceneRect();
|
||||
onHierarchyFlagChange(EASY_GLOBALS.only_current_thread_hierarchy);
|
||||
|
||||
repaintScene();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void EasyGraphicsView::onScrollbarValueChange(int)
|
||||
{
|
||||
if (!m_bUpdatingRect && !m_bEmpty)
|
||||
@ -1675,7 +1680,14 @@ void EasyGraphicsView::onIdleTimeout()
|
||||
lay->addWidget(new QLabel("Thread:", widget), row, 0, Qt::AlignRight);
|
||||
auto it = EASY_GLOBALS.profiler_blocks.find(cse->tree.node->id());
|
||||
if (it != EASY_GLOBALS.profiler_blocks.end())
|
||||
lay->addWidget(new QLabel(QString("%1 %2").arg(cse->tree.node->id()).arg(it->second.name()), widget), row, 1, 1, 2, Qt::AlignLeft);
|
||||
{
|
||||
if (EASY_GLOBALS.hex_thread_id)
|
||||
lay->addWidget(new QLabel(QString("0x%1 %2").arg(cse->tree.node->id(), 0, 16).arg(it->second.name()), widget), row, 1, 1, 2, Qt::AlignLeft);
|
||||
else
|
||||
lay->addWidget(new QLabel(QString("%1 %2").arg(cse->tree.node->id()).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(cse->tree.node->id(), 0, 16), widget), row, 1, 1, 2, Qt::AlignLeft);
|
||||
else
|
||||
lay->addWidget(new QLabel(QString::number(cse->tree.node->id()), widget), row, 1, 1, 2, Qt::AlignLeft);
|
||||
++row;
|
||||
|
@ -222,6 +222,7 @@ private slots:
|
||||
void onSelectedThreadChange(::profiler::thread_id_t _id);
|
||||
void onSelectedBlockChange(unsigned int _block_index);
|
||||
void onRefreshRequired();
|
||||
void onThreadViewChanged();
|
||||
|
||||
public:
|
||||
|
||||
|
@ -96,7 +96,7 @@ const auto SELECTED_ITEM_FONT = ::profiler_gui::EFont("Helvetica", 10, QFont::Bo
|
||||
|
||||
EasyGraphicsItem::EasyGraphicsItem(uint8_t _index, const::profiler::BlocksTreeRoot& _root)
|
||||
: QGraphicsItem(nullptr)
|
||||
, m_threadName(::profiler_gui::decoratedThreadName(EASY_GLOBALS.use_decorated_thread_name, _root))
|
||||
, m_threadName(::profiler_gui::decoratedThreadName(EASY_GLOBALS.use_decorated_thread_name, _root, EASY_GLOBALS.hex_thread_id))
|
||||
, m_pRoot(&_root)
|
||||
, m_index(_index)
|
||||
{
|
||||
@ -108,7 +108,7 @@ EasyGraphicsItem::~EasyGraphicsItem()
|
||||
|
||||
void EasyGraphicsItem::validateName()
|
||||
{
|
||||
m_threadName = ::profiler_gui::decoratedThreadName(EASY_GLOBALS.use_decorated_thread_name, *m_pRoot);
|
||||
m_threadName = ::profiler_gui::decoratedThreadName(EASY_GLOBALS.use_decorated_thread_name, *m_pRoot, EASY_GLOBALS.hex_thread_id);
|
||||
}
|
||||
|
||||
const EasyGraphicsView* EasyGraphicsItem::view() const
|
||||
|
@ -253,6 +253,7 @@ EasyHistogramItem::EasyHistogramItem() : Parent(nullptr)
|
||||
, m_workerImageScale(1)
|
||||
, m_workerTopDuration(0)
|
||||
, m_workerBottomDuration(0)
|
||||
, m_blockTotalDuraion(0)
|
||||
, m_timer(::std::bind(&This::onTimeout, this))
|
||||
, m_boundaryTimer([this](){ updateImage(); }, true)
|
||||
, m_pProfilerThread(nullptr)
|
||||
@ -749,26 +750,15 @@ void EasyHistogramItem::paintById(QPainter* _painter)
|
||||
_painter->setPen(Qt::black);
|
||||
rect.setRect(0, bottom + 2, width, widget->defaultFontHeight());
|
||||
|
||||
const auto* item = !::profiler_gui::is_max(EASY_GLOBALS.selected_block) ? &easyBlock(EASY_GLOBALS.selected_block) : (!m_selectedBlocks.empty() ? &easyBlock(m_selectedBlocks.front()) : nullptr);
|
||||
if (item != nullptr)
|
||||
if (!m_selectedBlocks.empty())
|
||||
{
|
||||
const auto name = *item->tree.node->name() != 0 ? item->tree.node->name() : easyDescriptor(item->tree.node->id()).name();
|
||||
if (item->tree.per_thread_stats != nullptr)
|
||||
{
|
||||
_painter->drawText(rect, Qt::AlignHCenter | Qt::TextDontClip, QString("%1 | %2 | %3 calls | %4% of thread profiled time").arg(m_threadName).arg(::profiler_gui::toUnicode(name))
|
||||
.arg(item->tree.per_thread_stats->calls_number)
|
||||
.arg(m_threadProfiledTime ? QString::number(100. * (double)item->tree.per_thread_stats->total_duration / (double)m_threadProfiledTime, 'f', 2) : QString("100")));
|
||||
}
|
||||
else
|
||||
{
|
||||
_painter->drawText(rect, Qt::AlignHCenter | Qt::TextDontClip, QString("%1 | %2 | %3 calls").arg(m_threadName).arg(::profiler_gui::toUnicode(name))
|
||||
.arg(m_selectedBlocks.size()));
|
||||
}
|
||||
_painter->drawText(rect, Qt::AlignHCenter | Qt::TextDontClip, QString("%1 | %2 | %3 calls | %4% of thread profiled time")
|
||||
.arg(m_threadName).arg(m_blockName).arg(m_selectedBlocks.size())
|
||||
.arg(m_threadProfiledTime ? QString::number(100. * (double)m_blockTotalDuraion / (double)m_threadProfiledTime, 'f', 2) : QString("100")));
|
||||
}
|
||||
else
|
||||
{
|
||||
_painter->drawText(rect, Qt::AlignHCenter | Qt::TextDontClip, QString("%1 | %2 | %3 calls").arg(m_threadName).arg(::profiler_gui::toUnicode(easyDescriptor(m_blockId).name()))
|
||||
.arg(m_selectedBlocks.size()));
|
||||
_painter->drawText(rect, Qt::AlignHCenter | Qt::TextDontClip, QString("%1 | %2 | 0 calls").arg(m_threadName).arg(m_blockName));
|
||||
}
|
||||
|
||||
_painter->drawText(rect, Qt::AlignLeft, bindMode ? " MODE: zoom" : " MODE: overview");
|
||||
@ -803,13 +793,16 @@ void EasyHistogramItem::setSource(::profiler::thread_id_t _thread_id, const ::pr
|
||||
if (m_workerThread.joinable())
|
||||
m_workerThread.join();
|
||||
|
||||
m_blockName.clear();
|
||||
m_blockTotalDuraion = 0;
|
||||
|
||||
delete m_workerImage;
|
||||
m_workerImage = nullptr;
|
||||
m_imageOriginUpdate = m_imageOrigin = 0;
|
||||
m_imageScaleUpdate = m_imageScale = 1;
|
||||
|
||||
m_selectedBlocks.clear();
|
||||
::profiler::BlocksTree::children_t().swap(m_selectedBlocks);
|
||||
{ ::profiler::BlocksTree::children_t().swap(m_selectedBlocks); }
|
||||
|
||||
m_bPermitImageUpdate = false;
|
||||
m_regime = Hist_Pointer;
|
||||
@ -826,7 +819,7 @@ void EasyHistogramItem::setSource(::profiler::thread_id_t _thread_id, const ::pr
|
||||
else
|
||||
{
|
||||
const auto& root = EASY_GLOBALS.profiler_blocks[_thread_id];
|
||||
m_threadName = ::profiler_gui::decoratedThreadName(EASY_GLOBALS.use_decorated_thread_name, root);
|
||||
m_threadName = ::profiler_gui::decoratedThreadName(EASY_GLOBALS.use_decorated_thread_name, root, EASY_GLOBALS.hex_thread_id);
|
||||
|
||||
if (root.children.empty())
|
||||
m_threadDuration = 0;
|
||||
@ -918,9 +911,6 @@ void EasyHistogramItem::setSource(::profiler::thread_id_t _thread_id, ::profiler
|
||||
|
||||
m_bPermitImageUpdate = false; // Set to false because m_workerThread have to parse input data first. This will be set to true when m_workerThread finish - see onTimeout()
|
||||
m_regime = Hist_Id;
|
||||
m_pSource = nullptr;
|
||||
m_topDurationStr.clear();
|
||||
m_bottomDurationStr.clear();
|
||||
|
||||
m_timer.stop();
|
||||
m_boundaryTimer.stop();
|
||||
@ -929,138 +919,173 @@ void EasyHistogramItem::setSource(::profiler::thread_id_t _thread_id, ::profiler
|
||||
if (m_workerThread.joinable())
|
||||
m_workerThread.join();
|
||||
|
||||
m_pSource = nullptr;
|
||||
m_topDurationStr.clear();
|
||||
m_bottomDurationStr.clear();
|
||||
m_blockName.clear();
|
||||
m_blockTotalDuraion = 0;
|
||||
|
||||
delete m_workerImage;
|
||||
m_workerImage = nullptr;
|
||||
m_imageOriginUpdate = m_imageOrigin = 0;
|
||||
m_imageScaleUpdate = m_imageScale = 1;
|
||||
|
||||
m_selectedBlocks.clear();
|
||||
::profiler::BlocksTree::children_t().swap(m_selectedBlocks);
|
||||
{ ::profiler::BlocksTree::children_t().swap(m_selectedBlocks); }
|
||||
|
||||
m_threadId = _thread_id;
|
||||
m_blockId = _block_id;
|
||||
|
||||
if (m_threadId != 0 && !::profiler_gui::is_max(m_blockId))
|
||||
{
|
||||
m_blockName = ::profiler_gui::toUnicode(easyDescriptor(m_blockId).name());
|
||||
|
||||
const auto& root = EASY_GLOBALS.profiler_blocks[_thread_id];
|
||||
m_threadName = ::profiler_gui::decoratedThreadName(EASY_GLOBALS.use_decorated_thread_name, root);
|
||||
|
||||
if (root.children.empty())
|
||||
m_threadDuration = 0;
|
||||
else
|
||||
m_threadDuration = easyBlock(root.children.back()).tree.node->end() - easyBlock(root.children.front()).tree.node->begin();
|
||||
|
||||
m_threadProfiledTime = root.profiled_time;
|
||||
m_threadWaitTime = root.wait_time;
|
||||
m_threadName = ::profiler_gui::decoratedThreadName(EASY_GLOBALS.use_decorated_thread_name, root, EASY_GLOBALS.hex_thread_id);
|
||||
m_pProfilerThread = &root;
|
||||
m_timeUnits = EASY_GLOBALS.time_units;
|
||||
|
||||
m_bReady.store(false, ::std::memory_order_release);
|
||||
m_workerThread = ::std::thread([this](decltype(root) profiler_thread)
|
||||
if (root.children.empty())
|
||||
{
|
||||
typedef ::std::vector<::std::pair<::profiler::block_index_t, ::profiler::block_index_t> > Stack;
|
||||
m_threadDuration = 0;
|
||||
m_threadProfiledTime = 0;
|
||||
m_threadWaitTime = 0;
|
||||
|
||||
m_maxDuration = 0;
|
||||
m_minDuration = 1e30;
|
||||
//const auto& profiler_thread = EASY_GLOBALS.profiler_blocks[m_threadId];
|
||||
Stack stack;
|
||||
stack.reserve(profiler_thread.depth);
|
||||
m_topDuration = m_maxDuration = 0;
|
||||
m_bottomDuration = m_minDuration = 1e30;
|
||||
|
||||
for (auto frame : profiler_thread.children)
|
||||
m_bPermitImageUpdate = true;
|
||||
|
||||
m_bReady.store(true, ::std::memory_order_release);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_threadDuration = easyBlock(root.children.back()).tree.node->end() - easyBlock(root.children.front()).tree.node->begin();
|
||||
m_threadProfiledTime = root.profiled_time;
|
||||
m_threadWaitTime = root.wait_time;
|
||||
|
||||
m_bReady.store(false, ::std::memory_order_release);
|
||||
m_workerThread = ::std::thread([this](decltype(root) profiler_thread, ::profiler::block_index_t selected_block)
|
||||
{
|
||||
const auto& frame_block = easyBlock(frame).tree;
|
||||
if (frame_block.node->id() == m_blockId)
|
||||
typedef ::std::vector<::std::pair<::profiler::block_index_t, ::profiler::block_index_t> > Stack;
|
||||
|
||||
m_maxDuration = 0;
|
||||
m_minDuration = 1e30;
|
||||
//const auto& profiler_thread = EASY_GLOBALS.profiler_blocks[m_threadId];
|
||||
Stack stack;
|
||||
stack.reserve(profiler_thread.depth);
|
||||
|
||||
const bool has_selected_block = !::profiler_gui::is_max(selected_block);
|
||||
|
||||
for (auto frame : profiler_thread.children)
|
||||
{
|
||||
m_selectedBlocks.push_back(frame);
|
||||
const auto& frame_block = easyBlock(frame).tree;
|
||||
if (frame_block.node->id() == m_blockId || (!has_selected_block && m_blockId == easyDescriptor(frame_block.node->id()).id()))
|
||||
{
|
||||
m_selectedBlocks.push_back(frame);
|
||||
|
||||
const auto w = frame_block.node->duration();
|
||||
if (w > m_maxDuration)
|
||||
m_maxDuration = w;
|
||||
const auto w = frame_block.node->duration();
|
||||
if (w > m_maxDuration)
|
||||
m_maxDuration = w;
|
||||
|
||||
if (w < m_minDuration)
|
||||
m_minDuration = w;
|
||||
}
|
||||
if (w < m_minDuration)
|
||||
m_minDuration = w;
|
||||
|
||||
stack.push_back(::std::make_pair(frame, 0U));
|
||||
while (!stack.empty())
|
||||
{
|
||||
if (m_bReady.load(::std::memory_order_acquire))
|
||||
return;
|
||||
m_blockTotalDuraion += w;
|
||||
}
|
||||
|
||||
auto& top = stack.back();
|
||||
const auto& top_children = easyBlock(top.first).tree.children;
|
||||
const auto stack_size = stack.size();
|
||||
for (auto end = top_children.size(); top.second < end; ++top.second)
|
||||
stack.push_back(::std::make_pair(frame, 0U));
|
||||
while (!stack.empty())
|
||||
{
|
||||
if (m_bReady.load(::std::memory_order_acquire))
|
||||
return;
|
||||
|
||||
const auto child_index = top_children[top.second];
|
||||
const auto& child = easyBlock(child_index).tree;
|
||||
if (child.node->id() == m_blockId)
|
||||
auto& top = stack.back();
|
||||
const auto& top_children = easyBlock(top.first).tree.children;
|
||||
const auto stack_size = stack.size();
|
||||
for (auto end = top_children.size(); top.second < end; ++top.second)
|
||||
{
|
||||
m_selectedBlocks.push_back(child_index);
|
||||
if (m_bReady.load(::std::memory_order_acquire))
|
||||
return;
|
||||
|
||||
const auto w = child.node->duration();
|
||||
if (w > m_maxDuration)
|
||||
m_maxDuration = w;
|
||||
if (w < m_minDuration)
|
||||
m_minDuration = w;
|
||||
const auto child_index = top_children[top.second];
|
||||
const auto& child = easyBlock(child_index).tree;
|
||||
if (child.node->id() == m_blockId || (!has_selected_block && m_blockId == easyDescriptor(child.node->id()).id()))
|
||||
{
|
||||
m_selectedBlocks.push_back(child_index);
|
||||
|
||||
const auto w = child.node->duration();
|
||||
if (w > m_maxDuration)
|
||||
m_maxDuration = w;
|
||||
|
||||
if (w < m_minDuration)
|
||||
m_minDuration = w;
|
||||
|
||||
m_blockTotalDuraion += w;
|
||||
}
|
||||
|
||||
if (!child.children.empty())
|
||||
{
|
||||
++top.second;
|
||||
stack.push_back(::std::make_pair(child_index, 0U));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!child.children.empty())
|
||||
if (stack_size == stack.size())
|
||||
{
|
||||
++top.second;
|
||||
stack.push_back(::std::make_pair(child_index, 0U));
|
||||
break;
|
||||
stack.pop_back();
|
||||
}
|
||||
}
|
||||
|
||||
if (stack_size == stack.size())
|
||||
{
|
||||
stack.pop_back();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (m_selectedBlocks.empty())
|
||||
{
|
||||
m_topDurationStr.clear();
|
||||
m_bottomDurationStr.clear();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_maxDuration *= 1e-3;
|
||||
m_minDuration *= 1e-3;
|
||||
|
||||
if ((m_maxDuration - m_minDuration) < 1e-3)
|
||||
if (m_selectedBlocks.empty())
|
||||
{
|
||||
if (m_minDuration > 0.1)
|
||||
m_topDurationStr.clear();
|
||||
m_bottomDurationStr.clear();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (has_selected_block)
|
||||
{
|
||||
m_minDuration -= 0.1;
|
||||
const auto& item = easyBlock(selected_block).tree;
|
||||
if (*item.node->name() != 0)
|
||||
m_blockName = ::profiler_gui::toUnicode(item.node->name());
|
||||
}
|
||||
else
|
||||
|
||||
m_maxDuration *= 1e-3;
|
||||
m_minDuration *= 1e-3;
|
||||
|
||||
if ((m_maxDuration - m_minDuration) < 1e-3)
|
||||
{
|
||||
m_maxDuration = 0.1;
|
||||
m_minDuration = 0;
|
||||
if (m_minDuration > 0.1)
|
||||
{
|
||||
m_minDuration -= 0.1;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_maxDuration = 0.1;
|
||||
m_minDuration = 0;
|
||||
}
|
||||
}
|
||||
|
||||
m_topDurationStr = ::profiler_gui::timeStringReal(m_timeUnits, m_maxDuration, 3);
|
||||
m_bottomDurationStr = ::profiler_gui::timeStringReal(m_timeUnits, m_minDuration, 3);
|
||||
}
|
||||
|
||||
m_topDurationStr = ::profiler_gui::timeStringReal(m_timeUnits, m_maxDuration, 3);
|
||||
m_bottomDurationStr = ::profiler_gui::timeStringReal(m_timeUnits, m_minDuration, 3);
|
||||
}
|
||||
|
||||
|
||||
m_topDuration = m_maxDuration;
|
||||
m_bottomDuration = m_minDuration;
|
||||
|
||||
m_topDuration = m_maxDuration;
|
||||
m_bottomDuration = m_minDuration;
|
||||
m_bReady.store(true, ::std::memory_order_release);
|
||||
|
||||
m_bReady.store(true, ::std::memory_order_release);
|
||||
}, std::ref(root), EASY_GLOBALS.selected_block);
|
||||
|
||||
}, std::ref(root));
|
||||
m_timeouts = 3;
|
||||
m_timer.start(WORKER_THREAD_CHECK_INTERVAL);
|
||||
}
|
||||
|
||||
m_timeouts = 3;
|
||||
m_timer.start(WORKER_THREAD_CHECK_INTERVAL);
|
||||
show();
|
||||
}
|
||||
else
|
||||
@ -1077,7 +1102,7 @@ void EasyHistogramItem::validateName()
|
||||
{
|
||||
if (m_threadName.isEmpty())
|
||||
return;
|
||||
m_threadName = ::profiler_gui::decoratedThreadName(EASY_GLOBALS.use_decorated_thread_name, EASY_GLOBALS.profiler_blocks[m_threadId]);
|
||||
m_threadName = ::profiler_gui::decoratedThreadName(EASY_GLOBALS.use_decorated_thread_name, EASY_GLOBALS.profiler_blocks[m_threadId], EASY_GLOBALS.hex_thread_id);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
@ -1712,14 +1737,8 @@ EasyGraphicsScrollbar::EasyGraphicsScrollbar(QWidget* _parent)
|
||||
m_histogramItem->onModeChanged();
|
||||
});
|
||||
|
||||
connect(&EASY_GLOBALS.events, &::profiler_gui::EasyGlobalSignals::threadNameDecorationChanged, [this]()
|
||||
{
|
||||
if (m_histogramItem->isVisible())
|
||||
{
|
||||
m_histogramItem->validateName();
|
||||
scene()->update();
|
||||
}
|
||||
});
|
||||
connect(&EASY_GLOBALS.events, &::profiler_gui::EasyGlobalSignals::threadNameDecorationChanged, this, &This::onThreadViewChanged);
|
||||
connect(&EASY_GLOBALS.events, &::profiler_gui::EasyGlobalSignals::hexThreadIdChanged, this, &This::onThreadViewChanged);
|
||||
|
||||
centerOn(0, 0);
|
||||
}
|
||||
@ -1731,6 +1750,17 @@ EasyGraphicsScrollbar::~EasyGraphicsScrollbar()
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void EasyGraphicsScrollbar::onThreadViewChanged()
|
||||
{
|
||||
if (m_histogramItem->isVisible())
|
||||
{
|
||||
m_histogramItem->validateName();
|
||||
scene()->update();
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void EasyGraphicsScrollbar::clear()
|
||||
{
|
||||
setHistogramSource(0, nullptr);
|
||||
@ -2003,54 +2033,6 @@ void EasyGraphicsScrollbar::resizeEvent(QResizeEvent* _event)
|
||||
m_histogramItem->updateImage();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
/*
|
||||
void EasyGraphicsScrollbar::contextMenuEvent(QContextMenuEvent* _event)
|
||||
{
|
||||
if (EASY_GLOBALS.profiler_blocks.empty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
QMenu menu;
|
||||
|
||||
for (const auto& it : EASY_GLOBALS.profiler_blocks)
|
||||
{
|
||||
QString label;
|
||||
if (it.second.got_name())
|
||||
label = ::std::move(QString("%1 Thread %2").arg(it.second.name()).arg(it.first));
|
||||
else
|
||||
label = ::std::move(QString("Thread %1").arg(it.first));
|
||||
|
||||
auto action = new QAction(label, nullptr);
|
||||
action->setData(it.first);
|
||||
action->setCheckable(true);
|
||||
action->setChecked(it.first == EASY_GLOBALS.selected_thread);
|
||||
connect(action, &QAction::triggered, this, &This::onThreadActionClicked);
|
||||
|
||||
menu.addAction(action);
|
||||
}
|
||||
|
||||
menu.exec(QCursor::pos());
|
||||
_event->accept();
|
||||
}
|
||||
*/
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void EasyGraphicsScrollbar::onThreadActionClicked(bool)
|
||||
{
|
||||
auto action = qobject_cast<QAction*>(sender());
|
||||
if (action == nullptr)
|
||||
return;
|
||||
|
||||
const auto thread_id = action->data().toUInt();
|
||||
if (thread_id != EASY_GLOBALS.selected_thread)
|
||||
{
|
||||
EASY_GLOBALS.selected_thread = thread_id;
|
||||
emit EASY_GLOBALS.events.selectedThreadChanged(thread_id);
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void EasyGraphicsScrollbar::onWindowWidthChange(qreal _width)
|
||||
|
@ -157,9 +157,11 @@ class EasyHistogramItem : public QGraphicsItem
|
||||
qreal m_workerImageScale;
|
||||
qreal m_workerTopDuration;
|
||||
qreal m_workerBottomDuration;
|
||||
::profiler::timestamp_t m_blockTotalDuraion;
|
||||
QString m_topDurationStr;
|
||||
QString m_bottomDurationStr;
|
||||
QString m_threadName;
|
||||
QString m_blockName;
|
||||
::profiler::BlocksTree::children_t m_selectedBlocks;
|
||||
QImage m_mainImage;
|
||||
EasyQTimer m_timer;
|
||||
@ -270,7 +272,6 @@ public:
|
||||
void mouseMoveEvent(QMouseEvent* _event) override;
|
||||
void wheelEvent(QWheelEvent* _event) override;
|
||||
void resizeEvent(QResizeEvent* _event) override;
|
||||
//void contextMenuEvent(QContextMenuEvent* _event) override;
|
||||
|
||||
void dragEnterEvent(QDragEnterEvent*) override {}
|
||||
|
||||
@ -325,7 +326,7 @@ signals:
|
||||
|
||||
private slots:
|
||||
|
||||
void onThreadActionClicked(bool);
|
||||
void onThreadViewChanged();
|
||||
void onWindowWidthChange(qreal _width);
|
||||
|
||||
}; // END of class EasyGraphicsScrollbar.
|
||||
|
@ -84,6 +84,7 @@ namespace profiler_gui {
|
||||
, connected(false)
|
||||
, fps_enabled(true)
|
||||
, use_decorated_thread_name(false)
|
||||
, hex_thread_id(false)
|
||||
, enable_event_markers(true)
|
||||
, enable_statistics(true)
|
||||
, enable_zero_length(true)
|
||||
|
@ -101,29 +101,47 @@ namespace profiler_gui {
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline QString decoratedThreadName(bool _use_decorated_thread_name, const::profiler::BlocksTreeRoot& _root, const QString& _unicodeThreadWord)
|
||||
inline QString decoratedThreadName(bool _use_decorated_thread_name, const::profiler::BlocksTreeRoot& _root, const QString& _unicodeThreadWord, bool _hex = false)
|
||||
{
|
||||
if (_root.got_name())
|
||||
{
|
||||
QString rootname(toUnicode(_root.name()));
|
||||
if (!_use_decorated_thread_name || rootname.contains(_unicodeThreadWord, Qt::CaseInsensitive))
|
||||
{
|
||||
if (_hex)
|
||||
return QString("%1 0x%2").arg(rootname).arg(_root.thread_id, 0, 16);
|
||||
return QString("%1 %2").arg(rootname).arg(_root.thread_id);
|
||||
}
|
||||
|
||||
if (_hex)
|
||||
return QString("%1 Thread 0x%2").arg(rootname).arg(_root.thread_id, 0, 16);
|
||||
return QString("%1 Thread %2").arg(rootname).arg(_root.thread_id);
|
||||
}
|
||||
|
||||
if (_hex)
|
||||
return QString("Thread 0x%1").arg(_root.thread_id, 0, 16);
|
||||
return QString("Thread %1").arg(_root.thread_id);
|
||||
}
|
||||
|
||||
inline QString decoratedThreadName(bool _use_decorated_thread_name, const ::profiler::BlocksTreeRoot& _root)
|
||||
inline QString decoratedThreadName(bool _use_decorated_thread_name, const ::profiler::BlocksTreeRoot& _root, bool _hex = false)
|
||||
{
|
||||
if (_root.got_name())
|
||||
{
|
||||
QString rootname(toUnicode(_root.name()));
|
||||
if (!_use_decorated_thread_name || rootname.contains(toUnicode("thread"), Qt::CaseInsensitive))
|
||||
{
|
||||
if (_hex)
|
||||
return QString("%1 0x%2").arg(rootname).arg(_root.thread_id, 0, 16);
|
||||
return QString("%1 %2").arg(rootname).arg(_root.thread_id);
|
||||
}
|
||||
|
||||
if (_hex)
|
||||
return QString("%1 Thread 0x%2").arg(rootname).arg(_root.thread_id, 0, 16);
|
||||
return QString("%1 Thread %2").arg(rootname).arg(_root.thread_id);
|
||||
}
|
||||
|
||||
if (_hex)
|
||||
return QString("Thread 0x%1").arg(_root.thread_id, 0, 16);
|
||||
return QString("Thread %1").arg(_root.thread_id);
|
||||
}
|
||||
|
||||
@ -163,6 +181,7 @@ namespace profiler_gui {
|
||||
bool connected; ///< Is connected to source (to be able to capture profiling information)
|
||||
bool fps_enabled; ///< Is FPS Monitor enabled
|
||||
bool use_decorated_thread_name; ///< Add "Thread" to the name of each thread (if there is no one)
|
||||
bool hex_thread_id; ///< Use hex view for thread-id instead of decimal
|
||||
bool enable_event_markers; ///< 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)
|
||||
bool enable_zero_length; ///< Enable zero length blocks (if true, then such blocks will have width == 1 pixel on each scale)
|
||||
|
@ -82,6 +82,7 @@ namespace profiler_gui {
|
||||
void autoAdjustHistogramChanged();
|
||||
void hierarchyFlagChanged(bool);
|
||||
void threadNameDecorationChanged();
|
||||
void hexThreadIdChanged();
|
||||
void refreshRequired();
|
||||
void blocksTreeModeChanged();
|
||||
|
||||
|
@ -385,6 +385,16 @@ EasyMainWindow::EasyMainWindow() : Parent(), m_lastAddress("localhost"), m_lastP
|
||||
emit EASY_GLOBALS.events.threadNameDecorationChanged();
|
||||
});
|
||||
|
||||
action = submenu->addAction("Display hex thread id");
|
||||
action->setToolTip("Display hex thread id instead of decimal.");
|
||||
action->setCheckable(true);
|
||||
action->setChecked(EASY_GLOBALS.hex_thread_id);
|
||||
connect(action, &QAction::triggered, [this](bool _checked)
|
||||
{
|
||||
EASY_GLOBALS.hex_thread_id = _checked;
|
||||
emit EASY_GLOBALS.events.hexThreadIdChanged();
|
||||
});
|
||||
|
||||
submenu->addSeparator();
|
||||
auto actionGroup = new QActionGroup(this);
|
||||
actionGroup->setExclusive(true);
|
||||
@ -1264,6 +1274,10 @@ void EasyMainWindow::loadSettings()
|
||||
if (!flag.isNull())
|
||||
EASY_GLOBALS.use_decorated_thread_name = flag.toBool();
|
||||
|
||||
flag = settings.value("hex_thread_id");
|
||||
if (!flag.isNull())
|
||||
EASY_GLOBALS.hex_thread_id = flag.toBool();
|
||||
|
||||
flag = settings.value("fps_timer_interval");
|
||||
if (!flag.isNull())
|
||||
EASY_GLOBALS.fps_timer_interval = flag.toInt();
|
||||
@ -1334,6 +1348,7 @@ void EasyMainWindow::saveSettingsAndGeometry()
|
||||
settings.setValue("enable_event_indicators", EASY_GLOBALS.enable_event_markers);
|
||||
settings.setValue("auto_adjust_histogram_height", EASY_GLOBALS.auto_adjust_histogram_height);
|
||||
settings.setValue("use_decorated_thread_name", EASY_GLOBALS.use_decorated_thread_name);
|
||||
settings.setValue("hex_thread_id", EASY_GLOBALS.hex_thread_id);
|
||||
settings.setValue("enable_statistics", EASY_GLOBALS.enable_statistics);
|
||||
settings.setValue("fps_timer_interval", EASY_GLOBALS.fps_timer_interval);
|
||||
settings.setValue("max_fps_history", EASY_GLOBALS.max_fps_history);
|
||||
|
@ -176,7 +176,7 @@ void EasyTreeWidgetLoader::fillTree(::profiler::timestamp_t& _beginTime, const u
|
||||
m_mode = _mode;
|
||||
m_thread = ::std::thread(&EasyTreeWidgetLoader::setTreeInternal1, this,
|
||||
::std::ref(_beginTime), _blocksNumber, ::std::ref(_blocksTree), _colorizeRows,
|
||||
EASY_GLOBALS.add_zero_blocks_to_hierarchy, EASY_GLOBALS.use_decorated_thread_name, EASY_GLOBALS.time_units);
|
||||
EASY_GLOBALS.add_zero_blocks_to_hierarchy, EASY_GLOBALS.use_decorated_thread_name, EASY_GLOBALS.hex_thread_id, 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, EasyTreeMode _mode)
|
||||
@ -185,12 +185,12 @@ void EasyTreeWidgetLoader::fillTreeBlocks(const::profiler_gui::TreeBlocks& _bloc
|
||||
m_mode = _mode;
|
||||
m_thread = ::std::thread(&EasyTreeWidgetLoader::setTreeInternal2, this,
|
||||
_beginTime, ::std::ref(_blocks), _left, _right, _strict, _colorizeRows,
|
||||
EASY_GLOBALS.add_zero_blocks_to_hierarchy, EASY_GLOBALS.use_decorated_thread_name, EASY_GLOBALS.time_units);
|
||||
EASY_GLOBALS.add_zero_blocks_to_hierarchy, EASY_GLOBALS.use_decorated_thread_name, EASY_GLOBALS.hex_thread_id, EASY_GLOBALS.time_units);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void EasyTreeWidgetLoader::setTreeInternal1(::profiler::timestamp_t& _beginTime, const unsigned int _blocksNumber, const ::profiler::thread_blocks_tree_t& _blocksTree, bool _colorizeRows, bool _addZeroBlocks, bool _decoratedThreadNames, ::profiler_gui::TimeUnits _units)
|
||||
void EasyTreeWidgetLoader::setTreeInternal1(::profiler::timestamp_t& _beginTime, const unsigned int _blocksNumber, const ::profiler::thread_blocks_tree_t& _blocksTree, bool _colorizeRows, bool _addZeroBlocks, bool _decoratedThreadNames, bool _hexThreadId, ::profiler_gui::TimeUnits _units)
|
||||
{
|
||||
m_items.reserve(_blocksNumber + _blocksTree.size()); // _blocksNumber does not include Thread root blocks
|
||||
|
||||
@ -219,7 +219,7 @@ void EasyTreeWidgetLoader::setTreeInternal1(::profiler::timestamp_t& _beginTime,
|
||||
|
||||
const auto& root = threadTree.second;
|
||||
auto item = new EasyTreeWidgetItem();
|
||||
item->setText(COL_NAME, ::profiler_gui::decoratedThreadName(_decoratedThreadNames, root, u_thread));
|
||||
item->setText(COL_NAME, ::profiler_gui::decoratedThreadName(_decoratedThreadNames, root, u_thread, _hexThreadId));
|
||||
|
||||
::profiler::timestamp_t duration = 0;
|
||||
if (!root.children.empty())
|
||||
@ -268,7 +268,7 @@ void EasyTreeWidgetLoader::setTreeInternal1(::profiler::timestamp_t& _beginTime,
|
||||
|
||||
typedef ::std::unordered_map<::profiler::thread_id_t, ::profiler::block_index_t, ::profiler_gui::do_no_hash<::profiler::thread_id_t>::hasher_t> BeginEndIndicesMap;
|
||||
|
||||
void EasyTreeWidgetLoader::setTreeInternal2(const ::profiler::timestamp_t& _beginTime, const ::profiler_gui::TreeBlocks& _blocks, ::profiler::timestamp_t _left, ::profiler::timestamp_t _right, bool _strict, bool _colorizeRows, bool _addZeroBlocks, bool _decoratedThreadNames, ::profiler_gui::TimeUnits _units)
|
||||
void EasyTreeWidgetLoader::setTreeInternal2(const ::profiler::timestamp_t& _beginTime, const ::profiler_gui::TreeBlocks& _blocks, ::profiler::timestamp_t _left, ::profiler::timestamp_t _right, bool _strict, bool _colorizeRows, bool _addZeroBlocks, bool _decoratedThreadNames, bool _hexThreadId, ::profiler_gui::TimeUnits _units)
|
||||
{
|
||||
//size_t blocksNumber = 0;
|
||||
//for (const auto& block : _blocks)
|
||||
@ -309,7 +309,7 @@ void EasyTreeWidgetLoader::setTreeInternal2(const ::profiler::timestamp_t& _begi
|
||||
else
|
||||
{
|
||||
thread_item = new EasyTreeWidgetItem();
|
||||
thread_item->setText(COL_NAME, ::profiler_gui::decoratedThreadName(_decoratedThreadNames, *block.root, u_thread));
|
||||
thread_item->setText(COL_NAME, ::profiler_gui::decoratedThreadName(_decoratedThreadNames, *block.root, u_thread, _hexThreadId));
|
||||
|
||||
if (!block.root->children.empty())
|
||||
duration = blocksTree(block.root->children.back()).node->end() - blocksTree(block.root->children.front()).node->begin();
|
||||
|
@ -122,8 +122,8 @@ private:
|
||||
void setDone();
|
||||
void setProgress(int _progress);
|
||||
|
||||
void setTreeInternal1(::profiler::timestamp_t& _beginTime, const unsigned int _blocksNumber, const ::profiler::thread_blocks_tree_t& _blocksTree, bool _colorizeRows, bool _addZeroBlocks, bool _decoratedThreadNames, ::profiler_gui::TimeUnits _units);
|
||||
void setTreeInternal2(const ::profiler::timestamp_t& _beginTime, const ::profiler_gui::TreeBlocks& _blocks, ::profiler::timestamp_t _left, ::profiler::timestamp_t _right, bool _strict, bool _colorizeRows, bool _addZeroBlocks, bool _decoratedThreadNames, ::profiler_gui::TimeUnits _units);
|
||||
void setTreeInternal1(::profiler::timestamp_t& _beginTime, const unsigned int _blocksNumber, const ::profiler::thread_blocks_tree_t& _blocksTree, bool _colorizeRows, bool _addZeroBlocks, bool _decoratedThreadNames, bool _hexThreadId, ::profiler_gui::TimeUnits _units);
|
||||
void setTreeInternal2(const ::profiler::timestamp_t& _beginTime, const ::profiler_gui::TreeBlocks& _blocks, ::profiler::timestamp_t _left, ::profiler::timestamp_t _right, bool _strict, bool _colorizeRows, bool _addZeroBlocks, bool _decoratedThreadNames, bool _hexThreadId, ::profiler_gui::TimeUnits _units);
|
||||
size_t setTreeInternal(const ::profiler::BlocksTreeRoot& _threadRoot, ::profiler::block_index_t _firstCswitch, const ::profiler::timestamp_t& _beginTime, const ::profiler::BlocksTree::children_t& _children, EasyTreeWidgetItem* _parent, EasyTreeWidgetItem* _frame, ::profiler::timestamp_t _left, ::profiler::timestamp_t _right, bool _strict, ::profiler::timestamp_t& _duration, bool _colorizeRows, bool _addZeroBlocks, ::profiler_gui::TimeUnits _units);
|
||||
size_t setTreeInternalPlain(const ::profiler::BlocksTreeRoot& _threadRoot, ::profiler::block_index_t _firstCswitch, const ::profiler::timestamp_t& _beginTime, const ::profiler::BlocksTree::children_t& _children, EasyTreeWidgetItem* _parent, EasyTreeWidgetItem* _frame, ::profiler::timestamp_t _left, ::profiler::timestamp_t _right, bool _strict, ::profiler::timestamp_t& _duration, bool _colorizeRows, bool _addZeroBlocks, ::profiler_gui::TimeUnits _units);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user