mirror of
https://github.com/yse/easy_profiler.git
synced 2025-01-14 00:27:55 +08:00
(GraphicsView) More effective memory consumption
This commit is contained in:
parent
5ca4158abf
commit
fa270ea3f2
@ -18,6 +18,8 @@
|
||||
* :
|
||||
* : * 2016/06/29 Victor Zarubkin: Highly optimized painting performance and memory consumption.
|
||||
* :
|
||||
* : * 2016/06/30 Victor Zarubkin: Replaced doubles with floats (in ProfBlockItem) for less memory consumption.
|
||||
* :
|
||||
* : *
|
||||
* ----------------- :
|
||||
* license : TODO: add license text
|
||||
@ -38,6 +40,66 @@ const qreal ROW_SPACING = 10;
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifdef PROF_BLOCK_ITEM_OPT_MEMORY
|
||||
void ProfBlockItem::setRect(preal _x, preal _y, preal _w, preal _h) {
|
||||
x = _x; y = _y; w = _w; h = _h;
|
||||
}
|
||||
|
||||
preal ProfBlockItem::left() const {
|
||||
return x;
|
||||
}
|
||||
|
||||
preal ProfBlockItem::top() const {
|
||||
return y;
|
||||
}
|
||||
|
||||
preal ProfBlockItem::width() const {
|
||||
return w;
|
||||
}
|
||||
|
||||
preal ProfBlockItem::height() const {
|
||||
return h;
|
||||
}
|
||||
|
||||
preal ProfBlockItem::right() const {
|
||||
return x + w;
|
||||
}
|
||||
|
||||
preal ProfBlockItem::bottom() const {
|
||||
return y + h;
|
||||
}
|
||||
#else
|
||||
void ProfBlockItem::setRect(preal _x, preal _y, preal _w, preal _h) {
|
||||
rect.setRect(_x, _y, _w, _h);
|
||||
}
|
||||
|
||||
preal ProfBlockItem::left() const {
|
||||
return rect.left();
|
||||
}
|
||||
|
||||
preal ProfBlockItem::top() const {
|
||||
return rect.top();
|
||||
}
|
||||
|
||||
preal ProfBlockItem::width() const {
|
||||
return rect.width();
|
||||
}
|
||||
|
||||
preal ProfBlockItem::height() const {
|
||||
return rect.height();
|
||||
}
|
||||
|
||||
preal ProfBlockItem::right() const {
|
||||
return rect.right();
|
||||
}
|
||||
|
||||
preal ProfBlockItem::bottom() const {
|
||||
return rect.bottom();
|
||||
}
|
||||
#endif
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ProfGraphicsItem::ProfGraphicsItem() : QGraphicsItem(nullptr), m_bTest(false)
|
||||
{
|
||||
}
|
||||
@ -92,7 +154,7 @@ void ProfGraphicsItem::paint(QPainter* _painter, const QStyleOptionGraphicsItem*
|
||||
QRgb previousColor = 0;
|
||||
for (auto& item : m_items)
|
||||
{
|
||||
item.draw = !(item.rect.left() > sceneRight || item.rect.right() < sceneLeft);
|
||||
item.draw = !(item.left() > sceneRight || item.right() < sceneLeft);
|
||||
if (!item.draw)
|
||||
{
|
||||
// this item is fully out of scene visible rect
|
||||
@ -106,7 +168,12 @@ void ProfGraphicsItem::paint(QPainter* _painter, const QStyleOptionGraphicsItem*
|
||||
_painter->setBrush(brush);
|
||||
}
|
||||
|
||||
#ifdef PROF_BLOCK_ITEM_OPT_MEMORY
|
||||
rect.setRect(item.x, item.y, item.w, item.h);
|
||||
_painter->drawRect(rect);
|
||||
#else
|
||||
_painter->drawRect(item.rect);
|
||||
#endif
|
||||
}
|
||||
|
||||
_painter->setPen(Qt::SolidLine);
|
||||
@ -119,11 +186,11 @@ void ProfGraphicsItem::paint(QPainter* _painter, const QStyleOptionGraphicsItem*
|
||||
if (!item.draw)
|
||||
continue;
|
||||
|
||||
auto w = item.rect.width() * currentScale;
|
||||
auto w = item.width() * currentScale;
|
||||
if (w < 20)
|
||||
continue;
|
||||
|
||||
rect.setRect(item.rect.left() * currentScale, item.rect.top(), w, item.rect.height());
|
||||
rect.setRect(item.left() * currentScale, item.top(), w, item.height());
|
||||
|
||||
_painter->drawText(rect, 0, "NOT VERY LONG TEST TEXT");
|
||||
}
|
||||
@ -136,11 +203,11 @@ void ProfGraphicsItem::paint(QPainter* _painter, const QStyleOptionGraphicsItem*
|
||||
if (!item.draw)
|
||||
continue;
|
||||
|
||||
auto w = item.rect.width() * currentScale;
|
||||
auto w = item.width() * currentScale;
|
||||
if (w < 20)
|
||||
continue;
|
||||
|
||||
rect.setRect(item.rect.left() * currentScale, item.rect.top(), w, item.rect.height());
|
||||
rect.setRect(item.left() * currentScale, item.top(), w, item.height());
|
||||
|
||||
if (previousColor != item.color)
|
||||
{
|
||||
@ -194,44 +261,83 @@ void ProfGraphicsItem::setBoundingRect(const QRectF& _rect)
|
||||
m_rect = _rect;
|
||||
}
|
||||
|
||||
|
||||
void ProfGraphicsItem::reserve(unsigned int _items)
|
||||
{
|
||||
m_items.reserve(_items);
|
||||
}
|
||||
|
||||
const ProfGraphicsItem::Children& ProfGraphicsItem::items() const
|
||||
{
|
||||
return m_items;
|
||||
}
|
||||
|
||||
const ProfBlockItem& ProfGraphicsItem::getItem(size_t _index) const
|
||||
{
|
||||
return m_items[_index];
|
||||
}
|
||||
|
||||
ProfBlockItem& ProfGraphicsItem::getItem(size_t _index)
|
||||
{
|
||||
return m_items[_index];
|
||||
}
|
||||
|
||||
size_t ProfGraphicsItem::addItem()
|
||||
{
|
||||
m_items.emplace_back();
|
||||
return m_items.size() - 1;
|
||||
}
|
||||
|
||||
size_t ProfGraphicsItem::addItem(const ProfBlockItem& _item)
|
||||
{
|
||||
m_items.emplace_back(_item);
|
||||
return m_items.size() - 1;
|
||||
}
|
||||
|
||||
size_t ProfGraphicsItem::addItem(ProfBlockItem&& _item)
|
||||
{
|
||||
m_items.emplace_back(::std::forward<ProfBlockItem&&>(_item));
|
||||
return m_items.size() - 1;
|
||||
}
|
||||
|
||||
|
||||
// void ProfGraphicsItem::setLevels(unsigned int _levels)
|
||||
// {
|
||||
// m_levels.resize(_levels);
|
||||
// }
|
||||
//
|
||||
// void ProfGraphicsItem::reserve(unsigned short _level, unsigned int _items)
|
||||
// {
|
||||
// m_levels[_level].reserve(_items);
|
||||
// }
|
||||
//
|
||||
// const ProfGraphicsItem::Children& ProfGraphicsItem::items(unsigned short _level) const
|
||||
// {
|
||||
// return m_levels[_level];
|
||||
// }
|
||||
//
|
||||
// const ProfBlockItem& ProfGraphicsItem::getItem(unsigned short _level, size_t _index) const
|
||||
// {
|
||||
// return m_levels[_level][_index];
|
||||
// }
|
||||
//
|
||||
// ProfBlockItem& ProfGraphicsItem::getItem(unsigned short _level, size_t _index)
|
||||
// {
|
||||
// return m_levels[_level][_index];
|
||||
// }
|
||||
//
|
||||
// size_t ProfGraphicsItem::addItem(unsigned short _level)
|
||||
// {
|
||||
// m_levels[_level].emplace_back();
|
||||
// return m_levels[_level].size() - 1;
|
||||
// }
|
||||
//
|
||||
// size_t ProfGraphicsItem::addItem(unsigned short _level, const ProfBlockItem& _item)
|
||||
// {
|
||||
// m_levels[_level].emplace_back(_item);
|
||||
// return m_levels[_level].size() - 1;
|
||||
// }
|
||||
//
|
||||
// size_t ProfGraphicsItem::addItem(unsigned short _level, ProfBlockItem&& _item)
|
||||
// {
|
||||
// m_levels[_level].emplace_back(::std::forward<ProfBlockItem&&>(_item));
|
||||
// return m_levels[_level].size() - 1;
|
||||
// }
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ProfGraphicsScene::ProfGraphicsScene(QGraphicsView* _parent, bool _test) : QGraphicsScene(_parent), m_beginTime(-1)
|
||||
@ -262,22 +368,22 @@ void fillChildren(ProfGraphicsItem* _item, qreal _x, qreal _y, size_t _childrenN
|
||||
|
||||
if (_childrenNumber > 0)
|
||||
{
|
||||
fillChildren(_item, _x, _y + 18, _childrenNumber, _total_items);
|
||||
fillChildren(_item, _x, _y + GRAPHICS_ROW_SIZE + 2, _childrenNumber, _total_items);
|
||||
|
||||
auto& last = _item->items().back();
|
||||
auto& b = _item->getItem(j);
|
||||
b.color = ((30 + rand() % 225) << 16) + ((30 + rand() % 225) << 8) + (30 + rand() % 225);
|
||||
b.rect.setRect(_x, _y, last.rect.right() - _x, 15);
|
||||
b.totalHeight = last.rect.bottom() - _y;
|
||||
_x = b.rect.right();
|
||||
b.setRect(_x, _y, last.right() - _x, GRAPHICS_ROW_SIZE);
|
||||
b.totalHeight = last.bottom() - _y;
|
||||
_x = b.right();
|
||||
}
|
||||
else
|
||||
{
|
||||
auto& b = _item->getItem(j);
|
||||
b.color = ((30 + rand() % 225) << 16) + ((30 + rand() % 225) << 8) + (30 + rand() % 225);
|
||||
b.rect.setRect(_x, _y, 10 + rand() % 40, 15);
|
||||
b.totalHeight = 15;
|
||||
_x = b.rect.right();
|
||||
b.setRect(_x, _y, 10 + rand() % 40, GRAPHICS_ROW_SIZE);
|
||||
b.totalHeight = GRAPHICS_ROW_SIZE;
|
||||
_x = b.right();
|
||||
}
|
||||
|
||||
++_total_items;
|
||||
@ -297,19 +403,19 @@ void ProfGraphicsScene::test(size_t _frames_number, size_t _total_items_number_e
|
||||
item->setPos(x, 0);
|
||||
|
||||
size_t j = item->addItem();
|
||||
fillChildren(item, 0, y + 18, first_level_children_count, total_items);
|
||||
fillChildren(item, 0, y + GRAPHICS_ROW_SIZE + 2, first_level_children_count, total_items);
|
||||
|
||||
auto& last = item->items().back();
|
||||
auto& b = item->getItem(j);
|
||||
b.color = ((30 + rand() % 225) << 16) + ((30 + rand() % 225) << 8) + (30 + rand() % 225);
|
||||
b.rect.setRect(0, 0, last.rect.right(), 15);
|
||||
b.totalHeight = last.rect.bottom() - y;
|
||||
item->setBoundingRect(0, 0, b.rect.width(), b.totalHeight);
|
||||
x += b.rect.width() + 500;
|
||||
b.setRect(0, 0, last.right(), GRAPHICS_ROW_SIZE);
|
||||
b.totalHeight = last.bottom() - y;
|
||||
item->setBoundingRect(0, 0, b.width(), b.totalHeight);
|
||||
x += b.width() + 500;
|
||||
|
||||
if (last.rect.bottom() > h)
|
||||
if (last.bottom() > h)
|
||||
{
|
||||
h = last.rect.bottom();
|
||||
h = last.bottom();
|
||||
}
|
||||
|
||||
item->addItem(b);
|
||||
@ -321,6 +427,10 @@ void ProfGraphicsScene::test(size_t _frames_number, size_t _total_items_number_e
|
||||
setSceneRect(0, 0, x, h);
|
||||
}
|
||||
|
||||
void ProfGraphicsScene::test2(size_t _frames_number, size_t _total_items_number_estimate, int _depth)
|
||||
{
|
||||
}
|
||||
|
||||
void ProfGraphicsScene::clearSilent()
|
||||
{
|
||||
const QSignalBlocker b(this); // block all scene signals (otherwise clear() would be extremely slow!)
|
||||
@ -342,7 +452,7 @@ void ProfGraphicsScene::setTree(const thread_blocks_tree_t& _blocksTree)
|
||||
|
||||
// fill scene with new items
|
||||
qreal h = 0;
|
||||
setTreeInternal(threadTree.second.children, h, y);
|
||||
setTree(threadTree.second.children, h, y);
|
||||
y += h + ROW_SPACING;
|
||||
}
|
||||
|
||||
@ -350,8 +460,9 @@ void ProfGraphicsScene::setTree(const thread_blocks_tree_t& _blocksTree)
|
||||
setSceneRect(QRectF(0, 0, endX, y + ROW_SPACING));
|
||||
}
|
||||
|
||||
qreal ProfGraphicsScene::setTreeInternal(const BlocksTree::children_t& _children, qreal& _height, qreal _y)
|
||||
qreal ProfGraphicsScene::setTree(const BlocksTree::children_t& _children, qreal& _height, qreal _y)
|
||||
{
|
||||
//return 0;
|
||||
qreal total_duration = 0, prev_end = 0, maxh = 0;
|
||||
for (const auto& child : _children)
|
||||
{
|
||||
@ -376,7 +487,7 @@ qreal ProfGraphicsScene::setTreeInternal(const BlocksTree::children_t& _children
|
||||
auto i = item->addItem();
|
||||
|
||||
qreal h = 0;
|
||||
const auto children_duration = setTreeInternal(item, child.children, h, _y + GRAPHICS_ROW_SIZE_FULL);
|
||||
const auto children_duration = setTree(item, child.children, h, _y + GRAPHICS_ROW_SIZE_FULL);
|
||||
if (duration < children_duration)
|
||||
{
|
||||
duration = children_duration;
|
||||
@ -391,7 +502,7 @@ qreal ProfGraphicsScene::setTreeInternal(const BlocksTree::children_t& _children
|
||||
auto& b = item->getItem(i);
|
||||
b.block = &child;
|
||||
b.color = (::profiler::colors::get_red(color) << 16) + (::profiler::colors::get_green(color) << 8) + ::profiler::colors::get_blue(color);
|
||||
b.rect.setRect(0, 0, duration, GRAPHICS_ROW_SIZE);
|
||||
b.setRect(0, 0, duration, GRAPHICS_ROW_SIZE);
|
||||
b.totalHeight = GRAPHICS_ROW_SIZE + h;
|
||||
|
||||
item->setBoundingRect(0, 0, duration, b.totalHeight);
|
||||
@ -407,7 +518,7 @@ qreal ProfGraphicsScene::setTreeInternal(const BlocksTree::children_t& _children
|
||||
return total_duration;
|
||||
}
|
||||
|
||||
qreal ProfGraphicsScene::setTreeInternal(ProfGraphicsItem* _item, const BlocksTree::children_t& _children, qreal& _height, qreal _y)
|
||||
qreal ProfGraphicsScene::setTree(ProfGraphicsItem* _item, const BlocksTree::children_t& _children, qreal& _height, qreal _y)
|
||||
{
|
||||
if (_children.empty())
|
||||
{
|
||||
@ -435,7 +546,7 @@ qreal ProfGraphicsScene::setTreeInternal(ProfGraphicsItem* _item, const BlocksTr
|
||||
auto i = _item->addItem();
|
||||
|
||||
qreal h = 0;
|
||||
const auto children_duration = setTreeInternal(_item, child.children, h, _y + GRAPHICS_ROW_SIZE_FULL);
|
||||
const auto children_duration = setTree(_item, child.children, h, _y + GRAPHICS_ROW_SIZE_FULL);
|
||||
if (duration < children_duration)
|
||||
{
|
||||
duration = children_duration;
|
||||
@ -450,7 +561,7 @@ qreal ProfGraphicsScene::setTreeInternal(ProfGraphicsItem* _item, const BlocksTr
|
||||
auto& b = _item->getItem(i);
|
||||
b.block = &child;
|
||||
b.color = (::profiler::colors::get_red(color) << 16) + (::profiler::colors::get_green(color) << 8) + ::profiler::colors::get_blue(color);
|
||||
b.rect.setRect(xbegin - _item->x(), _y - _item->y(), duration, GRAPHICS_ROW_SIZE);
|
||||
b.setRect(xbegin - _item->x(), _y - _item->y(), duration, GRAPHICS_ROW_SIZE);
|
||||
b.totalHeight = GRAPHICS_ROW_SIZE + h;
|
||||
|
||||
total_duration += duration;
|
||||
|
@ -14,6 +14,8 @@
|
||||
* :
|
||||
* : * 2016/06/29 Victor Zarubkin: Highly optimized painting performance and memory consumption.
|
||||
* :
|
||||
* : * 2016/06/30 Victor Zarubkin: Replaced doubles with floats (in ProfBlockItem) for less memory consumption.
|
||||
* :
|
||||
* : *
|
||||
* ----------------- :
|
||||
* license : TODO: add license text
|
||||
@ -33,25 +35,46 @@
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define PROF_BLOCK_ITEM_OPT_MEMORY
|
||||
|
||||
#ifdef PROF_BLOCK_ITEM_OPT_MEMORY
|
||||
typedef float preal;
|
||||
#else
|
||||
typedef qreal preal;
|
||||
#endif
|
||||
|
||||
#pragma pack(push, 1)
|
||||
struct ProfBlockItem
|
||||
{
|
||||
QRectF rect;
|
||||
qreal totalHeight;
|
||||
#ifdef PROF_BLOCK_ITEM_OPT_MEMORY
|
||||
const BlocksTree* block;
|
||||
preal x, y, w, h;
|
||||
#else
|
||||
QRectF rect;
|
||||
const BlocksTree* block;
|
||||
#endif
|
||||
|
||||
float totalHeight;
|
||||
QRgb color;
|
||||
bool draw;
|
||||
|
||||
ProfBlockItem() : totalHeight(0), block(nullptr), color(0), draw(true)
|
||||
{
|
||||
}
|
||||
void setRect(preal _x, preal _y, preal _w, preal _h);
|
||||
preal left() const;
|
||||
preal top() const;
|
||||
preal width() const;
|
||||
preal height() const;
|
||||
preal right() const;
|
||||
preal bottom() const;
|
||||
};
|
||||
#pragma pack(pop)
|
||||
|
||||
class ProfGraphicsItem : public QGraphicsItem
|
||||
{
|
||||
typedef ::std::vector<ProfBlockItem> Children;
|
||||
//typedef ::std::vector<Children> Sublevels;
|
||||
|
||||
Children m_items;
|
||||
//Sublevels m_levels;
|
||||
QRectF m_rect;
|
||||
const bool m_bTest;
|
||||
|
||||
@ -68,15 +91,25 @@ public:
|
||||
void setBoundingRect(const QRectF& _rect);
|
||||
|
||||
void reserve(unsigned int _items);
|
||||
|
||||
const Children& items() const;
|
||||
const ProfBlockItem& getItem(size_t _index) const;
|
||||
ProfBlockItem& getItem(size_t _index);
|
||||
|
||||
size_t addItem();
|
||||
size_t addItem(const ProfBlockItem& _item);
|
||||
size_t addItem(ProfBlockItem&& _item);
|
||||
|
||||
|
||||
// void setLevels(unsigned int _levels);
|
||||
// void reserve(unsigned short _level, unsigned int _items);
|
||||
//
|
||||
// const Children& items(unsigned short _level) const;
|
||||
// const ProfBlockItem& getItem(unsigned short _level, size_t _index) const;
|
||||
// ProfBlockItem& getItem(unsigned short _level, size_t _index);
|
||||
//
|
||||
// size_t addItem(unsigned short _level);
|
||||
// size_t addItem(unsigned short _level, const ProfBlockItem& _item);
|
||||
// size_t addItem(unsigned short _level, ProfBlockItem&& _item);
|
||||
|
||||
}; // END of class ProfGraphicsItem.
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
@ -102,13 +135,14 @@ public:
|
||||
private:
|
||||
|
||||
void test(size_t _frames_number, size_t _total_items_number_estimate, int _depth);
|
||||
void test2(size_t _frames_number, size_t _total_items_number_estimate, int _depth);
|
||||
|
||||
void clearSilent();
|
||||
|
||||
void setTree(const thread_blocks_tree_t& _blocksTree);
|
||||
|
||||
qreal setTreeInternal(const BlocksTree::children_t& _children, qreal& _height, qreal _y);
|
||||
qreal setTreeInternal(ProfGraphicsItem* _item, const BlocksTree::children_t& _children, qreal& _height, qreal _y);
|
||||
qreal setTree(const BlocksTree::children_t& _children, qreal& _height, qreal _y);
|
||||
qreal setTree(ProfGraphicsItem* _item, const BlocksTree::children_t& _children, qreal& _height, qreal _y);
|
||||
|
||||
inline qreal time2position(const profiler::timestamp_t& _time) const
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user