mirror of
https://github.com/yse/easy_profiler.git
synced 2025-01-14 00:27:55 +08:00
(profiler reader) Gathering per frame statistics + refactoring;
(profiler GUI) Lightening profiler::colors to be more bright; (ProfTreeWidget) Displaying per frame and per thread statistics; (ProfGraphicsView) Draw chronometer item text in Difference mode to be more readable.
This commit is contained in:
parent
888ea2e61c
commit
3017be305a
@ -94,19 +94,21 @@ namespace profiler {
|
||||
|
||||
typedef ::std::list<BlocksTree> children_t;
|
||||
|
||||
children_t children; ///< List of children blocks. May be empty.
|
||||
::profiler::SerilizedBlock* node; ///< Pointer to serilized data (type, name, begin, end etc.)
|
||||
::profiler::BlockStatistics* frame_statistics; ///< Pointer to statistics for this block within the parent (may be nullptr for top-level blocks)
|
||||
::profiler::BlockStatistics* total_statistics; ///< Pointer to statistics for this block within the bounds of all frames per current thread
|
||||
children_t children; ///< List of children blocks. May be empty.
|
||||
::profiler::SerilizedBlock* node; ///< Pointer to serilized data (type, name, begin, end etc.)
|
||||
::profiler::BlockStatistics* per_parent_stats; ///< Pointer to statistics for this block within the parent (may be nullptr for top-level blocks)
|
||||
::profiler::BlockStatistics* per_frame_stats; ///< Pointer to statistics for this block within the frame (may be nullptr for top-level blocks)
|
||||
::profiler::BlockStatistics* per_thread_stats; ///< Pointer to statistics for this block within the bounds of all frames per current thread
|
||||
|
||||
unsigned int block_index; ///< Index of this block
|
||||
unsigned int total_children_number; ///< Number of all children including number of grandchildren (and so on)
|
||||
unsigned short depth; ///< Maximum number of sublevels (maximum children depth)
|
||||
unsigned int block_index; ///< Index of this block
|
||||
unsigned int total_children_number; ///< Number of all children including number of grandchildren (and so on)
|
||||
unsigned short depth; ///< Maximum number of sublevels (maximum children depth)
|
||||
|
||||
BlocksTree()
|
||||
: node(nullptr)
|
||||
, frame_statistics(nullptr)
|
||||
, total_statistics(nullptr)
|
||||
, per_parent_stats(nullptr)
|
||||
, per_frame_stats(nullptr)
|
||||
, per_thread_stats(nullptr)
|
||||
, block_index(0)
|
||||
, total_children_number(0)
|
||||
, depth(0)
|
||||
@ -132,8 +134,9 @@ namespace profiler {
|
||||
delete node;
|
||||
}
|
||||
|
||||
release(total_statistics);
|
||||
release(frame_statistics);
|
||||
release(per_thread_stats);
|
||||
release(per_parent_stats);
|
||||
release(per_frame_stats);
|
||||
}
|
||||
|
||||
bool operator < (const This& other) const
|
||||
@ -157,28 +160,35 @@ namespace profiler {
|
||||
delete node;
|
||||
}
|
||||
|
||||
if (total_statistics != that.total_statistics)
|
||||
if (per_thread_stats != that.per_thread_stats)
|
||||
{
|
||||
release(total_statistics);
|
||||
release(per_thread_stats);
|
||||
}
|
||||
|
||||
if (frame_statistics != that.frame_statistics)
|
||||
if (per_parent_stats != that.per_parent_stats)
|
||||
{
|
||||
release(frame_statistics);
|
||||
release(per_parent_stats);
|
||||
}
|
||||
|
||||
if (per_frame_stats != that.per_frame_stats)
|
||||
{
|
||||
release(per_frame_stats);
|
||||
}
|
||||
|
||||
children = ::std::move(that.children);
|
||||
node = that.node;
|
||||
frame_statistics = that.frame_statistics;
|
||||
total_statistics = that.total_statistics;
|
||||
per_parent_stats = that.per_parent_stats;
|
||||
per_frame_stats = that.per_frame_stats;
|
||||
per_thread_stats = that.per_thread_stats;
|
||||
|
||||
block_index = that.block_index;
|
||||
total_children_number = that.total_children_number;
|
||||
depth = that.depth;
|
||||
|
||||
that.node = nullptr;
|
||||
that.frame_statistics = nullptr;
|
||||
that.total_statistics = nullptr;
|
||||
that.per_parent_stats = nullptr;
|
||||
that.per_frame_stats = nullptr;
|
||||
that.per_thread_stats = nullptr;
|
||||
}
|
||||
|
||||
}; // END of class BlocksTree.
|
||||
|
@ -52,7 +52,7 @@ const unsigned short ROW_SPACING = 4;
|
||||
const QRgb BORDERS_COLOR = 0x00a07050;
|
||||
const QRgb BACKGROUND_1 = 0x00dddddd;
|
||||
const QRgb BACKGROUND_2 = 0x00ffffff;
|
||||
const QColor CHRONOMETER_COLOR2 = QColor::fromRgba(0x40408040);
|
||||
const QColor CHRONOMETER_COLOR2 = QColor::fromRgba(0x20408040);
|
||||
|
||||
const unsigned int TEST_PROGRESSION_BASE = 4;
|
||||
|
||||
@ -589,6 +589,7 @@ void ProfChronometerItem::paint(QPainter* _painter, const QStyleOptionGraphicsIt
|
||||
_painter->drawRect(rect);
|
||||
|
||||
// draw text
|
||||
_painter->setCompositionMode(QPainter::CompositionMode_Difference); // This lets the text to be visible on every background
|
||||
_painter->setPen(0xffffffff - m_color.rgb());
|
||||
_painter->setFont(m_font);
|
||||
|
||||
@ -604,7 +605,7 @@ void ProfChronometerItem::paint(QPainter* _painter, const QStyleOptionGraphicsIt
|
||||
|
||||
if (!m_bMain)
|
||||
{
|
||||
rect.setTop(rect.top() + textRect.height() * 1.33);
|
||||
rect.setTop(rect.top() + textRect.height() * 1.5);
|
||||
}
|
||||
|
||||
if (textRect.width() < rect.width())
|
||||
@ -979,7 +980,7 @@ void ProfGraphicsView::setTree(const ::profiler::thread_blocks_tree_t& _blocksTr
|
||||
}
|
||||
|
||||
// Calculating scene rect
|
||||
const qreal endX = time2position(finish) + 1.0;
|
||||
const qreal endX = time2position(finish) + 1500.0;
|
||||
scene()->setSceneRect(0, 0, endX, y);
|
||||
|
||||
// Stub! :O
|
||||
@ -1074,7 +1075,7 @@ qreal ProfGraphicsView::setTree(ProfGraphicsItem* _item, const ::profiler::Block
|
||||
|
||||
const auto color = child.node->block()->getColor();
|
||||
b.block = &child;
|
||||
b.color = ::profiler_gui::toRgb(::profiler::colors::get_red(color), ::profiler::colors::get_green(color), ::profiler::colors::get_blue(color));
|
||||
b.color = ::profiler_gui::fromProfilerRgb(::profiler::colors::get_red(color), ::profiler::colors::get_green(color), ::profiler::colors::get_blue(color));
|
||||
b.setRect(xbegin, _y, duration, GRAPHICS_ROW_SIZE);
|
||||
b.totalHeight = GRAPHICS_ROW_SIZE + h;
|
||||
|
||||
@ -1113,6 +1114,10 @@ void ProfGraphicsView::setScrollbar(ProfGraphicsScrollbar* _scrollbar)
|
||||
void ProfGraphicsView::updateVisibleSceneRect()
|
||||
{
|
||||
m_visibleSceneRect = mapToScene(rect()).boundingRect();
|
||||
|
||||
auto vbar = verticalScrollBar();
|
||||
if (vbar && vbar->isVisible())
|
||||
m_visibleSceneRect.setWidth(m_visibleSceneRect.width() - vbar->width() - 2);
|
||||
}
|
||||
|
||||
void ProfGraphicsView::updateScene()
|
||||
@ -1375,7 +1380,7 @@ void ProfGraphicsView::mouseMoveEvent(QMouseEvent* _event)
|
||||
updateVisibleSceneRect(); // Update scene visible rect only once
|
||||
|
||||
// Update flicker speed
|
||||
m_flickerSpeedX += delta.x() >> 2;
|
||||
m_flickerSpeedX += delta.x() >> 1;
|
||||
m_flickerSpeedY += delta.y() >> 1;
|
||||
if (!m_flickerTimer.isActive())
|
||||
{
|
||||
|
@ -39,21 +39,38 @@ enum ColumnsIndexes
|
||||
COL_UNKNOWN = -1,
|
||||
|
||||
COL_NAME = 0,
|
||||
|
||||
COL_BEGIN,
|
||||
|
||||
COL_DURATION,
|
||||
COL_SELF_DURATION,
|
||||
COL_DURATION_SUM_PER_PARENT,
|
||||
COL_DURATION_SUM_PER_FRAME,
|
||||
COL_DURATION_SUM_PER_THREAD,
|
||||
|
||||
COL_SELF_DURATION_PERCENT,
|
||||
COL_PERCENT_OF_PARENT,
|
||||
COL_PERCENT_OF_FRAME,
|
||||
COL_PERCENT_PER_PARENT,
|
||||
COL_PERCENT_PER_FRAME,
|
||||
COL_PERCENT_SUM_PER_PARENT,
|
||||
COL_PERCENT_SUM_PER_FRAME,
|
||||
COL_PERCENT_SUM_PER_THREAD,
|
||||
|
||||
COL_END,
|
||||
COL_MIN,
|
||||
COL_MAX,
|
||||
COL_AVERAGE,
|
||||
COL_NCALLS,
|
||||
COL_MIN_TOTAL,
|
||||
COL_MAX_TOTAL,
|
||||
COL_AVERAGE_TOTAL,
|
||||
COL_NCALLS_TOTAL,
|
||||
|
||||
COL_MIN_PER_FRAME,
|
||||
COL_MAX_PER_FRAME,
|
||||
COL_AVERAGE_PER_FRAME,
|
||||
COL_NCALLS_PER_FRAME,
|
||||
|
||||
COL_MIN_PER_PARENT,
|
||||
COL_MAX_PER_PARENT,
|
||||
COL_AVERAGE_PER_PARENT,
|
||||
COL_NCALLS_PER_PARENT,
|
||||
|
||||
COL_MIN_PER_THREAD,
|
||||
COL_MAX_PER_THREAD,
|
||||
COL_AVERAGE_PER_THREAD,
|
||||
COL_NCALLS_PER_THREAD,
|
||||
|
||||
COL_COLUMNS_NUMBER
|
||||
};
|
||||
@ -87,15 +104,19 @@ bool ProfTreeWidgetItem::operator < (const Parent& _other) const
|
||||
return Parent::operator < (_other);
|
||||
}
|
||||
|
||||
case COL_NCALLS_TOTAL:
|
||||
case COL_NCALLS:
|
||||
case COL_NCALLS_PER_THREAD:
|
||||
case COL_NCALLS_PER_PARENT:
|
||||
case COL_NCALLS_PER_FRAME:
|
||||
{
|
||||
return data(col, Qt::UserRole).toUInt() < _other.data(col, Qt::UserRole).toUInt();
|
||||
}
|
||||
|
||||
case COL_SELF_DURATION_PERCENT:
|
||||
case COL_PERCENT_OF_PARENT:
|
||||
case COL_PERCENT_OF_FRAME:
|
||||
case COL_PERCENT_PER_PARENT:
|
||||
case COL_PERCENT_PER_FRAME:
|
||||
case COL_PERCENT_SUM_PER_PARENT:
|
||||
case COL_PERCENT_SUM_PER_FRAME:
|
||||
case COL_PERCENT_SUM_PER_THREAD:
|
||||
{
|
||||
return data(col, Qt::UserRole).toInt() < _other.data(col, Qt::UserRole).toInt();
|
||||
}
|
||||
@ -122,6 +143,11 @@ const ::profiler::BlocksTree* ProfTreeWidgetItem::block() const
|
||||
return data(COL_DURATION, Qt::UserRole).toULongLong();
|
||||
}
|
||||
|
||||
::profiler::timestamp_t ProfTreeWidgetItem::selfDuration() const
|
||||
{
|
||||
return data(COL_SELF_DURATION, Qt::UserRole).toULongLong();
|
||||
}
|
||||
|
||||
void ProfTreeWidgetItem::setTimeSmart(int _column, const ::profiler::timestamp_t& _time)
|
||||
{
|
||||
const ::profiler::timestamp_t nanosecondsTime = PROF_NANOSECONDS(_time);
|
||||
@ -219,40 +245,46 @@ ProfTreeWidget::ProfTreeWidget(QWidget* _parent) : Parent(_parent), m_beginTime(
|
||||
setColumnCount(COL_COLUMNS_NUMBER);
|
||||
|
||||
auto header = new QTreeWidgetItem();
|
||||
|
||||
header->setText(COL_NAME, "Name");
|
||||
|
||||
header->setText(COL_BEGIN, "Begin, ms");
|
||||
|
||||
header->setText(COL_DURATION, "Duration");
|
||||
header->setText(COL_SELF_DURATION, "Self Dur.");
|
||||
header->setText(COL_DURATION_SUM_PER_PARENT, "Tot. Dur./Parent");
|
||||
header->setText(COL_DURATION_SUM_PER_FRAME, "Tot. Dur./Frame");
|
||||
header->setText(COL_DURATION_SUM_PER_THREAD, "Tot. Dur./Thread");
|
||||
|
||||
header->setText(COL_SELF_DURATION_PERCENT, "Self %");
|
||||
header->setText(COL_PERCENT_OF_PARENT, "Parent %");
|
||||
header->setText(COL_PERCENT_OF_FRAME, "Frame %");
|
||||
header->setText(COL_PERCENT_PER_PARENT, "% / Parent");
|
||||
header->setText(COL_PERCENT_PER_FRAME, "% / Frame");
|
||||
header->setText(COL_PERCENT_SUM_PER_FRAME, "Tot. % / Frame");
|
||||
header->setText(COL_PERCENT_SUM_PER_PARENT, "Tot. % / Parent");
|
||||
header->setText(COL_PERCENT_SUM_PER_THREAD, "Tot. % / Thread");
|
||||
|
||||
header->setText(COL_END, "End, ms");
|
||||
header->setText(COL_MIN_TOTAL, "Min dur. total");
|
||||
header->setText(COL_MAX_TOTAL, "Max dur. total");
|
||||
header->setText(COL_AVERAGE_TOTAL, "Average dur. total");
|
||||
header->setText(COL_MIN, "Min dur.");
|
||||
header->setText(COL_MAX, "Max dur.");
|
||||
header->setText(COL_AVERAGE, "Average dur.");
|
||||
header->setText(COL_NCALLS, "N Calls");
|
||||
header->setText(COL_NCALLS_TOTAL, "N Calls total");
|
||||
|
||||
header->setText(COL_MIN_PER_FRAME, "Min dur./Frame");
|
||||
header->setText(COL_MAX_PER_FRAME, "Max dur./Frame");
|
||||
header->setText(COL_AVERAGE_PER_FRAME, "Average dur./Frame");
|
||||
header->setText(COL_NCALLS_PER_FRAME, "N Calls/Frame");
|
||||
|
||||
header->setText(COL_MIN_PER_PARENT, "Min dur./Parent");
|
||||
header->setText(COL_MAX_PER_PARENT, "Max dur./Parent");
|
||||
header->setText(COL_AVERAGE_PER_PARENT, "Average dur./Parent");
|
||||
header->setText(COL_NCALLS_PER_PARENT, "N Calls/Parent");
|
||||
|
||||
header->setText(COL_MIN_PER_THREAD, "Min dur./Thread");
|
||||
header->setText(COL_MAX_PER_THREAD, "Max dur./Thread");
|
||||
header->setText(COL_AVERAGE_PER_THREAD, "Average dur./Thread");
|
||||
header->setText(COL_NCALLS_PER_THREAD, "N Calls/Thread");
|
||||
|
||||
setHeaderItem(header);
|
||||
|
||||
connect(&::profiler_gui::EASY_GLOBALS.events, &::profiler_gui::ProfGlobalSignals::selectedThreadChanged, this, &This::onSelectedThreadChange);
|
||||
|
||||
QSettings settings(profiler_gui::ORGANAZATION_NAME, profiler_gui::APPLICATION_NAME);
|
||||
settings.beginGroup("tree_widget");
|
||||
|
||||
auto color_rows_set = settings.value("color_rows");
|
||||
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);
|
||||
}
|
||||
|
||||
settings.endGroup();
|
||||
loadSettings();
|
||||
}
|
||||
|
||||
ProfTreeWidget::ProfTreeWidget(const unsigned int _blocksNumber, const ::profiler::thread_blocks_tree_t& _blocksTree, QWidget* _parent) : This(_parent)
|
||||
@ -320,6 +352,7 @@ void ProfTreeWidget::clearSilent(bool _global)
|
||||
}
|
||||
|
||||
m_items.clear();
|
||||
m_roots.clear();
|
||||
|
||||
const QSignalBlocker b(this);
|
||||
clear();
|
||||
@ -376,8 +409,14 @@ size_t ProfTreeWidget::setTreeInternal(const unsigned int _blocksNumber, const :
|
||||
item->setTextColor(::profiler_gui::SELECTED_THREAD_FOREGROUND);
|
||||
m_items.push_back(item);
|
||||
|
||||
// TODO: Optimize children duration calculation (it must be calculated before setTreeInternal now)
|
||||
::profiler::timestamp_t children_duration = 0;
|
||||
const auto children_items_number = setTreeInternal(block.children, item, nullptr, m_beginTime, finishtime + 1000000000ULL, false, children_duration);
|
||||
for (const auto& child : block.children)
|
||||
children_duration += child.node->block()->duration();
|
||||
item->setTimeSmart(COL_SELF_DURATION, children_duration);
|
||||
|
||||
children_duration = 0;
|
||||
const auto children_items_number = setTreeInternal(block.children, item, nullptr, item, m_beginTime, finishtime + 1000000000ULL, false, children_duration);
|
||||
|
||||
if (children_items_number > 0)
|
||||
{
|
||||
@ -390,11 +429,6 @@ size_t ProfTreeWidget::setTreeInternal(const unsigned int _blocksNumber, const :
|
||||
}
|
||||
|
||||
m_roots[threadTree.first] = item;
|
||||
|
||||
if (children_duration > 0)
|
||||
{
|
||||
item->setTimeSmart(COL_SELF_DURATION, children_duration);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -463,6 +497,13 @@ size_t ProfTreeWidget::setTreeInternal(const ::profiler_gui::TreeBlocks& _blocks
|
||||
thread_item->setTimeSmart(COL_DURATION, duration);
|
||||
thread_item->setBackgroundColor(::profiler_gui::SELECTED_THREAD_BACKGROUND);
|
||||
thread_item->setTextColor(::profiler_gui::SELECTED_THREAD_FOREGROUND);
|
||||
|
||||
// Calculate clean duration (sum of all children durations)
|
||||
::profiler::timestamp_t children_duration = 0;
|
||||
for (const auto& child : block.root->tree.children)
|
||||
children_duration += child.node->block()->duration();
|
||||
thread_item->setTimeSmart(COL_SELF_DURATION, children_duration);
|
||||
|
||||
threadsMap.insert(::std::make_pair(block.root->thread_id, thread_item));
|
||||
}
|
||||
|
||||
@ -478,34 +519,56 @@ size_t ProfTreeWidget::setTreeInternal(const ::profiler_gui::TreeBlocks& _blocks
|
||||
item->setTimeMs(COL_BEGIN, startTime - m_beginTime);
|
||||
item->setTimeMs(COL_END, endTime - m_beginTime);
|
||||
|
||||
item->setData(COL_PERCENT_OF_PARENT, Qt::UserRole, 0);
|
||||
item->setText(COL_PERCENT_OF_PARENT, "");
|
||||
item->setData(COL_PERCENT_PER_PARENT, Qt::UserRole, 0);
|
||||
item->setText(COL_PERCENT_PER_PARENT, "");
|
||||
|
||||
item->setData(COL_PERCENT_OF_FRAME, Qt::UserRole, 0);
|
||||
item->setText(COL_PERCENT_OF_FRAME, "");
|
||||
item->setData(COL_PERCENT_PER_FRAME, Qt::UserRole, 0);
|
||||
item->setText(COL_PERCENT_PER_FRAME, "");
|
||||
|
||||
if (block.tree->total_statistics)
|
||||
if (block.tree->per_thread_stats)
|
||||
{
|
||||
item->setTimeSmart(COL_MIN_TOTAL, block.tree->total_statistics->min_duration);
|
||||
item->setTimeSmart(COL_MAX_TOTAL, block.tree->total_statistics->max_duration);
|
||||
item->setTimeSmart(COL_AVERAGE_TOTAL, block.tree->total_statistics->average_duration());
|
||||
item->setTimeSmart(COL_MIN_PER_THREAD, block.tree->per_thread_stats->min_duration);
|
||||
item->setTimeSmart(COL_MAX_PER_THREAD, block.tree->per_thread_stats->max_duration);
|
||||
item->setTimeSmart(COL_AVERAGE_PER_THREAD, block.tree->per_thread_stats->average_duration());
|
||||
item->setTimeSmart(COL_DURATION_SUM_PER_THREAD, block.tree->per_thread_stats->total_duration);
|
||||
|
||||
item->setData(COL_NCALLS_TOTAL, Qt::UserRole, block.tree->total_statistics->calls_number);
|
||||
item->setText(COL_NCALLS_TOTAL, QString::number(block.tree->total_statistics->calls_number));
|
||||
item->setData(COL_NCALLS_PER_THREAD, Qt::UserRole, block.tree->per_thread_stats->calls_number);
|
||||
item->setText(COL_NCALLS_PER_THREAD, QString::number(block.tree->per_thread_stats->calls_number));
|
||||
|
||||
auto percentage_per_thread = static_cast<int>(0.5 + 100. * static_cast<double>(block.tree->per_thread_stats->total_duration) / static_cast<double>(thread_item->selfDuration()));
|
||||
item->setData(COL_PERCENT_SUM_PER_THREAD, Qt::UserRole, percentage_per_thread);
|
||||
item->setText(COL_PERCENT_SUM_PER_THREAD, QString::number(percentage_per_thread));
|
||||
}
|
||||
else
|
||||
{
|
||||
item->setData(COL_PERCENT_SUM_PER_THREAD, Qt::UserRole, 0);
|
||||
item->setText(COL_PERCENT_SUM_PER_THREAD, "");
|
||||
}
|
||||
|
||||
if (block.tree->frame_statistics)
|
||||
if (block.tree->per_parent_stats)
|
||||
{
|
||||
item->setTimeSmart(COL_MIN, block.tree->frame_statistics->min_duration);
|
||||
item->setTimeSmart(COL_MAX, block.tree->frame_statistics->max_duration);
|
||||
item->setTimeSmart(COL_AVERAGE, block.tree->frame_statistics->average_duration());
|
||||
item->setTimeSmart(COL_MIN_PER_PARENT, block.tree->per_parent_stats->min_duration);
|
||||
item->setTimeSmart(COL_MAX_PER_PARENT, block.tree->per_parent_stats->max_duration);
|
||||
item->setTimeSmart(COL_AVERAGE_PER_PARENT, block.tree->per_parent_stats->average_duration());
|
||||
item->setTimeSmart(COL_DURATION_SUM_PER_PARENT, block.tree->per_parent_stats->total_duration);
|
||||
|
||||
item->setData(COL_NCALLS, Qt::UserRole, block.tree->frame_statistics->calls_number);
|
||||
item->setText(COL_NCALLS, QString::number(block.tree->frame_statistics->calls_number));
|
||||
item->setData(COL_NCALLS_PER_PARENT, Qt::UserRole, block.tree->per_parent_stats->calls_number);
|
||||
item->setText(COL_NCALLS_PER_PARENT, QString::number(block.tree->per_parent_stats->calls_number));
|
||||
}
|
||||
|
||||
if (block.tree->per_frame_stats)
|
||||
{
|
||||
item->setTimeSmart(COL_MIN_PER_FRAME, block.tree->per_frame_stats->min_duration);
|
||||
item->setTimeSmart(COL_MAX_PER_FRAME, block.tree->per_frame_stats->max_duration);
|
||||
item->setTimeSmart(COL_AVERAGE_PER_FRAME, block.tree->per_frame_stats->average_duration());
|
||||
item->setTimeSmart(COL_DURATION_SUM_PER_FRAME, block.tree->per_frame_stats->total_duration);
|
||||
|
||||
item->setData(COL_NCALLS_PER_FRAME, Qt::UserRole, block.tree->per_frame_stats->calls_number);
|
||||
item->setText(COL_NCALLS_PER_FRAME, QString::number(block.tree->per_frame_stats->calls_number));
|
||||
}
|
||||
|
||||
const auto color = block.tree->node->block()->getColor();
|
||||
const auto bgColor = ::profiler_gui::toRgb(::profiler::colors::get_red(color), ::profiler::colors::get_green(color), ::profiler::colors::get_blue(color));
|
||||
const auto bgColor = ::profiler_gui::fromProfilerRgb(::profiler::colors::get_red(color), ::profiler::colors::get_green(color), ::profiler::colors::get_blue(color));
|
||||
const auto fgColor = 0x00ffffff - bgColor;
|
||||
item->setBackgroundColor(bgColor);
|
||||
item->setTextColor(fgColor);
|
||||
@ -516,7 +579,7 @@ size_t ProfTreeWidget::setTreeInternal(const ::profiler_gui::TreeBlocks& _blocks
|
||||
::profiler::timestamp_t children_duration = 0;
|
||||
if (!block.tree->children.empty())
|
||||
{
|
||||
children_items_number = setTreeInternal(block.tree->children, item, item, _left, _right, _strict, children_duration);
|
||||
children_items_number = setTreeInternal(block.tree->children, item, item, thread_item, _left, _right, _strict, children_duration);
|
||||
}
|
||||
|
||||
int percentage = 100;
|
||||
@ -563,16 +626,6 @@ size_t ProfTreeWidget::setTreeInternal(const ::profiler_gui::TreeBlocks& _blocks
|
||||
m_roots[it.first] = item;
|
||||
m_items.push_back(item);
|
||||
++total_items;
|
||||
|
||||
// Calculate clean duration (sum of all children durations)
|
||||
::profiler::timestamp_t children_duration = 0;
|
||||
auto itemBlock = item->block();
|
||||
for (const auto& child : itemBlock->children)
|
||||
{
|
||||
children_duration += child.node->block()->duration();
|
||||
}
|
||||
|
||||
item->setTimeSmart(COL_SELF_DURATION, children_duration);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -583,7 +636,7 @@ size_t ProfTreeWidget::setTreeInternal(const ::profiler_gui::TreeBlocks& _blocks
|
||||
return total_items;
|
||||
}
|
||||
|
||||
size_t ProfTreeWidget::setTreeInternal(const ::profiler::BlocksTree::children_t& _children, ProfTreeWidgetItem* _parent, ProfTreeWidgetItem* _frame, ::profiler::timestamp_t _left, ::profiler::timestamp_t _right, bool _strict, ::profiler::timestamp_t& _duration)
|
||||
size_t ProfTreeWidget::setTreeInternal(const ::profiler::BlocksTree::children_t& _children, ProfTreeWidgetItem* _parent, ProfTreeWidgetItem* _frame, ProfTreeWidgetItem* _thread, ::profiler::timestamp_t _left, ::profiler::timestamp_t _right, bool _strict, ::profiler::timestamp_t& _duration)
|
||||
{
|
||||
size_t total_items = 0;
|
||||
for (const auto& child : _children)
|
||||
@ -607,49 +660,78 @@ size_t ProfTreeWidget::setTreeInternal(const ::profiler::BlocksTree::children_t&
|
||||
item->setTimeSmart(COL_DURATION, duration);
|
||||
item->setTimeMs(COL_BEGIN, startTime - m_beginTime);
|
||||
item->setTimeMs(COL_END, endTime - m_beginTime);
|
||||
item->setData(COL_PERCENT_SUM_PER_THREAD, Qt::UserRole, 0);
|
||||
|
||||
auto percentage = duration == 0 ? 0 : static_cast<int>(0.5 + 100. * static_cast<double>(duration) / static_cast<double>(_parent->duration()));
|
||||
auto percentage_sum = child.per_parent_stats ? static_cast<int>(0.5 + 100. * static_cast<double>(child.per_parent_stats->total_duration) / static_cast<double>(_parent->duration())) : 0;
|
||||
item->setData(COL_PERCENT_PER_PARENT, Qt::UserRole, percentage);
|
||||
item->setText(COL_PERCENT_PER_PARENT, QString::number(percentage));
|
||||
item->setData(COL_PERCENT_SUM_PER_PARENT, Qt::UserRole, percentage_sum);
|
||||
item->setText(COL_PERCENT_SUM_PER_PARENT, QString::number(percentage_sum));
|
||||
|
||||
if (_frame != nullptr)
|
||||
{
|
||||
auto percentage = duration == 0 ? 0 : static_cast<int>(0.5 + 100. * static_cast<double>(duration) / static_cast<double>(_parent->duration()));
|
||||
item->setData(COL_PERCENT_OF_PARENT, Qt::UserRole, percentage);
|
||||
item->setText(COL_PERCENT_OF_PARENT, QString::number(percentage));
|
||||
|
||||
if (_parent != _frame)
|
||||
{
|
||||
percentage = duration == 0 ? 0 : static_cast<int>(0.5 + 100. * static_cast<double>(duration) / static_cast<double>(_frame->duration()));
|
||||
item->setData(COL_PERCENT_OF_FRAME, Qt::UserRole, percentage);
|
||||
item->setText(COL_PERCENT_OF_FRAME, QString::number(percentage));
|
||||
percentage_sum = child.per_frame_stats ? static_cast<int>(0.5 + 100. * static_cast<double>(child.per_frame_stats->total_duration) / static_cast<double>(_frame->duration())) : 0;
|
||||
}
|
||||
|
||||
item->setData(COL_PERCENT_PER_FRAME, Qt::UserRole, percentage);
|
||||
item->setText(COL_PERCENT_PER_FRAME, QString::number(percentage));
|
||||
item->setData(COL_PERCENT_SUM_PER_FRAME, Qt::UserRole, percentage_sum);
|
||||
item->setText(COL_PERCENT_SUM_PER_FRAME, QString::number(percentage_sum));
|
||||
}
|
||||
else
|
||||
{
|
||||
item->setData(COL_PERCENT_OF_PARENT, Qt::UserRole, 0);
|
||||
item->setText(COL_PERCENT_OF_PARENT, "");
|
||||
|
||||
item->setData(COL_PERCENT_OF_FRAME, Qt::UserRole, 0);
|
||||
item->setText(COL_PERCENT_OF_FRAME, "");
|
||||
item->setData(COL_PERCENT_PER_FRAME, Qt::UserRole, 0);
|
||||
item->setText(COL_PERCENT_PER_FRAME, "");
|
||||
item->setData(COL_PERCENT_SUM_PER_FRAME, Qt::UserRole, 0);
|
||||
item->setText(COL_PERCENT_SUM_PER_FRAME, "");
|
||||
}
|
||||
|
||||
if (child.total_statistics)
|
||||
if (child.per_thread_stats)
|
||||
{
|
||||
item->setTimeSmart(COL_MIN_TOTAL, child.total_statistics->min_duration);
|
||||
item->setTimeSmart(COL_MAX_TOTAL, child.total_statistics->max_duration);
|
||||
item->setTimeSmart(COL_AVERAGE_TOTAL, child.total_statistics->average_duration());
|
||||
item->setTimeSmart(COL_MIN_PER_THREAD, child.per_thread_stats->min_duration);
|
||||
item->setTimeSmart(COL_MAX_PER_THREAD, child.per_thread_stats->max_duration);
|
||||
item->setTimeSmart(COL_AVERAGE_PER_THREAD, child.per_thread_stats->average_duration());
|
||||
item->setTimeSmart(COL_DURATION_SUM_PER_THREAD, child.per_thread_stats->total_duration);
|
||||
|
||||
item->setData(COL_NCALLS_TOTAL, Qt::UserRole, child.total_statistics->calls_number);
|
||||
item->setText(COL_NCALLS_TOTAL, QString::number(child.total_statistics->calls_number));
|
||||
item->setData(COL_NCALLS_PER_THREAD, Qt::UserRole, child.per_thread_stats->calls_number);
|
||||
item->setText(COL_NCALLS_PER_THREAD, QString::number(child.per_thread_stats->calls_number));
|
||||
|
||||
if (_thread)
|
||||
{
|
||||
auto percentage_per_thread = static_cast<int>(0.5 + 100. * static_cast<double>(child.per_thread_stats->total_duration) / static_cast<double>(_thread->selfDuration()));
|
||||
item->setData(COL_PERCENT_SUM_PER_THREAD, Qt::UserRole, percentage_per_thread);
|
||||
item->setText(COL_PERCENT_SUM_PER_THREAD, QString::number(percentage_per_thread));
|
||||
}
|
||||
}
|
||||
|
||||
if (child.frame_statistics)
|
||||
if (child.per_parent_stats)
|
||||
{
|
||||
item->setTimeSmart(COL_MIN, child.frame_statistics->min_duration);
|
||||
item->setTimeSmart(COL_MAX, child.frame_statistics->max_duration);
|
||||
item->setTimeSmart(COL_AVERAGE, child.frame_statistics->average_duration());
|
||||
item->setTimeSmart(COL_MIN_PER_PARENT, child.per_parent_stats->min_duration);
|
||||
item->setTimeSmart(COL_MAX_PER_PARENT, child.per_parent_stats->max_duration);
|
||||
item->setTimeSmart(COL_AVERAGE_PER_PARENT, child.per_parent_stats->average_duration());
|
||||
item->setTimeSmart(COL_DURATION_SUM_PER_PARENT, child.per_parent_stats->total_duration);
|
||||
|
||||
item->setData(COL_NCALLS, Qt::UserRole, child.frame_statistics->calls_number);
|
||||
item->setText(COL_NCALLS, QString::number(child.frame_statistics->calls_number));
|
||||
item->setData(COL_NCALLS_PER_PARENT, Qt::UserRole, child.per_parent_stats->calls_number);
|
||||
item->setText(COL_NCALLS_PER_PARENT, QString::number(child.per_parent_stats->calls_number));
|
||||
}
|
||||
|
||||
if (child.per_frame_stats)
|
||||
{
|
||||
item->setTimeSmart(COL_MIN_PER_FRAME, child.per_frame_stats->min_duration);
|
||||
item->setTimeSmart(COL_MAX_PER_FRAME, child.per_frame_stats->max_duration);
|
||||
item->setTimeSmart(COL_AVERAGE_PER_FRAME, child.per_frame_stats->average_duration());
|
||||
item->setTimeSmart(COL_DURATION_SUM_PER_FRAME, child.per_frame_stats->total_duration);
|
||||
|
||||
item->setData(COL_NCALLS_PER_FRAME, Qt::UserRole, child.per_frame_stats->calls_number);
|
||||
item->setText(COL_NCALLS_PER_FRAME, QString::number(child.per_frame_stats->calls_number));
|
||||
}
|
||||
|
||||
const auto color = child.node->block()->getColor();
|
||||
const auto bgColor = ::profiler_gui::toRgb(::profiler::colors::get_red(color), ::profiler::colors::get_green(color), ::profiler::colors::get_blue(color));
|
||||
const auto bgColor = ::profiler_gui::fromProfilerRgb(::profiler::colors::get_red(color), ::profiler::colors::get_green(color), ::profiler::colors::get_blue(color));
|
||||
const auto fgColor = 0x00ffffff - bgColor;
|
||||
item->setBackgroundColor(bgColor);
|
||||
item->setTextColor(fgColor);
|
||||
@ -660,10 +742,10 @@ size_t ProfTreeWidget::setTreeInternal(const ::profiler::BlocksTree::children_t&
|
||||
::profiler::timestamp_t children_duration = 0;
|
||||
if (!child.children.empty())
|
||||
{
|
||||
children_items_number = setTreeInternal(child.children, item, _frame ? _frame : item, _left, _right, _strict, children_duration);
|
||||
children_items_number = setTreeInternal(child.children, item, _frame ? _frame : item, _thread, _left, _right, _strict, children_duration);
|
||||
}
|
||||
|
||||
int percentage = 100;
|
||||
percentage = 100;
|
||||
auto self_duration = duration - children_duration;
|
||||
if (children_duration > 0 && duration > 0)
|
||||
{
|
||||
@ -735,8 +817,9 @@ void ProfTreeWidget::contextMenuEvent(QContextMenuEvent* _event)
|
||||
{
|
||||
switch (col)
|
||||
{
|
||||
case COL_MIN_TOTAL:
|
||||
case COL_MIN:
|
||||
case COL_MIN_PER_THREAD:
|
||||
case COL_MIN_PER_PARENT:
|
||||
case COL_MIN_PER_FRAME:
|
||||
{
|
||||
menu.addSeparator();
|
||||
auto itemAction = new ProfItemAction("Jump to such item", item);
|
||||
@ -745,8 +828,9 @@ void ProfTreeWidget::contextMenuEvent(QContextMenuEvent* _event)
|
||||
break;
|
||||
}
|
||||
|
||||
case COL_MAX_TOTAL:
|
||||
case COL_MAX:
|
||||
case COL_MAX_PER_THREAD:
|
||||
case COL_MAX_PER_PARENT:
|
||||
case COL_MAX_PER_FRAME:
|
||||
{
|
||||
menu.addSeparator();
|
||||
auto itemAction = new ProfItemAction("Jump to such item", item);
|
||||
@ -780,7 +864,7 @@ void ProfTreeWidget::contextMenuEvent(QContextMenuEvent* _event)
|
||||
|
||||
void ProfTreeWidget::onJumpToMinItemClicked(ProfTreeWidgetItem* _item)
|
||||
{
|
||||
auto item = ::profiler_gui::EASY_GLOBALS.gui_blocks[_item->block()->total_statistics->min_duration_block].tree_item;
|
||||
auto item = ::profiler_gui::EASY_GLOBALS.gui_blocks[_item->block()->per_thread_stats->min_duration_block].tree_item;
|
||||
if (item != nullptr)
|
||||
{
|
||||
scrollToItem(item, QAbstractItemView::PositionAtCenter);
|
||||
@ -790,7 +874,7 @@ void ProfTreeWidget::onJumpToMinItemClicked(ProfTreeWidgetItem* _item)
|
||||
|
||||
void ProfTreeWidget::onJumpToMaxItemClicked(ProfTreeWidgetItem* _item)
|
||||
{
|
||||
auto item = ::profiler_gui::EASY_GLOBALS.gui_blocks[_item->block()->total_statistics->max_duration_block].tree_item;
|
||||
auto item = ::profiler_gui::EASY_GLOBALS.gui_blocks[_item->block()->per_thread_stats->max_duration_block].tree_item;
|
||||
if (item != nullptr)
|
||||
{
|
||||
scrollToItem(item, QAbstractItemView::PositionAtCenter);
|
||||
@ -900,9 +984,27 @@ void ProfTreeWidget::onHideShowColumn(int _column)
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void ProfTreeWidget::loadSettings()
|
||||
{
|
||||
QSettings settings(::profiler_gui::ORGANAZATION_NAME, ::profiler_gui::APPLICATION_NAME);
|
||||
settings.beginGroup("tree_widget");
|
||||
|
||||
auto color_rows_set = settings.value("color_rows");
|
||||
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);
|
||||
}
|
||||
|
||||
settings.endGroup();
|
||||
}
|
||||
|
||||
void ProfTreeWidget::saveSettings()
|
||||
{
|
||||
QSettings settings(profiler_gui::ORGANAZATION_NAME, profiler_gui::APPLICATION_NAME);
|
||||
QSettings settings(::profiler_gui::ORGANAZATION_NAME, ::profiler_gui::APPLICATION_NAME);
|
||||
settings.beginGroup("tree_widget");
|
||||
|
||||
settings.setValue("color_rows", m_bColorRows);
|
||||
@ -914,3 +1016,5 @@ void ProfTreeWidget::saveSettings()
|
||||
|
||||
settings.endGroup();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
@ -60,6 +60,7 @@ public:
|
||||
const ::profiler::BlocksTree* block() const;
|
||||
|
||||
::profiler::timestamp_t duration() const;
|
||||
::profiler::timestamp_t selfDuration() const;
|
||||
|
||||
void setTimeSmart(int _column, const ::profiler::timestamp_t& _time);
|
||||
|
||||
@ -137,7 +138,7 @@ protected:
|
||||
|
||||
size_t setTreeInternal(const ::profiler_gui::TreeBlocks& _blocks, ::profiler::timestamp_t _left, ::profiler::timestamp_t _right, bool _strict);
|
||||
|
||||
size_t setTreeInternal(const ::profiler::BlocksTree::children_t& _children, ProfTreeWidgetItem* _parent, ProfTreeWidgetItem* _frame, ::profiler::timestamp_t _left, ::profiler::timestamp_t _right, bool _strict, ::profiler::timestamp_t& _duration);
|
||||
size_t setTreeInternal(const ::profiler::BlocksTree::children_t& _children, ProfTreeWidgetItem* _parent, ProfTreeWidgetItem* _frame, ProfTreeWidgetItem* _thread, ::profiler::timestamp_t _left, ::profiler::timestamp_t _right, bool _strict, ::profiler::timestamp_t& _duration);
|
||||
|
||||
void contextMenuEvent(QContextMenuEvent* _event) override;
|
||||
|
||||
@ -167,6 +168,7 @@ private slots:
|
||||
|
||||
protected:
|
||||
|
||||
void loadSettings();
|
||||
void saveSettings();
|
||||
|
||||
}; // END of class ProfTreeWidget.
|
||||
|
@ -87,13 +87,18 @@ struct do_no_hash {
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
const QRgb DEFAULT_COLOR = 0x00f0e094;
|
||||
const QRgb DEFAULT_COLOR = 0x00d4b494;//0x00f0e094;
|
||||
|
||||
inline QRgb toRgb(unsigned int _red, unsigned int _green, unsigned int _blue)
|
||||
{
|
||||
return (_red << 16) + (_green << 8) + _blue;
|
||||
}
|
||||
|
||||
inline QRgb fromProfilerRgb(unsigned int _red, unsigned int _green, unsigned int _blue)
|
||||
{
|
||||
if (_red == 0 && _green == 0 && _blue == 0)
|
||||
return DEFAULT_COLOR;
|
||||
return (_red << 16) + (_green << 8) + _blue;
|
||||
return toRgb(_red, _green, _blue) | 0x00141414;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
@ -36,8 +36,8 @@ namespace profiler_gui {
|
||||
const QString ORGANAZATION_NAME = "EasyProfiler";
|
||||
const QString APPLICATION_NAME = "Easy profiler gui application";
|
||||
|
||||
const QColor CHRONOMETER_COLOR = QColor::fromRgba(0x402020c0);
|
||||
const QRgb SELECTED_THREAD_BACKGROUND = 0x00d8d840;
|
||||
const QColor CHRONOMETER_COLOR = QColor::fromRgba(0x202020c0);
|
||||
const QRgb SELECTED_THREAD_BACKGROUND = 0x00e0e060;
|
||||
const QRgb SELECTED_THREAD_FOREGROUND = 0x00ffffff - SELECTED_THREAD_BACKGROUND;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
@ -167,13 +167,14 @@ void ProfMinimapItem::paint(QPainter* _painter, const QStyleOptionGraphicsItem*
|
||||
|
||||
const auto h = ::std::max((item.width() - m_minDuration) * coeff, 5.0);
|
||||
const auto col = h * heightRevert;
|
||||
const auto color = ::profiler_gui::toRgb(col * 255, (1.0 - col) * 255, 0); // item.color;
|
||||
//const auto color = ::profiler_gui::toRgb(col * 255, (1.0 - col) * 255, 0); // item.color;
|
||||
const auto color = 0x00ffffff & QColor::fromHsvF((1.0 - col) * 0.35, 0.85, 0.85).rgb();
|
||||
|
||||
if (previousColor != color)
|
||||
{
|
||||
// Set background color brush for rectangle
|
||||
previousColor = color;
|
||||
brush.setColor(QColor::fromRgba(0x80000000 | color));
|
||||
brush.setColor(QColor::fromRgba(0xc0000000 | color));
|
||||
_painter->setBrush(brush);
|
||||
}
|
||||
|
||||
@ -274,7 +275,7 @@ ProfGraphicsScrollbar::ProfGraphicsScrollbar(QWidget* _parent)
|
||||
m_chronometerIndicator = new ProfGraphicsSliderItem();
|
||||
m_chronometerIndicator->setPos(0, 0);
|
||||
m_chronometerIndicator->setZValue(10);
|
||||
m_chronometerIndicator->setColor(::profiler_gui::CHRONOMETER_COLOR);
|
||||
m_chronometerIndicator->setColor(0x40000000 | ::profiler_gui::CHRONOMETER_COLOR.rgba());
|
||||
selfScene->addItem(m_chronometerIndicator);
|
||||
m_chronometerIndicator->hide();
|
||||
|
||||
|
@ -171,7 +171,7 @@ void update_statistics(StatsMap& _stats_map, const ::profiler::BlocksTree& _curr
|
||||
{
|
||||
// Update already existing statistics
|
||||
|
||||
_stats = it->second; // write pointer to statistics into output (this is BlocksTree::total_statistics or BlocksTree::frame_statistics)
|
||||
_stats = it->second; // write pointer to statistics into output (this is BlocksTree:: per_thread_stats or per_parent_stats or per_frame_stats)
|
||||
|
||||
++_stats->calls_number; // update calls number of this block
|
||||
_stats->total_duration += duration; // update summary duration of all block calls
|
||||
@ -205,22 +205,39 @@ void update_statistics(StatsMap& _stats_map, const ::profiler::BlocksTree& _curr
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void update_statistics_recursive(StatsMap& _stats_map, ::profiler::BlocksTree& _current)
|
||||
{
|
||||
update_statistics(_stats_map, _current, _current.per_frame_stats);
|
||||
|
||||
for (auto& child : _current.children)
|
||||
{
|
||||
update_statistics_recursive(_stats_map, child);
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
typedef ::std::map<::profiler::thread_id_t, StatsMap> PerThreadStats;
|
||||
|
||||
extern "C"{
|
||||
|
||||
unsigned int fillTreesFromFile(const char* filename, ::profiler::thread_blocks_tree_t& threaded_trees, bool gather_statistics)
|
||||
{
|
||||
PROFILER_BEGIN_FUNCTION_BLOCK_GROUPED(::profiler::colors::Cyan)
|
||||
|
||||
::std::ifstream inFile(filename, ::std::fstream::binary);
|
||||
|
||||
if (!inFile.is_open()){
|
||||
return 0;
|
||||
}
|
||||
|
||||
StatsMap overall_statistics, frame_statistics;
|
||||
//StatsMap overall_statistics;
|
||||
PerThreadStats thread_statistics, parent_statistics, frame_statistics;
|
||||
|
||||
unsigned int blocks_counter = 0;
|
||||
|
||||
while (!inFile.eof()){
|
||||
PROFILER_BEGIN_BLOCK("Read block from file")
|
||||
PROFILER_BEGIN_BLOCK_GROUPED("Read block from file", ::profiler::colors::Green)
|
||||
uint16_t sz = 0;
|
||||
inFile.read((char*)&sz, sizeof(sz));
|
||||
if (sz == 0)
|
||||
@ -234,7 +251,10 @@ extern "C"{
|
||||
inFile.read((char*)&data[0], sz);
|
||||
::profiler::BaseBlockData* baseData = (::profiler::BaseBlockData*)data;
|
||||
|
||||
auto& root = threaded_trees[baseData->getThreadId()];
|
||||
auto block_thread_id = baseData->getThreadId();
|
||||
auto& root = threaded_trees[block_thread_id];
|
||||
auto& per_parent_statistics = parent_statistics[block_thread_id];
|
||||
auto& per_thread_statistics = thread_statistics[block_thread_id];
|
||||
|
||||
::profiler::BlocksTree tree;
|
||||
tree.node = new ::profiler::SerilizedBlock(sz, data);
|
||||
@ -254,7 +274,7 @@ extern "C"{
|
||||
{
|
||||
//auto lower = ::std::lower_bound(root.children.begin(), root.children.end(), tree);
|
||||
/**/
|
||||
PROFILER_BEGIN_BLOCK("Find children")
|
||||
PROFILER_BEGIN_BLOCK_GROUPED("Find children", ::profiler::colors::Blue)
|
||||
auto rlower1 = ++root.tree.children.rbegin();
|
||||
for(; rlower1 != root.tree.children.rend(); ++rlower1){
|
||||
if(mt0 > rlower1->node->block()->getBegin())
|
||||
@ -270,16 +290,16 @@ extern "C"{
|
||||
::profiler::timestamp_t children_duration = 0;
|
||||
if (gather_statistics)
|
||||
{
|
||||
PROFILER_BEGIN_BLOCK("Gather statistic for frame")
|
||||
frame_statistics.clear();
|
||||
PROFILER_BEGIN_BLOCK_GROUPED("Gather statistic within parent", ::profiler::colors::Magenta)
|
||||
per_parent_statistics.clear();
|
||||
|
||||
//frame_statistics.reserve(tree.children.size()); // this gives slow-down on Windows
|
||||
//frame_statistics.reserve(tree.children.size() * 2); // this gives no speed-up on Windows
|
||||
//per_parent_statistics.reserve(tree.children.size()); // this gives slow-down on Windows
|
||||
//per_parent_statistics.reserve(tree.children.size() * 2); // this gives no speed-up on Windows
|
||||
// TODO: check this behavior on Linux
|
||||
|
||||
for (auto& child : tree.children)
|
||||
{
|
||||
update_statistics(frame_statistics, child, child.frame_statistics);
|
||||
update_statistics(per_parent_statistics, child, child.per_parent_stats);
|
||||
|
||||
children_duration += child.node->block()->duration();
|
||||
tree.total_children_number += child.total_children_number;
|
||||
@ -312,14 +332,14 @@ extern "C"{
|
||||
|
||||
if (gather_statistics)
|
||||
{
|
||||
PROFILER_BEGIN_BLOCK("Gather statistics")
|
||||
PROFILER_BEGIN_BLOCK_GROUPED("Gather per thread statistics", ::profiler::colors::Coral)
|
||||
auto& current = root.tree.children.back();
|
||||
update_statistics(overall_statistics, current, current.total_statistics);
|
||||
update_statistics(per_thread_statistics, current, current.per_thread_stats);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
PROFILER_BEGIN_BLOCK("Gather statistics for roots")
|
||||
PROFILER_BEGIN_BLOCK_GROUPED("Gather statistics for roots", ::profiler::colors::Purple)
|
||||
if (gather_statistics)
|
||||
{
|
||||
for (auto& it : threaded_trees)
|
||||
@ -327,11 +347,19 @@ extern "C"{
|
||||
auto& root = it.second;
|
||||
root.thread_id = it.first;
|
||||
|
||||
frame_statistics.clear();
|
||||
auto& per_parent_statistics = parent_statistics[it.first];
|
||||
auto& per_frame_statistics = frame_statistics[it.first];
|
||||
|
||||
per_parent_statistics.clear();
|
||||
for (auto& frame : root.tree.children)
|
||||
{
|
||||
update_statistics(per_parent_statistics, frame, frame.per_parent_stats);
|
||||
|
||||
// TODO: Optimize per frame stats gathering
|
||||
per_frame_statistics.clear();
|
||||
update_statistics_recursive(per_frame_statistics, frame);
|
||||
|
||||
root.tree.total_children_number += frame.total_children_number;
|
||||
update_statistics(frame_statistics, frame, frame.frame_statistics);
|
||||
if (root.tree.depth < frame.depth)
|
||||
root.tree.depth = frame.depth;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user