mirror of
https://github.com/yse/easy_profiler.git
synced 2024-12-26 16:11:02 +08:00
(profiler_gui) Memory consumption optimization + File reading speed-up.
This commit is contained in:
parent
245bc6c386
commit
9560c5b5cf
@ -72,23 +72,21 @@ namespace profiler {
|
||||
|
||||
public:
|
||||
|
||||
typedef ::std::vector<BlocksTree> children_t;
|
||||
typedef ::std::vector<This> blocks_t;
|
||||
typedef ::std::vector<::profiler::block_index_t> children_t;
|
||||
|
||||
children_t children; ///< List of children blocks. May be empty.
|
||||
::profiler::SerializedBlock* 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
|
||||
|
||||
::profiler::block_index_t block_index; ///< Index of this block
|
||||
unsigned short depth; ///< Maximum number of sublevels (maximum children depth)
|
||||
uint16_t depth; ///< Maximum number of sublevels (maximum children depth)
|
||||
|
||||
BlocksTree()
|
||||
: node(nullptr)
|
||||
, per_parent_stats(nullptr)
|
||||
, per_frame_stats(nullptr)
|
||||
, per_thread_stats(nullptr)
|
||||
, block_index(0)
|
||||
, depth(0)
|
||||
{
|
||||
|
||||
@ -143,33 +141,20 @@ namespace profiler {
|
||||
|
||||
void makeMove(This&& that)
|
||||
{
|
||||
//if (node && node != that.node)
|
||||
//{
|
||||
// delete node;
|
||||
//}
|
||||
|
||||
if (per_thread_stats != that.per_thread_stats)
|
||||
{
|
||||
release_stats(per_thread_stats);
|
||||
}
|
||||
|
||||
if (per_parent_stats != that.per_parent_stats)
|
||||
{
|
||||
release_stats(per_parent_stats);
|
||||
}
|
||||
|
||||
if (per_frame_stats != that.per_frame_stats)
|
||||
{
|
||||
release_stats(per_frame_stats);
|
||||
}
|
||||
|
||||
children = ::std::move(that.children);
|
||||
node = that.node;
|
||||
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;
|
||||
depth = that.depth;
|
||||
|
||||
that.node = nullptr;
|
||||
@ -188,29 +173,31 @@ namespace profiler {
|
||||
|
||||
public:
|
||||
|
||||
BlocksTree tree;
|
||||
BlocksTree::children_t children;
|
||||
const char* thread_name;
|
||||
::profiler::thread_id_t thread_id;
|
||||
uint16_t depth;
|
||||
|
||||
BlocksTreeRoot() : thread_name(""), thread_id(0)
|
||||
BlocksTreeRoot() : thread_name(""), thread_id(0), depth(0)
|
||||
{
|
||||
}
|
||||
|
||||
BlocksTreeRoot(This&& that) : tree(::std::move(that.tree)), thread_name(that.thread_name), thread_id(that.thread_id)
|
||||
BlocksTreeRoot(This&& that) : children(::std::move(that.children)), thread_name(that.thread_name), thread_id(that.thread_id), depth(that.depth)
|
||||
{
|
||||
}
|
||||
|
||||
This& operator = (This&& that)
|
||||
{
|
||||
tree = ::std::move(that.tree);
|
||||
children = ::std::move(that.children);
|
||||
thread_name = that.thread_name;
|
||||
thread_id = that.thread_id;
|
||||
depth = that.depth;
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool operator < (const This& other) const
|
||||
{
|
||||
return tree < other.tree;
|
||||
return thread_id < other.thread_id;
|
||||
}
|
||||
|
||||
private:
|
||||
@ -220,6 +207,7 @@ namespace profiler {
|
||||
|
||||
}; // END of class BlocksTreeRoot.
|
||||
|
||||
typedef ::profiler::BlocksTree::blocks_t blocks_t;
|
||||
typedef ::std::map<::profiler::thread_id_t, ::profiler::BlocksTreeRoot> thread_blocks_tree_t;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
@ -283,11 +271,21 @@ namespace profiler {
|
||||
|
||||
} // END of namespace profiler.
|
||||
|
||||
extern "C" unsigned int PROFILER_API fillTreesFromFile(::std::atomic<int>& progress, const char* filename, ::profiler::SerializedData& serialized_blocks, ::profiler::SerializedData& serialized_descriptors, ::profiler::descriptors_list_t& descriptors, ::profiler::thread_blocks_tree_t& threaded_trees, bool gather_statistics = false);
|
||||
extern "C" ::profiler::block_index_t PROFILER_API fillTreesFromFile(::std::atomic<int>& progress, const char* filename,
|
||||
::profiler::SerializedData& serialized_blocks,
|
||||
::profiler::SerializedData& serialized_descriptors,
|
||||
::profiler::descriptors_list_t& descriptors,
|
||||
::profiler::blocks_t& _blocks,
|
||||
::profiler::thread_blocks_tree_t& threaded_trees,
|
||||
bool gather_statistics = false);
|
||||
|
||||
inline unsigned int fillTreesFromFile(const char* filename, ::profiler::SerializedData& serialized_blocks, ::profiler::SerializedData& serialized_descriptors, ::profiler::descriptors_list_t& descriptors, ::profiler::thread_blocks_tree_t& threaded_trees, bool gather_statistics = false) {
|
||||
inline ::profiler::block_index_t fillTreesFromFile(const char* filename, ::profiler::SerializedData& serialized_blocks,
|
||||
::profiler::SerializedData& serialized_descriptors, ::profiler::descriptors_list_t& descriptors,
|
||||
::profiler::blocks_t& _blocks, ::profiler::thread_blocks_tree_t& threaded_trees,
|
||||
bool gather_statistics = false)
|
||||
{
|
||||
::std::atomic<int> progress = ATOMIC_VAR_INIT(0);
|
||||
return fillTreesFromFile(progress, filename, serialized_blocks, serialized_descriptors, descriptors, threaded_trees, gather_statistics);
|
||||
return fillTreesFromFile(progress, filename, serialized_blocks, serialized_descriptors, descriptors, _blocks, threaded_trees, gather_statistics);
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -153,7 +153,7 @@ void EasyGraphicsItem::paint(QPainter* _painter, const QStyleOptionGraphicsItem*
|
||||
|
||||
// Search for first visible top-level item
|
||||
auto& level0 = m_levels.front();
|
||||
auto first = ::std::lower_bound(level0.begin(), level0.end(), sceneLeft, [](const ::profiler_gui::ProfBlockItem& _item, qreal _value)
|
||||
auto first = ::std::lower_bound(level0.begin(), level0.end(), sceneLeft, [](const ::profiler_gui::EasyBlockItem& _item, qreal _value)
|
||||
{
|
||||
return _item.left() < _value;
|
||||
});
|
||||
@ -183,7 +183,7 @@ void EasyGraphicsItem::paint(QPainter* _painter, const QStyleOptionGraphicsItem*
|
||||
_painter->setTransform(QTransform::fromTranslate(dx - offset * currentScale, -y()), true);
|
||||
|
||||
|
||||
if (::profiler_gui::EASY_GLOBALS.draw_graphics_items_borders)
|
||||
if (EASY_GLOBALS.draw_graphics_items_borders)
|
||||
{
|
||||
previousPenStyle = Qt::SolidLine;
|
||||
_painter->setPen(BORDERS_COLOR);
|
||||
@ -194,8 +194,8 @@ void EasyGraphicsItem::paint(QPainter* _painter, const QStyleOptionGraphicsItem*
|
||||
}
|
||||
|
||||
|
||||
static const auto MAX_CHILD_INDEX = ::profiler_gui::numeric_max<decltype(::profiler_gui::ProfBlockItem::children_begin)>();
|
||||
auto const skip_children = [this, &levelsNumber](short next_level, decltype(::profiler_gui::ProfBlockItem::children_begin) children_begin)
|
||||
static const auto MAX_CHILD_INDEX = ::profiler_gui::numeric_max<decltype(::profiler_gui::EasyBlockItem::children_begin)>();
|
||||
auto const skip_children = [this, &levelsNumber](short next_level, decltype(::profiler_gui::EasyBlockItem::children_begin) children_begin)
|
||||
{
|
||||
// Mark that we would not paint children of current item
|
||||
if (next_level < levelsNumber && children_begin != MAX_CHILD_INDEX)
|
||||
@ -243,8 +243,9 @@ void EasyGraphicsItem::paint(QPainter* _painter, const QStyleOptionGraphicsItem*
|
||||
continue;
|
||||
}
|
||||
|
||||
const auto& itemBlock = easyBlock(item.block);
|
||||
int h = 0, flags = 0;
|
||||
if (w < 20 || !::profiler_gui::EASY_GLOBALS.gui_blocks[item.block->block_index].expanded)
|
||||
if (w < 20 || !itemBlock.expanded)
|
||||
{
|
||||
// Items which width is less than 20 will be painted as big rectangles which are hiding it's children
|
||||
|
||||
@ -255,7 +256,7 @@ void EasyGraphicsItem::paint(QPainter* _painter, const QStyleOptionGraphicsItem*
|
||||
h -= dh;
|
||||
|
||||
bool changepen = false;
|
||||
if (item.block->block_index == ::profiler_gui::EASY_GLOBALS.selected_block)
|
||||
if (item.block == EASY_GLOBALS.selected_block)
|
||||
{
|
||||
selectedItemsWasPainted = true;
|
||||
changepen = true;
|
||||
@ -281,7 +282,7 @@ void EasyGraphicsItem::paint(QPainter* _painter, const QStyleOptionGraphicsItem*
|
||||
_painter->setBrush(brush);
|
||||
}
|
||||
|
||||
if (::profiler_gui::EASY_GLOBALS.draw_graphics_items_borders)
|
||||
if (EASY_GLOBALS.draw_graphics_items_borders)
|
||||
{
|
||||
//if (w < 2)
|
||||
//{
|
||||
@ -349,7 +350,7 @@ void EasyGraphicsItem::paint(QPainter* _painter, const QStyleOptionGraphicsItem*
|
||||
m_levels[next_level][item.children_begin].state = BLOCK_ITEM_DO_PAINT;
|
||||
}
|
||||
|
||||
if (item.block->block_index == ::profiler_gui::EASY_GLOBALS.selected_block)
|
||||
if (item.block == EASY_GLOBALS.selected_block)
|
||||
{
|
||||
selectedItemsWasPainted = true;
|
||||
QPen pen(Qt::SolidLine);
|
||||
@ -374,7 +375,7 @@ void EasyGraphicsItem::paint(QPainter* _painter, const QStyleOptionGraphicsItem*
|
||||
_painter->setBrush(brush);
|
||||
}
|
||||
|
||||
if (::profiler_gui::EASY_GLOBALS.draw_graphics_items_borders && (previousPenStyle != Qt::SolidLine || colorChange))
|
||||
if (EASY_GLOBALS.draw_graphics_items_borders && (previousPenStyle != Qt::SolidLine || colorChange))
|
||||
{
|
||||
// Restore pen for item which is wide enough to paint borders
|
||||
previousPenStyle = Qt::SolidLine;
|
||||
@ -422,7 +423,7 @@ void EasyGraphicsItem::paint(QPainter* _painter, const QStyleOptionGraphicsItem*
|
||||
_painter->setPen(textColor);
|
||||
|
||||
// drawing text
|
||||
auto name = *item.block->node->name() != 0 ? item.block->node->name() : ::profiler_gui::EASY_GLOBALS.descriptors[item.block->node->id()]->name();
|
||||
auto name = *itemBlock.tree.node->name() != 0 ? itemBlock.tree.node->name() : easyDescriptor(itemBlock.tree.node->id()).name();
|
||||
_painter->drawText(rect, flags, ::profiler_gui::toUnicode(name));
|
||||
|
||||
// restore previous pen color
|
||||
@ -434,9 +435,9 @@ void EasyGraphicsItem::paint(QPainter* _painter, const QStyleOptionGraphicsItem*
|
||||
}
|
||||
}
|
||||
|
||||
if (!selectedItemsWasPainted && ::profiler_gui::EASY_GLOBALS.selected_block < ::profiler_gui::EASY_GLOBALS.gui_blocks.size())
|
||||
if (!selectedItemsWasPainted && EASY_GLOBALS.selected_block < EASY_GLOBALS.gui_blocks.size())
|
||||
{
|
||||
const auto& guiblock = ::profiler_gui::EASY_GLOBALS.gui_blocks[::profiler_gui::EASY_GLOBALS.selected_block];
|
||||
const auto& guiblock = EASY_GLOBALS.gui_blocks[EASY_GLOBALS.selected_block];
|
||||
if (guiblock.graphics_item == m_index)
|
||||
{
|
||||
const auto& item = m_levels[guiblock.graphics_item_level][guiblock.graphics_item_index];
|
||||
@ -482,7 +483,8 @@ void EasyGraphicsItem::paint(QPainter* _painter, const QStyleOptionGraphicsItem*
|
||||
_painter->setPen(textColor);
|
||||
|
||||
// drawing text
|
||||
auto name = *item.block->node->name() != 0 ? item.block->node->name() : ::profiler_gui::EASY_GLOBALS.descriptors[item.block->node->id()]->name();
|
||||
const auto& itemBlock = easyBlock(item.block);
|
||||
auto name = *itemBlock.tree.node->name() != 0 ? itemBlock.tree.node->name() : easyDescriptor(itemBlock.tree.node->id()).name();
|
||||
_painter->drawText(rect, Qt::AlignCenter, ::profiler_gui::toUnicode(name));
|
||||
// END Draw text~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
}
|
||||
@ -511,7 +513,7 @@ void EasyGraphicsItem::getBlocks(qreal _left, qreal _right, ::profiler_gui::Tree
|
||||
|
||||
// Search for first visible top-level item
|
||||
auto& level0 = m_levels.front();
|
||||
auto first = ::std::lower_bound(level0.begin(), level0.end(), _left, [](const ::profiler_gui::ProfBlockItem& _item, qreal _value)
|
||||
auto first = ::std::lower_bound(level0.begin(), level0.end(), _left, [](const ::profiler_gui::EasyBlockItem& _item, qreal _value)
|
||||
{
|
||||
return _item.left() < _value;
|
||||
});
|
||||
@ -552,7 +554,7 @@ void EasyGraphicsItem::getBlocks(qreal _left, qreal _right, ::profiler_gui::Tree
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
const ::profiler_gui::ProfBlockItem* EasyGraphicsItem::intersect(const QPointF& _pos) const
|
||||
const ::profiler_gui::EasyBlockItem* EasyGraphicsItem::intersect(const QPointF& _pos) const
|
||||
{
|
||||
if (m_levels.empty() || m_levels.front().empty())
|
||||
{
|
||||
@ -588,7 +590,7 @@ const ::profiler_gui::ProfBlockItem* EasyGraphicsItem::intersect(const QPointF&
|
||||
const auto& level = m_levels[i];
|
||||
|
||||
// Search for first visible item
|
||||
auto first = ::std::lower_bound(level.begin() + firstItem, level.begin() + lastItem, _pos.x(), [](const ::profiler_gui::ProfBlockItem& _item, qreal _value)
|
||||
auto first = ::std::lower_bound(level.begin() + firstItem, level.begin() + lastItem, _pos.x(), [](const ::profiler_gui::EasyBlockItem& _item, qreal _value)
|
||||
{
|
||||
return _item.left() < _value;
|
||||
});
|
||||
@ -620,7 +622,7 @@ const ::profiler_gui::ProfBlockItem* EasyGraphicsItem::intersect(const QPointF&
|
||||
}
|
||||
|
||||
const auto w = item.width() * currentScale;
|
||||
if (i == levelIndex || w < 20 || !::profiler_gui::EASY_GLOBALS.gui_blocks[item.block->block_index].expanded)
|
||||
if (i == levelIndex || w < 20 || !easyBlock(item.block).expanded)
|
||||
{
|
||||
return &item;
|
||||
}
|
||||
@ -725,12 +727,12 @@ const EasyGraphicsItem::Children& EasyGraphicsItem::items(unsigned char _level)
|
||||
return m_levels[_level];
|
||||
}
|
||||
|
||||
const ::profiler_gui::ProfBlockItem& EasyGraphicsItem::getItem(unsigned char _level, unsigned int _index) const
|
||||
const ::profiler_gui::EasyBlockItem& EasyGraphicsItem::getItem(unsigned char _level, unsigned int _index) const
|
||||
{
|
||||
return m_levels[_level][_index];
|
||||
}
|
||||
|
||||
::profiler_gui::ProfBlockItem& EasyGraphicsItem::getItem(unsigned char _level, unsigned int _index)
|
||||
::profiler_gui::EasyBlockItem& EasyGraphicsItem::getItem(unsigned char _level, unsigned int _index)
|
||||
{
|
||||
return m_levels[_level][_index];
|
||||
}
|
||||
@ -862,7 +864,7 @@ void EasyChronometerItem::paint(QPainter* _painter, const QStyleOptionGraphicsIt
|
||||
_painter->setFont(CHRONOMETER_FONT);
|
||||
|
||||
int textFlags = 0;
|
||||
switch (::profiler_gui::EASY_GLOBALS.chrono_text_position)
|
||||
switch (EASY_GLOBALS.chrono_text_position)
|
||||
{
|
||||
case ::profiler_gui::ChronoTextPosition_Top:
|
||||
textFlags = Qt::AlignTop | Qt::AlignHCenter;
|
||||
@ -1001,7 +1003,7 @@ void EasyBackgroundItem::paint(QPainter* _painter, const QStyleOptionGraphicsIte
|
||||
if (top > h || bottom < 0)
|
||||
continue;
|
||||
|
||||
if (item->threadId() == ::profiler_gui::EASY_GLOBALS.selected_thread)
|
||||
if (item->threadId() == EASY_GLOBALS.selected_thread)
|
||||
_painter->setBrush(QBrush(QColor::fromRgb(::profiler_gui::SELECTED_THREAD_BACKGROUND)));
|
||||
else
|
||||
_painter->setBrush(brushes[i & 1]);
|
||||
@ -1291,8 +1293,8 @@ void EasyGraphicsView::test(unsigned int _frames_number, unsigned int _total_ite
|
||||
if (longestItem != nullptr)
|
||||
{
|
||||
m_pScrollbar->setMinimapFrom(0, longestItem->items(0));
|
||||
::profiler_gui::EASY_GLOBALS.selected_thread = 0;
|
||||
emit::profiler_gui::EASY_GLOBALS.events.selectedThreadChanged(0);
|
||||
EASY_GLOBALS.selected_thread = 0;
|
||||
emitEASY_GLOBALS.events.selectedThreadChanged(0);
|
||||
}
|
||||
|
||||
// Create new chronometer item (previous item was destroyed by scene on scene()->clear()).
|
||||
@ -1359,13 +1361,13 @@ void EasyGraphicsView::setTree(const ::profiler::thread_blocks_tree_t& _blocksTr
|
||||
|
||||
// Calculating start and end time
|
||||
::profiler::timestamp_t finish = 0;
|
||||
const ::profiler::BlocksTree* longestTree = nullptr;
|
||||
::profiler::thread_id_t longestTree = 0;
|
||||
const EasyGraphicsItem* longestItem = nullptr;
|
||||
for (const auto& threadTree : _blocksTree)
|
||||
{
|
||||
const auto& tree = threadTree.second.tree;
|
||||
const auto timestart = tree.children.front().node->begin();
|
||||
const auto timefinish = tree.children.back().node->end();
|
||||
const auto& tree = threadTree.second.children;
|
||||
const auto timestart = blocksTree(tree.front()).node->begin();
|
||||
const auto timefinish = blocksTree(tree.back()).node->end();
|
||||
|
||||
if (m_beginTime > timestart)
|
||||
{
|
||||
@ -1375,7 +1377,7 @@ void EasyGraphicsView::setTree(const ::profiler::thread_blocks_tree_t& _blocksTr
|
||||
if (finish < timefinish)
|
||||
{
|
||||
finish = timefinish;
|
||||
longestTree = &tree;
|
||||
longestTree = threadTree.first;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1391,13 +1393,13 @@ void EasyGraphicsView::setTree(const ::profiler::thread_blocks_tree_t& _blocksTr
|
||||
}
|
||||
|
||||
// fill scene with new items
|
||||
const auto& tree = threadTree.second.tree;
|
||||
qreal h = 0, x = time2position(tree.children.front().node->begin());
|
||||
const auto& tree = threadTree.second.children;
|
||||
qreal h = 0, x = time2position(blocksTree(tree.front()).node->begin());
|
||||
auto item = new EasyGraphicsItem(static_cast<unsigned char>(m_items.size()), &threadTree.second);
|
||||
item->setLevels(tree.depth);
|
||||
item->setLevels(threadTree.second.depth);
|
||||
item->setPos(0, y);
|
||||
|
||||
const auto children_duration = setTree(item, tree.children, h, y, 0);
|
||||
const auto children_duration = setTree(item, tree, h, y, 0);
|
||||
|
||||
item->setBoundingRect(0, 0, children_duration + x, h);
|
||||
m_items.push_back(item);
|
||||
@ -1405,7 +1407,7 @@ void EasyGraphicsView::setTree(const ::profiler::thread_blocks_tree_t& _blocksTr
|
||||
|
||||
y += h + THREADS_ROW_SPACING;
|
||||
|
||||
if (longestTree == &tree)
|
||||
if (longestTree == threadTree.first)
|
||||
{
|
||||
longestItem = item;
|
||||
}
|
||||
@ -1424,8 +1426,8 @@ void EasyGraphicsView::setTree(const ::profiler::thread_blocks_tree_t& _blocksTr
|
||||
if (longestItem != nullptr)
|
||||
{
|
||||
m_pScrollbar->setMinimapFrom(longestItem->threadId(), longestItem->items(0));
|
||||
::profiler_gui::EASY_GLOBALS.selected_thread = longestItem->threadId();
|
||||
emit::profiler_gui::EASY_GLOBALS.events.selectedThreadChanged(longestItem->threadId());
|
||||
EASY_GLOBALS.selected_thread = longestItem->threadId();
|
||||
emit EASY_GLOBALS.events.selectedThreadChanged(longestItem->threadId());
|
||||
}
|
||||
|
||||
// Create new chronometer item (previous item was destroyed by scene on scene()->clear()).
|
||||
@ -1466,8 +1468,11 @@ qreal EasyGraphicsView::setTree(EasyGraphicsItem* _item, const ::profiler::Block
|
||||
bool warned = false;
|
||||
qreal total_duration = 0, prev_end = 0, maxh = 0;
|
||||
qreal start_time = -1;
|
||||
for (const auto& child : _children)
|
||||
for (auto child_index : _children)
|
||||
{
|
||||
auto& gui_block = easyBlock(child_index);
|
||||
const auto& child = gui_block.tree;
|
||||
|
||||
auto xbegin = time2position(child.node->begin());
|
||||
if (start_time < 0)
|
||||
{
|
||||
@ -1491,7 +1496,6 @@ qreal EasyGraphicsView::setTree(EasyGraphicsItem* _item, const ::profiler::Block
|
||||
auto i = _item->addItem(level);
|
||||
auto& b = _item->getItem(level, i);
|
||||
|
||||
auto& gui_block = ::profiler_gui::EASY_GLOBALS.gui_blocks[child.block_index];
|
||||
gui_block.graphics_item = _item->index();
|
||||
gui_block.graphics_item_level = level;
|
||||
gui_block.graphics_item_index = i;
|
||||
@ -1528,8 +1532,8 @@ qreal EasyGraphicsView::setTree(EasyGraphicsItem* _item, const ::profiler::Block
|
||||
maxh = h;
|
||||
}
|
||||
|
||||
const auto color = ::profiler_gui::EASY_GLOBALS.descriptors[child.node->id()]->color();
|
||||
b.block = &child;
|
||||
const auto color = EASY_GLOBALS.descriptors[child.node->id()]->color();
|
||||
b.block = child_index;// &child;
|
||||
b.color = ::profiler_gui::fromProfilerRgb(::profiler::colors::get_red(color), ::profiler::colors::get_green(color), ::profiler::colors::get_blue(color));
|
||||
b.setPos(xbegin, duration);
|
||||
b.totalHeight = GRAPHICS_ROW_SIZE + h;
|
||||
@ -1570,8 +1574,8 @@ void EasyGraphicsView::setScrollbar(EasyGraphicsScrollbar* _scrollbar)
|
||||
connect(m_pScrollbar, &EasyGraphicsScrollbar::wheeled, this, &This::onGraphicsScrollbarWheel);
|
||||
}
|
||||
|
||||
::profiler_gui::EASY_GLOBALS.selected_thread = 0;
|
||||
emit ::profiler_gui::EASY_GLOBALS.events.selectedThreadChanged(0);
|
||||
EASY_GLOBALS.selected_thread = 0;
|
||||
emit EASY_GLOBALS.events.selectedThreadChanged(0);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
@ -1646,7 +1650,7 @@ void EasyGraphicsView::onGraphicsScrollbarWheel(qreal _mouseX, int _wheelDelta)
|
||||
{
|
||||
for (auto item : m_items)
|
||||
{
|
||||
if (item->threadId() == ::profiler_gui::EASY_GLOBALS.selected_thread)
|
||||
if (item->threadId() == EASY_GLOBALS.selected_thread)
|
||||
{
|
||||
m_bUpdatingRect = true;
|
||||
auto vbar = verticalScrollBar();
|
||||
@ -1779,8 +1783,8 @@ void EasyGraphicsView::mouseReleaseEvent(QMouseEvent* _event)
|
||||
}
|
||||
}
|
||||
|
||||
const ::profiler_gui::ProfBlockItem* selectedBlock = nullptr;
|
||||
const auto previouslySelectedBlock = ::profiler_gui::EASY_GLOBALS.selected_block;
|
||||
const ::profiler_gui::EasyBlockItem* selectedBlock = nullptr;
|
||||
const auto previouslySelectedBlock = EASY_GLOBALS.selected_block;
|
||||
if (m_mouseButtons & Qt::LeftButton)
|
||||
{
|
||||
bool clicked = false;
|
||||
@ -1813,15 +1817,15 @@ void EasyGraphicsView::mouseReleaseEvent(QMouseEvent* _event)
|
||||
{
|
||||
changedSelectedItem = true;
|
||||
selectedBlock = block;
|
||||
::profiler_gui::EASY_GLOBALS.selected_block = block->block->block_index;
|
||||
EASY_GLOBALS.selected_block = block->block;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!changedSelectedItem && ::profiler_gui::EASY_GLOBALS.selected_block != ::profiler_gui::numeric_max(::profiler_gui::EASY_GLOBALS.selected_block))
|
||||
if (!changedSelectedItem && EASY_GLOBALS.selected_block != ::profiler_gui::numeric_max(EASY_GLOBALS.selected_block))
|
||||
{
|
||||
changedSelectedItem = true;
|
||||
::profiler_gui::set_max(::profiler_gui::EASY_GLOBALS.selected_block);
|
||||
::profiler_gui::set_max(EASY_GLOBALS.selected_block);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1841,12 +1845,12 @@ void EasyGraphicsView::mouseReleaseEvent(QMouseEvent* _event)
|
||||
if (changedSelectedItem)
|
||||
{
|
||||
m_bUpdatingRect = true;
|
||||
if (selectedBlock != nullptr && previouslySelectedBlock == ::profiler_gui::EASY_GLOBALS.selected_block && !selectedBlock->block->children.empty())
|
||||
if (selectedBlock != nullptr && previouslySelectedBlock == EASY_GLOBALS.selected_block && !blocksTree(selectedBlock->block).children.empty())
|
||||
{
|
||||
::profiler_gui::EASY_GLOBALS.gui_blocks[previouslySelectedBlock].expanded = !::profiler_gui::EASY_GLOBALS.gui_blocks[previouslySelectedBlock].expanded;
|
||||
emit ::profiler_gui::EASY_GLOBALS.events.itemsExpandStateChanged();
|
||||
EASY_GLOBALS.gui_blocks[previouslySelectedBlock].expanded = !EASY_GLOBALS.gui_blocks[previouslySelectedBlock].expanded;
|
||||
emit EASY_GLOBALS.events.itemsExpandStateChanged();
|
||||
}
|
||||
emit ::profiler_gui::EASY_GLOBALS.events.selectedBlockChanged(::profiler_gui::EASY_GLOBALS.selected_block);
|
||||
emit EASY_GLOBALS.events.selectedBlockChanged(EASY_GLOBALS.selected_block);
|
||||
m_bUpdatingRect = false;
|
||||
|
||||
updateScene();
|
||||
@ -1998,7 +2002,7 @@ void EasyGraphicsView::initMode()
|
||||
connect(verticalScrollBar(), &QScrollBar::valueChanged, this, &This::onScrollbarValueChange);
|
||||
connect(&m_flickerTimer, &QTimer::timeout, this, &This::onFlickerTimeout);
|
||||
|
||||
auto globalSignals = &::profiler_gui::EASY_GLOBALS.events;
|
||||
auto globalSignals = &EASY_GLOBALS.events;
|
||||
connect(globalSignals, &::profiler_gui::EasyGlobalSignals::selectedThreadChanged, this, &This::onSelectedThreadChange);
|
||||
connect(globalSignals, &::profiler_gui::EasyGlobalSignals::selectedBlockChanged, this, &This::onSelectedBlockChange);
|
||||
connect(globalSignals, &::profiler_gui::EasyGlobalSignals::itemsExpandStateChanged, this, &This::onItemsEspandStateChange);
|
||||
@ -2101,11 +2105,11 @@ void EasyGraphicsView::onSelectedBlockChange(unsigned int _block_index)
|
||||
{
|
||||
if (!m_bUpdatingRect)
|
||||
{
|
||||
if (_block_index < ::profiler_gui::EASY_GLOBALS.gui_blocks.size())
|
||||
if (_block_index < EASY_GLOBALS.gui_blocks.size())
|
||||
{
|
||||
// Scroll to item
|
||||
|
||||
const auto& guiblock = ::profiler_gui::EASY_GLOBALS.gui_blocks[_block_index];
|
||||
const auto& guiblock = EASY_GLOBALS.gui_blocks[_block_index];
|
||||
const auto thread_item = m_items[guiblock.graphics_item];
|
||||
const auto& item = thread_item->items(guiblock.graphics_item_level)[guiblock.graphics_item_index];
|
||||
|
||||
@ -2180,7 +2184,7 @@ EasyThreadViewWidget::EasyThreadViewWidget(QWidget *parent, EasyGraphicsView* vi
|
||||
//m_layout->addWidget(m_label);
|
||||
//setLayout(m_layout);
|
||||
//show();
|
||||
connect(&::profiler_gui::EASY_GLOBALS.events, &::profiler_gui::EasyGlobalSignals::selectedThreadChanged, this, &This::onSelectedThreadChange);
|
||||
connect(&EASY_GLOBALS.events, &::profiler_gui::EasyGlobalSignals::selectedThreadChanged, this, &This::onSelectedThreadChange);
|
||||
}
|
||||
|
||||
EasyThreadViewWidget::~EasyThreadViewWidget()
|
||||
@ -2191,14 +2195,14 @@ EasyThreadViewWidget::~EasyThreadViewWidget()
|
||||
void EasyThreadViewWidget::onSelectedThreadChange(::profiler::thread_id_t _id)
|
||||
{
|
||||
/*
|
||||
auto threadName = ::profiler_gui::EASY_GLOBALS.profiler_blocks[::profiler_gui::EASY_GLOBALS.selected_thread].thread_name;
|
||||
auto threadName = EASY_GLOBALS.profiler_blocks[EASY_GLOBALS.selected_thread].thread_name;
|
||||
if(threadName[0]!=0)
|
||||
{
|
||||
m_label->setText(threadName);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_label->setText(QString("Thread %1").arg(::profiler_gui::EASY_GLOBALS.selected_thread));
|
||||
m_label->setText(QString("Thread %1").arg(EASY_GLOBALS.selected_thread));
|
||||
}
|
||||
*/
|
||||
QLayoutItem *ditem;
|
||||
|
@ -58,7 +58,7 @@ inline qreal microseconds2units(qreal _value)
|
||||
|
||||
class EasyGraphicsItem : public QGraphicsItem
|
||||
{
|
||||
typedef ::profiler_gui::ProfItems Children;
|
||||
typedef ::profiler_gui::EasyItems Children;
|
||||
typedef ::std::vector<unsigned int> DrawIndexes;
|
||||
typedef ::std::vector<Children> Sublevels;
|
||||
|
||||
@ -118,13 +118,13 @@ public:
|
||||
|
||||
\param _level Index of the level
|
||||
\param _index Index of required item */
|
||||
const ::profiler_gui::ProfBlockItem& getItem(unsigned char _level, unsigned int _index) const;
|
||||
const ::profiler_gui::EasyBlockItem& getItem(unsigned char _level, unsigned int _index) const;
|
||||
|
||||
/**\brief Returns reference to the item with required index on specified level.
|
||||
|
||||
\param _level Index of the level
|
||||
\param _index Index of required item */
|
||||
::profiler_gui::ProfBlockItem& getItem(unsigned char _level, unsigned int _index);
|
||||
::profiler_gui::EasyBlockItem& getItem(unsigned char _level, unsigned int _index);
|
||||
|
||||
/** \brief Adds new item to required level.
|
||||
|
||||
@ -142,7 +142,7 @@ public:
|
||||
\param _blocks Reference to the array of selected blocks */
|
||||
void getBlocks(qreal _left, qreal _right, ::profiler_gui::TreeBlocks& _blocks) const;
|
||||
|
||||
const ::profiler_gui::ProfBlockItem* intersect(const QPointF& _pos) const;
|
||||
const ::profiler_gui::EasyBlockItem* intersect(const QPointF& _pos) const;
|
||||
|
||||
private:
|
||||
|
||||
|
@ -104,8 +104,8 @@ EasyTreeWidget::EasyTreeWidget(QWidget* _parent)
|
||||
|
||||
setHeaderItem(header);
|
||||
|
||||
connect(&::profiler_gui::EASY_GLOBALS.events, &::profiler_gui::EasyGlobalSignals::selectedThreadChanged, this, &This::onSelectedThreadChange);
|
||||
connect(&::profiler_gui::EASY_GLOBALS.events, &::profiler_gui::EasyGlobalSignals::selectedBlockChanged, this, &This::onSelectedBlockChange);
|
||||
connect(&EASY_GLOBALS.events, &::profiler_gui::EasyGlobalSignals::selectedThreadChanged, this, &This::onSelectedThreadChange);
|
||||
connect(&EASY_GLOBALS.events, &::profiler_gui::EasyGlobalSignals::selectedBlockChanged, this, &This::onSelectedBlockChange);
|
||||
connect(&m_fillTimer, &QTimer::timeout, this, &This::onFillTimerTimeout);
|
||||
|
||||
loadSettings();
|
||||
@ -163,8 +163,8 @@ void EasyTreeWidget::onFillTimerTimeout()
|
||||
connect(this, &Parent::itemExpanded, this, &This::onItemExpand);
|
||||
connect(this, &Parent::itemCollapsed, this, &This::onItemCollapse);
|
||||
connect(this, &Parent::currentItemChanged, this, &This::onCurrentItemChange);
|
||||
onSelectedThreadChange(::profiler_gui::EASY_GLOBALS.selected_thread);
|
||||
onSelectedBlockChange(::profiler_gui::EASY_GLOBALS.selected_block);
|
||||
onSelectedThreadChange(EASY_GLOBALS.selected_thread);
|
||||
onSelectedBlockChange(EASY_GLOBALS.selected_block);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -194,7 +194,7 @@ void EasyTreeWidget::setTree(const unsigned int _blocksNumber, const ::profiler:
|
||||
// {
|
||||
// addTopLevelItem(item.second);
|
||||
// m_roots[item.first] = item.second;
|
||||
// if (item.first == ::profiler_gui::EASY_GLOBALS.selected_thread)
|
||||
// if (item.first == EASY_GLOBALS.selected_thread)
|
||||
// item.second->colorize(true);
|
||||
// }
|
||||
//}
|
||||
@ -227,7 +227,7 @@ void EasyTreeWidget::setTreeBlocks(const ::profiler_gui::TreeBlocks& _blocks, ::
|
||||
// {
|
||||
// addTopLevelItem(item.second);
|
||||
// m_roots[item.first] = item.second;
|
||||
// if (item.first == ::profiler_gui::EASY_GLOBALS.selected_thread)
|
||||
// if (item.first == EASY_GLOBALS.selected_thread)
|
||||
// item.second->colorize(true);
|
||||
// }
|
||||
//}
|
||||
@ -238,7 +238,7 @@ void EasyTreeWidget::setTreeBlocks(const ::profiler_gui::TreeBlocks& _blocks, ::
|
||||
|
||||
//connect(this, &Parent::itemExpanded, this, &This::onItemExpand);
|
||||
//connect(this, &Parent::itemCollapsed, this, &This::onItemCollapse);
|
||||
//onSelectedBlockChange(::profiler_gui::EASY_GLOBALS.selected_block);
|
||||
//onSelectedBlockChange(EASY_GLOBALS.selected_block);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
@ -265,15 +265,15 @@ void EasyTreeWidget::clearSilent(bool _global)
|
||||
|
||||
if (!_global)
|
||||
{
|
||||
if (::profiler_gui::EASY_GLOBALS.collapse_items_on_tree_close) for (auto item : m_items)
|
||||
if (EASY_GLOBALS.collapse_items_on_tree_close) for (auto item : m_items)
|
||||
{
|
||||
auto& gui_block = ::profiler_gui::EASY_GLOBALS.gui_blocks[item->block()->block_index];
|
||||
auto& gui_block = item->guiBlock();
|
||||
::profiler_gui::set_max(gui_block.tree_item);
|
||||
gui_block.expanded = false;
|
||||
}
|
||||
else for (auto item : m_items)
|
||||
{
|
||||
::profiler_gui::set_max(::profiler_gui::EASY_GLOBALS.gui_blocks[item->block()->block_index].tree_item);
|
||||
::profiler_gui::set_max(item->guiBlock().tree_item);
|
||||
}
|
||||
}
|
||||
|
||||
@ -294,7 +294,7 @@ void EasyTreeWidget::clearSilent(bool _global)
|
||||
//clear();
|
||||
|
||||
if (!_global)
|
||||
emit::profiler_gui::EASY_GLOBALS.events.itemsExpandStateChanged();
|
||||
emit EASY_GLOBALS.events.itemsExpandStateChanged();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
@ -339,7 +339,7 @@ void EasyTreeWidget::contextMenuEvent(QContextMenuEvent* _event)
|
||||
action->setChecked(m_bColorRows);
|
||||
connect(action, &QAction::triggered, this, &This::onColorizeRowsTriggered);
|
||||
|
||||
if (item != nullptr)
|
||||
if (item != nullptr && item->parent() != nullptr)
|
||||
{
|
||||
//auto itemAction = new EasyItemAction("Show this item on scene", item->block()->block_index);
|
||||
//itemAction->setToolTip("Scroll graphics scene to current item in the tree");
|
||||
@ -357,16 +357,16 @@ void EasyTreeWidget::contextMenuEvent(QContextMenuEvent* _event)
|
||||
case COL_MAX_PER_PARENT:
|
||||
case COL_MAX_PER_FRAME:
|
||||
{
|
||||
auto block = item->block();
|
||||
auto& block = item->block();
|
||||
auto i = ::profiler_gui::numeric_max<unsigned int>();
|
||||
switch (col)
|
||||
{
|
||||
case COL_MIN_PER_THREAD: i = block->per_thread_stats->min_duration_block; break;
|
||||
case COL_MIN_PER_PARENT: i = block->per_parent_stats->min_duration_block; break;
|
||||
case COL_MIN_PER_FRAME: i = block->per_frame_stats->min_duration_block; break;
|
||||
case COL_MAX_PER_THREAD: i = block->per_thread_stats->max_duration_block; break;
|
||||
case COL_MAX_PER_PARENT: i = block->per_parent_stats->max_duration_block; break;
|
||||
case COL_MAX_PER_FRAME: i = block->per_frame_stats->max_duration_block; break;
|
||||
case COL_MIN_PER_THREAD: i = block.per_thread_stats->min_duration_block; break;
|
||||
case COL_MIN_PER_PARENT: i = block.per_parent_stats->min_duration_block; break;
|
||||
case COL_MIN_PER_FRAME: i = block.per_frame_stats->min_duration_block; break;
|
||||
case COL_MAX_PER_THREAD: i = block.per_thread_stats->max_duration_block; break;
|
||||
case COL_MAX_PER_PARENT: i = block.per_parent_stats->max_duration_block; break;
|
||||
case COL_MAX_PER_FRAME: i = block.per_frame_stats->max_duration_block; break;
|
||||
}
|
||||
|
||||
if (i != ::profiler_gui::numeric_max(i))
|
||||
@ -427,8 +427,8 @@ void EasyTreeWidget::alignProgressBar()
|
||||
|
||||
void EasyTreeWidget::onJumpToItemClicked(unsigned int _block_index)
|
||||
{
|
||||
::profiler_gui::EASY_GLOBALS.selected_block = _block_index;
|
||||
emit ::profiler_gui::EASY_GLOBALS.events.selectedBlockChanged(_block_index);
|
||||
EASY_GLOBALS.selected_block = _block_index;
|
||||
emit EASY_GLOBALS.events.selectedBlockChanged(_block_index);
|
||||
}
|
||||
|
||||
void EasyTreeWidget::onCollapseAllClicked(bool)
|
||||
@ -439,11 +439,11 @@ void EasyTreeWidget::onCollapseAllClicked(bool)
|
||||
collapseAll();
|
||||
m_bSilentExpandCollapse = false;
|
||||
|
||||
if (::profiler_gui::EASY_GLOBALS.bind_scene_and_tree_expand_status)
|
||||
if (EASY_GLOBALS.bind_scene_and_tree_expand_status)
|
||||
{
|
||||
for (auto item : m_items)
|
||||
::profiler_gui::EASY_GLOBALS.gui_blocks[item->block()->block_index].expanded = false;
|
||||
emit::profiler_gui::EASY_GLOBALS.events.itemsExpandStateChanged();
|
||||
item->guiBlock().expanded = false;
|
||||
emit EASY_GLOBALS.events.itemsExpandStateChanged();
|
||||
}
|
||||
}
|
||||
|
||||
@ -456,11 +456,15 @@ void EasyTreeWidget::onExpandAllClicked(bool)
|
||||
resizeColumnsToContents();
|
||||
m_bSilentExpandCollapse = false;
|
||||
|
||||
if (::profiler_gui::EASY_GLOBALS.bind_scene_and_tree_expand_status)
|
||||
if (EASY_GLOBALS.bind_scene_and_tree_expand_status)
|
||||
{
|
||||
for (auto item : m_items)
|
||||
::profiler_gui::EASY_GLOBALS.gui_blocks[item->block()->block_index].expanded = !item->block()->children.empty();
|
||||
emit::profiler_gui::EASY_GLOBALS.events.itemsExpandStateChanged();
|
||||
{
|
||||
auto& b = item->guiBlock();
|
||||
b.expanded = !b.tree.children.empty();
|
||||
}
|
||||
|
||||
emit EASY_GLOBALS.events.itemsExpandStateChanged();
|
||||
}
|
||||
}
|
||||
|
||||
@ -475,7 +479,7 @@ void EasyTreeWidget::onCollapseAllChildrenClicked(bool)
|
||||
current->collapseAll();
|
||||
m_bSilentExpandCollapse = false;
|
||||
|
||||
emit ::profiler_gui::EASY_GLOBALS.events.itemsExpandStateChanged();
|
||||
emit EASY_GLOBALS.events.itemsExpandStateChanged();
|
||||
}
|
||||
}
|
||||
|
||||
@ -491,7 +495,7 @@ void EasyTreeWidget::onExpandAllChildrenClicked(bool)
|
||||
resizeColumnsToContents();
|
||||
m_bSilentExpandCollapse = false;
|
||||
|
||||
emit ::profiler_gui::EASY_GLOBALS.events.itemsExpandStateChanged();
|
||||
emit EASY_GLOBALS.events.itemsExpandStateChanged();
|
||||
}
|
||||
}
|
||||
|
||||
@ -499,30 +503,30 @@ void EasyTreeWidget::onExpandAllChildrenClicked(bool)
|
||||
|
||||
void EasyTreeWidget::onItemExpand(QTreeWidgetItem* _item)
|
||||
{
|
||||
if (!::profiler_gui::EASY_GLOBALS.bind_scene_and_tree_expand_status)
|
||||
if (!EASY_GLOBALS.bind_scene_and_tree_expand_status)
|
||||
{
|
||||
resizeColumnsToContents();
|
||||
return;
|
||||
}
|
||||
|
||||
::profiler_gui::EASY_GLOBALS.gui_blocks[static_cast<EasyTreeWidgetItem*>(_item)->block()->block_index].expanded = true;
|
||||
static_cast<EasyTreeWidgetItem*>(_item)->guiBlock().expanded = true;
|
||||
|
||||
if (!m_bSilentExpandCollapse)
|
||||
{
|
||||
resizeColumnsToContents();
|
||||
emit ::profiler_gui::EASY_GLOBALS.events.itemsExpandStateChanged();
|
||||
emit EASY_GLOBALS.events.itemsExpandStateChanged();
|
||||
}
|
||||
}
|
||||
|
||||
void EasyTreeWidget::onItemCollapse(QTreeWidgetItem* _item)
|
||||
{
|
||||
if (!::profiler_gui::EASY_GLOBALS.bind_scene_and_tree_expand_status)
|
||||
if (!EASY_GLOBALS.bind_scene_and_tree_expand_status)
|
||||
return;
|
||||
|
||||
::profiler_gui::EASY_GLOBALS.gui_blocks[static_cast<EasyTreeWidgetItem*>(_item)->block()->block_index].expanded = false;
|
||||
static_cast<EasyTreeWidgetItem*>(_item)->guiBlock().expanded = false;
|
||||
|
||||
if (!m_bSilentExpandCollapse)
|
||||
emit ::profiler_gui::EASY_GLOBALS.events.itemsExpandStateChanged();
|
||||
emit EASY_GLOBALS.events.itemsExpandStateChanged();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
@ -530,13 +534,13 @@ void EasyTreeWidget::onItemCollapse(QTreeWidgetItem* _item)
|
||||
void EasyTreeWidget::onCurrentItemChange(QTreeWidgetItem* _item, QTreeWidgetItem*)
|
||||
{
|
||||
if (_item == nullptr)
|
||||
::profiler_gui::set_max(::profiler_gui::EASY_GLOBALS.selected_block);
|
||||
::profiler_gui::set_max(EASY_GLOBALS.selected_block);
|
||||
else
|
||||
::profiler_gui::EASY_GLOBALS.selected_block = static_cast<EasyTreeWidgetItem*>(_item)->block()->block_index;
|
||||
EASY_GLOBALS.selected_block = static_cast<EasyTreeWidgetItem*>(_item)->block_index();
|
||||
|
||||
disconnect(&::profiler_gui::EASY_GLOBALS.events, &::profiler_gui::EasyGlobalSignals::selectedBlockChanged, this, &This::onSelectedBlockChange);
|
||||
emit ::profiler_gui::EASY_GLOBALS.events.selectedBlockChanged(::profiler_gui::EASY_GLOBALS.selected_block);
|
||||
connect(&::profiler_gui::EASY_GLOBALS.events, &::profiler_gui::EasyGlobalSignals::selectedBlockChanged, this, &This::onSelectedBlockChange);
|
||||
disconnect(&EASY_GLOBALS.events, &::profiler_gui::EasyGlobalSignals::selectedBlockChanged, this, &This::onSelectedBlockChange);
|
||||
emit EASY_GLOBALS.events.selectedBlockChanged(EASY_GLOBALS.selected_block);
|
||||
connect(&EASY_GLOBALS.events, &::profiler_gui::EasyGlobalSignals::selectedBlockChanged, this, &This::onSelectedBlockChange);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
@ -581,9 +585,9 @@ void EasyTreeWidget::onSelectedBlockChange(unsigned int _block_index)
|
||||
|
||||
EasyTreeWidgetItem* item = nullptr;
|
||||
|
||||
if (_block_index < ::profiler_gui::EASY_GLOBALS.gui_blocks.size())
|
||||
if (_block_index < EASY_GLOBALS.gui_blocks.size())
|
||||
{
|
||||
const auto i = ::profiler_gui::EASY_GLOBALS.gui_blocks[_block_index].tree_item;
|
||||
const auto i = easyBlock(_block_index).tree_item;
|
||||
if (i < m_items.size())
|
||||
item = m_items[i];
|
||||
}
|
||||
@ -592,19 +596,19 @@ void EasyTreeWidget::onSelectedBlockChange(unsigned int _block_index)
|
||||
{
|
||||
//const QSignalBlocker b(this);
|
||||
|
||||
if (::profiler_gui::EASY_GLOBALS.bind_scene_and_tree_expand_status)
|
||||
if (EASY_GLOBALS.bind_scene_and_tree_expand_status)
|
||||
{
|
||||
m_bSilentExpandCollapse = true;
|
||||
setCurrentItem(item);
|
||||
scrollToItem(item, QAbstractItemView::PositionAtCenter);
|
||||
if (::profiler_gui::EASY_GLOBALS.gui_blocks[item->block()->block_index].expanded)
|
||||
if (item->guiBlock().expanded)
|
||||
expandItem(item);
|
||||
else
|
||||
collapseItem(item);
|
||||
resizeColumnsToContents();
|
||||
m_bSilentExpandCollapse = false;
|
||||
|
||||
emit ::profiler_gui::EASY_GLOBALS.events.itemsExpandStateChanged();
|
||||
emit EASY_GLOBALS.events.itemsExpandStateChanged();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -105,14 +105,15 @@ inline QRgb fromProfilerRgb(unsigned int _red, unsigned int _green, unsigned int
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma pack(push, 1)
|
||||
struct ProfBlockItem final
|
||||
struct EasyBlockItem final
|
||||
{
|
||||
const ::profiler::BlocksTree* block; ///< Pointer to profiler block
|
||||
//const ::profiler::BlocksTree* block; ///< Pointer to profiler block
|
||||
qreal x; ///< x coordinate of the item (this is made qreal=double to avoid mistakes on very wide scene)
|
||||
float w; ///< Width of the item
|
||||
QRgb color; ///< Background color of the item
|
||||
unsigned int children_begin; ///< Index of first child item on the next sublevel
|
||||
unsigned short totalHeight; ///< Total height of the item including heights of all it's children
|
||||
::profiler::block_index_t block; ///< Index of profiler block
|
||||
uint32_t children_begin; ///< Index of first child item on the next sublevel
|
||||
uint16_t totalHeight; ///< Total height of the item including heights of all it's children
|
||||
char state; ///< 0 = no change, 1 = paint, -1 = do not paint
|
||||
|
||||
// Possible optimizations:
|
||||
@ -125,31 +126,58 @@ struct ProfBlockItem final
|
||||
inline qreal right() const { return x + w; }
|
||||
inline float width() const { return w; }
|
||||
|
||||
}; // END of struct ProfBlockItem.
|
||||
#pragma pack(pop)
|
||||
}; // END of struct EasyBlockItem.
|
||||
|
||||
typedef ::std::vector<ProfBlockItem> ProfItems;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
struct ProfSelectedBlock final
|
||||
struct EasyBlock final
|
||||
{
|
||||
const ::profiler::BlocksTreeRoot* root;
|
||||
const ::profiler::BlocksTree* tree;
|
||||
::profiler::BlocksTree tree;
|
||||
uint32_t tree_item;
|
||||
uint32_t graphics_item_index;
|
||||
uint8_t graphics_item_level;
|
||||
uint8_t graphics_item;
|
||||
bool expanded;
|
||||
|
||||
ProfSelectedBlock() : root(nullptr), tree(nullptr)
|
||||
EasyBlock() = default;
|
||||
|
||||
EasyBlock(EasyBlock&& that)
|
||||
: tree(::std::move(tree))
|
||||
, tree_item(that.tree_item)
|
||||
, graphics_item_index(that.graphics_item_index)
|
||||
, graphics_item_level(that.graphics_item_level)
|
||||
, graphics_item(that.graphics_item)
|
||||
, expanded(that.expanded)
|
||||
{
|
||||
}
|
||||
|
||||
ProfSelectedBlock(const ::profiler::BlocksTreeRoot* _root, const ::profiler::BlocksTree* _tree)
|
||||
private:
|
||||
|
||||
EasyBlock(const EasyBlock&) = delete;
|
||||
};
|
||||
#pragma pack(pop)
|
||||
|
||||
typedef ::std::vector<EasyBlockItem> EasyItems;
|
||||
typedef ::std::vector<EasyBlock> EasyBlocks;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
struct EasySelectedBlock final
|
||||
{
|
||||
const ::profiler::BlocksTreeRoot* root;
|
||||
::profiler::block_index_t tree;
|
||||
|
||||
EasySelectedBlock() : root(nullptr), tree(0xffffffff)
|
||||
{
|
||||
}
|
||||
|
||||
EasySelectedBlock(const ::profiler::BlocksTreeRoot* _root, const ::profiler::block_index_t _tree)
|
||||
: root(_root)
|
||||
, tree(_tree)
|
||||
{
|
||||
}
|
||||
|
||||
}; // END of struct ProfSelectedBlock.
|
||||
}; // END of struct EasySelectedBlock.
|
||||
|
||||
typedef ::std::vector<ProfSelectedBlock> TreeBlocks;
|
||||
typedef ::std::vector<EasySelectedBlock> TreeBlocks;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
@ -42,19 +42,6 @@ namespace profiler_gui {
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma pack(push, 1)
|
||||
struct EasyBlock final
|
||||
{
|
||||
unsigned int tree_item;
|
||||
unsigned int graphics_item_index;
|
||||
unsigned char graphics_item_level;
|
||||
unsigned char graphics_item;
|
||||
bool expanded;
|
||||
};
|
||||
#pragma pack(pop)
|
||||
|
||||
typedef ::std::vector<EasyBlock> EasyBlocks;
|
||||
|
||||
template <class T>
|
||||
inline auto toUnicode(const T& _inputString) -> decltype(QTextCodec::codecForLocale()->toUnicode(_inputString))
|
||||
{
|
||||
@ -97,13 +84,26 @@ namespace profiler_gui {
|
||||
|
||||
}; // END of struct EasyGlobals.
|
||||
|
||||
#ifndef IGNORE_GLOBALS_DECLARATION
|
||||
static EasyGlobals& EASY_GLOBALS = EasyGlobals::instance();
|
||||
#endif
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
} // END of namespace profiler_gui.
|
||||
|
||||
#ifndef IGNORE_GLOBALS_DECLARATION
|
||||
static ::profiler_gui::EasyGlobals& EASY_GLOBALS = ::profiler_gui::EasyGlobals::instance();
|
||||
|
||||
inline ::profiler_gui::EasyBlock& easyBlock(::profiler::block_index_t i) {
|
||||
return EASY_GLOBALS.gui_blocks[i];
|
||||
}
|
||||
|
||||
inline ::profiler::SerializedBlockDescriptor& easyDescriptor(::profiler::block_id_t i) {
|
||||
return *EASY_GLOBALS.descriptors[i];
|
||||
}
|
||||
|
||||
inline ::profiler::BlocksTree& blocksTree(::profiler::block_index_t i) {
|
||||
return easyBlock(i).tree;
|
||||
}
|
||||
#endif
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
@ -238,7 +238,7 @@ void EasyMinimapItem::setBoundingRect(qreal x, qreal y, qreal w, qreal h)
|
||||
m_boundingRect.setRect(x, y, w, h);
|
||||
}
|
||||
|
||||
void EasyMinimapItem::setSource(::profiler::thread_id_t _thread_id, const ::profiler_gui::ProfItems* _items)
|
||||
void EasyMinimapItem::setSource(::profiler::thread_id_t _thread_id, const ::profiler_gui::EasyItems* _items)
|
||||
{
|
||||
m_pSource = _items;
|
||||
m_threadId = _thread_id;
|
||||
@ -428,7 +428,7 @@ void EasyGraphicsScrollbar::hideChrono()
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void EasyGraphicsScrollbar::setMinimapFrom(::profiler::thread_id_t _thread_id, const ::profiler_gui::ProfItems* _items)
|
||||
void EasyGraphicsScrollbar::setMinimapFrom(::profiler::thread_id_t _thread_id, const ::profiler_gui::EasyItems* _items)
|
||||
{
|
||||
m_minimap->setSource(_thread_id, _items);
|
||||
m_slider->setVisible(m_minimap->isVisible());
|
||||
@ -493,14 +493,14 @@ void EasyGraphicsScrollbar::resizeEvent(QResizeEvent* _event)
|
||||
|
||||
void EasyGraphicsScrollbar::contextMenuEvent(QContextMenuEvent* _event)
|
||||
{
|
||||
if (::profiler_gui::EASY_GLOBALS.profiler_blocks.empty())
|
||||
if (EASY_GLOBALS.profiler_blocks.empty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
QMenu menu;
|
||||
|
||||
for (const auto& it : ::profiler_gui::EASY_GLOBALS.profiler_blocks)
|
||||
for (const auto& it : EASY_GLOBALS.profiler_blocks)
|
||||
{
|
||||
QString label;
|
||||
if (it.second.thread_name && it.second.thread_name[0] != 0)
|
||||
@ -514,7 +514,7 @@ void EasyGraphicsScrollbar::contextMenuEvent(QContextMenuEvent* _event)
|
||||
|
||||
auto action = new EasyIdAction(label, it.first);
|
||||
action->setCheckable(true);
|
||||
action->setChecked(it.first == ::profiler_gui::EASY_GLOBALS.selected_thread);
|
||||
action->setChecked(it.first == EASY_GLOBALS.selected_thread);
|
||||
connect(action, &EasyIdAction::clicked, this, &This::onThreadActionClicked);
|
||||
|
||||
menu.addAction(action);
|
||||
@ -530,8 +530,8 @@ void EasyGraphicsScrollbar::onThreadActionClicked(::profiler::thread_id_t _id)
|
||||
{
|
||||
if (_id != m_minimap->threadId())
|
||||
{
|
||||
::profiler_gui::EASY_GLOBALS.selected_thread = _id;
|
||||
emit ::profiler_gui::EASY_GLOBALS.events.selectedThreadChanged(_id);
|
||||
EASY_GLOBALS.selected_thread = _id;
|
||||
emit EASY_GLOBALS.events.selectedThreadChanged(_id);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -66,7 +66,7 @@ class EasyMinimapItem : public QGraphicsItem
|
||||
QRectF m_boundingRect;
|
||||
qreal m_maxDuration;
|
||||
qreal m_minDuration;
|
||||
const ::profiler_gui::ProfItems* m_pSource;
|
||||
const ::profiler_gui::EasyItems* m_pSource;
|
||||
::profiler::thread_id_t m_threadId;
|
||||
|
||||
public:
|
||||
@ -88,7 +88,7 @@ public:
|
||||
void setBoundingRect(const QRectF& _rect);
|
||||
void setBoundingRect(qreal x, qreal y, qreal w, qreal h);
|
||||
|
||||
void setSource(::profiler::thread_id_t _thread_id, const ::profiler_gui::ProfItems* _items);
|
||||
void setSource(::profiler::thread_id_t _thread_id, const ::profiler_gui::EasyItems* _items);
|
||||
|
||||
}; // END of class EasyMinimapItem.
|
||||
|
||||
@ -190,9 +190,9 @@ public:
|
||||
void showChrono();
|
||||
void hideChrono();
|
||||
|
||||
void setMinimapFrom(::profiler::thread_id_t _thread_id, const::profiler_gui::ProfItems* _items);
|
||||
void setMinimapFrom(::profiler::thread_id_t _thread_id, const::profiler_gui::EasyItems* _items);
|
||||
|
||||
inline void setMinimapFrom(::profiler::thread_id_t _thread_id, const ::profiler_gui::ProfItems& _items)
|
||||
inline void setMinimapFrom(::profiler::thread_id_t _thread_id, const ::profiler_gui::EasyItems& _items)
|
||||
{
|
||||
setMinimapFrom(_thread_id, &_items);
|
||||
}
|
||||
|
@ -100,22 +100,22 @@ EasyMainWindow::EasyMainWindow() : Parent(), m_treeWidget(nullptr), m_graphicsVi
|
||||
menu->addSeparator();
|
||||
action = menu->addAction("Draw items' borders");
|
||||
action->setCheckable(true);
|
||||
action->setChecked(::profiler_gui::EASY_GLOBALS.draw_graphics_items_borders);
|
||||
action->setChecked(EASY_GLOBALS.draw_graphics_items_borders);
|
||||
connect(action, &QAction::triggered, this, &This::onDrawBordersChanged);
|
||||
|
||||
action = menu->addAction("Collapse items on tree reset");
|
||||
action->setCheckable(true);
|
||||
action->setChecked(::profiler_gui::EASY_GLOBALS.collapse_items_on_tree_close);
|
||||
action->setChecked(EASY_GLOBALS.collapse_items_on_tree_close);
|
||||
connect(action, &QAction::triggered, this, &This::onCollapseItemsAfterCloseChanged);
|
||||
|
||||
action = menu->addAction("Expand all on file open");
|
||||
action->setCheckable(true);
|
||||
action->setChecked(::profiler_gui::EASY_GLOBALS.all_items_expanded_by_default);
|
||||
action->setChecked(EASY_GLOBALS.all_items_expanded_by_default);
|
||||
connect(action, &QAction::triggered, this, &This::onAllItemsExpandedByDefaultChange);
|
||||
|
||||
action = menu->addAction("Bind scene and tree expand");
|
||||
action->setCheckable(true);
|
||||
action->setChecked(::profiler_gui::EASY_GLOBALS.bind_scene_and_tree_expand_status);
|
||||
action->setChecked(EASY_GLOBALS.bind_scene_and_tree_expand_status);
|
||||
connect(action, &QAction::triggered, this, &This::onBindExpandStatusChange);
|
||||
|
||||
menu->addSeparator();
|
||||
@ -126,7 +126,7 @@ EasyMainWindow::EasyMainWindow() : Parent(), m_treeWidget(nullptr), m_graphicsVi
|
||||
action = new QAction("At top", actionGroup);
|
||||
action->setCheckable(true);
|
||||
action->setData(static_cast<int>(::profiler_gui::ChronoTextPosition_Top));
|
||||
if (::profiler_gui::EASY_GLOBALS.chrono_text_position == ::profiler_gui::ChronoTextPosition_Top)
|
||||
if (EASY_GLOBALS.chrono_text_position == ::profiler_gui::ChronoTextPosition_Top)
|
||||
action->setChecked(true);
|
||||
submenu->addAction(action);
|
||||
connect(action, &QAction::triggered, this, &This::onChronoTextPosChanged);
|
||||
@ -134,7 +134,7 @@ EasyMainWindow::EasyMainWindow() : Parent(), m_treeWidget(nullptr), m_graphicsVi
|
||||
action = new QAction("At center", actionGroup);
|
||||
action->setCheckable(true);
|
||||
action->setData(static_cast<int>(::profiler_gui::ChronoTextPosition_Center));
|
||||
if (::profiler_gui::EASY_GLOBALS.chrono_text_position == ::profiler_gui::ChronoTextPosition_Center)
|
||||
if (EASY_GLOBALS.chrono_text_position == ::profiler_gui::ChronoTextPosition_Center)
|
||||
action->setChecked(true);
|
||||
submenu->addAction(action);
|
||||
connect(action, &QAction::triggered, this, &This::onChronoTextPosChanged);
|
||||
@ -142,7 +142,7 @@ EasyMainWindow::EasyMainWindow() : Parent(), m_treeWidget(nullptr), m_graphicsVi
|
||||
action = new QAction("At bottom", actionGroup);
|
||||
action->setCheckable(true);
|
||||
action->setData(static_cast<int>(::profiler_gui::ChronoTextPosition_Bottom));
|
||||
if (::profiler_gui::EASY_GLOBALS.chrono_text_position == ::profiler_gui::ChronoTextPosition_Bottom)
|
||||
if (EASY_GLOBALS.chrono_text_position == ::profiler_gui::ChronoTextPosition_Bottom)
|
||||
action->setChecked(true);
|
||||
submenu->addAction(action);
|
||||
connect(action, &QAction::triggered, this, &This::onChronoTextPosChanged);
|
||||
@ -250,39 +250,39 @@ void EasyMainWindow::onEncodingChanged(bool)
|
||||
void EasyMainWindow::onChronoTextPosChanged(bool)
|
||||
{
|
||||
auto _sender = qobject_cast<QAction*>(sender());
|
||||
::profiler_gui::EASY_GLOBALS.chrono_text_position = static_cast<::profiler_gui::ChronometerTextPosition>(_sender->data().toInt());
|
||||
emit ::profiler_gui::EASY_GLOBALS.events.chronoPositionChanged();
|
||||
EASY_GLOBALS.chrono_text_position = static_cast<::profiler_gui::ChronometerTextPosition>(_sender->data().toInt());
|
||||
emit EASY_GLOBALS.events.chronoPositionChanged();
|
||||
}
|
||||
|
||||
void EasyMainWindow::onDrawBordersChanged(bool _checked)
|
||||
{
|
||||
::profiler_gui::EASY_GLOBALS.draw_graphics_items_borders = _checked;
|
||||
emit ::profiler_gui::EASY_GLOBALS.events.drawBordersChanged();
|
||||
EASY_GLOBALS.draw_graphics_items_borders = _checked;
|
||||
emit EASY_GLOBALS.events.drawBordersChanged();
|
||||
}
|
||||
|
||||
void EasyMainWindow::onCollapseItemsAfterCloseChanged(bool _checked)
|
||||
{
|
||||
::profiler_gui::EASY_GLOBALS.collapse_items_on_tree_close = _checked;
|
||||
EASY_GLOBALS.collapse_items_on_tree_close = _checked;
|
||||
}
|
||||
|
||||
void EasyMainWindow::onAllItemsExpandedByDefaultChange(bool _checked)
|
||||
{
|
||||
::profiler_gui::EASY_GLOBALS.all_items_expanded_by_default = _checked;
|
||||
EASY_GLOBALS.all_items_expanded_by_default = _checked;
|
||||
}
|
||||
|
||||
void EasyMainWindow::onBindExpandStatusChange(bool _checked)
|
||||
{
|
||||
::profiler_gui::EASY_GLOBALS.bind_scene_and_tree_expand_status = _checked;
|
||||
EASY_GLOBALS.bind_scene_and_tree_expand_status = _checked;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void EasyMainWindow::onExpandAllClicked(bool)
|
||||
{
|
||||
for (auto& block : ::profiler_gui::EASY_GLOBALS.gui_blocks)
|
||||
for (auto& block : EASY_GLOBALS.gui_blocks)
|
||||
block.expanded = true;
|
||||
|
||||
emit ::profiler_gui::EASY_GLOBALS.events.itemsExpandStateChanged();
|
||||
emit EASY_GLOBALS.events.itemsExpandStateChanged();
|
||||
|
||||
auto tree = static_cast<EasyTreeWidget*>(m_treeWidget->widget());
|
||||
const QSignalBlocker b(tree);
|
||||
@ -291,10 +291,10 @@ void EasyMainWindow::onExpandAllClicked(bool)
|
||||
|
||||
void EasyMainWindow::onCollapseAllClicked(bool)
|
||||
{
|
||||
for (auto& block : ::profiler_gui::EASY_GLOBALS.gui_blocks)
|
||||
for (auto& block : EASY_GLOBALS.gui_blocks)
|
||||
block.expanded = false;
|
||||
|
||||
emit ::profiler_gui::EASY_GLOBALS.events.itemsExpandStateChanged();
|
||||
emit EASY_GLOBALS.events.itemsExpandStateChanged();
|
||||
|
||||
auto tree = static_cast<EasyTreeWidget*>(m_treeWidget->widget());
|
||||
const QSignalBlocker b(tree);
|
||||
@ -326,32 +326,32 @@ void EasyMainWindow::loadSettings()
|
||||
auto val = settings.value("chrono_text_position");
|
||||
if (!val.isNull())
|
||||
{
|
||||
::profiler_gui::EASY_GLOBALS.chrono_text_position = static_cast<::profiler_gui::ChronometerTextPosition>(val.toInt());
|
||||
EASY_GLOBALS.chrono_text_position = static_cast<::profiler_gui::ChronometerTextPosition>(val.toInt());
|
||||
}
|
||||
|
||||
|
||||
auto flag = settings.value("draw_graphics_items_borders");
|
||||
if (!flag.isNull())
|
||||
{
|
||||
::profiler_gui::EASY_GLOBALS.draw_graphics_items_borders = flag.toBool();
|
||||
EASY_GLOBALS.draw_graphics_items_borders = flag.toBool();
|
||||
}
|
||||
|
||||
flag = settings.value("collapse_items_on_tree_close");
|
||||
if (!flag.isNull())
|
||||
{
|
||||
::profiler_gui::EASY_GLOBALS.collapse_items_on_tree_close = flag.toBool();
|
||||
EASY_GLOBALS.collapse_items_on_tree_close = flag.toBool();
|
||||
}
|
||||
|
||||
flag = settings.value("all_items_expanded_by_default");
|
||||
if (!flag.isNull())
|
||||
{
|
||||
::profiler_gui::EASY_GLOBALS.all_items_expanded_by_default = flag.toBool();
|
||||
EASY_GLOBALS.all_items_expanded_by_default = flag.toBool();
|
||||
}
|
||||
|
||||
flag = settings.value("bind_scene_and_tree_expand_status");
|
||||
if (!flag.isNull())
|
||||
{
|
||||
::profiler_gui::EASY_GLOBALS.bind_scene_and_tree_expand_status = flag.toBool();
|
||||
EASY_GLOBALS.bind_scene_and_tree_expand_status = flag.toBool();
|
||||
}
|
||||
|
||||
QString encoding = settings.value("encoding", "UTF-8").toString();
|
||||
@ -379,11 +379,11 @@ void EasyMainWindow::saveSettingsAndGeometry()
|
||||
|
||||
settings.setValue("geometry", this->saveGeometry());
|
||||
settings.setValue("last_file", m_lastFile);
|
||||
settings.setValue("chrono_text_position", static_cast<int>(::profiler_gui::EASY_GLOBALS.chrono_text_position));
|
||||
settings.setValue("draw_graphics_items_borders", ::profiler_gui::EASY_GLOBALS.draw_graphics_items_borders);
|
||||
settings.setValue("collapse_items_on_tree_close", ::profiler_gui::EASY_GLOBALS.collapse_items_on_tree_close);
|
||||
settings.setValue("all_items_expanded_by_default", ::profiler_gui::EASY_GLOBALS.all_items_expanded_by_default);
|
||||
settings.setValue("bind_scene_and_tree_expand_status", ::profiler_gui::EASY_GLOBALS.bind_scene_and_tree_expand_status);
|
||||
settings.setValue("chrono_text_position", static_cast<int>(EASY_GLOBALS.chrono_text_position));
|
||||
settings.setValue("draw_graphics_items_borders", EASY_GLOBALS.draw_graphics_items_borders);
|
||||
settings.setValue("collapse_items_on_tree_close", EASY_GLOBALS.collapse_items_on_tree_close);
|
||||
settings.setValue("all_items_expanded_by_default", EASY_GLOBALS.all_items_expanded_by_default);
|
||||
settings.setValue("bind_scene_and_tree_expand_status", EASY_GLOBALS.bind_scene_and_tree_expand_status);
|
||||
settings.setValue("encoding", QTextCodec::codecForLocale()->name());
|
||||
|
||||
settings.endGroup();
|
||||
@ -402,28 +402,34 @@ void EasyMainWindow::onFileReaderTimeout()
|
||||
|
||||
::profiler::SerializedData serialized_blocks, serialized_descriptors;
|
||||
::profiler::descriptors_list_t descriptors;
|
||||
::profiler::thread_blocks_tree_t prof_blocks;
|
||||
::profiler::blocks_t blocks;
|
||||
::profiler::thread_blocks_tree_t threads_map;
|
||||
QString filename;
|
||||
m_reader.get(serialized_blocks, serialized_descriptors, descriptors, prof_blocks, filename);
|
||||
m_reader.get(serialized_blocks, serialized_descriptors, descriptors, blocks, threads_map, filename);
|
||||
|
||||
if (prof_blocks.size() > 0xff)
|
||||
if (threads_map.size() > 0xff)
|
||||
{
|
||||
qWarning() << "Warning: file " << filename << " contains " << prof_blocks.size() << " threads!";
|
||||
qWarning() << "Warning: file " << filename << " contains " << threads_map.size() << " threads!";
|
||||
qWarning() << "Warning: Currently, maximum number of displayed threads is 255! Some threads will not be displayed.";
|
||||
}
|
||||
|
||||
m_lastFile = ::std::move(filename);
|
||||
m_serializedBlocks = ::std::move(serialized_blocks);
|
||||
m_serializedDescriptors = ::std::move(serialized_descriptors);
|
||||
::profiler_gui::EASY_GLOBALS.selected_thread = 0;
|
||||
::profiler_gui::set_max(::profiler_gui::EASY_GLOBALS.selected_block);
|
||||
::profiler_gui::EASY_GLOBALS.profiler_blocks.swap(prof_blocks);
|
||||
::profiler_gui::EASY_GLOBALS.descriptors.swap(descriptors);
|
||||
::profiler_gui::EASY_GLOBALS.gui_blocks.resize(nblocks);
|
||||
memset(::profiler_gui::EASY_GLOBALS.gui_blocks.data(), 0, sizeof(::profiler_gui::EasyBlock) * nblocks);
|
||||
for (auto& guiblock : ::profiler_gui::EASY_GLOBALS.gui_blocks) ::profiler_gui::set_max(guiblock.tree_item);
|
||||
EASY_GLOBALS.selected_thread = 0;
|
||||
::profiler_gui::set_max(EASY_GLOBALS.selected_block);
|
||||
EASY_GLOBALS.profiler_blocks.swap(threads_map);
|
||||
EASY_GLOBALS.descriptors.swap(descriptors);
|
||||
|
||||
static_cast<EasyGraphicsViewWidget*>(m_graphicsView->widget())->view()->setTree(::profiler_gui::EASY_GLOBALS.profiler_blocks);
|
||||
EASY_GLOBALS.gui_blocks.resize(nblocks);
|
||||
memset(EASY_GLOBALS.gui_blocks.data(), 0, sizeof(::profiler_gui::EasyBlock) * nblocks);
|
||||
for (decltype(nblocks) i = 0; i < nblocks; ++i) {
|
||||
auto& guiblock = EASY_GLOBALS.gui_blocks[i];
|
||||
guiblock.tree = ::std::move(blocks[i]);
|
||||
::profiler_gui::set_max(guiblock.tree_item);
|
||||
}
|
||||
|
||||
static_cast<EasyGraphicsViewWidget*>(m_graphicsView->widget())->view()->setTree(EASY_GLOBALS.profiler_blocks);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -436,7 +442,7 @@ void EasyMainWindow::onFileReaderTimeout()
|
||||
m_progress->setValue(100);
|
||||
//m_progress->hide();
|
||||
|
||||
if (::profiler_gui::EASY_GLOBALS.all_items_expanded_by_default)
|
||||
if (EASY_GLOBALS.all_items_expanded_by_default)
|
||||
{
|
||||
onExpandAllClicked(true);
|
||||
}
|
||||
@ -493,7 +499,7 @@ void EasyFileReader::load(const QString& _filename)
|
||||
|
||||
m_filename = _filename;
|
||||
m_thread = ::std::move(::std::thread([this]() {
|
||||
m_size.store(fillTreesFromFile(m_progress, m_filename.toStdString().c_str(), m_serializedBlocks, m_serializedDescriptors, m_descriptors, m_blocksTree, true));
|
||||
m_size.store(fillTreesFromFile(m_progress, m_filename.toStdString().c_str(), m_serializedBlocks, m_serializedDescriptors, m_descriptors, m_blocks, m_blocksTree, true));
|
||||
m_progress.store(100);
|
||||
m_bDone.store(true);
|
||||
}));
|
||||
@ -511,17 +517,20 @@ void EasyFileReader::interrupt()
|
||||
m_serializedBlocks.clear();
|
||||
m_serializedDescriptors.clear();
|
||||
m_descriptors.clear();
|
||||
m_blocks.clear();
|
||||
m_blocksTree.clear();
|
||||
}
|
||||
|
||||
void EasyFileReader::get(::profiler::SerializedData& _serializedBlocks, ::profiler::SerializedData& _serializedDescriptors,
|
||||
::profiler::descriptors_list_t& _descriptors, ::profiler::thread_blocks_tree_t& _tree, QString& _filename)
|
||||
::profiler::descriptors_list_t& _descriptors, ::profiler::blocks_t& _blocks, ::profiler::thread_blocks_tree_t& _tree,
|
||||
QString& _filename)
|
||||
{
|
||||
if (done())
|
||||
{
|
||||
m_serializedBlocks.swap(_serializedBlocks);
|
||||
m_serializedDescriptors.swap(_serializedDescriptors);
|
||||
::profiler::descriptors_list_t(m_descriptors).swap(_descriptors);
|
||||
::profiler::descriptors_list_t(::std::move(m_descriptors)).swap(_descriptors);
|
||||
m_blocks.swap(_blocks);
|
||||
m_blocksTree.swap(_tree);
|
||||
m_filename.swap(_filename);
|
||||
}
|
||||
|
@ -35,6 +35,7 @@ class EasyFileReader final
|
||||
::profiler::SerializedData m_serializedBlocks; ///<
|
||||
::profiler::SerializedData m_serializedDescriptors; ///<
|
||||
::profiler::descriptors_list_t m_descriptors; ///<
|
||||
::profiler::blocks_t m_blocks; ///<
|
||||
::profiler::thread_blocks_tree_t m_blocksTree; ///<
|
||||
QString m_filename; ///<
|
||||
::std::thread m_thread; ///<
|
||||
@ -55,7 +56,8 @@ public:
|
||||
void load(const QString& _filename);
|
||||
void interrupt();
|
||||
void get(::profiler::SerializedData& _serializedBlocks, ::profiler::SerializedData& _serializedDescriptors,
|
||||
::profiler::descriptors_list_t& _descriptors, ::profiler::thread_blocks_tree_t& _tree, QString& _filename);
|
||||
::profiler::descriptors_list_t& _descriptors, ::profiler::blocks_t& _blocks, ::profiler::thread_blocks_tree_t& _tree,
|
||||
QString& _filename);
|
||||
|
||||
}; // END of class EasyFileReader.
|
||||
|
||||
|
@ -21,7 +21,7 @@
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
EasyTreeWidgetItem::EasyTreeWidgetItem(const ::profiler::BlocksTree* _treeBlock, Parent* _parent)
|
||||
EasyTreeWidgetItem::EasyTreeWidgetItem(const ::profiler::block_index_t _treeBlock, Parent* _parent)
|
||||
: Parent(_parent)
|
||||
, m_block(_treeBlock)
|
||||
, m_customBGColor(0)
|
||||
@ -75,15 +75,25 @@ bool EasyTreeWidgetItem::operator < (const Parent& _other) const
|
||||
return false;
|
||||
}
|
||||
|
||||
const ::profiler::BlocksTree* EasyTreeWidgetItem::block() const
|
||||
::profiler::block_index_t EasyTreeWidgetItem::block_index() const
|
||||
{
|
||||
return m_block;
|
||||
}
|
||||
|
||||
::profiler_gui::EasyBlock& EasyTreeWidgetItem::guiBlock()
|
||||
{
|
||||
return easyBlock(m_block);
|
||||
}
|
||||
|
||||
const ::profiler::BlocksTree& EasyTreeWidgetItem::block() const
|
||||
{
|
||||
return blocksTree(m_block);
|
||||
}
|
||||
|
||||
::profiler::timestamp_t EasyTreeWidgetItem::duration() const
|
||||
{
|
||||
if (m_block->node)
|
||||
return m_block->node->duration();
|
||||
if (parent() != nullptr)
|
||||
return block().node->duration();
|
||||
return data(COL_DURATION, Qt::UserRole).toULongLong();
|
||||
}
|
||||
|
||||
@ -173,7 +183,8 @@ void EasyTreeWidgetItem::collapseAll()
|
||||
}
|
||||
|
||||
setExpanded(false);
|
||||
::profiler_gui::EASY_GLOBALS.gui_blocks[m_block->block_index].expanded = false;
|
||||
if (parent() != nullptr)
|
||||
guiBlock().expanded = false;
|
||||
}
|
||||
|
||||
void EasyTreeWidgetItem::expandAll()
|
||||
@ -184,7 +195,8 @@ void EasyTreeWidgetItem::expandAll()
|
||||
}
|
||||
|
||||
setExpanded(true);
|
||||
::profiler_gui::EASY_GLOBALS.gui_blocks[m_block->block_index].expanded = true;
|
||||
if (parent() != nullptr)
|
||||
guiBlock().expanded = true;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
@ -75,7 +75,7 @@ class EasyTreeWidgetItem : public QTreeWidgetItem
|
||||
typedef QTreeWidgetItem Parent;
|
||||
typedef EasyTreeWidgetItem This;
|
||||
|
||||
const ::profiler::BlocksTree* m_block;
|
||||
const ::profiler::block_index_t m_block;
|
||||
QRgb m_customBGColor;
|
||||
QRgb m_customTextColor;
|
||||
|
||||
@ -84,14 +84,16 @@ public:
|
||||
using Parent::setBackgroundColor;
|
||||
using Parent::setTextColor;
|
||||
|
||||
EasyTreeWidgetItem(const ::profiler::BlocksTree* _treeBlock, Parent* _parent = nullptr);
|
||||
EasyTreeWidgetItem(const ::profiler::block_index_t _treeBlock = ::profiler_gui::numeric_max<decltype(m_block)>(), Parent* _parent = nullptr);
|
||||
virtual ~EasyTreeWidgetItem();
|
||||
|
||||
bool operator < (const Parent& _other) const override;
|
||||
|
||||
public:
|
||||
|
||||
const ::profiler::BlocksTree* block() const;
|
||||
::profiler::block_index_t block_index() const;
|
||||
::profiler_gui::EasyBlock& guiBlock();
|
||||
const ::profiler::BlocksTree& block() const;
|
||||
|
||||
::profiler::timestamp_t duration() const;
|
||||
::profiler::timestamp_t selfDuration() const;
|
||||
|
@ -126,7 +126,7 @@ void FillTreeClass<T>::setTreeInternal1(T& _safelocker, Items& _items, ThreadedI
|
||||
::profiler::timestamp_t finishtime = 0;
|
||||
for (const auto& threadTree : _blocksTree)
|
||||
{
|
||||
const auto node_block = threadTree.second.tree.children.front().node;
|
||||
const auto node_block = blocksTree(threadTree.second.children.front()).node;
|
||||
const auto startTime = node_block->begin();
|
||||
const auto endTime = node_block->end();
|
||||
|
||||
@ -145,49 +145,49 @@ void FillTreeClass<T>::setTreeInternal1(T& _safelocker, Items& _items, ThreadedI
|
||||
if (_safelocker.interrupted())
|
||||
break;
|
||||
|
||||
auto& block = threadTree.second.tree;
|
||||
auto item = new EasyTreeWidgetItem(&block);
|
||||
const auto& root = threadTree.second;
|
||||
auto item = new EasyTreeWidgetItem();
|
||||
|
||||
if (threadTree.second.thread_name && threadTree.second.thread_name[0] != 0)
|
||||
if (root.thread_name && root.thread_name[0] != 0)
|
||||
{
|
||||
item->setText(COL_NAME, QString("%1 Thread %2").arg(threadTree.second.thread_name).arg(threadTree.first));
|
||||
item->setText(COL_NAME, QString("%1 Thread %2").arg(root.thread_name).arg(root.thread_id));
|
||||
}
|
||||
else
|
||||
{
|
||||
item->setText(COL_NAME, QString("Thread %1").arg(threadTree.first));
|
||||
item->setText(COL_NAME, QString("Thread %1").arg(root.thread_id));
|
||||
}
|
||||
|
||||
::profiler::timestamp_t duration = 0;
|
||||
if (!block.children.empty())
|
||||
if (!root.children.empty())
|
||||
{
|
||||
duration = block.children.back().node->end() - block.children.front().node->begin();
|
||||
duration = blocksTree(root.children.back()).node->end() - blocksTree(root.children.front()).node->begin();
|
||||
}
|
||||
|
||||
item->setTimeSmart(COL_DURATION, duration);
|
||||
item->setBackgroundColor(::profiler_gui::SELECTED_THREAD_BACKGROUND);
|
||||
item->setTextColor(::profiler_gui::SELECTED_THREAD_FOREGROUND);
|
||||
|
||||
_items.push_back(item);
|
||||
//_items.push_back(item);
|
||||
|
||||
// TODO: Optimize children duration calculation (it must be calculated before setTreeInternal now)
|
||||
::profiler::timestamp_t children_duration = 0;
|
||||
for (const auto& child : block.children)
|
||||
children_duration += child.node->duration();
|
||||
for (auto i : root.children)
|
||||
children_duration += blocksTree(i).node->duration();
|
||||
item->setTimeSmart(COL_SELF_DURATION, children_duration);
|
||||
|
||||
children_duration = 0;
|
||||
const auto children_items_number = FillTreeClass<T>::setTreeInternal(_safelocker, _items, _beginTime, block.children, item, nullptr, item, _beginTime, finishtime + 1000000000ULL, false, children_duration, _colorizeRows);
|
||||
const auto children_items_number = FillTreeClass<T>::setTreeInternal(_safelocker, _items, _beginTime, root.children, item, nullptr, item, _beginTime, finishtime + 1000000000ULL, false, children_duration, _colorizeRows);
|
||||
|
||||
if (children_items_number > 0)
|
||||
{
|
||||
//total_items += children_items_number + 1;
|
||||
//addTopLevelItem(item);
|
||||
//m_roots[threadTree.first] = item;
|
||||
_topLevelItems.emplace_back(threadTree.first, item);
|
||||
_topLevelItems.emplace_back(root.thread_id, item);
|
||||
}
|
||||
else
|
||||
{
|
||||
_items.pop_back();
|
||||
//_items.pop_back();
|
||||
delete item;
|
||||
}
|
||||
|
||||
@ -200,11 +200,11 @@ void FillTreeClass<T>::setTreeInternal1(T& _safelocker, Items& _items, ThreadedI
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
auto calculateTotalChildrenNumber(const ::profiler::BlocksTree* _tree) -> decltype(_tree->children.size())
|
||||
auto calculateTotalChildrenNumber(const ::profiler::BlocksTree& _tree) -> decltype(_tree.children.size())
|
||||
{
|
||||
auto children_number = _tree->children.size();
|
||||
for (const auto& child : _tree->children)
|
||||
children_number += calculateTotalChildrenNumber(&child);
|
||||
auto children_number = _tree.children.size();
|
||||
for (auto i : _tree.children)
|
||||
children_number += calculateTotalChildrenNumber(blocksTree(i));
|
||||
return children_number;
|
||||
}
|
||||
|
||||
@ -213,7 +213,7 @@ void FillTreeClass<T>::setTreeInternal2(T& _safelocker, Items& _items, ThreadedI
|
||||
{
|
||||
//size_t blocksNumber = 0;
|
||||
//for (const auto& block : _blocks)
|
||||
// blocksNumber += calculateTotalChildrenNumber(block.tree);
|
||||
// blocksNumber += calculateTotalChildrenNumber(*block.tree);
|
||||
// //blocksNumber += block.tree->total_children_number;
|
||||
//m_items.reserve(blocksNumber + _blocks.size()); // blocksNumber does not include root blocks
|
||||
|
||||
@ -226,8 +226,9 @@ void FillTreeClass<T>::setTreeInternal2(T& _safelocker, Items& _items, ThreadedI
|
||||
if (_safelocker.interrupted())
|
||||
break;
|
||||
|
||||
const auto startTime = block.tree->node->begin();
|
||||
const auto endTime = block.tree->node->end();
|
||||
auto& gui_block = easyBlock(block.tree);
|
||||
const auto startTime = gui_block.tree.node->begin();
|
||||
const auto endTime = gui_block.tree.node->end();
|
||||
if (startTime > _right || endTime < _left)
|
||||
{
|
||||
_safelocker.setProgress((90 * ++i) / total);
|
||||
@ -243,7 +244,7 @@ void FillTreeClass<T>::setTreeInternal2(T& _safelocker, Items& _items, ThreadedI
|
||||
}
|
||||
else
|
||||
{
|
||||
thread_item = new EasyTreeWidgetItem(&block.root->tree);
|
||||
thread_item = new EasyTreeWidgetItem();
|
||||
|
||||
if (block.root->thread_name && block.root->thread_name[0] != 0)
|
||||
{
|
||||
@ -254,9 +255,9 @@ void FillTreeClass<T>::setTreeInternal2(T& _safelocker, Items& _items, ThreadedI
|
||||
thread_item->setText(COL_NAME, QString("Thread %1").arg(block.root->thread_id));
|
||||
}
|
||||
|
||||
if (!block.root->tree.children.empty())
|
||||
if (!block.root->children.empty())
|
||||
{
|
||||
duration = block.root->tree.children.back().node->end() - block.root->tree.children.front().node->begin();
|
||||
duration = blocksTree(block.root->children.back()).node->end() - blocksTree(block.root->children.front()).node->begin();
|
||||
}
|
||||
|
||||
thread_item->setTimeSmart(COL_DURATION, duration);
|
||||
@ -265,8 +266,8 @@ void FillTreeClass<T>::setTreeInternal2(T& _safelocker, Items& _items, ThreadedI
|
||||
|
||||
// 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->duration();
|
||||
for (auto i : block.root->children)
|
||||
children_duration += blocksTree(i).node->duration();
|
||||
thread_item->setTimeSmart(COL_SELF_DURATION, children_duration);
|
||||
|
||||
threadsMap.insert(::std::make_pair(block.root->thread_id, thread_item));
|
||||
@ -275,7 +276,7 @@ void FillTreeClass<T>::setTreeInternal2(T& _safelocker, Items& _items, ThreadedI
|
||||
auto item = new EasyTreeWidgetItem(block.tree, thread_item);
|
||||
duration = endTime - startTime;
|
||||
|
||||
auto name = *block.tree->node->name() != 0 ? block.tree->node->name() : ::profiler_gui::EASY_GLOBALS.descriptors[block.tree->node->id()]->name();
|
||||
auto name = *gui_block.tree.node->name() != 0 ? gui_block.tree.node->name() : easyDescriptor(gui_block.tree.node->id()).name();
|
||||
item->setText(COL_NAME, ::profiler_gui::toUnicode(name));
|
||||
item->setTimeSmart(COL_DURATION, duration);
|
||||
item->setTimeMs(COL_BEGIN, startTime - _beginTime);
|
||||
@ -287,14 +288,14 @@ void FillTreeClass<T>::setTreeInternal2(T& _safelocker, Items& _items, ThreadedI
|
||||
item->setData(COL_PERCENT_PER_FRAME, Qt::UserRole, 0);
|
||||
item->setText(COL_PERCENT_PER_FRAME, "");
|
||||
|
||||
if (block.tree->per_thread_stats != nullptr) // if there is per_thread_stats then there are other stats also
|
||||
if (gui_block.tree.per_thread_stats != nullptr) // if there is per_thread_stats then there are other stats also
|
||||
{
|
||||
const auto& per_thread_stats = block.tree->per_thread_stats;
|
||||
const auto& per_parent_stats = block.tree->per_parent_stats;
|
||||
const auto& per_frame_stats = block.tree->per_frame_stats;
|
||||
const auto& per_thread_stats = gui_block.tree.per_thread_stats;
|
||||
const auto& per_parent_stats = gui_block.tree.per_parent_stats;
|
||||
const auto& per_frame_stats = gui_block.tree.per_frame_stats;
|
||||
|
||||
|
||||
if (per_thread_stats->calls_number > 1 || !::profiler_gui::EASY_GLOBALS.display_only_relevant_stats)
|
||||
if (per_thread_stats->calls_number > 1 || !EASY_GLOBALS.display_only_relevant_stats)
|
||||
{
|
||||
item->setTimeSmart(COL_MIN_PER_THREAD, per_thread_stats->min_duration, "min ");
|
||||
item->setTimeSmart(COL_MAX_PER_THREAD, per_thread_stats->max_duration, "max ");
|
||||
@ -310,7 +311,7 @@ void FillTreeClass<T>::setTreeInternal2(T& _safelocker, Items& _items, ThreadedI
|
||||
item->setText(COL_PERCENT_SUM_PER_THREAD, QString::number(percentage_per_thread));
|
||||
|
||||
|
||||
if (per_parent_stats->calls_number > 1 || !::profiler_gui::EASY_GLOBALS.display_only_relevant_stats)
|
||||
if (per_parent_stats->calls_number > 1 || !EASY_GLOBALS.display_only_relevant_stats)
|
||||
{
|
||||
item->setTimeSmart(COL_MIN_PER_PARENT, per_parent_stats->min_duration, "min ");
|
||||
item->setTimeSmart(COL_MAX_PER_PARENT, per_parent_stats->max_duration, "max ");
|
||||
@ -322,7 +323,7 @@ void FillTreeClass<T>::setTreeInternal2(T& _safelocker, Items& _items, ThreadedI
|
||||
item->setText(COL_NCALLS_PER_PARENT, QString::number(per_parent_stats->calls_number));
|
||||
|
||||
|
||||
if (per_frame_stats->calls_number > 1 || !::profiler_gui::EASY_GLOBALS.display_only_relevant_stats)
|
||||
if (per_frame_stats->calls_number > 1 || !EASY_GLOBALS.display_only_relevant_stats)
|
||||
{
|
||||
item->setTimeSmart(COL_MIN_PER_FRAME, per_frame_stats->min_duration, "min ");
|
||||
item->setTimeSmart(COL_MAX_PER_FRAME, per_frame_stats->max_duration, "max ");
|
||||
@ -339,7 +340,7 @@ void FillTreeClass<T>::setTreeInternal2(T& _safelocker, Items& _items, ThreadedI
|
||||
item->setText(COL_PERCENT_SUM_PER_THREAD, "");
|
||||
}
|
||||
|
||||
const auto color = ::profiler_gui::EASY_GLOBALS.descriptors[block.tree->node->id()]->color();
|
||||
const auto color = easyDescriptor(gui_block.tree.node->id()).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);
|
||||
@ -350,9 +351,9 @@ void FillTreeClass<T>::setTreeInternal2(T& _safelocker, Items& _items, ThreadedI
|
||||
|
||||
size_t children_items_number = 0;
|
||||
::profiler::timestamp_t children_duration = 0;
|
||||
if (!block.tree->children.empty())
|
||||
if (!gui_block.tree.children.empty())
|
||||
{
|
||||
children_items_number = FillTreeClass<T>::setTreeInternal(_safelocker, _items, _beginTime, block.tree->children, item, item, thread_item, _left, _right, _strict, children_duration, _colorizeRows);
|
||||
children_items_number = FillTreeClass<T>::setTreeInternal(_safelocker, _items, _beginTime, gui_block.tree.children, item, item, thread_item, _left, _right, _strict, children_duration, _colorizeRows);
|
||||
if (_safelocker.interrupted())
|
||||
break;
|
||||
}
|
||||
@ -371,12 +372,12 @@ void FillTreeClass<T>::setTreeInternal2(T& _safelocker, Items& _items, ThreadedI
|
||||
if (children_items_number > 0 || !_strict || (startTime >= _left && endTime <= _right))
|
||||
{
|
||||
//total_items += children_items_number + 1;
|
||||
::profiler_gui::EASY_GLOBALS.gui_blocks[block.tree->block_index].tree_item = item_index;
|
||||
gui_block.tree_item = item_index;
|
||||
|
||||
if (_colorizeRows)
|
||||
item->colorize(_colorizeRows);
|
||||
|
||||
if (::profiler_gui::EASY_GLOBALS.gui_blocks[block.tree->block_index].expanded)
|
||||
if (gui_block.expanded)
|
||||
item->setExpanded(true);
|
||||
|
||||
}
|
||||
@ -400,7 +401,7 @@ void FillTreeClass<T>::setTreeInternal2(T& _safelocker, Items& _items, ThreadedI
|
||||
//addTopLevelItem(item);
|
||||
//m_roots[it.first] = item;
|
||||
|
||||
_items.push_back(item);
|
||||
//_items.push_back(item);
|
||||
_topLevelItems.emplace_back(it.first, item);
|
||||
|
||||
//++total_items;
|
||||
@ -421,11 +422,13 @@ template <class T>
|
||||
size_t FillTreeClass<T>::setTreeInternal(T& _safelocker, Items& _items, const ::profiler::timestamp_t& _beginTime, const ::profiler::BlocksTree::children_t& _children, EasyTreeWidgetItem* _parent, EasyTreeWidgetItem* _frame, EasyTreeWidgetItem* _thread, ::profiler::timestamp_t _left, ::profiler::timestamp_t _right, bool _strict, ::profiler::timestamp_t& _duration, bool _colorizeRows)
|
||||
{
|
||||
size_t total_items = 0;
|
||||
for (const auto& child : _children)
|
||||
for (auto child_index : _children)
|
||||
{
|
||||
if (_safelocker.interrupted())
|
||||
break;
|
||||
|
||||
auto& gui_block = easyBlock(child_index);
|
||||
const auto& child = gui_block.tree;
|
||||
const auto startTime = child.node->begin();
|
||||
const auto endTime = child.node->end();
|
||||
const auto duration = endTime - startTime;
|
||||
@ -436,9 +439,9 @@ size_t FillTreeClass<T>::setTreeInternal(T& _safelocker, Items& _items, const ::
|
||||
continue;
|
||||
}
|
||||
|
||||
auto item = new EasyTreeWidgetItem(&child, _parent);
|
||||
auto item = new EasyTreeWidgetItem(child_index, _parent);
|
||||
|
||||
auto name = *child.node->name() != 0 ? child.node->name() : ::profiler_gui::EASY_GLOBALS.descriptors[child.node->id()]->name();
|
||||
auto name = *child.node->name() != 0 ? child.node->name() : easyDescriptor(child.node->id()).name();
|
||||
item->setText(COL_NAME, ::profiler_gui::toUnicode(name));
|
||||
item->setTimeSmart(COL_DURATION, duration);
|
||||
item->setTimeMs(COL_BEGIN, startTime - _beginTime);
|
||||
@ -480,7 +483,7 @@ size_t FillTreeClass<T>::setTreeInternal(T& _safelocker, Items& _items, const ::
|
||||
}
|
||||
|
||||
|
||||
if (per_thread_stats->calls_number > 1 || !::profiler_gui::EASY_GLOBALS.display_only_relevant_stats)
|
||||
if (per_thread_stats->calls_number > 1 || !EASY_GLOBALS.display_only_relevant_stats)
|
||||
{
|
||||
item->setTimeSmart(COL_MIN_PER_THREAD, per_thread_stats->min_duration, "min ");
|
||||
item->setTimeSmart(COL_MAX_PER_THREAD, per_thread_stats->max_duration, "max ");
|
||||
@ -499,7 +502,7 @@ size_t FillTreeClass<T>::setTreeInternal(T& _safelocker, Items& _items, const ::
|
||||
}
|
||||
|
||||
|
||||
if (per_parent_stats->calls_number > 1 || !::profiler_gui::EASY_GLOBALS.display_only_relevant_stats)
|
||||
if (per_parent_stats->calls_number > 1 || !EASY_GLOBALS.display_only_relevant_stats)
|
||||
{
|
||||
item->setTimeSmart(COL_MIN_PER_PARENT, per_parent_stats->min_duration, "min ");
|
||||
item->setTimeSmart(COL_MAX_PER_PARENT, per_parent_stats->max_duration, "max ");
|
||||
@ -511,7 +514,7 @@ size_t FillTreeClass<T>::setTreeInternal(T& _safelocker, Items& _items, const ::
|
||||
item->setText(COL_NCALLS_PER_PARENT, QString::number(per_parent_stats->calls_number));
|
||||
|
||||
|
||||
if (per_frame_stats->calls_number > 1 || !::profiler_gui::EASY_GLOBALS.display_only_relevant_stats)
|
||||
if (per_frame_stats->calls_number > 1 || !EASY_GLOBALS.display_only_relevant_stats)
|
||||
{
|
||||
item->setTimeSmart(COL_MIN_PER_FRAME, per_frame_stats->min_duration, "min ");
|
||||
item->setTimeSmart(COL_MAX_PER_FRAME, per_frame_stats->max_duration, "max ");
|
||||
@ -532,13 +535,13 @@ size_t FillTreeClass<T>::setTreeInternal(T& _safelocker, Items& _items, const ::
|
||||
item->setText(COL_PERCENT_SUM_PER_THREAD, "");
|
||||
}
|
||||
|
||||
const auto color = ::profiler_gui::EASY_GLOBALS.descriptors[child.node->id()]->color();
|
||||
const auto color = easyDescriptor(child.node->id()).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);
|
||||
|
||||
auto item_index = static_cast<unsigned int>(_items.size());
|
||||
auto item_index = static_cast<uint32_t>(_items.size());
|
||||
_items.push_back(item);
|
||||
|
||||
size_t children_items_number = 0;
|
||||
@ -564,12 +567,12 @@ size_t FillTreeClass<T>::setTreeInternal(T& _safelocker, Items& _items, const ::
|
||||
if (children_items_number > 0 || !_strict || (startTime >= _left && endTime <= _right))
|
||||
{
|
||||
total_items += children_items_number + 1;
|
||||
::profiler_gui::EASY_GLOBALS.gui_blocks[child.block_index].tree_item = item_index;
|
||||
gui_block.tree_item = item_index;
|
||||
|
||||
if (_colorizeRows)
|
||||
item->colorize(_colorizeRows);
|
||||
|
||||
if (::profiler_gui::EASY_GLOBALS.gui_blocks[child.block_index].expanded)
|
||||
if (gui_block.expanded)
|
||||
item->setExpanded(true);
|
||||
}
|
||||
else
|
||||
|
@ -112,7 +112,8 @@ int main(int argc, char* argv[])
|
||||
|
||||
::profiler::SerializedData serialized_blocks, serialized_descriptors;
|
||||
::profiler::descriptors_list_t descriptors;
|
||||
auto blocks_counter = fillTreesFromFile(filename.c_str(), serialized_blocks, serialized_descriptors, descriptors, threaded_trees, true);
|
||||
::profiler::blocks_t blocks;
|
||||
auto blocks_counter = fillTreesFromFile(filename.c_str(), serialized_blocks, serialized_descriptors, descriptors, blocks, threaded_trees, true);
|
||||
|
||||
auto end = std::chrono::system_clock::now();
|
||||
|
||||
|
475
src/reader.cpp
475
src/reader.cpp
@ -198,7 +198,7 @@ typedef ::std::unordered_map<::std::string, ::profiler::block_id_t> IdMap;
|
||||
automatically receive statistics update.
|
||||
|
||||
*/
|
||||
::profiler::BlockStatistics* update_statistics(StatsMap& _stats_map, const ::profiler::BlocksTree& _current)
|
||||
::profiler::BlockStatistics* update_statistics(StatsMap& _stats_map, const ::profiler::BlocksTree& _current, ::profiler::block_index_t _current_index)
|
||||
{
|
||||
auto duration = _current.node->duration();
|
||||
//StatsMap::key_type key(_current.node->name());
|
||||
@ -216,14 +216,14 @@ automatically receive statistics update.
|
||||
if (duration > stats->max_duration)
|
||||
{
|
||||
// update max duration
|
||||
stats->max_duration_block = _current.block_index;
|
||||
stats->max_duration_block = _current_index;
|
||||
stats->max_duration = duration;
|
||||
}
|
||||
|
||||
if (duration < stats->min_duration)
|
||||
{
|
||||
// update min duraton
|
||||
stats->min_duration_block = _current.block_index;
|
||||
stats->min_duration_block = _current_index;
|
||||
stats->min_duration = duration;
|
||||
}
|
||||
|
||||
@ -234,7 +234,7 @@ automatically receive statistics update.
|
||||
|
||||
// This is first time the block appear in the file.
|
||||
// Create new statistics.
|
||||
auto stats = new ::profiler::BlockStatistics(duration, _current.block_index);
|
||||
auto stats = new ::profiler::BlockStatistics(duration, _current_index);
|
||||
//_stats_map.emplace(key, stats);
|
||||
_stats_map.emplace(_current.node->id(), stats);
|
||||
|
||||
@ -243,289 +243,288 @@ automatically receive statistics update.
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void update_statistics_recursive(StatsMap& _stats_map, ::profiler::BlocksTree& _current)
|
||||
void update_statistics_recursive(StatsMap& _stats_map, ::profiler::BlocksTree& _current, ::profiler::block_index_t _current_index, ::profiler::blocks_t& _blocks)
|
||||
{
|
||||
_current.per_frame_stats = update_statistics(_stats_map, _current);
|
||||
for (auto& child : _current.children)
|
||||
_current.per_frame_stats = update_statistics(_stats_map, _current, _current_index);
|
||||
for (auto i : _current.children)
|
||||
{
|
||||
update_statistics_recursive(_stats_map, child);
|
||||
update_statistics_recursive(_stats_map, _blocks[i], i, _blocks);
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
typedef ::std::map<::profiler::thread_id_t, StatsMap> PerThreadStats;
|
||||
extern "C" ::profiler::block_index_t fillTreesFromFile(::std::atomic<int>& progress, const char* filename, ::profiler::SerializedData& serialized_blocks, ::profiler::SerializedData& serialized_descriptors, ::profiler::descriptors_list_t& descriptors, ::profiler::blocks_t& _blocks, ::profiler::thread_blocks_tree_t& threaded_trees, bool gather_statistics)
|
||||
{
|
||||
EASY_FUNCTION(::profiler::colors::Cyan);
|
||||
|
||||
extern "C" {
|
||||
::std::ifstream inFile(filename, ::std::fstream::binary);
|
||||
progress.store(0);
|
||||
|
||||
unsigned int fillTreesFromFile(::std::atomic<int>& progress, const char* filename, ::profiler::SerializedData& serialized_blocks, ::profiler::SerializedData& serialized_descriptors, ::profiler::descriptors_list_t& descriptors, ::profiler::thread_blocks_tree_t& threaded_trees, bool gather_statistics)
|
||||
{
|
||||
EASY_FUNCTION(::profiler::colors::Cyan);
|
||||
if (!inFile.is_open())
|
||||
return 0;
|
||||
|
||||
::std::ifstream inFile(filename, ::std::fstream::binary);
|
||||
progress.store(0);
|
||||
uint32_t total_blocks_number = 0;
|
||||
inFile.read((char*)&total_blocks_number, sizeof(decltype(total_blocks_number)));
|
||||
if (total_blocks_number == 0)
|
||||
return 0;
|
||||
|
||||
if (!inFile.is_open())
|
||||
uint64_t memory_size = 0;
|
||||
inFile.read((char*)&memory_size, sizeof(decltype(memory_size)));
|
||||
if (memory_size == 0)
|
||||
return 0;
|
||||
|
||||
serialized_blocks.set(new char[memory_size]);
|
||||
//memset(serialized_blocks[0], 0, memory_size);
|
||||
|
||||
|
||||
uint32_t total_descriptors_number = 0;
|
||||
inFile.read((char*)&total_descriptors_number, sizeof(decltype(total_descriptors_number)));
|
||||
if (total_descriptors_number == 0)
|
||||
return 0;
|
||||
|
||||
uint64_t descriptors_memory_size = 0;
|
||||
inFile.read((char*)&descriptors_memory_size, sizeof(decltype(descriptors_memory_size)));
|
||||
if (descriptors_memory_size == 0)
|
||||
return 0;
|
||||
|
||||
descriptors.reserve(total_descriptors_number);
|
||||
serialized_descriptors.set(new char[descriptors_memory_size]);
|
||||
|
||||
uint64_t i = 0;
|
||||
while (!inFile.eof() && descriptors.size() < total_descriptors_number)
|
||||
{
|
||||
uint16_t sz = 0;
|
||||
inFile.read((char*)&sz, sizeof(sz));
|
||||
if (sz == 0)
|
||||
return 0;
|
||||
|
||||
PerThreadStats thread_statistics, parent_statistics, frame_statistics;
|
||||
unsigned int blocks_counter = 0;
|
||||
//if (i + sz > descriptors_memory_size)
|
||||
//{
|
||||
// printf("FILE CORRUPTED\n");
|
||||
// return 0;
|
||||
//}
|
||||
|
||||
uint32_t total_blocks_number = 0;
|
||||
inFile.read((char*)&total_blocks_number, sizeof(decltype(total_blocks_number)));
|
||||
if (total_blocks_number == 0)
|
||||
return 0;
|
||||
char* data = serialized_descriptors[i];
|
||||
inFile.read(data, sz);
|
||||
auto descriptor = reinterpret_cast<::profiler::SerializedBlockDescriptor*>(data);
|
||||
descriptors.push_back(descriptor);
|
||||
|
||||
uint64_t memory_size = 0;
|
||||
inFile.read((char*)&memory_size, sizeof(decltype(memory_size)));
|
||||
if (memory_size == 0)
|
||||
return 0;
|
||||
i += sz;
|
||||
progress.store(static_cast<int>(10 * i / descriptors_memory_size));
|
||||
}
|
||||
|
||||
serialized_blocks.set(new char[memory_size]);
|
||||
//memset(serialized_blocks[0], 0, memory_size);
|
||||
typedef ::std::map<::profiler::thread_id_t, StatsMap> PerThreadStats;
|
||||
PerThreadStats thread_statistics, parent_statistics, frame_statistics;
|
||||
IdMap identification_table;
|
||||
|
||||
i = 0;
|
||||
uint32_t read_number = 0;
|
||||
::profiler::block_index_t blocks_counter = 0;
|
||||
_blocks.reserve(total_blocks_number);
|
||||
while (!inFile.eof() && read_number < total_blocks_number)
|
||||
{
|
||||
EASY_BLOCK("Read thread data", ::profiler::colors::Darkgreen);
|
||||
|
||||
uint32_t total_descriptors_number = 0;
|
||||
inFile.read((char*)&total_descriptors_number, sizeof(decltype(total_descriptors_number)));
|
||||
if (total_descriptors_number == 0)
|
||||
return 0;
|
||||
::profiler::thread_id_t thread_id = 0;
|
||||
inFile.read((char*)&thread_id, sizeof(decltype(thread_id)));
|
||||
|
||||
uint64_t descriptors_memory_size = 0;
|
||||
inFile.read((char*)&descriptors_memory_size, sizeof(decltype(descriptors_memory_size)));
|
||||
if (descriptors_memory_size == 0)
|
||||
return 0;
|
||||
uint32_t blocks_number_in_thread = 0;
|
||||
inFile.read((char*)&blocks_number_in_thread, sizeof(decltype(blocks_number_in_thread)));
|
||||
|
||||
descriptors.reserve(total_descriptors_number);
|
||||
serialized_descriptors.set(new char[descriptors_memory_size]);
|
||||
|
||||
uint64_t i = 0;
|
||||
while (!inFile.eof() && descriptors.size() < total_descriptors_number)
|
||||
auto& root = threaded_trees[thread_id];
|
||||
const auto threshold = read_number + blocks_number_in_thread;
|
||||
while (!inFile.eof() && read_number < threshold)
|
||||
{
|
||||
EASY_BLOCK("Read block", ::profiler::colors::Green);
|
||||
|
||||
++read_number;
|
||||
|
||||
uint16_t sz = 0;
|
||||
inFile.read((char*)&sz, sizeof(sz));
|
||||
if (sz == 0)
|
||||
return 0;
|
||||
|
||||
//if (i + sz > descriptors_memory_size)
|
||||
//{
|
||||
// printf("FILE CORRUPTED\n");
|
||||
// return 0;
|
||||
//}
|
||||
|
||||
char* data = serialized_descriptors[i];
|
||||
char* data = serialized_blocks[i];
|
||||
inFile.read(data, sz);
|
||||
auto descriptor = reinterpret_cast<::profiler::SerializedBlockDescriptor*>(data);
|
||||
descriptors.push_back(descriptor);
|
||||
|
||||
i += sz;
|
||||
progress.store(static_cast<int>(10 * i / descriptors_memory_size));
|
||||
}
|
||||
auto baseData = reinterpret_cast<::profiler::SerializedBlock*>(data);
|
||||
|
||||
IdMap identification_table;
|
||||
_blocks.emplace_back();
|
||||
::profiler::BlocksTree& tree = _blocks.back();
|
||||
tree.node = baseData;// new ::profiler::SerializedBlock(sz, data);
|
||||
const auto block_index = blocks_counter++;
|
||||
|
||||
i = 0;
|
||||
uint32_t read_number = 0;
|
||||
while (!inFile.eof() && read_number < total_blocks_number)
|
||||
{
|
||||
EASY_BLOCK("Read thread data", ::profiler::colors::Darkgreen);
|
||||
auto& per_parent_statistics = parent_statistics[thread_id];
|
||||
auto& per_thread_statistics = thread_statistics[thread_id];
|
||||
auto descriptor = descriptors[baseData->id()];
|
||||
|
||||
::profiler::thread_id_t thread_id = 0;
|
||||
inFile.read((char*)&thread_id, sizeof(decltype(thread_id)));
|
||||
|
||||
uint32_t blocks_number_in_thread = 0;
|
||||
inFile.read((char*)&blocks_number_in_thread, sizeof(decltype(blocks_number_in_thread)));
|
||||
|
||||
auto& root = threaded_trees[thread_id];
|
||||
const auto threshold = read_number + blocks_number_in_thread;
|
||||
while (!inFile.eof() && read_number < threshold)
|
||||
if (descriptor->type() == ::profiler::BLOCK_TYPE_THREAD_SIGN)
|
||||
{
|
||||
EASY_BLOCK("Read block", ::profiler::colors::Green);
|
||||
root.thread_name = tree.node->name();
|
||||
}
|
||||
|
||||
++read_number;
|
||||
if (*tree.node->name() != 0)
|
||||
{
|
||||
// If block has runtime name then generate new id for such block.
|
||||
// Blocks with the same name will have same id.
|
||||
|
||||
uint16_t sz = 0;
|
||||
inFile.read((char*)&sz, sizeof(sz));
|
||||
if (sz == 0)
|
||||
return 0;
|
||||
|
||||
char* data = serialized_blocks[i];
|
||||
inFile.read(data, sz);
|
||||
i += sz;
|
||||
auto baseData = reinterpret_cast<::profiler::SerializedBlock*>(data);
|
||||
|
||||
::profiler::BlocksTree tree;
|
||||
tree.node = baseData;// new ::profiler::SerializedBlock(sz, data);
|
||||
tree.block_index = blocks_counter++;
|
||||
|
||||
auto& per_parent_statistics = parent_statistics[thread_id];
|
||||
auto& per_thread_statistics = thread_statistics[thread_id];
|
||||
auto descriptor = descriptors[baseData->id()];
|
||||
|
||||
if (descriptor->type() == ::profiler::BLOCK_TYPE_THREAD_SIGN)
|
||||
IdMap::key_type key(tree.node->name());
|
||||
auto it = identification_table.find(key);
|
||||
if (it != identification_table.end())
|
||||
{
|
||||
root.thread_name = tree.node->name();
|
||||
// There is already block with such name, use it's id
|
||||
baseData->setId(it->second);
|
||||
}
|
||||
|
||||
if (*tree.node->name() != 0)
|
||||
else
|
||||
{
|
||||
IdMap::key_type key(tree.node->name());
|
||||
auto it = identification_table.find(key);
|
||||
if (it != identification_table.end())
|
||||
// There were no blocks with such name, generate new id and save it in the table for further usage.
|
||||
auto id = static_cast<::profiler::block_id_t>(descriptors.size());
|
||||
identification_table.emplace(key, id);
|
||||
descriptors.push_back(descriptors[baseData->id()]);
|
||||
baseData->setId(id);
|
||||
}
|
||||
}
|
||||
|
||||
if (!root.children.empty())
|
||||
{
|
||||
auto& back = _blocks[root.children.back()];
|
||||
auto t1 = back.node->end();
|
||||
auto mt0 = tree.node->begin();
|
||||
if (mt0 < t1)//parent - starts earlier than last ends
|
||||
{
|
||||
//auto lower = ::std::lower_bound(root.children.begin(), root.children.end(), tree);
|
||||
/**/
|
||||
EASY_BLOCK("Find children", ::profiler::colors::Blue);
|
||||
auto rlower1 = ++root.children.rbegin();
|
||||
for (; rlower1 != root.children.rend() && !(mt0 > _blocks[*rlower1].node->begin()); ++rlower1);
|
||||
auto lower = rlower1.base();
|
||||
::std::move(lower, root.children.end(), ::std::back_inserter(tree.children));
|
||||
|
||||
root.children.erase(lower, root.children.end());
|
||||
EASY_END_BLOCK;
|
||||
|
||||
::profiler::timestamp_t children_duration = 0;
|
||||
if (gather_statistics)
|
||||
{
|
||||
baseData->setId(it->second);
|
||||
EASY_BLOCK("Gather statistic within parent", ::profiler::colors::Magenta);
|
||||
per_parent_statistics.clear();
|
||||
|
||||
//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 i : tree.children)
|
||||
{
|
||||
auto& child = _blocks[i];
|
||||
child.per_parent_stats = update_statistics(per_parent_statistics, child, i);
|
||||
|
||||
children_duration += child.node->duration();
|
||||
if (tree.depth < child.depth)
|
||||
tree.depth = child.depth;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
auto id = static_cast<::profiler::block_id_t>(descriptors.size());
|
||||
identification_table.emplace(key, id);
|
||||
descriptors.push_back(descriptors[baseData->id()]);
|
||||
baseData->setId(id);
|
||||
for (auto i : tree.children)
|
||||
{
|
||||
const auto& child = _blocks[i];
|
||||
children_duration += child.node->duration();
|
||||
if (tree.depth < child.depth)
|
||||
tree.depth = child.depth;
|
||||
}
|
||||
}
|
||||
|
||||
++tree.depth;
|
||||
}
|
||||
|
||||
if (!root.tree.children.empty())
|
||||
{
|
||||
auto& back = root.tree.children.back();
|
||||
auto t1 = back.node->end();
|
||||
auto mt0 = tree.node->begin();
|
||||
if (mt0 < t1)//parent - starts earlier than last ends
|
||||
{
|
||||
//auto lower = ::std::lower_bound(root.children.begin(), root.children.end(), tree);
|
||||
/**/
|
||||
EASY_BLOCK("Find children", ::profiler::colors::Blue);
|
||||
auto rlower1 = ++root.tree.children.rbegin();
|
||||
for (; rlower1 != root.tree.children.rend(); ++rlower1)
|
||||
{
|
||||
if (mt0 > rlower1->node->begin())
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
auto lower = rlower1.base();
|
||||
::std::move(lower, root.tree.children.end(), ::std::back_inserter(tree.children));
|
||||
|
||||
root.tree.children.erase(lower, root.tree.children.end());
|
||||
EASY_END_BLOCK;
|
||||
|
||||
::profiler::timestamp_t children_duration = 0;
|
||||
if (gather_statistics)
|
||||
{
|
||||
EASY_BLOCK("Gather statistic within parent", ::profiler::colors::Magenta);
|
||||
per_parent_statistics.clear();
|
||||
|
||||
//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)
|
||||
{
|
||||
child.per_parent_stats = update_statistics(per_parent_statistics, child);
|
||||
|
||||
children_duration += child.node->duration();
|
||||
if (tree.depth < child.depth)
|
||||
tree.depth = child.depth;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (const auto& child : tree.children)
|
||||
{
|
||||
children_duration += child.node->duration();
|
||||
if (tree.depth < child.depth)
|
||||
tree.depth = child.depth;
|
||||
}
|
||||
}
|
||||
|
||||
++tree.depth;
|
||||
}
|
||||
}
|
||||
|
||||
root.tree.children.emplace_back(::std::move(tree));
|
||||
|
||||
|
||||
|
||||
if (gather_statistics)
|
||||
{
|
||||
EASY_BLOCK("Gather per thread statistics", ::profiler::colors::Coral);
|
||||
auto& current = root.tree.children.back();
|
||||
current.per_thread_stats = update_statistics(per_thread_statistics, current);
|
||||
}
|
||||
|
||||
if (progress.load() < 0)
|
||||
break;
|
||||
progress.store(10 + static_cast<int>(80 * i / memory_size));
|
||||
}
|
||||
}
|
||||
|
||||
if (progress.load() < 0)
|
||||
root.children.emplace_back(block_index);// ::std::move(tree));
|
||||
|
||||
|
||||
|
||||
if (gather_statistics)
|
||||
{
|
||||
EASY_BLOCK("Gather per thread statistics", ::profiler::colors::Coral);
|
||||
tree.per_thread_stats = update_statistics(per_thread_statistics, tree, block_index);
|
||||
}
|
||||
|
||||
if (progress.load() < 0)
|
||||
break;
|
||||
progress.store(10 + static_cast<int>(80 * i / memory_size));
|
||||
}
|
||||
}
|
||||
|
||||
if (progress.load() < 0)
|
||||
{
|
||||
serialized_blocks.clear();
|
||||
threaded_trees.clear();
|
||||
return 0;
|
||||
}
|
||||
|
||||
EASY_BLOCK("Gather statistics for roots", ::profiler::colors::Purple);
|
||||
if (gather_statistics)
|
||||
{
|
||||
::std::vector<::std::thread> statistics_threads;
|
||||
statistics_threads.reserve(threaded_trees.size());
|
||||
|
||||
for (auto& it : threaded_trees)
|
||||
{
|
||||
serialized_blocks.clear();
|
||||
threaded_trees.clear();
|
||||
return 0;
|
||||
auto& root = it.second;
|
||||
root.thread_id = it.first;
|
||||
//root.tree.shrink_to_fit();
|
||||
|
||||
auto& per_frame_statistics = frame_statistics[root.thread_id];
|
||||
auto& per_parent_statistics = parent_statistics[it.first];
|
||||
per_parent_statistics.clear();
|
||||
|
||||
statistics_threads.emplace_back(::std::thread([&per_parent_statistics, &per_frame_statistics, &_blocks](::profiler::BlocksTreeRoot& root)
|
||||
{
|
||||
for (auto i : root.children)
|
||||
{
|
||||
auto& frame = _blocks[i];
|
||||
frame.per_parent_stats = update_statistics(per_parent_statistics, frame, i);
|
||||
|
||||
per_frame_statistics.clear();
|
||||
update_statistics_recursive(per_frame_statistics, frame, i, _blocks);
|
||||
|
||||
if (root.depth < frame.depth)
|
||||
root.depth = frame.depth;
|
||||
}
|
||||
|
||||
++root.depth;
|
||||
}, ::std::ref(root)));
|
||||
}
|
||||
|
||||
EASY_BLOCK("Gather statistics for roots", ::profiler::colors::Purple);
|
||||
if (gather_statistics)
|
||||
{
|
||||
::std::vector<::std::thread> statistics_threads;
|
||||
statistics_threads.reserve(threaded_trees.size());
|
||||
|
||||
for (auto& it : threaded_trees)
|
||||
{
|
||||
auto& root = it.second;
|
||||
root.thread_id = it.first;
|
||||
root.tree.shrink_to_fit();
|
||||
|
||||
auto& per_frame_statistics = frame_statistics[root.thread_id];
|
||||
auto& per_parent_statistics = parent_statistics[it.first];
|
||||
per_parent_statistics.clear();
|
||||
|
||||
statistics_threads.emplace_back(::std::thread([&per_parent_statistics, &per_frame_statistics](::profiler::BlocksTreeRoot& root)
|
||||
{
|
||||
for (auto& frame : root.tree.children)
|
||||
{
|
||||
frame.per_parent_stats = update_statistics(per_parent_statistics, frame);
|
||||
|
||||
per_frame_statistics.clear();
|
||||
update_statistics_recursive(per_frame_statistics, frame);
|
||||
|
||||
if (root.tree.depth < frame.depth)
|
||||
root.tree.depth = frame.depth;
|
||||
}
|
||||
|
||||
++root.tree.depth;
|
||||
}, ::std::ref(root)));
|
||||
}
|
||||
|
||||
int j = 0, n = static_cast<int>(statistics_threads.size());
|
||||
for (auto& t : statistics_threads)
|
||||
{
|
||||
t.join();
|
||||
progress.store(90 + (10 * ++j) / n);
|
||||
}
|
||||
}
|
||||
else
|
||||
int j = 0, n = static_cast<int>(statistics_threads.size());
|
||||
for (auto& t : statistics_threads)
|
||||
{
|
||||
int j = 0, n = static_cast<int>(threaded_trees.size());
|
||||
for (auto& it : threaded_trees)
|
||||
{
|
||||
auto& root = it.second;
|
||||
root.thread_id = it.first;
|
||||
|
||||
root.tree.shrink_to_fit();
|
||||
for (auto& frame : root.tree.children)
|
||||
{
|
||||
if (root.tree.depth < frame.depth)
|
||||
root.tree.depth = frame.depth;
|
||||
}
|
||||
|
||||
++root.tree.depth;
|
||||
|
||||
progress.store(90 + (10 * ++j) / n);
|
||||
}
|
||||
t.join();
|
||||
progress.store(90 + (10 * ++j) / n);
|
||||
}
|
||||
// No need to delete BlockStatistics instances - they will be deleted inside BlocksTree destructors
|
||||
}
|
||||
else
|
||||
{
|
||||
int j = 0, n = static_cast<int>(threaded_trees.size());
|
||||
for (auto& it : threaded_trees)
|
||||
{
|
||||
auto& root = it.second;
|
||||
root.thread_id = it.first;
|
||||
|
||||
return blocks_counter;
|
||||
}
|
||||
//root.tree.shrink_to_fit();
|
||||
for (auto i : root.children)
|
||||
{
|
||||
auto& frame = _blocks[i];
|
||||
if (root.depth < frame.depth)
|
||||
root.depth = frame.depth;
|
||||
}
|
||||
|
||||
++root.depth;
|
||||
|
||||
progress.store(90 + (10 * ++j) / n);
|
||||
}
|
||||
}
|
||||
// No need to delete BlockStatistics instances - they will be deleted inside BlocksTree destructors
|
||||
|
||||
return blocks_counter;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user