0
0
mirror of https://github.com/yse/easy_profiler.git synced 2024-12-27 00:21:11 +08:00

(profiler_gui) Memory consumption optimization + File reading speed-up.

This commit is contained in:
Victor Zarubkin 2016-08-30 22:51:18 +03:00
parent 245bc6c386
commit 9560c5b5cf
15 changed files with 581 additions and 519 deletions

View File

@ -72,23 +72,21 @@ namespace profiler {
public: 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. children_t children; ///< List of children blocks. May be empty.
::profiler::SerializedBlock* node; ///< Pointer to serilized data (type, name, begin, end etc.) ::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_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_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::BlockStatistics* per_thread_stats; ///< Pointer to statistics for this block within the bounds of all frames per current thread
uint16_t depth; ///< Maximum number of sublevels (maximum children depth)
::profiler::block_index_t block_index; ///< Index of this block
unsigned short depth; ///< Maximum number of sublevels (maximum children depth)
BlocksTree() BlocksTree()
: node(nullptr) : node(nullptr)
, per_parent_stats(nullptr) , per_parent_stats(nullptr)
, per_frame_stats(nullptr) , per_frame_stats(nullptr)
, per_thread_stats(nullptr) , per_thread_stats(nullptr)
, block_index(0)
, depth(0) , depth(0)
{ {
@ -143,33 +141,20 @@ namespace profiler {
void makeMove(This&& that) void makeMove(This&& that)
{ {
//if (node && node != that.node)
//{
// delete node;
//}
if (per_thread_stats != that.per_thread_stats) if (per_thread_stats != that.per_thread_stats)
{
release_stats(per_thread_stats); release_stats(per_thread_stats);
}
if (per_parent_stats != that.per_parent_stats) if (per_parent_stats != that.per_parent_stats)
{
release_stats(per_parent_stats); release_stats(per_parent_stats);
}
if (per_frame_stats != that.per_frame_stats) if (per_frame_stats != that.per_frame_stats)
{
release_stats(per_frame_stats); release_stats(per_frame_stats);
}
children = ::std::move(that.children); children = ::std::move(that.children);
node = that.node; node = that.node;
per_parent_stats = that.per_parent_stats; per_parent_stats = that.per_parent_stats;
per_frame_stats = that.per_frame_stats; per_frame_stats = that.per_frame_stats;
per_thread_stats = that.per_thread_stats; per_thread_stats = that.per_thread_stats;
block_index = that.block_index;
depth = that.depth; depth = that.depth;
that.node = nullptr; that.node = nullptr;
@ -188,29 +173,31 @@ namespace profiler {
public: public:
BlocksTree tree; BlocksTree::children_t children;
const char* thread_name; const char* thread_name;
::profiler::thread_id_t thread_id; ::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) This& operator = (This&& that)
{ {
tree = ::std::move(that.tree); children = ::std::move(that.children);
thread_name = that.thread_name; thread_name = that.thread_name;
thread_id = that.thread_id; thread_id = that.thread_id;
depth = that.depth;
return *this; return *this;
} }
bool operator < (const This& other) const bool operator < (const This& other) const
{ {
return tree < other.tree; return thread_id < other.thread_id;
} }
private: private:
@ -220,6 +207,7 @@ namespace profiler {
}; // END of class BlocksTreeRoot. }; // END of class BlocksTreeRoot.
typedef ::profiler::BlocksTree::blocks_t blocks_t;
typedef ::std::map<::profiler::thread_id_t, ::profiler::BlocksTreeRoot> thread_blocks_tree_t; typedef ::std::map<::profiler::thread_id_t, ::profiler::BlocksTreeRoot> thread_blocks_tree_t;
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
@ -283,11 +271,21 @@ namespace profiler {
} // END of 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); ::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);
} }
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

View File

@ -153,7 +153,7 @@ void EasyGraphicsItem::paint(QPainter* _painter, const QStyleOptionGraphicsItem*
// Search for first visible top-level item // Search for first visible top-level item
auto& level0 = m_levels.front(); 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; return _item.left() < _value;
}); });
@ -183,7 +183,7 @@ void EasyGraphicsItem::paint(QPainter* _painter, const QStyleOptionGraphicsItem*
_painter->setTransform(QTransform::fromTranslate(dx - offset * currentScale, -y()), true); _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; previousPenStyle = Qt::SolidLine;
_painter->setPen(BORDERS_COLOR); _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)>(); 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::ProfBlockItem::children_begin) 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 // Mark that we would not paint children of current item
if (next_level < levelsNumber && children_begin != MAX_CHILD_INDEX) if (next_level < levelsNumber && children_begin != MAX_CHILD_INDEX)
@ -243,8 +243,9 @@ void EasyGraphicsItem::paint(QPainter* _painter, const QStyleOptionGraphicsItem*
continue; continue;
} }
const auto& itemBlock = easyBlock(item.block);
int h = 0, flags = 0; 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 // 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; h -= dh;
bool changepen = false; bool changepen = false;
if (item.block->block_index == ::profiler_gui::EASY_GLOBALS.selected_block) if (item.block == EASY_GLOBALS.selected_block)
{ {
selectedItemsWasPainted = true; selectedItemsWasPainted = true;
changepen = true; changepen = true;
@ -281,7 +282,7 @@ void EasyGraphicsItem::paint(QPainter* _painter, const QStyleOptionGraphicsItem*
_painter->setBrush(brush); _painter->setBrush(brush);
} }
if (::profiler_gui::EASY_GLOBALS.draw_graphics_items_borders) if (EASY_GLOBALS.draw_graphics_items_borders)
{ {
//if (w < 2) //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; 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; selectedItemsWasPainted = true;
QPen pen(Qt::SolidLine); QPen pen(Qt::SolidLine);
@ -374,7 +375,7 @@ void EasyGraphicsItem::paint(QPainter* _painter, const QStyleOptionGraphicsItem*
_painter->setBrush(brush); _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 // Restore pen for item which is wide enough to paint borders
previousPenStyle = Qt::SolidLine; previousPenStyle = Qt::SolidLine;
@ -422,7 +423,7 @@ void EasyGraphicsItem::paint(QPainter* _painter, const QStyleOptionGraphicsItem*
_painter->setPen(textColor); _painter->setPen(textColor);
// drawing text // 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)); _painter->drawText(rect, flags, ::profiler_gui::toUnicode(name));
// restore previous pen color // 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) if (guiblock.graphics_item == m_index)
{ {
const auto& item = m_levels[guiblock.graphics_item_level][guiblock.graphics_item_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); _painter->setPen(textColor);
// drawing text // 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)); _painter->drawText(rect, Qt::AlignCenter, ::profiler_gui::toUnicode(name));
// END Draw text~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // END Draw text~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
} }
@ -511,7 +513,7 @@ void EasyGraphicsItem::getBlocks(qreal _left, qreal _right, ::profiler_gui::Tree
// Search for first visible top-level item // Search for first visible top-level item
auto& level0 = m_levels.front(); 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; 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()) 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]; const auto& level = m_levels[i];
// Search for first visible item // 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; return _item.left() < _value;
}); });
@ -620,7 +622,7 @@ const ::profiler_gui::ProfBlockItem* EasyGraphicsItem::intersect(const QPointF&
} }
const auto w = item.width() * currentScale; 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; return &item;
} }
@ -725,12 +727,12 @@ const EasyGraphicsItem::Children& EasyGraphicsItem::items(unsigned char _level)
return m_levels[_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]; 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]; return m_levels[_level][_index];
} }
@ -862,7 +864,7 @@ void EasyChronometerItem::paint(QPainter* _painter, const QStyleOptionGraphicsIt
_painter->setFont(CHRONOMETER_FONT); _painter->setFont(CHRONOMETER_FONT);
int textFlags = 0; int textFlags = 0;
switch (::profiler_gui::EASY_GLOBALS.chrono_text_position) switch (EASY_GLOBALS.chrono_text_position)
{ {
case ::profiler_gui::ChronoTextPosition_Top: case ::profiler_gui::ChronoTextPosition_Top:
textFlags = Qt::AlignTop | Qt::AlignHCenter; textFlags = Qt::AlignTop | Qt::AlignHCenter;
@ -1001,7 +1003,7 @@ void EasyBackgroundItem::paint(QPainter* _painter, const QStyleOptionGraphicsIte
if (top > h || bottom < 0) if (top > h || bottom < 0)
continue; 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))); _painter->setBrush(QBrush(QColor::fromRgb(::profiler_gui::SELECTED_THREAD_BACKGROUND)));
else else
_painter->setBrush(brushes[i & 1]); _painter->setBrush(brushes[i & 1]);
@ -1291,8 +1293,8 @@ void EasyGraphicsView::test(unsigned int _frames_number, unsigned int _total_ite
if (longestItem != nullptr) if (longestItem != nullptr)
{ {
m_pScrollbar->setMinimapFrom(0, longestItem->items(0)); m_pScrollbar->setMinimapFrom(0, longestItem->items(0));
::profiler_gui::EASY_GLOBALS.selected_thread = 0; EASY_GLOBALS.selected_thread = 0;
emit::profiler_gui::EASY_GLOBALS.events.selectedThreadChanged(0); emitEASY_GLOBALS.events.selectedThreadChanged(0);
} }
// Create new chronometer item (previous item was destroyed by scene on scene()->clear()). // 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 // Calculating start and end time
::profiler::timestamp_t finish = 0; ::profiler::timestamp_t finish = 0;
const ::profiler::BlocksTree* longestTree = nullptr; ::profiler::thread_id_t longestTree = 0;
const EasyGraphicsItem* longestItem = nullptr; const EasyGraphicsItem* longestItem = nullptr;
for (const auto& threadTree : _blocksTree) for (const auto& threadTree : _blocksTree)
{ {
const auto& tree = threadTree.second.tree; const auto& tree = threadTree.second.children;
const auto timestart = tree.children.front().node->begin(); const auto timestart = blocksTree(tree.front()).node->begin();
const auto timefinish = tree.children.back().node->end(); const auto timefinish = blocksTree(tree.back()).node->end();
if (m_beginTime > timestart) if (m_beginTime > timestart)
{ {
@ -1375,7 +1377,7 @@ void EasyGraphicsView::setTree(const ::profiler::thread_blocks_tree_t& _blocksTr
if (finish < timefinish) if (finish < timefinish)
{ {
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 // fill scene with new items
const auto& tree = threadTree.second.tree; const auto& tree = threadTree.second.children;
qreal h = 0, x = time2position(tree.children.front().node->begin()); qreal h = 0, x = time2position(blocksTree(tree.front()).node->begin());
auto item = new EasyGraphicsItem(static_cast<unsigned char>(m_items.size()), &threadTree.second); 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); 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); item->setBoundingRect(0, 0, children_duration + x, h);
m_items.push_back(item); m_items.push_back(item);
@ -1405,7 +1407,7 @@ void EasyGraphicsView::setTree(const ::profiler::thread_blocks_tree_t& _blocksTr
y += h + THREADS_ROW_SPACING; y += h + THREADS_ROW_SPACING;
if (longestTree == &tree) if (longestTree == threadTree.first)
{ {
longestItem = item; longestItem = item;
} }
@ -1424,8 +1426,8 @@ void EasyGraphicsView::setTree(const ::profiler::thread_blocks_tree_t& _blocksTr
if (longestItem != nullptr) if (longestItem != nullptr)
{ {
m_pScrollbar->setMinimapFrom(longestItem->threadId(), longestItem->items(0)); m_pScrollbar->setMinimapFrom(longestItem->threadId(), longestItem->items(0));
::profiler_gui::EASY_GLOBALS.selected_thread = longestItem->threadId(); EASY_GLOBALS.selected_thread = longestItem->threadId();
emit::profiler_gui::EASY_GLOBALS.events.selectedThreadChanged(longestItem->threadId()); emit EASY_GLOBALS.events.selectedThreadChanged(longestItem->threadId());
} }
// Create new chronometer item (previous item was destroyed by scene on scene()->clear()). // 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; bool warned = false;
qreal total_duration = 0, prev_end = 0, maxh = 0; qreal total_duration = 0, prev_end = 0, maxh = 0;
qreal start_time = -1; 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()); auto xbegin = time2position(child.node->begin());
if (start_time < 0) if (start_time < 0)
{ {
@ -1491,7 +1496,6 @@ qreal EasyGraphicsView::setTree(EasyGraphicsItem* _item, const ::profiler::Block
auto i = _item->addItem(level); auto i = _item->addItem(level);
auto& b = _item->getItem(level, i); 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 = _item->index();
gui_block.graphics_item_level = level; gui_block.graphics_item_level = level;
gui_block.graphics_item_index = i; gui_block.graphics_item_index = i;
@ -1528,8 +1532,8 @@ qreal EasyGraphicsView::setTree(EasyGraphicsItem* _item, const ::profiler::Block
maxh = h; maxh = h;
} }
const auto color = ::profiler_gui::EASY_GLOBALS.descriptors[child.node->id()]->color(); const auto color = EASY_GLOBALS.descriptors[child.node->id()]->color();
b.block = &child; 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.color = ::profiler_gui::fromProfilerRgb(::profiler::colors::get_red(color), ::profiler::colors::get_green(color), ::profiler::colors::get_blue(color));
b.setPos(xbegin, duration); b.setPos(xbegin, duration);
b.totalHeight = GRAPHICS_ROW_SIZE + h; b.totalHeight = GRAPHICS_ROW_SIZE + h;
@ -1570,8 +1574,8 @@ void EasyGraphicsView::setScrollbar(EasyGraphicsScrollbar* _scrollbar)
connect(m_pScrollbar, &EasyGraphicsScrollbar::wheeled, this, &This::onGraphicsScrollbarWheel); connect(m_pScrollbar, &EasyGraphicsScrollbar::wheeled, this, &This::onGraphicsScrollbarWheel);
} }
::profiler_gui::EASY_GLOBALS.selected_thread = 0; EASY_GLOBALS.selected_thread = 0;
emit ::profiler_gui::EASY_GLOBALS.events.selectedThreadChanged(0); emit EASY_GLOBALS.events.selectedThreadChanged(0);
} }
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
@ -1646,7 +1650,7 @@ void EasyGraphicsView::onGraphicsScrollbarWheel(qreal _mouseX, int _wheelDelta)
{ {
for (auto item : m_items) for (auto item : m_items)
{ {
if (item->threadId() == ::profiler_gui::EASY_GLOBALS.selected_thread) if (item->threadId() == EASY_GLOBALS.selected_thread)
{ {
m_bUpdatingRect = true; m_bUpdatingRect = true;
auto vbar = verticalScrollBar(); auto vbar = verticalScrollBar();
@ -1779,8 +1783,8 @@ void EasyGraphicsView::mouseReleaseEvent(QMouseEvent* _event)
} }
} }
const ::profiler_gui::ProfBlockItem* selectedBlock = nullptr; const ::profiler_gui::EasyBlockItem* selectedBlock = nullptr;
const auto previouslySelectedBlock = ::profiler_gui::EASY_GLOBALS.selected_block; const auto previouslySelectedBlock = EASY_GLOBALS.selected_block;
if (m_mouseButtons & Qt::LeftButton) if (m_mouseButtons & Qt::LeftButton)
{ {
bool clicked = false; bool clicked = false;
@ -1813,15 +1817,15 @@ void EasyGraphicsView::mouseReleaseEvent(QMouseEvent* _event)
{ {
changedSelectedItem = true; changedSelectedItem = true;
selectedBlock = block; selectedBlock = block;
::profiler_gui::EASY_GLOBALS.selected_block = block->block->block_index; EASY_GLOBALS.selected_block = block->block;
break; 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; 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) if (changedSelectedItem)
{ {
m_bUpdatingRect = true; 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; EASY_GLOBALS.gui_blocks[previouslySelectedBlock].expanded = !EASY_GLOBALS.gui_blocks[previouslySelectedBlock].expanded;
emit ::profiler_gui::EASY_GLOBALS.events.itemsExpandStateChanged(); 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; m_bUpdatingRect = false;
updateScene(); updateScene();
@ -1998,7 +2002,7 @@ void EasyGraphicsView::initMode()
connect(verticalScrollBar(), &QScrollBar::valueChanged, this, &This::onScrollbarValueChange); connect(verticalScrollBar(), &QScrollBar::valueChanged, this, &This::onScrollbarValueChange);
connect(&m_flickerTimer, &QTimer::timeout, this, &This::onFlickerTimeout); 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::selectedThreadChanged, this, &This::onSelectedThreadChange);
connect(globalSignals, &::profiler_gui::EasyGlobalSignals::selectedBlockChanged, this, &This::onSelectedBlockChange); connect(globalSignals, &::profiler_gui::EasyGlobalSignals::selectedBlockChanged, this, &This::onSelectedBlockChange);
connect(globalSignals, &::profiler_gui::EasyGlobalSignals::itemsExpandStateChanged, this, &This::onItemsEspandStateChange); connect(globalSignals, &::profiler_gui::EasyGlobalSignals::itemsExpandStateChanged, this, &This::onItemsEspandStateChange);
@ -2101,11 +2105,11 @@ void EasyGraphicsView::onSelectedBlockChange(unsigned int _block_index)
{ {
if (!m_bUpdatingRect) if (!m_bUpdatingRect)
{ {
if (_block_index < ::profiler_gui::EASY_GLOBALS.gui_blocks.size()) if (_block_index < EASY_GLOBALS.gui_blocks.size())
{ {
// Scroll to item // 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 thread_item = m_items[guiblock.graphics_item];
const auto& item = thread_item->items(guiblock.graphics_item_level)[guiblock.graphics_item_index]; 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); //m_layout->addWidget(m_label);
//setLayout(m_layout); //setLayout(m_layout);
//show(); //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() EasyThreadViewWidget::~EasyThreadViewWidget()
@ -2191,14 +2195,14 @@ EasyThreadViewWidget::~EasyThreadViewWidget()
void EasyThreadViewWidget::onSelectedThreadChange(::profiler::thread_id_t _id) 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) if(threadName[0]!=0)
{ {
m_label->setText(threadName); m_label->setText(threadName);
} }
else 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; QLayoutItem *ditem;

View File

@ -58,7 +58,7 @@ inline qreal microseconds2units(qreal _value)
class EasyGraphicsItem : public QGraphicsItem class EasyGraphicsItem : public QGraphicsItem
{ {
typedef ::profiler_gui::ProfItems Children; typedef ::profiler_gui::EasyItems Children;
typedef ::std::vector<unsigned int> DrawIndexes; typedef ::std::vector<unsigned int> DrawIndexes;
typedef ::std::vector<Children> Sublevels; typedef ::std::vector<Children> Sublevels;
@ -118,13 +118,13 @@ public:
\param _level Index of the level \param _level Index of the level
\param _index Index of required item */ \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. /**\brief Returns reference to the item with required index on specified level.
\param _level Index of the level \param _level Index of the level
\param _index Index of required item */ \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. /** \brief Adds new item to required level.
@ -142,7 +142,7 @@ public:
\param _blocks Reference to the array of selected blocks */ \param _blocks Reference to the array of selected blocks */
void getBlocks(qreal _left, qreal _right, ::profiler_gui::TreeBlocks& _blocks) const; 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: private:

View File

@ -104,8 +104,8 @@ EasyTreeWidget::EasyTreeWidget(QWidget* _parent)
setHeaderItem(header); setHeaderItem(header);
connect(&::profiler_gui::EASY_GLOBALS.events, &::profiler_gui::EasyGlobalSignals::selectedThreadChanged, this, &This::onSelectedThreadChange); connect(&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::selectedBlockChanged, this, &This::onSelectedBlockChange);
connect(&m_fillTimer, &QTimer::timeout, this, &This::onFillTimerTimeout); connect(&m_fillTimer, &QTimer::timeout, this, &This::onFillTimerTimeout);
loadSettings(); loadSettings();
@ -163,8 +163,8 @@ void EasyTreeWidget::onFillTimerTimeout()
connect(this, &Parent::itemExpanded, this, &This::onItemExpand); connect(this, &Parent::itemExpanded, this, &This::onItemExpand);
connect(this, &Parent::itemCollapsed, this, &This::onItemCollapse); connect(this, &Parent::itemCollapsed, this, &This::onItemCollapse);
connect(this, &Parent::currentItemChanged, this, &This::onCurrentItemChange); connect(this, &Parent::currentItemChanged, this, &This::onCurrentItemChange);
onSelectedThreadChange(::profiler_gui::EASY_GLOBALS.selected_thread); onSelectedThreadChange(EASY_GLOBALS.selected_thread);
onSelectedBlockChange(::profiler_gui::EASY_GLOBALS.selected_block); onSelectedBlockChange(EASY_GLOBALS.selected_block);
} }
else else
{ {
@ -194,7 +194,7 @@ void EasyTreeWidget::setTree(const unsigned int _blocksNumber, const ::profiler:
// { // {
// addTopLevelItem(item.second); // addTopLevelItem(item.second);
// m_roots[item.first] = 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); // item.second->colorize(true);
// } // }
//} //}
@ -227,7 +227,7 @@ void EasyTreeWidget::setTreeBlocks(const ::profiler_gui::TreeBlocks& _blocks, ::
// { // {
// addTopLevelItem(item.second); // addTopLevelItem(item.second);
// m_roots[item.first] = 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); // 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::itemExpanded, this, &This::onItemExpand);
//connect(this, &Parent::itemCollapsed, this, &This::onItemCollapse); //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 (!_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); ::profiler_gui::set_max(gui_block.tree_item);
gui_block.expanded = false; gui_block.expanded = false;
} }
else for (auto item : m_items) 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(); //clear();
if (!_global) 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); action->setChecked(m_bColorRows);
connect(action, &QAction::triggered, this, &This::onColorizeRowsTriggered); 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); //auto itemAction = new EasyItemAction("Show this item on scene", item->block()->block_index);
//itemAction->setToolTip("Scroll graphics scene to current item in the tree"); //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_PARENT:
case COL_MAX_PER_FRAME: case COL_MAX_PER_FRAME:
{ {
auto block = item->block(); auto& block = item->block();
auto i = ::profiler_gui::numeric_max<unsigned int>(); auto i = ::profiler_gui::numeric_max<unsigned int>();
switch (col) switch (col)
{ {
case COL_MIN_PER_THREAD: i = block->per_thread_stats->min_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_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_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_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_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_MAX_PER_FRAME: i = block.per_frame_stats->max_duration_block; break;
} }
if (i != ::profiler_gui::numeric_max(i)) if (i != ::profiler_gui::numeric_max(i))
@ -427,8 +427,8 @@ void EasyTreeWidget::alignProgressBar()
void EasyTreeWidget::onJumpToItemClicked(unsigned int _block_index) void EasyTreeWidget::onJumpToItemClicked(unsigned int _block_index)
{ {
::profiler_gui::EASY_GLOBALS.selected_block = _block_index; EASY_GLOBALS.selected_block = _block_index;
emit ::profiler_gui::EASY_GLOBALS.events.selectedBlockChanged(_block_index); emit EASY_GLOBALS.events.selectedBlockChanged(_block_index);
} }
void EasyTreeWidget::onCollapseAllClicked(bool) void EasyTreeWidget::onCollapseAllClicked(bool)
@ -439,11 +439,11 @@ void EasyTreeWidget::onCollapseAllClicked(bool)
collapseAll(); collapseAll();
m_bSilentExpandCollapse = false; 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) for (auto item : m_items)
::profiler_gui::EASY_GLOBALS.gui_blocks[item->block()->block_index].expanded = false; item->guiBlock().expanded = false;
emit::profiler_gui::EASY_GLOBALS.events.itemsExpandStateChanged(); emit EASY_GLOBALS.events.itemsExpandStateChanged();
} }
} }
@ -456,11 +456,15 @@ void EasyTreeWidget::onExpandAllClicked(bool)
resizeColumnsToContents(); resizeColumnsToContents();
m_bSilentExpandCollapse = false; 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) 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(); current->collapseAll();
m_bSilentExpandCollapse = false; m_bSilentExpandCollapse = false;
emit ::profiler_gui::EASY_GLOBALS.events.itemsExpandStateChanged(); emit EASY_GLOBALS.events.itemsExpandStateChanged();
} }
} }
@ -491,7 +495,7 @@ void EasyTreeWidget::onExpandAllChildrenClicked(bool)
resizeColumnsToContents(); resizeColumnsToContents();
m_bSilentExpandCollapse = false; 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) 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(); resizeColumnsToContents();
return; 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) if (!m_bSilentExpandCollapse)
{ {
resizeColumnsToContents(); resizeColumnsToContents();
emit ::profiler_gui::EASY_GLOBALS.events.itemsExpandStateChanged(); emit EASY_GLOBALS.events.itemsExpandStateChanged();
} }
} }
void EasyTreeWidget::onItemCollapse(QTreeWidgetItem* _item) 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; 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) 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*) void EasyTreeWidget::onCurrentItemChange(QTreeWidgetItem* _item, QTreeWidgetItem*)
{ {
if (_item == nullptr) if (_item == nullptr)
::profiler_gui::set_max(::profiler_gui::EASY_GLOBALS.selected_block); ::profiler_gui::set_max(EASY_GLOBALS.selected_block);
else 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); disconnect(&EASY_GLOBALS.events, &::profiler_gui::EasyGlobalSignals::selectedBlockChanged, this, &This::onSelectedBlockChange);
emit ::profiler_gui::EASY_GLOBALS.events.selectedBlockChanged(::profiler_gui::EASY_GLOBALS.selected_block); emit EASY_GLOBALS.events.selectedBlockChanged(EASY_GLOBALS.selected_block);
connect(&::profiler_gui::EASY_GLOBALS.events, &::profiler_gui::EasyGlobalSignals::selectedBlockChanged, this, &This::onSelectedBlockChange); 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; 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()) if (i < m_items.size())
item = m_items[i]; item = m_items[i];
} }
@ -592,19 +596,19 @@ void EasyTreeWidget::onSelectedBlockChange(unsigned int _block_index)
{ {
//const QSignalBlocker b(this); //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; m_bSilentExpandCollapse = true;
setCurrentItem(item); setCurrentItem(item);
scrollToItem(item, QAbstractItemView::PositionAtCenter); scrollToItem(item, QAbstractItemView::PositionAtCenter);
if (::profiler_gui::EASY_GLOBALS.gui_blocks[item->block()->block_index].expanded) if (item->guiBlock().expanded)
expandItem(item); expandItem(item);
else else
collapseItem(item); collapseItem(item);
resizeColumnsToContents(); resizeColumnsToContents();
m_bSilentExpandCollapse = false; m_bSilentExpandCollapse = false;
emit ::profiler_gui::EASY_GLOBALS.events.itemsExpandStateChanged(); emit EASY_GLOBALS.events.itemsExpandStateChanged();
} }
else else
{ {

View File

@ -105,14 +105,15 @@ inline QRgb fromProfilerRgb(unsigned int _red, unsigned int _green, unsigned int
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
#pragma pack(push, 1) #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) 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 float w; ///< Width of the item
QRgb color; ///< Background color of the item QRgb color; ///< Background color of the item
unsigned int children_begin; ///< Index of first child item on the next sublevel ::profiler::block_index_t block; ///< Index of profiler block
unsigned short totalHeight; ///< Total height of the item including heights of all it's children 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 char state; ///< 0 = no change, 1 = paint, -1 = do not paint
// Possible optimizations: // Possible optimizations:
@ -125,31 +126,58 @@ struct ProfBlockItem final
inline qreal right() const { return x + w; } inline qreal right() const { return x + w; }
inline float width() const { return w; } inline float width() const { return w; }
}; // END of struct ProfBlockItem. }; // END of struct EasyBlockItem.
#pragma pack(pop)
typedef ::std::vector<ProfBlockItem> ProfItems; struct EasyBlock final
//////////////////////////////////////////////////////////////////////////
struct ProfSelectedBlock final
{ {
const ::profiler::BlocksTreeRoot* root; ::profiler::BlocksTree tree;
const ::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) : root(_root)
, tree(_tree) , tree(_tree)
{ {
} }
}; // END of struct ProfSelectedBlock. }; // END of struct EasySelectedBlock.
typedef ::std::vector<ProfSelectedBlock> TreeBlocks; typedef ::std::vector<EasySelectedBlock> TreeBlocks;
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////

View File

@ -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> template <class T>
inline auto toUnicode(const T& _inputString) -> decltype(QTextCodec::codecForLocale()->toUnicode(_inputString)) inline auto toUnicode(const T& _inputString) -> decltype(QTextCodec::codecForLocale()->toUnicode(_inputString))
{ {
@ -97,13 +84,26 @@ namespace profiler_gui {
}; // END of struct EasyGlobals. }; // END of struct EasyGlobals.
#ifndef IGNORE_GLOBALS_DECLARATION
static EasyGlobals& EASY_GLOBALS = EasyGlobals::instance();
#endif
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
} // END of namespace profiler_gui. } // 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
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////

View File

@ -238,7 +238,7 @@ void EasyMinimapItem::setBoundingRect(qreal x, qreal y, qreal w, qreal h)
m_boundingRect.setRect(x, y, w, 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_pSource = _items;
m_threadId = _thread_id; 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_minimap->setSource(_thread_id, _items);
m_slider->setVisible(m_minimap->isVisible()); m_slider->setVisible(m_minimap->isVisible());
@ -493,14 +493,14 @@ void EasyGraphicsScrollbar::resizeEvent(QResizeEvent* _event)
void EasyGraphicsScrollbar::contextMenuEvent(QContextMenuEvent* _event) void EasyGraphicsScrollbar::contextMenuEvent(QContextMenuEvent* _event)
{ {
if (::profiler_gui::EASY_GLOBALS.profiler_blocks.empty()) if (EASY_GLOBALS.profiler_blocks.empty())
{ {
return; return;
} }
QMenu menu; QMenu menu;
for (const auto& it : ::profiler_gui::EASY_GLOBALS.profiler_blocks) for (const auto& it : EASY_GLOBALS.profiler_blocks)
{ {
QString label; QString label;
if (it.second.thread_name && it.second.thread_name[0] != 0) 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); auto action = new EasyIdAction(label, it.first);
action->setCheckable(true); 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); connect(action, &EasyIdAction::clicked, this, &This::onThreadActionClicked);
menu.addAction(action); menu.addAction(action);
@ -530,8 +530,8 @@ void EasyGraphicsScrollbar::onThreadActionClicked(::profiler::thread_id_t _id)
{ {
if (_id != m_minimap->threadId()) if (_id != m_minimap->threadId())
{ {
::profiler_gui::EASY_GLOBALS.selected_thread = _id; EASY_GLOBALS.selected_thread = _id;
emit ::profiler_gui::EASY_GLOBALS.events.selectedThreadChanged(_id); emit EASY_GLOBALS.events.selectedThreadChanged(_id);
} }
} }

View File

@ -66,7 +66,7 @@ class EasyMinimapItem : public QGraphicsItem
QRectF m_boundingRect; QRectF m_boundingRect;
qreal m_maxDuration; qreal m_maxDuration;
qreal m_minDuration; qreal m_minDuration;
const ::profiler_gui::ProfItems* m_pSource; const ::profiler_gui::EasyItems* m_pSource;
::profiler::thread_id_t m_threadId; ::profiler::thread_id_t m_threadId;
public: public:
@ -88,7 +88,7 @@ public:
void setBoundingRect(const QRectF& _rect); void setBoundingRect(const QRectF& _rect);
void setBoundingRect(qreal x, qreal y, qreal w, qreal h); 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. }; // END of class EasyMinimapItem.
@ -190,9 +190,9 @@ public:
void showChrono(); void showChrono();
void hideChrono(); 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); setMinimapFrom(_thread_id, &_items);
} }

View File

@ -100,22 +100,22 @@ EasyMainWindow::EasyMainWindow() : Parent(), m_treeWidget(nullptr), m_graphicsVi
menu->addSeparator(); menu->addSeparator();
action = menu->addAction("Draw items' borders"); action = menu->addAction("Draw items' borders");
action->setCheckable(true); 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); connect(action, &QAction::triggered, this, &This::onDrawBordersChanged);
action = menu->addAction("Collapse items on tree reset"); action = menu->addAction("Collapse items on tree reset");
action->setCheckable(true); 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); connect(action, &QAction::triggered, this, &This::onCollapseItemsAfterCloseChanged);
action = menu->addAction("Expand all on file open"); action = menu->addAction("Expand all on file open");
action->setCheckable(true); 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); connect(action, &QAction::triggered, this, &This::onAllItemsExpandedByDefaultChange);
action = menu->addAction("Bind scene and tree expand"); action = menu->addAction("Bind scene and tree expand");
action->setCheckable(true); 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); connect(action, &QAction::triggered, this, &This::onBindExpandStatusChange);
menu->addSeparator(); menu->addSeparator();
@ -126,7 +126,7 @@ EasyMainWindow::EasyMainWindow() : Parent(), m_treeWidget(nullptr), m_graphicsVi
action = new QAction("At top", actionGroup); action = new QAction("At top", actionGroup);
action->setCheckable(true); action->setCheckable(true);
action->setData(static_cast<int>(::profiler_gui::ChronoTextPosition_Top)); 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); action->setChecked(true);
submenu->addAction(action); submenu->addAction(action);
connect(action, &QAction::triggered, this, &This::onChronoTextPosChanged); 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 = new QAction("At center", actionGroup);
action->setCheckable(true); action->setCheckable(true);
action->setData(static_cast<int>(::profiler_gui::ChronoTextPosition_Center)); 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); action->setChecked(true);
submenu->addAction(action); submenu->addAction(action);
connect(action, &QAction::triggered, this, &This::onChronoTextPosChanged); 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 = new QAction("At bottom", actionGroup);
action->setCheckable(true); action->setCheckable(true);
action->setData(static_cast<int>(::profiler_gui::ChronoTextPosition_Bottom)); 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); action->setChecked(true);
submenu->addAction(action); submenu->addAction(action);
connect(action, &QAction::triggered, this, &This::onChronoTextPosChanged); connect(action, &QAction::triggered, this, &This::onChronoTextPosChanged);
@ -250,39 +250,39 @@ void EasyMainWindow::onEncodingChanged(bool)
void EasyMainWindow::onChronoTextPosChanged(bool) void EasyMainWindow::onChronoTextPosChanged(bool)
{ {
auto _sender = qobject_cast<QAction*>(sender()); auto _sender = qobject_cast<QAction*>(sender());
::profiler_gui::EASY_GLOBALS.chrono_text_position = static_cast<::profiler_gui::ChronometerTextPosition>(_sender->data().toInt()); EASY_GLOBALS.chrono_text_position = static_cast<::profiler_gui::ChronometerTextPosition>(_sender->data().toInt());
emit ::profiler_gui::EASY_GLOBALS.events.chronoPositionChanged(); emit EASY_GLOBALS.events.chronoPositionChanged();
} }
void EasyMainWindow::onDrawBordersChanged(bool _checked) void EasyMainWindow::onDrawBordersChanged(bool _checked)
{ {
::profiler_gui::EASY_GLOBALS.draw_graphics_items_borders = _checked; EASY_GLOBALS.draw_graphics_items_borders = _checked;
emit ::profiler_gui::EASY_GLOBALS.events.drawBordersChanged(); emit EASY_GLOBALS.events.drawBordersChanged();
} }
void EasyMainWindow::onCollapseItemsAfterCloseChanged(bool _checked) 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) 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) 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) void EasyMainWindow::onExpandAllClicked(bool)
{ {
for (auto& block : ::profiler_gui::EASY_GLOBALS.gui_blocks) for (auto& block : EASY_GLOBALS.gui_blocks)
block.expanded = true; block.expanded = true;
emit ::profiler_gui::EASY_GLOBALS.events.itemsExpandStateChanged(); emit EASY_GLOBALS.events.itemsExpandStateChanged();
auto tree = static_cast<EasyTreeWidget*>(m_treeWidget->widget()); auto tree = static_cast<EasyTreeWidget*>(m_treeWidget->widget());
const QSignalBlocker b(tree); const QSignalBlocker b(tree);
@ -291,10 +291,10 @@ void EasyMainWindow::onExpandAllClicked(bool)
void EasyMainWindow::onCollapseAllClicked(bool) void EasyMainWindow::onCollapseAllClicked(bool)
{ {
for (auto& block : ::profiler_gui::EASY_GLOBALS.gui_blocks) for (auto& block : EASY_GLOBALS.gui_blocks)
block.expanded = false; block.expanded = false;
emit ::profiler_gui::EASY_GLOBALS.events.itemsExpandStateChanged(); emit EASY_GLOBALS.events.itemsExpandStateChanged();
auto tree = static_cast<EasyTreeWidget*>(m_treeWidget->widget()); auto tree = static_cast<EasyTreeWidget*>(m_treeWidget->widget());
const QSignalBlocker b(tree); const QSignalBlocker b(tree);
@ -326,32 +326,32 @@ void EasyMainWindow::loadSettings()
auto val = settings.value("chrono_text_position"); auto val = settings.value("chrono_text_position");
if (!val.isNull()) 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"); auto flag = settings.value("draw_graphics_items_borders");
if (!flag.isNull()) 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"); flag = settings.value("collapse_items_on_tree_close");
if (!flag.isNull()) 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"); flag = settings.value("all_items_expanded_by_default");
if (!flag.isNull()) 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"); flag = settings.value("bind_scene_and_tree_expand_status");
if (!flag.isNull()) 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(); QString encoding = settings.value("encoding", "UTF-8").toString();
@ -379,11 +379,11 @@ void EasyMainWindow::saveSettingsAndGeometry()
settings.setValue("geometry", this->saveGeometry()); settings.setValue("geometry", this->saveGeometry());
settings.setValue("last_file", m_lastFile); settings.setValue("last_file", m_lastFile);
settings.setValue("chrono_text_position", static_cast<int>(::profiler_gui::EASY_GLOBALS.chrono_text_position)); settings.setValue("chrono_text_position", static_cast<int>(EASY_GLOBALS.chrono_text_position));
settings.setValue("draw_graphics_items_borders", ::profiler_gui::EASY_GLOBALS.draw_graphics_items_borders); settings.setValue("draw_graphics_items_borders", EASY_GLOBALS.draw_graphics_items_borders);
settings.setValue("collapse_items_on_tree_close", ::profiler_gui::EASY_GLOBALS.collapse_items_on_tree_close); settings.setValue("collapse_items_on_tree_close", 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("all_items_expanded_by_default", 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("bind_scene_and_tree_expand_status", EASY_GLOBALS.bind_scene_and_tree_expand_status);
settings.setValue("encoding", QTextCodec::codecForLocale()->name()); settings.setValue("encoding", QTextCodec::codecForLocale()->name());
settings.endGroup(); settings.endGroup();
@ -402,28 +402,34 @@ void EasyMainWindow::onFileReaderTimeout()
::profiler::SerializedData serialized_blocks, serialized_descriptors; ::profiler::SerializedData serialized_blocks, serialized_descriptors;
::profiler::descriptors_list_t 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; 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."; qWarning() << "Warning: Currently, maximum number of displayed threads is 255! Some threads will not be displayed.";
} }
m_lastFile = ::std::move(filename); m_lastFile = ::std::move(filename);
m_serializedBlocks = ::std::move(serialized_blocks); m_serializedBlocks = ::std::move(serialized_blocks);
m_serializedDescriptors = ::std::move(serialized_descriptors); m_serializedDescriptors = ::std::move(serialized_descriptors);
::profiler_gui::EASY_GLOBALS.selected_thread = 0; EASY_GLOBALS.selected_thread = 0;
::profiler_gui::set_max(::profiler_gui::EASY_GLOBALS.selected_block); ::profiler_gui::set_max(EASY_GLOBALS.selected_block);
::profiler_gui::EASY_GLOBALS.profiler_blocks.swap(prof_blocks); EASY_GLOBALS.profiler_blocks.swap(threads_map);
::profiler_gui::EASY_GLOBALS.descriptors.swap(descriptors); 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);
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 else
{ {
@ -436,7 +442,7 @@ void EasyMainWindow::onFileReaderTimeout()
m_progress->setValue(100); m_progress->setValue(100);
//m_progress->hide(); //m_progress->hide();
if (::profiler_gui::EASY_GLOBALS.all_items_expanded_by_default) if (EASY_GLOBALS.all_items_expanded_by_default)
{ {
onExpandAllClicked(true); onExpandAllClicked(true);
} }
@ -493,7 +499,7 @@ void EasyFileReader::load(const QString& _filename)
m_filename = _filename; m_filename = _filename;
m_thread = ::std::move(::std::thread([this]() { 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_progress.store(100);
m_bDone.store(true); m_bDone.store(true);
})); }));
@ -511,17 +517,20 @@ void EasyFileReader::interrupt()
m_serializedBlocks.clear(); m_serializedBlocks.clear();
m_serializedDescriptors.clear(); m_serializedDescriptors.clear();
m_descriptors.clear(); m_descriptors.clear();
m_blocks.clear();
m_blocksTree.clear(); m_blocksTree.clear();
} }
void EasyFileReader::get(::profiler::SerializedData& _serializedBlocks, ::profiler::SerializedData& _serializedDescriptors, 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()) if (done())
{ {
m_serializedBlocks.swap(_serializedBlocks); m_serializedBlocks.swap(_serializedBlocks);
m_serializedDescriptors.swap(_serializedDescriptors); 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_blocksTree.swap(_tree);
m_filename.swap(_filename); m_filename.swap(_filename);
} }

View File

@ -35,6 +35,7 @@ class EasyFileReader final
::profiler::SerializedData m_serializedBlocks; ///< ::profiler::SerializedData m_serializedBlocks; ///<
::profiler::SerializedData m_serializedDescriptors; ///< ::profiler::SerializedData m_serializedDescriptors; ///<
::profiler::descriptors_list_t m_descriptors; ///< ::profiler::descriptors_list_t m_descriptors; ///<
::profiler::blocks_t m_blocks; ///<
::profiler::thread_blocks_tree_t m_blocksTree; ///< ::profiler::thread_blocks_tree_t m_blocksTree; ///<
QString m_filename; ///< QString m_filename; ///<
::std::thread m_thread; ///< ::std::thread m_thread; ///<
@ -55,7 +56,8 @@ public:
void load(const QString& _filename); void load(const QString& _filename);
void interrupt(); void interrupt();
void get(::profiler::SerializedData& _serializedBlocks, ::profiler::SerializedData& _serializedDescriptors, 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. }; // END of class EasyFileReader.

View File

@ -21,7 +21,7 @@
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
EasyTreeWidgetItem::EasyTreeWidgetItem(const ::profiler::BlocksTree* _treeBlock, Parent* _parent) EasyTreeWidgetItem::EasyTreeWidgetItem(const ::profiler::block_index_t _treeBlock, Parent* _parent)
: Parent(_parent) : Parent(_parent)
, m_block(_treeBlock) , m_block(_treeBlock)
, m_customBGColor(0) , m_customBGColor(0)
@ -75,15 +75,25 @@ bool EasyTreeWidgetItem::operator < (const Parent& _other) const
return false; return false;
} }
const ::profiler::BlocksTree* EasyTreeWidgetItem::block() const ::profiler::block_index_t EasyTreeWidgetItem::block_index() const
{ {
return m_block; 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 ::profiler::timestamp_t EasyTreeWidgetItem::duration() const
{ {
if (m_block->node) if (parent() != nullptr)
return m_block->node->duration(); return block().node->duration();
return data(COL_DURATION, Qt::UserRole).toULongLong(); return data(COL_DURATION, Qt::UserRole).toULongLong();
} }
@ -173,7 +183,8 @@ void EasyTreeWidgetItem::collapseAll()
} }
setExpanded(false); setExpanded(false);
::profiler_gui::EASY_GLOBALS.gui_blocks[m_block->block_index].expanded = false; if (parent() != nullptr)
guiBlock().expanded = false;
} }
void EasyTreeWidgetItem::expandAll() void EasyTreeWidgetItem::expandAll()
@ -184,7 +195,8 @@ void EasyTreeWidgetItem::expandAll()
} }
setExpanded(true); setExpanded(true);
::profiler_gui::EASY_GLOBALS.gui_blocks[m_block->block_index].expanded = true; if (parent() != nullptr)
guiBlock().expanded = true;
} }
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////

View File

@ -75,7 +75,7 @@ class EasyTreeWidgetItem : public QTreeWidgetItem
typedef QTreeWidgetItem Parent; typedef QTreeWidgetItem Parent;
typedef EasyTreeWidgetItem This; typedef EasyTreeWidgetItem This;
const ::profiler::BlocksTree* m_block; const ::profiler::block_index_t m_block;
QRgb m_customBGColor; QRgb m_customBGColor;
QRgb m_customTextColor; QRgb m_customTextColor;
@ -84,14 +84,16 @@ public:
using Parent::setBackgroundColor; using Parent::setBackgroundColor;
using Parent::setTextColor; 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(); virtual ~EasyTreeWidgetItem();
bool operator < (const Parent& _other) const override; bool operator < (const Parent& _other) const override;
public: 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 duration() const;
::profiler::timestamp_t selfDuration() const; ::profiler::timestamp_t selfDuration() const;

View File

@ -126,7 +126,7 @@ void FillTreeClass<T>::setTreeInternal1(T& _safelocker, Items& _items, ThreadedI
::profiler::timestamp_t finishtime = 0; ::profiler::timestamp_t finishtime = 0;
for (const auto& threadTree : _blocksTree) 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 startTime = node_block->begin();
const auto endTime = node_block->end(); const auto endTime = node_block->end();
@ -145,49 +145,49 @@ void FillTreeClass<T>::setTreeInternal1(T& _safelocker, Items& _items, ThreadedI
if (_safelocker.interrupted()) if (_safelocker.interrupted())
break; break;
auto& block = threadTree.second.tree; const auto& root = threadTree.second;
auto item = new EasyTreeWidgetItem(&block); 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 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; ::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->setTimeSmart(COL_DURATION, duration);
item->setBackgroundColor(::profiler_gui::SELECTED_THREAD_BACKGROUND); item->setBackgroundColor(::profiler_gui::SELECTED_THREAD_BACKGROUND);
item->setTextColor(::profiler_gui::SELECTED_THREAD_FOREGROUND); 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) // TODO: Optimize children duration calculation (it must be calculated before setTreeInternal now)
::profiler::timestamp_t children_duration = 0; ::profiler::timestamp_t children_duration = 0;
for (const auto& child : block.children) for (auto i : root.children)
children_duration += child.node->duration(); children_duration += blocksTree(i).node->duration();
item->setTimeSmart(COL_SELF_DURATION, children_duration); item->setTimeSmart(COL_SELF_DURATION, children_duration);
children_duration = 0; 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) if (children_items_number > 0)
{ {
//total_items += children_items_number + 1; //total_items += children_items_number + 1;
//addTopLevelItem(item); //addTopLevelItem(item);
//m_roots[threadTree.first] = item; //m_roots[threadTree.first] = item;
_topLevelItems.emplace_back(threadTree.first, item); _topLevelItems.emplace_back(root.thread_id, item);
} }
else else
{ {
_items.pop_back(); //_items.pop_back();
delete item; 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(); auto children_number = _tree.children.size();
for (const auto& child : _tree->children) for (auto i : _tree.children)
children_number += calculateTotalChildrenNumber(&child); children_number += calculateTotalChildrenNumber(blocksTree(i));
return children_number; return children_number;
} }
@ -213,7 +213,7 @@ void FillTreeClass<T>::setTreeInternal2(T& _safelocker, Items& _items, ThreadedI
{ {
//size_t blocksNumber = 0; //size_t blocksNumber = 0;
//for (const auto& block : _blocks) //for (const auto& block : _blocks)
// blocksNumber += calculateTotalChildrenNumber(block.tree); // blocksNumber += calculateTotalChildrenNumber(*block.tree);
// //blocksNumber += block.tree->total_children_number; // //blocksNumber += block.tree->total_children_number;
//m_items.reserve(blocksNumber + _blocks.size()); // blocksNumber does not include root blocks //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()) if (_safelocker.interrupted())
break; break;
const auto startTime = block.tree->node->begin(); auto& gui_block = easyBlock(block.tree);
const auto endTime = block.tree->node->end(); const auto startTime = gui_block.tree.node->begin();
const auto endTime = gui_block.tree.node->end();
if (startTime > _right || endTime < _left) if (startTime > _right || endTime < _left)
{ {
_safelocker.setProgress((90 * ++i) / total); _safelocker.setProgress((90 * ++i) / total);
@ -243,7 +244,7 @@ void FillTreeClass<T>::setTreeInternal2(T& _safelocker, Items& _items, ThreadedI
} }
else else
{ {
thread_item = new EasyTreeWidgetItem(&block.root->tree); thread_item = new EasyTreeWidgetItem();
if (block.root->thread_name && block.root->thread_name[0] != 0) 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)); 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); 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) // Calculate clean duration (sum of all children durations)
::profiler::timestamp_t children_duration = 0; ::profiler::timestamp_t children_duration = 0;
for (const auto& child : block.root->tree.children) for (auto i : block.root->children)
children_duration += child.node->duration(); children_duration += blocksTree(i).node->duration();
thread_item->setTimeSmart(COL_SELF_DURATION, children_duration); thread_item->setTimeSmart(COL_SELF_DURATION, children_duration);
threadsMap.insert(::std::make_pair(block.root->thread_id, thread_item)); 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); auto item = new EasyTreeWidgetItem(block.tree, thread_item);
duration = endTime - startTime; 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->setText(COL_NAME, ::profiler_gui::toUnicode(name));
item->setTimeSmart(COL_DURATION, duration); item->setTimeSmart(COL_DURATION, duration);
item->setTimeMs(COL_BEGIN, startTime - _beginTime); 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->setData(COL_PERCENT_PER_FRAME, Qt::UserRole, 0);
item->setText(COL_PERCENT_PER_FRAME, ""); 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_thread_stats = gui_block.tree.per_thread_stats;
const auto& per_parent_stats = block.tree->per_parent_stats; const auto& per_parent_stats = gui_block.tree.per_parent_stats;
const auto& per_frame_stats = block.tree->per_frame_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_MIN_PER_THREAD, per_thread_stats->min_duration, "min ");
item->setTimeSmart(COL_MAX_PER_THREAD, per_thread_stats->max_duration, "max "); 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)); 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_MIN_PER_PARENT, per_parent_stats->min_duration, "min ");
item->setTimeSmart(COL_MAX_PER_PARENT, per_parent_stats->max_duration, "max "); 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)); 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_MIN_PER_FRAME, per_frame_stats->min_duration, "min ");
item->setTimeSmart(COL_MAX_PER_FRAME, per_frame_stats->max_duration, "max "); 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, ""); 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 bgColor = ::profiler_gui::fromProfilerRgb(::profiler::colors::get_red(color), ::profiler::colors::get_green(color), ::profiler::colors::get_blue(color));
const auto fgColor = 0x00ffffff - bgColor; const auto fgColor = 0x00ffffff - bgColor;
item->setBackgroundColor(bgColor); item->setBackgroundColor(bgColor);
@ -350,9 +351,9 @@ void FillTreeClass<T>::setTreeInternal2(T& _safelocker, Items& _items, ThreadedI
size_t children_items_number = 0; size_t children_items_number = 0;
::profiler::timestamp_t children_duration = 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()) if (_safelocker.interrupted())
break; break;
} }
@ -371,12 +372,12 @@ void FillTreeClass<T>::setTreeInternal2(T& _safelocker, Items& _items, ThreadedI
if (children_items_number > 0 || !_strict || (startTime >= _left && endTime <= _right)) if (children_items_number > 0 || !_strict || (startTime >= _left && endTime <= _right))
{ {
//total_items += children_items_number + 1; //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) if (_colorizeRows)
item->colorize(_colorizeRows); item->colorize(_colorizeRows);
if (::profiler_gui::EASY_GLOBALS.gui_blocks[block.tree->block_index].expanded) if (gui_block.expanded)
item->setExpanded(true); item->setExpanded(true);
} }
@ -400,7 +401,7 @@ void FillTreeClass<T>::setTreeInternal2(T& _safelocker, Items& _items, ThreadedI
//addTopLevelItem(item); //addTopLevelItem(item);
//m_roots[it.first] = item; //m_roots[it.first] = item;
_items.push_back(item); //_items.push_back(item);
_topLevelItems.emplace_back(it.first, item); _topLevelItems.emplace_back(it.first, item);
//++total_items; //++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 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; size_t total_items = 0;
for (const auto& child : _children) for (auto child_index : _children)
{ {
if (_safelocker.interrupted()) if (_safelocker.interrupted())
break; break;
auto& gui_block = easyBlock(child_index);
const auto& child = gui_block.tree;
const auto startTime = child.node->begin(); const auto startTime = child.node->begin();
const auto endTime = child.node->end(); const auto endTime = child.node->end();
const auto duration = endTime - startTime; const auto duration = endTime - startTime;
@ -436,9 +439,9 @@ size_t FillTreeClass<T>::setTreeInternal(T& _safelocker, Items& _items, const ::
continue; 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->setText(COL_NAME, ::profiler_gui::toUnicode(name));
item->setTimeSmart(COL_DURATION, duration); item->setTimeSmart(COL_DURATION, duration);
item->setTimeMs(COL_BEGIN, startTime - _beginTime); 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_MIN_PER_THREAD, per_thread_stats->min_duration, "min ");
item->setTimeSmart(COL_MAX_PER_THREAD, per_thread_stats->max_duration, "max "); 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_MIN_PER_PARENT, per_parent_stats->min_duration, "min ");
item->setTimeSmart(COL_MAX_PER_PARENT, per_parent_stats->max_duration, "max "); 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)); 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_MIN_PER_FRAME, per_frame_stats->min_duration, "min ");
item->setTimeSmart(COL_MAX_PER_FRAME, per_frame_stats->max_duration, "max "); 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, ""); 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 bgColor = ::profiler_gui::fromProfilerRgb(::profiler::colors::get_red(color), ::profiler::colors::get_green(color), ::profiler::colors::get_blue(color));
const auto fgColor = 0x00ffffff - bgColor; const auto fgColor = 0x00ffffff - bgColor;
item->setBackgroundColor(bgColor); item->setBackgroundColor(bgColor);
item->setTextColor(fgColor); 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); _items.push_back(item);
size_t children_items_number = 0; 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)) if (children_items_number > 0 || !_strict || (startTime >= _left && endTime <= _right))
{ {
total_items += children_items_number + 1; 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) if (_colorizeRows)
item->colorize(_colorizeRows); item->colorize(_colorizeRows);
if (::profiler_gui::EASY_GLOBALS.gui_blocks[child.block_index].expanded) if (gui_block.expanded)
item->setExpanded(true); item->setExpanded(true);
} }
else else

View File

@ -112,7 +112,8 @@ int main(int argc, char* argv[])
::profiler::SerializedData serialized_blocks, serialized_descriptors; ::profiler::SerializedData serialized_blocks, serialized_descriptors;
::profiler::descriptors_list_t 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(); auto end = std::chrono::system_clock::now();

View File

@ -198,7 +198,7 @@ typedef ::std::unordered_map<::std::string, ::profiler::block_id_t> IdMap;
automatically receive statistics update. 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(); auto duration = _current.node->duration();
//StatsMap::key_type key(_current.node->name()); //StatsMap::key_type key(_current.node->name());
@ -216,14 +216,14 @@ automatically receive statistics update.
if (duration > stats->max_duration) if (duration > stats->max_duration)
{ {
// update max duration // update max duration
stats->max_duration_block = _current.block_index; stats->max_duration_block = _current_index;
stats->max_duration = duration; stats->max_duration = duration;
} }
if (duration < stats->min_duration) if (duration < stats->min_duration)
{ {
// update min duraton // update min duraton
stats->min_duration_block = _current.block_index; stats->min_duration_block = _current_index;
stats->min_duration = duration; stats->min_duration = duration;
} }
@ -234,7 +234,7 @@ automatically receive statistics update.
// This is first time the block appear in the file. // This is first time the block appear in the file.
// Create new statistics. // 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(key, stats);
_stats_map.emplace(_current.node->id(), 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); _current.per_frame_stats = update_statistics(_stats_map, _current, _current_index);
for (auto& child : _current.children) 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) if (!inFile.is_open())
{ return 0;
EASY_FUNCTION(::profiler::colors::Cyan);
::std::ifstream inFile(filename, ::std::fstream::binary); uint32_t total_blocks_number = 0;
progress.store(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; return 0;
PerThreadStats thread_statistics, parent_statistics, frame_statistics; //if (i + sz > descriptors_memory_size)
unsigned int blocks_counter = 0; //{
// printf("FILE CORRUPTED\n");
// return 0;
//}
uint32_t total_blocks_number = 0; char* data = serialized_descriptors[i];
inFile.read((char*)&total_blocks_number, sizeof(decltype(total_blocks_number))); inFile.read(data, sz);
if (total_blocks_number == 0) auto descriptor = reinterpret_cast<::profiler::SerializedBlockDescriptor*>(data);
return 0; descriptors.push_back(descriptor);
uint64_t memory_size = 0; i += sz;
inFile.read((char*)&memory_size, sizeof(decltype(memory_size))); progress.store(static_cast<int>(10 * i / descriptors_memory_size));
if (memory_size == 0) }
return 0;
serialized_blocks.set(new char[memory_size]); typedef ::std::map<::profiler::thread_id_t, StatsMap> PerThreadStats;
//memset(serialized_blocks[0], 0, memory_size); 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; ::profiler::thread_id_t thread_id = 0;
inFile.read((char*)&total_descriptors_number, sizeof(decltype(total_descriptors_number))); inFile.read((char*)&thread_id, sizeof(decltype(thread_id)));
if (total_descriptors_number == 0)
return 0;
uint64_t descriptors_memory_size = 0; uint32_t blocks_number_in_thread = 0;
inFile.read((char*)&descriptors_memory_size, sizeof(decltype(descriptors_memory_size))); inFile.read((char*)&blocks_number_in_thread, sizeof(decltype(blocks_number_in_thread)));
if (descriptors_memory_size == 0)
return 0;
descriptors.reserve(total_descriptors_number); auto& root = threaded_trees[thread_id];
serialized_descriptors.set(new char[descriptors_memory_size]); const auto threshold = read_number + blocks_number_in_thread;
while (!inFile.eof() && read_number < threshold)
uint64_t i = 0;
while (!inFile.eof() && descriptors.size() < total_descriptors_number)
{ {
EASY_BLOCK("Read block", ::profiler::colors::Green);
++read_number;
uint16_t sz = 0; uint16_t sz = 0;
inFile.read((char*)&sz, sizeof(sz)); inFile.read((char*)&sz, sizeof(sz));
if (sz == 0) if (sz == 0)
return 0; return 0;
//if (i + sz > descriptors_memory_size) char* data = serialized_blocks[i];
//{
// printf("FILE CORRUPTED\n");
// return 0;
//}
char* data = serialized_descriptors[i];
inFile.read(data, sz); inFile.read(data, sz);
auto descriptor = reinterpret_cast<::profiler::SerializedBlockDescriptor*>(data);
descriptors.push_back(descriptor);
i += sz; 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; auto& per_parent_statistics = parent_statistics[thread_id];
uint32_t read_number = 0; auto& per_thread_statistics = thread_statistics[thread_id];
while (!inFile.eof() && read_number < total_blocks_number) auto descriptor = descriptors[baseData->id()];
{
EASY_BLOCK("Read thread data", ::profiler::colors::Darkgreen);
::profiler::thread_id_t thread_id = 0; if (descriptor->type() == ::profiler::BLOCK_TYPE_THREAD_SIGN)
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)
{ {
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; IdMap::key_type key(tree.node->name());
inFile.read((char*)&sz, sizeof(sz)); auto it = identification_table.find(key);
if (sz == 0) if (it != identification_table.end())
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)
{ {
root.thread_name = tree.node->name(); // There is already block with such name, use it's id
baseData->setId(it->second);
} }
else
if (*tree.node->name() != 0)
{ {
IdMap::key_type key(tree.node->name()); // There were no blocks with such name, generate new id and save it in the table for further usage.
auto it = identification_table.find(key); auto id = static_cast<::profiler::block_id_t>(descriptors.size());
if (it != identification_table.end()) 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 else
{ {
auto id = static_cast<::profiler::block_id_t>(descriptors.size()); for (auto i : tree.children)
identification_table.emplace(key, id); {
descriptors.push_back(descriptors[baseData->id()]); const auto& child = _blocks[i];
baseData->setId(id); 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(); auto& root = it.second;
threaded_trees.clear(); root.thread_id = it.first;
return 0; //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); int j = 0, n = static_cast<int>(statistics_threads.size());
if (gather_statistics) for (auto& t : statistics_threads)
{
::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>(threaded_trees.size()); t.join();
for (auto& it : threaded_trees) progress.store(90 + (10 * ++j) / n);
{
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);
}
} }
// 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;
} }