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

(GUI) Less buggy and more efficient recursive painting algorithm for blocks at diagram. Test mode.

Note: with recursive algorithm it is possible to iterate through blocks in parallel to make painting just more efficient - this is my future todo
This commit is contained in:
Victor Zarubkin 2016-12-27 22:07:44 +03:00
parent 5a14887ec8
commit bf7bf10b80
5 changed files with 516 additions and 160 deletions

View File

@ -479,7 +479,8 @@ void EasyGraphicsView::setTree(const ::profiler::thread_blocks_tree_t& _blocksTr
if (!t.children.empty())
{
children_duration = setTree(item, t.children, h, y, 0);
uint32_t dummy = 0;
children_duration = setTree(item, t.children, h, dummy, y, 0);
}
else
{
@ -551,7 +552,7 @@ const EasyGraphicsView::Items &EasyGraphicsView::getItems() const
return m_items;
}
qreal EasyGraphicsView::setTree(EasyGraphicsItem* _item, const ::profiler::BlocksTree::children_t& _children, qreal& _height, qreal _y, short _level)
qreal EasyGraphicsView::setTree(EasyGraphicsItem* _item, const ::profiler::BlocksTree::children_t& _children, qreal& _height, uint32_t& _maxDepthChild, qreal _y, short _level)
{
if (_children.empty())
{
@ -562,6 +563,8 @@ qreal EasyGraphicsView::setTree(EasyGraphicsItem* _item, const ::profiler::Block
const auto n = static_cast<unsigned int>(_children.size());
_item->reserve(level, n);
_maxDepthChild = 0;
uint16_t maxDepth = 0;
const short next_level = _level + 1;
bool warned = false;
qreal total_duration = 0, prev_end = 0, maxh = 0;
@ -571,6 +574,11 @@ qreal EasyGraphicsView::setTree(EasyGraphicsItem* _item, const ::profiler::Block
{
auto& gui_block = easyBlock(child_index);
const auto& child = gui_block.tree;
if (child.depth > maxDepth)
{
maxDepth = child.depth;
_maxDepthChild = j;
}
auto xbegin = time2position(child.node->begin());
if (start_time < 0)
@ -609,10 +617,11 @@ qreal EasyGraphicsView::setTree(EasyGraphicsItem* _item, const ::profiler::Block
qreal h = 0;
qreal children_duration = 0;
uint32_t maxDepthChild = 0;
if (next_level < 256)
{
children_duration = setTree(_item, child.children, h, _y + ::profiler_gui::GRAPHICS_ROW_SIZE_FULL, next_level);
children_duration = setTree(_item, child.children, h, maxDepthChild, _y + ::profiler_gui::GRAPHICS_ROW_SIZE_FULL, next_level);
}
else if (!child.children.empty() && !warned)
{
@ -631,10 +640,16 @@ qreal EasyGraphicsView::setTree(EasyGraphicsItem* _item, const ::profiler::Block
}
b.block = child_index;// &child;
#ifndef EASY_GRAPHICS_ITEM_RECURSIVE_PAINT
b.neighbours = n;
b.state = j > 0 || level == 0 ? 0 : -1;
#else
b.max_depth_child = maxDepthChild;
#endif
b.setPos(xbegin, duration);
//b.totalHeight = ::profiler_gui::GRAPHICS_ROW_SIZE + h;
b.state = j > 0 || level == 0 ? 0 : -1;
prev_end = xbegin + duration;
total_duration = prev_end - start_time;

View File

@ -193,7 +193,7 @@ private:
void scaleTo(qreal _scale);
void scrollTo(const EasyGraphicsItem* _item);
void onWheel(qreal _mouseX, int _wheelDelta);
qreal setTree(EasyGraphicsItem* _item, const ::profiler::BlocksTree::children_t& _children, qreal& _height, qreal _y, short _level);
qreal setTree(EasyGraphicsItem* _item, const ::profiler::BlocksTree::children_t& _children, qreal& _height, uint32_t& _maxDepthChild, qreal _y, short _level);
private slots:

View File

@ -152,15 +152,24 @@ inline ::profiler::color_t textColorForRgb(::profiler::color_t _color)
//////////////////////////////////////////////////////////////////////////
#define EASY_GRAPHICS_ITEM_RECURSIVE_PAINT
//#undef EASY_GRAPHICS_ITEM_RECURSIVE_PAINT
#pragma pack(push, 1)
struct EasyBlockItem Q_DECL_FINAL
{
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
::profiler::block_index_t block; ///< Index of profiler block
#ifndef EASY_GRAPHICS_ITEM_RECURSIVE_PAINT
::profiler::block_index_t neighbours; ///< Number of neighbours (parent.children.size())
uint32_t children_begin; ///< Index of first child item on the next sublevel
int8_t state; ///< 0 = no change, 1 = paint, -1 = do not paint
#else
::profiler::block_index_t max_depth_child; ///< Index of child with maximum tree depth
uint32_t children_begin; ///< Index of first child item on the next sublevel
#endif
// Possible optimizations:
// 1) We can save 1 more byte per block if we will use char instead of short + real time calculations for "totalHeight" var;

File diff suppressed because it is too large Load Diff

View File

@ -61,10 +61,12 @@ class EasyGraphicsView;
class EasyGraphicsItem : public QGraphicsItem
{
typedef ::profiler_gui::EasyItems Children;
typedef ::std::vector<unsigned int> DrawIndexes;
typedef ::std::vector<uint32_t> DrawIndexes;
typedef ::std::vector<qreal> RightBounds;
typedef ::std::vector<Children> Sublevels;
DrawIndexes m_levelsIndexes; ///< Indexes of first item on each level from which we must start painting
RightBounds m_rightBounds; ///<
Sublevels m_levels; ///< Arrays of items for each level
QRectF m_boundingRect; ///< boundingRect (see QGraphicsItem)
@ -158,6 +160,10 @@ private:
///< Returns pointer to the EasyGraphicsView widget.
const EasyGraphicsView* view() const;
#ifdef EASY_GRAPHICS_ITEM_RECURSIVE_PAINT
void paintChildren(const float _minWidth, const int _narrowSizeHalf, const uint8_t _levelsNumber, QPainter* _painter, struct EasyPainterInformation& p, ::profiler_gui::EasyBlockItem& _item, const ::profiler_gui::EasyBlock& _itemBlock, RightBounds& _rightBounds, uint8_t _level, int8_t _mode);
#endif
public:
// Public inline methods