0
0
mirror of https://github.com/yse/easy_profiler.git synced 2025-01-14 08:37:55 +08:00

(GUI) Added possibility to torn on/off decorated thread names (add/don't add "Thread" word info thread name. Example, "Render" convert to "Render Thread", "WorkerThread" "My thread" will not convert in any way). See Settings->View->Use decorated thread names.

* (GUI) Fixed lagging when painting very long block on large scale.
This commit is contained in:
Victor Zarubkin 2016-12-14 21:47:33 +03:00
parent 0304a55c15
commit eafcb40970
11 changed files with 226 additions and 106 deletions

View File

@ -56,8 +56,6 @@
#include <QGraphicsScene> #include <QGraphicsScene>
#include <QGraphicsProxyWidget> #include <QGraphicsProxyWidget>
#include <QFormLayout>
#include <QLabel>
#include <QWheelEvent> #include <QWheelEvent>
#include <QMouseEvent> #include <QMouseEvent>
#include <QKeyEvent> #include <QKeyEvent>
@ -119,6 +117,20 @@ inline T logn(T _value)
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
EasyBoldLabel::EasyBoldLabel(const QString& _text, QWidget* _parent) : QLabel(_text, _parent)
{
auto f = font();
f.setBold(true);
setFont(f);
}
EasyBoldLabel::~EasyBoldLabel()
{
}
//////////////////////////////////////////////////////////////////////////
void EasyBackgroundItem::paint(QPainter* _painter, const QStyleOptionGraphicsItem*, QWidget*) void EasyBackgroundItem::paint(QPainter* _painter, const QStyleOptionGraphicsItem*, QWidget*)
{ {
auto const sceneView = static_cast<EasyGraphicsView*>(scene()->parent()); auto const sceneView = static_cast<EasyGraphicsView*>(scene()->parent());
@ -429,11 +441,20 @@ void EasyGraphicsView::setTree(const ::profiler::thread_blocks_tree_t& _blocksTr
m_beginTime -= ::std::min(m_beginTime, additional_offset); m_beginTime -= ::std::min(m_beginTime, additional_offset);
EASY_GLOBALS.begin_time = m_beginTime; EASY_GLOBALS.begin_time = m_beginTime;
// Sort threads by name
::std::vector<::std::reference_wrapper<const ::profiler::BlocksTreeRoot> > sorted_roots;
sorted_roots.reserve(_blocksTree.size());
for (const auto& threadTree : _blocksTree)
sorted_roots.push_back(threadTree.second);
::std::sort(sorted_roots.begin(), sorted_roots.end(), [](const ::profiler::BlocksTreeRoot& _a, const ::profiler::BlocksTreeRoot& _b) {
return _a.thread_name < _b.thread_name;
});
// Filling scene with items // Filling scene with items
m_items.reserve(_blocksTree.size()); m_items.reserve(_blocksTree.size());
qreal y = TIMELINE_ROW_SIZE; qreal y = TIMELINE_ROW_SIZE;
const EasyGraphicsItem *longestItem = nullptr, *mainThreadItem = nullptr; const EasyGraphicsItem *longestItem = nullptr, *mainThreadItem = nullptr;
for (const auto& threadTree : _blocksTree) for (const ::profiler::BlocksTreeRoot& t : sorted_roots)
{ {
if (m_items.size() == 0xff) if (m_items.size() == 0xff)
{ {
@ -441,8 +462,6 @@ void EasyGraphicsView::setTree(const ::profiler::thread_blocks_tree_t& _blocksTr
break; break;
} }
const auto& t = threadTree.second;
// fill scene with new items // fill scene with new items
qreal h = 0, x = 0; qreal h = 0, x = 0;
@ -475,10 +494,10 @@ void EasyGraphicsView::setTree(const ::profiler::thread_blocks_tree_t& _blocksTr
y += h + ::profiler_gui::THREADS_ROW_SPACING; y += h + ::profiler_gui::THREADS_ROW_SPACING;
if (longestTree == threadTree.first) if (longestTree == t.thread_id)
longestItem = item; longestItem = item;
if (mainTree == threadTree.first) if (mainTree == t.thread_id)
mainThreadItem = item; mainThreadItem = item;
} }
@ -1253,6 +1272,22 @@ void EasyGraphicsView::initMode()
m_pScrollbar->setHystogramFrom(EASY_GLOBALS.selected_thread, EASY_GLOBALS.selected_block_id); m_pScrollbar->setHystogramFrom(EASY_GLOBALS.selected_thread, EASY_GLOBALS.selected_block_id);
onRefreshRequired(); 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();
});
} }
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
@ -1371,8 +1406,8 @@ void EasyGraphicsView::onIdleTimeout()
int row = 0; int row = 0;
if (itemDesc.type() == ::profiler::BLOCK_TYPE_BLOCK) if (itemDesc.type() == ::profiler::BLOCK_TYPE_BLOCK)
{ {
lay->addWidget(new QLabel("Block:", widget), row, 0, Qt::AlignRight); //lay->addWidget(new QLabel("Name:", widget), row, 0, Qt::AlignRight);
lay->addWidget(new QLabel(name, widget), row, 1, 1, 4, Qt::AlignLeft); lay->addWidget(new EasyBoldLabel(name, widget), row, 0, 1, 5, Qt::AlignHCenter);
++row; ++row;
lay->addWidget(new QLabel("Duration:", widget), row, 0, Qt::AlignRight); lay->addWidget(new QLabel("Duration:", widget), row, 0, Qt::AlignRight);
@ -1381,7 +1416,10 @@ void EasyGraphicsView::onIdleTimeout()
} }
else else
{ {
lay->addWidget(new QLabel("Event:", widget), row, 0, Qt::AlignRight); lay->addWidget(new EasyBoldLabel("User defined event", widget), row, 0, 1, 2, Qt::AlignHCenter);
++row;
lay->addWidget(new QLabel("Name:", widget), row, 0, Qt::AlignRight);
lay->addWidget(new QLabel(name, widget), row, 1, Qt::AlignLeft); lay->addWidget(new QLabel(name, widget), row, 1, Qt::AlignLeft);
++row; ++row;
} }
@ -1396,7 +1434,7 @@ void EasyGraphicsView::onIdleTimeout()
lay->addWidget(new QLabel(::profiler_gui::timeStringRealNs(EASY_GLOBALS.time_units, itemBlock.per_thread_stats->average_duration(), 3), widget), row, 1, 1, 3, Qt::AlignLeft); lay->addWidget(new QLabel(::profiler_gui::timeStringRealNs(EASY_GLOBALS.time_units, itemBlock.per_thread_stats->average_duration(), 3), widget), row, 1, 1, 3, Qt::AlignLeft);
++row; ++row;
lay->addWidget(new QLabel("-------- Statistics --------", widget), row, 0, 1, 5, Qt::AlignHCenter); lay->addWidget(new EasyBoldLabel("-------- Statistics --------", widget), row, 0, 1, 5, Qt::AlignHCenter);
lay->addWidget(new QLabel("per ", widget), row + 1, 0, Qt::AlignRight); 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("This %:", widget), row + 2, 0, Qt::AlignRight);
lay->addWidget(new QLabel("Sum %:", widget), row + 3, 0, Qt::AlignRight); lay->addWidget(new QLabel("Sum %:", widget), row + 3, 0, Qt::AlignRight);
@ -1449,7 +1487,7 @@ void EasyGraphicsView::onIdleTimeout()
} }
else else
{ {
lay->addWidget(new QLabel("N calls/Thread:", widget), 1, 0, Qt::AlignRight); lay->addWidget(new QLabel("N calls/Thread:", widget), row, 0, Qt::AlignRight);
lay->addWidget(new QLabel(QString::number(itemBlock.per_thread_stats->calls_number), widget), row, 1, Qt::AlignLeft); lay->addWidget(new QLabel(QString::number(itemBlock.per_thread_stats->calls_number), widget), row, 1, Qt::AlignLeft);
} }
} }
@ -1464,16 +1502,26 @@ void EasyGraphicsView::onIdleTimeout()
if (cse) if (cse)
{ {
auto widget = new QWidget(); auto widget = new QWidget();
auto lay = new QFormLayout(widget); auto lay = new QGridLayout(widget);
lay->setLabelAlignment(Qt::AlignRight);
int row = 0;
lay->addWidget(new EasyBoldLabel("Context switch event", widget), row, 0, 1, 2, Qt::AlignHCenter);
++row;
lay->addWidget(new QLabel("Thread:", widget), row, 0, Qt::AlignRight);
auto it = EASY_GLOBALS.profiler_blocks.find(cse->tree.node->id()); auto it = EASY_GLOBALS.profiler_blocks.find(cse->tree.node->id());
if (it != EASY_GLOBALS.profiler_blocks.end()) if (it != EASY_GLOBALS.profiler_blocks.end())
lay->addRow("Thread:", new QLabel(QString("%1 %2").arg(cse->tree.node->id()).arg(it->second.name()))); lay->addWidget(new QLabel(QString("%1 %2").arg(cse->tree.node->id()).arg(it->second.name()), widget), row, 1, Qt::AlignLeft);
else else
lay->addRow("Thread:", new QLabel(QString::number(cse->tree.node->id()))); lay->addWidget(new QLabel(QString::number(cse->tree.node->id()), widget), row, 1, Qt::AlignLeft);
lay->addRow("Process:", new QLabel(cse->tree.node->name()));
lay->addRow("Duration:", new QLabel(::profiler_gui::timeStringRealNs(EASY_GLOBALS.time_units, cse->tree.node->duration(), 3))); ++row;
lay->addWidget(new QLabel("Process:", widget), row, 0, Qt::AlignRight);
lay->addWidget(new QLabel(cse->tree.node->name(), widget), row, 1, Qt::AlignLeft);
++row;
lay->addWidget(new QLabel("Duration:", widget), row, 0, Qt::AlignRight);
lay->addWidget(new QLabel(::profiler_gui::timeStringRealNs(EASY_GLOBALS.time_units, cse->tree.node->duration(), 3), widget), row, 1, Qt::AlignLeft);
m_csInfoWidget = new QGraphicsProxyWidget(); m_csInfoWidget = new QGraphicsProxyWidget();
m_csInfoWidget->setWidget(widget); m_csInfoWidget->setWidget(widget);

View File

@ -60,6 +60,7 @@
#include <QPoint> #include <QPoint>
#include <QRectF> #include <QRectF>
#include <QTimer> #include <QTimer>
#include <QLabel>
#include "easy/reader.h" #include "easy/reader.h"
#include "common_types.h" #include "common_types.h"
@ -94,6 +95,13 @@ EASY_QGRAPHICSITEM(EasyThreadNameItem);
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
struct EasyBoldLabel : public QLabel {
EasyBoldLabel(const QString& _text, QWidget* _parent = nullptr);
virtual ~EasyBoldLabel();
};
//////////////////////////////////////////////////////////////////////////
class EasyGraphicsView : public QGraphicsView class EasyGraphicsView : public QGraphicsView
{ {
Q_OBJECT Q_OBJECT

View File

@ -86,28 +86,21 @@ const auto SELECTED_ITEM_FONT = ::profiler_gui::EFont("Helvetica", 10, QFont::Bo
EasyGraphicsItem::EasyGraphicsItem(uint8_t _index, const::profiler::BlocksTreeRoot& _root) EasyGraphicsItem::EasyGraphicsItem(uint8_t _index, const::profiler::BlocksTreeRoot& _root)
: QGraphicsItem(nullptr) : QGraphicsItem(nullptr)
, m_threadName(::profiler_gui::decoratedThreadName(EASY_GLOBALS.use_decorated_thread_name, _root))
, m_pRoot(&_root) , m_pRoot(&_root)
, m_index(_index) , m_index(_index)
{ {
const auto u_thread = ::profiler_gui::toUnicode("thread");
if (_root.got_name())
{
QString rootname(::profiler_gui::toUnicode(_root.name()));
if (rootname.contains(u_thread, Qt::CaseInsensitive))
m_threadName = ::std::move(QString("%1 %2").arg(rootname).arg(_root.thread_id));
else
m_threadName = ::std::move(QString("%1 Thread %2").arg(rootname).arg(_root.thread_id));
}
else
{
m_threadName = ::std::move(QString("Thread %1").arg(_root.thread_id));
}
} }
EasyGraphicsItem::~EasyGraphicsItem() EasyGraphicsItem::~EasyGraphicsItem()
{ {
} }
void EasyGraphicsItem::validateName()
{
m_threadName = ::profiler_gui::decoratedThreadName(EASY_GLOBALS.use_decorated_thread_name, *m_pRoot);
}
const EasyGraphicsView* EasyGraphicsItem::view() const const EasyGraphicsView* EasyGraphicsItem::view() const
{ {
return static_cast<const EasyGraphicsView*>(scene()->parent()); return static_cast<const EasyGraphicsView*>(scene()->parent());
@ -375,6 +368,25 @@ void EasyGraphicsItem::paint(QPainter* _painter, const QStyleOptionGraphicsItem*
_painter->setPen(Qt::NoPen); _painter->setPen(Qt::NoPen);
} }
const auto wprev = w;
decltype(w) dw = 0;
if (item.left() < sceneLeft)
{
// if item left border is out of screen then attach text to the left border of the screen
// to ensure text is always visible for items presenting on the screen.
w += (item.left() - sceneLeft) * currentScale;
x = sceneLeft * currentScale - dx - 2;
w += 2;
dw = 2;
}
if (item.right() > sceneRight)
{
w -= (item.right() - sceneRight) * currentScale;
w += 2;
dw += 2;
}
if (w < EASY_GLOBALS.blocks_size_min) if (w < EASY_GLOBALS.blocks_size_min)
w = EASY_GLOBALS.blocks_size_min; w = EASY_GLOBALS.blocks_size_min;
@ -384,13 +396,18 @@ void EasyGraphicsItem::paint(QPainter* _painter, const QStyleOptionGraphicsItem*
prevRight = rect.right() + EASY_GLOBALS.blocks_spacing; prevRight = rect.right() + EASY_GLOBALS.blocks_spacing;
//skip_children(next_level, item.children_begin); //skip_children(next_level, item.children_begin);
if (w < EASY_GLOBALS.blocks_narrow_size) if (wprev < EASY_GLOBALS.blocks_narrow_size)
continue; continue;
if (totalHeight > ::profiler_gui::GRAPHICS_ROW_SIZE) if (totalHeight > ::profiler_gui::GRAPHICS_ROW_SIZE)
flags = Qt::AlignCenter; flags = Qt::AlignCenter;
else if (!(item.width() < 1)) else if (!(item.width() < 1))
flags = Qt::AlignHCenter; flags = Qt::AlignHCenter;
if (dw > 1) {
w -= dw;
x += 2;
}
} }
else else
{ {
@ -440,6 +457,25 @@ void EasyGraphicsItem::paint(QPainter* _painter, const QStyleOptionGraphicsItem*
if (dh > 0) if (dh > 0)
h -= dh; h -= dh;
const auto wprev = w;
decltype(w) dw = 0;
if (item.left() < sceneLeft)
{
// if item left border is out of screen then attach text to the left border of the screen
// to ensure text is always visible for items presenting on the screen.
w += (item.left() - sceneLeft) * currentScale;
x = sceneLeft * currentScale - dx - 2;
w += 2;
dw = 2;
}
if (item.right() > sceneRight)
{
w -= (item.right() - sceneRight) * currentScale;
w += 2;
dw += 2;
}
if (w < EASY_GLOBALS.blocks_size_min) if (w < EASY_GLOBALS.blocks_size_min)
w = EASY_GLOBALS.blocks_size_min; w = EASY_GLOBALS.blocks_size_min;
@ -447,34 +483,24 @@ void EasyGraphicsItem::paint(QPainter* _painter, const QStyleOptionGraphicsItem*
_painter->drawRect(rect); _painter->drawRect(rect);
prevRight = rect.right() + EASY_GLOBALS.blocks_spacing; prevRight = rect.right() + EASY_GLOBALS.blocks_spacing;
if (w < EASY_GLOBALS.blocks_narrow_size) if (wprev < EASY_GLOBALS.blocks_narrow_size)
{ {
dont_skip_children(next_level, item.children_begin, w < narrow_size_half ? BLOCK_ITEM_DO_PAINT_FIRST : BLOCK_ITEM_DO_PAINT); dont_skip_children(next_level, item.children_begin, wprev < narrow_size_half ? BLOCK_ITEM_DO_PAINT_FIRST : BLOCK_ITEM_DO_PAINT);
continue; continue;
} }
dont_skip_children(next_level, item.children_begin, BLOCK_ITEM_DO_PAINT); dont_skip_children(next_level, item.children_begin, BLOCK_ITEM_DO_PAINT);
if (!(item.width() < 1)) if (!(item.width() < 1))
flags = Qt::AlignHCenter; flags = Qt::AlignHCenter;
if (dw > 1) {
w -= dw;
x += 2;
}
} }
// Draw text----------------------------------- // Draw text-----------------------------------
// calculating text coordinates rect.setRect(x + 1, top, w - 1, h);
auto xtext = x;
if (item.left() < sceneLeft)
{
// if item left border is out of screen then attach text to the left border of the screen
// to ensure text is always visible for items presenting on the screen.
w += (item.left() - sceneLeft) * currentScale;
xtext = sceneLeft * currentScale - dx;
}
if (item.right() > sceneRight)
{
w -= (item.right() - sceneRight) * currentScale;
}
rect.setRect(xtext + 1, top, w - 1, h);
// text will be painted with inverse color // text will be painted with inverse color
//auto textColor = inverseColor < 0x00808080 ? profiler::colors::Black : profiler::colors::White; //auto textColor = inverseColor < 0x00808080 ? profiler::colors::Black : profiler::colors::White;
@ -547,28 +573,36 @@ void EasyGraphicsItem::paint(QPainter* _painter, const QStyleOptionGraphicsItem*
} }
auto x = item.left() * currentScale - dx; auto x = item.left() * currentScale - dx;
decltype(w) dw = 0;
if (item.left() < sceneLeft)
{
// if item left border is out of screen then attach text to the left border of the screen
// to ensure text is always visible for items presenting on the screen.
w += (item.left() - sceneLeft) * currentScale;
x = sceneLeft * currentScale - dx - 2;
w += 2;
dw = 2;
}
if (item.right() > sceneRight)
{
w -= (item.right() - sceneRight) * currentScale;
w += 2;
dw += 2;
}
rect.setRect(x, top, w, h); rect.setRect(x, top, w, h);
_painter->drawRect(rect); _painter->drawRect(rect);
if (!selectedItemsWasPainted && w > EASY_GLOBALS.blocks_narrow_size) if (!selectedItemsWasPainted && w > EASY_GLOBALS.blocks_narrow_size)
{ {
if (dw > 1) {
w -= dw;
x += 2;
}
// Draw text----------------------------------- // Draw text-----------------------------------
// calculating text coordinates rect.setRect(x + 1, top, w - 1, h);
auto xtext = x;
if (item.left() < sceneLeft)
{
// if item left border is out of screen then attach text to the left border of the screen
// to ensure text is always visible for items presenting on the screen.
w += (item.left() - sceneLeft) * currentScale;
xtext = sceneLeft * currentScale - dx;
}
if (item.right() > sceneRight)
{
w -= (item.right() - sceneRight) * currentScale;
}
rect.setRect(xtext + 1, top, w - 1, h);
// text will be painted with inverse color // text will be painted with inverse color
//auto textColor = 0x00ffffff - previousColor; //auto textColor = 0x00ffffff - previousColor;

View File

@ -87,6 +87,8 @@ public:
// Public non-virtual methods // Public non-virtual methods
void validateName();
const ::profiler::BlocksTreeRoot* root() const; const ::profiler::BlocksTreeRoot* root() const;
const QString& threadName() const; const QString& threadName() const;

View File

@ -762,10 +762,7 @@ void EasyHystogramItem::setSource(::profiler::thread_id_t _thread_id, const ::pr
else else
{ {
const auto& root = EASY_GLOBALS.profiler_blocks[_thread_id]; const auto& root = EASY_GLOBALS.profiler_blocks[_thread_id];
if (root.got_name()) m_threadName = ::profiler_gui::decoratedThreadName(EASY_GLOBALS.use_decorated_thread_name, root);
m_threadName = ::std::move(QString("%1 Thread %2").arg(root.name()).arg(_thread_id));
else
m_threadName = ::std::move(QString("Thread %1").arg(_thread_id));
if (root.children.empty()) if (root.children.empty())
m_threadDuration = 0; m_threadDuration = 0;
@ -813,10 +810,7 @@ void EasyHystogramItem::setSource(::profiler::thread_id_t _thread_id, ::profiler
if (m_threadId != 0 && !::profiler_gui::is_max(m_blockId)) if (m_threadId != 0 && !::profiler_gui::is_max(m_blockId))
{ {
const auto& root = EASY_GLOBALS.profiler_blocks[_thread_id]; const auto& root = EASY_GLOBALS.profiler_blocks[_thread_id];
if (root.got_name()) m_threadName = ::profiler_gui::decoratedThreadName(EASY_GLOBALS.use_decorated_thread_name, root);
m_threadName = ::std::move(QString("%1 Thread %2").arg(root.name()).arg(_thread_id));
else
m_threadName = ::std::move(QString("Thread %1").arg(_thread_id));
if (root.children.empty()) if (root.children.empty())
m_threadDuration = 0; m_threadDuration = 0;
@ -918,6 +912,15 @@ void EasyHystogramItem::setSource(::profiler::thread_id_t _thread_id, ::profiler
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
void EasyHystogramItem::validateName()
{
if (m_threadName.isEmpty())
return;
m_threadName = ::profiler_gui::decoratedThreadName(EASY_GLOBALS.use_decorated_thread_name, EASY_GLOBALS.profiler_blocks[m_threadId]);
}
//////////////////////////////////////////////////////////////////////////
void EasyHystogramItem::onTimeout() void EasyHystogramItem::onTimeout()
{ {
if (!isVisible()) if (!isVisible())
@ -1189,6 +1192,14 @@ EasyGraphicsScrollbar::EasyGraphicsScrollbar(QWidget* _parent)
scene()->update(); scene()->update();
}); });
connect(&EASY_GLOBALS.events, &::profiler_gui::EasyGlobalSignals::threadNameDecorationChanged, [this]()
{
if (!m_hystogramItem->isVisible())
return;
m_hystogramItem->validateName();
scene()->update();
});
centerOn(0, 0); centerOn(0, 0);
} }

View File

@ -178,6 +178,7 @@ public:
void setSource(::profiler::thread_id_t _thread_id, const ::profiler_gui::EasyItems* _items); void setSource(::profiler::thread_id_t _thread_id, const ::profiler_gui::EasyItems* _items);
void setSource(::profiler::thread_id_t _thread_id, ::profiler::block_id_t _block_id); void setSource(::profiler::thread_id_t _thread_id, ::profiler::block_id_t _block_id);
void validateName();
void updateImage(); void updateImage();
private: private:

View File

@ -69,6 +69,7 @@ namespace profiler_gui {
, chrono_text_position(ChronoTextPosition_Center) , chrono_text_position(ChronoTextPosition_Center)
, time_units(TimeUnits_auto) , time_units(TimeUnits_auto)
, connected(false) , connected(false)
, use_decorated_thread_name(true)
, enable_event_indicators(true) , enable_event_indicators(true)
, enable_statistics(true) , enable_statistics(true)
, enable_zero_length(true) , enable_zero_length(true)

View File

@ -90,6 +90,34 @@ namespace profiler_gui {
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
inline QString decoratedThreadName(bool _use_decorated_thread_name, const::profiler::BlocksTreeRoot& _root, const QString& _unicodeThreadWord)
{
if (_root.got_name())
{
QString rootname(toUnicode(_root.name()));
if (!_use_decorated_thread_name || rootname.contains(_unicodeThreadWord, Qt::CaseInsensitive))
return QString("%1 %2").arg(rootname).arg(_root.thread_id);
return QString("%1 Thread %2").arg(rootname).arg(_root.thread_id);
}
return QString("Thread %1").arg(_root.thread_id);
}
inline QString decoratedThreadName(bool _use_decorated_thread_name, const ::profiler::BlocksTreeRoot& _root)
{
if (_root.got_name())
{
QString rootname(toUnicode(_root.name()));
if (!_use_decorated_thread_name || rootname.contains(toUnicode("thread"), Qt::CaseInsensitive))
return QString("%1 %2").arg(rootname).arg(_root.thread_id);
return QString("%1 Thread %2").arg(rootname).arg(_root.thread_id);
}
return QString("Thread %1").arg(_root.thread_id);
}
//////////////////////////////////////////////////////////////////////////
enum ChronometerTextPosition : int8_t enum ChronometerTextPosition : int8_t
{ {
ChronoTextPosition_Center = 0, ChronoTextPosition_Center = 0,
@ -119,6 +147,7 @@ namespace profiler_gui {
ChronometerTextPosition chrono_text_position; ///< Selected interval text position ChronometerTextPosition chrono_text_position; ///< Selected interval text position
TimeUnits time_units; ///< Units type for time (milliseconds, microseconds, nanoseconds or auto-definition) 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 connected; ///< Is connected to source (to be able to capture profiling information)
bool use_decorated_thread_name; ///< Add "Thread" to the name of each thread (if there is no one)
bool enable_event_indicators; ///< Enable event indicators painting (These are narrow rectangles at the bottom of each thread) 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) 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) bool enable_zero_length; ///< Enable zero length blocks (if true, then such blocks will have width == 1 pixel on each scale)

View File

@ -56,6 +56,7 @@ namespace profiler_gui {
void blocksRefreshRequired(bool); void blocksRefreshRequired(bool);
void timelineMarkerChanged(); void timelineMarkerChanged();
void hierarchyFlagChanged(bool); void hierarchyFlagChanged(bool);
void threadNameDecorationChanged();
void refreshRequired(); void refreshRequired();
}; // END of class EasyGlobalSignals. }; // END of class EasyGlobalSignals.

View File

@ -336,6 +336,16 @@ EasyMainWindow::EasyMainWindow() : Parent(), m_lastAddress("localhost"), m_lastP
action->setChecked(EASY_GLOBALS.enable_event_indicators); action->setChecked(EASY_GLOBALS.enable_event_indicators);
connect(action, &QAction::triggered, this, &This::onEventIndicatorsChange); connect(action, &QAction::triggered, this, &This::onEventIndicatorsChange);
action = submenu->addAction("Use decorated thread names");
action->setToolTip("Add \'Thread\' word into thread name if there is no one already.\nExamples: \'Render\' will change to \'Render Thread\'\n\'WorkerThread\' will not change.");
action->setCheckable(true);
action->setChecked(EASY_GLOBALS.use_decorated_thread_name);
connect(action, &QAction::triggered, [this](bool _checked)
{
EASY_GLOBALS.use_decorated_thread_name = _checked;
emit EASY_GLOBALS.events.threadNameDecorationChanged();
});
submenu->addSeparator(); submenu->addSeparator();
auto actionGroup = new QActionGroup(this); auto actionGroup = new QActionGroup(this);
actionGroup->setExclusive(true); actionGroup->setExclusive(true);
@ -1014,6 +1024,10 @@ void EasyMainWindow::loadSettings()
if (!flag.isNull()) if (!flag.isNull())
EASY_GLOBALS.enable_event_indicators = flag.toBool(); EASY_GLOBALS.enable_event_indicators = flag.toBool();
flag = settings.value("use_decorated_thread_name");
if (!flag.isNull())
EASY_GLOBALS.use_decorated_thread_name = flag.toBool();
flag = settings.value("enable_statistics"); flag = settings.value("enable_statistics");
if (!flag.isNull()) if (!flag.isNull())
EASY_GLOBALS.enable_statistics = flag.toBool(); EASY_GLOBALS.enable_statistics = flag.toBool();
@ -1070,6 +1084,7 @@ void EasyMainWindow::saveSettingsAndGeometry()
settings.setValue("bind_scene_and_tree_expand_status", EASY_GLOBALS.bind_scene_and_tree_expand_status); settings.setValue("bind_scene_and_tree_expand_status", EASY_GLOBALS.bind_scene_and_tree_expand_status);
settings.setValue("selecting_block_changes_thread", EASY_GLOBALS.selecting_block_changes_thread); settings.setValue("selecting_block_changes_thread", EASY_GLOBALS.selecting_block_changes_thread);
settings.setValue("enable_event_indicators", EASY_GLOBALS.enable_event_indicators); settings.setValue("enable_event_indicators", EASY_GLOBALS.enable_event_indicators);
settings.setValue("use_decorated_thread_name", EASY_GLOBALS.use_decorated_thread_name);
settings.setValue("enable_statistics", EASY_GLOBALS.enable_statistics); settings.setValue("enable_statistics", EASY_GLOBALS.enable_statistics);
settings.setValue("encoding", QTextCodec::codecForLocale()->name()); settings.setValue("encoding", QTextCodec::codecForLocale()->name());

View File

@ -196,22 +196,7 @@ void FillTreeClass<T>::setTreeInternal1(T& _safelocker, Items& _items, ThreadedI
const auto& root = threadTree.second; const auto& root = threadTree.second;
auto item = new EasyTreeWidgetItem(); auto item = new EasyTreeWidgetItem();
item->setText(COL_NAME, ::profiler_gui::decoratedThreadName(EASY_GLOBALS.use_decorated_thread_name, root, u_thread));
QString threadName;
if (root.got_name())
{
QString rootname(::profiler_gui::toUnicode(root.name()));
if (rootname.contains(u_thread, Qt::CaseInsensitive))
threadName = ::std::move(QString("%1 %2").arg(rootname).arg(root.thread_id));
else
threadName = ::std::move(QString("%1 Thread %2").arg(rootname).arg(root.thread_id));
}
else
{
threadName = ::std::move(QString("Thread %1").arg(root.thread_id));
}
item->setText(COL_NAME, threadName);
::profiler::timestamp_t duration = 0; ::profiler::timestamp_t duration = 0;
if (!root.children.empty()) if (!root.children.empty())
@ -296,22 +281,7 @@ void FillTreeClass<T>::setTreeInternal2(T& _safelocker, Items& _items, ThreadedI
else else
{ {
thread_item = new EasyTreeWidgetItem(); thread_item = new EasyTreeWidgetItem();
thread_item->setText(COL_NAME, ::profiler_gui::decoratedThreadName(EASY_GLOBALS.use_decorated_thread_name, *block.root, u_thread));
QString threadName;
if (block.root->got_name())
{
QString rootname(::profiler_gui::toUnicode(block.root->name()));
if (rootname.contains(u_thread, Qt::CaseInsensitive))
threadName = ::std::move(QString("%1 %2").arg(rootname).arg(block.root->thread_id));
else
threadName = ::std::move(QString("%1 Thread %2").arg(rootname).arg(block.root->thread_id));
}
else
{
threadName = ::std::move(QString("Thread %1").arg(block.root->thread_id));
}
thread_item->setText(COL_NAME, threadName);
if (!block.root->children.empty()) if (!block.root->children.empty())
duration = blocksTree(block.root->children.back()).node->end() - blocksTree(block.root->children.front()).node->begin(); duration = blocksTree(block.root->children.back()).node->end() - blocksTree(block.root->children.front()).node->begin();