diff --git a/include/profiler/reader.h b/include/profiler/reader.h index f0c7af4..946a25f 100644 --- a/include/profiler/reader.h +++ b/include/profiler/reader.h @@ -95,7 +95,7 @@ struct BlocksTree children_t children; ::profiler::SerilizedBlock* node; ::profiler::BlockStatistics* frame_statistics; ///< Pointer to statistics for this block within the parent (may be nullptr for top-level blocks) - ::profiler::BlockStatistics* total_statistics; ///< Pointer to statistics for this block within the bounds of all frames per current thread + ::profiler::BlockStatistics* total_statistics; ///< Pointer to statistics for this block within the bounds of all frames per current thread BlocksTree() : node(nullptr), frame_statistics(nullptr), total_statistics(nullptr) { @@ -168,7 +168,7 @@ private: typedef ::std::map<::profiler::thread_id_t, BlocksTree> thread_blocks_tree_t; extern "C"{ - int PROFILER_API fillTreesFromFile(const char* filename, thread_blocks_tree_t& threaded_trees, bool gather_statistics = false); + unsigned int PROFILER_API fillTreesFromFile(const char* filename, thread_blocks_tree_t& threaded_trees, bool gather_statistics = false); } diff --git a/profiler_gui/blocks_graphics_view.cpp b/profiler_gui/blocks_graphics_view.cpp index 126f5fe..536819d 100644 --- a/profiler_gui/blocks_graphics_view.cpp +++ b/profiler_gui/blocks_graphics_view.cpp @@ -12,6 +12,8 @@ * change log : * 2016/06/26 Victor Zarubkin: Moved sources from graphics_view.h * : and renamed classes from My* to Prof*. * : * 2016/06/27 Victor Zarubkin: Added text shifting relatively to it's parent item. +* : Disabled border lines painting because of vertical lines painting bug. +* : Changed height of blocks. Variable thread-block height. * : * * ----------------- : * license : TODO: add license text @@ -26,6 +28,9 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// const qreal BASE_TEXT_SHIFT = 5; ///< Text position relatively to parent polygon item +const qreal GRAPHICS_ROW_SIZE = 15; +const qreal GRAPHICS_ROW_SIZE_FULL = GRAPHICS_ROW_SIZE + 1; +const qreal ROW_SPACING = 5; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -43,30 +48,35 @@ ProfGraphicsPolygonItem::~ProfGraphicsPolygonItem() { } -void ProfGraphicsPolygonItem::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget) -{ - if (m_bDrawBorders) - { - const auto currentScale = static_cast(scene()->parent())->currentScale(); - if (boundingRect().width() * currentScale < 5) - { - auto linePen = pen(); - if (linePen.style() != Qt::NoPen) - { - linePen.setStyle(Qt::NoPen); - setPen(linePen); - } - } - else - { - auto linePen = pen(); - linePen.setWidthF(1. / currentScale); - setPen(linePen); - } - } - - QGraphicsPolygonItem::paint(painter, option, widget); -} +//void ProfGraphicsPolygonItem::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget) +//{ +// if (m_bDrawBorders) +// { +// const auto currentScale = static_cast(scene()->parent())->currentScale(); +//// if (boundingRect().width() * currentScale < 5) +//// { +//// auto linePen = pen(); +//// if (linePen.style() != Qt::NoPen) +//// { +//// linePen.setStyle(Qt::NoPen); +//// setPen(linePen); +//// } +//// } +//// else +//// { +//// auto linePen = pen(); +//// //linePen.setWidthF(1.25 / currentScale); +//// +//// if (linePen.style() != Qt::SolidLine) +//// { +//// linePen.setStyle(Qt::SolidLine); +//// setPen(linePen); +//// } +//// } +// } +// +// QGraphicsPolygonItem::paint(painter, option, widget); +//} ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -82,11 +92,12 @@ ProfGraphicsTextItem::~ProfGraphicsTextItem() void ProfGraphicsTextItem::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget) { const auto currentScale = static_cast(parentItem()->scene()->parent())->currentScale(); - const auto dx = BASE_TEXT_SHIFT / currentScale; + const auto scaleRevert = 1. / currentScale; + const auto dx = BASE_TEXT_SHIFT * scaleRevert; if ((boundingRect().width() + dx) < parentItem()->boundingRect().width() * currentScale) { - painter->setTransform(QTransform::fromScale(1. / currentScale, 1), true); - //setScale(1. / currentScale); + painter->setTransform(QTransform::fromScale(scaleRevert, 1), true); + //setScale(scaleRevert); setX(dx); QGraphicsSimpleTextItem::paint(painter, option, widget); } @@ -149,33 +160,35 @@ void ProfGraphicsScene::setTree(const thread_blocks_tree_t& _blocksTree) void ProfGraphicsScene::setTreeInternal(const thread_blocks_tree_t& _blocksTree) { // calculate scene size - profiler::timestamp_t finish = 0; + ::profiler::timestamp_t finish = 0; + qreal y = ROW_SPACING; for (const auto& threadTree : _blocksTree) { const auto timestart = threadTree.second.children.front().node->block()->getBegin(); const auto timefinish = threadTree.second.children.back().node->block()->getEnd(); if (m_start > timestart) m_start = timestart; if (finish < timefinish) finish = timefinish; + + unsigned short depth = 0; + setTreeInternal(threadTree.second.children, depth, y, 0); + y += static_cast(depth) * GRAPHICS_ROW_SIZE_FULL + ROW_SPACING; } const qreal endX = time2position(finish + 1000000); - setSceneRect(QRectF(0, 0, endX, 110 * _blocksTree.size())); - - // fill scene with items - qreal y = 0; - for (const auto& threadTree : _blocksTree) - { - setTreeInternal(threadTree.second.children, y); - y += 110; // each thread is shifted to 110 points down - } + setSceneRect(QRectF(0, 0, endX, y)); } -void ProfGraphicsScene::setTreeInternal(const BlocksTree::children_t& _children, qreal _y, int _level) +qreal ProfGraphicsScene::setTreeInternal(const BlocksTree::children_t& _children, unsigned short& _depth, qreal _y, unsigned short _level) { + if (_depth < _level) + { + _depth = _level; + } + + qreal total_duration = 0; for (const auto& child : _children) { const qreal xbegin = time2position(child.node->block()->getBegin()); - const qreal height = 100 - _level * 5; qreal duration = time2position(child.node->block()->getEnd()) - xbegin; const bool drawBorders = duration > 1; @@ -185,25 +198,34 @@ void ProfGraphicsScene::setTreeInternal(const BlocksTree::children_t& _children, } ProfGraphicsPolygonItem* item = new ProfGraphicsPolygonItem(drawBorders); - item->setPolygon(QRectF(0, _level * 5, duration, height)); item->setPos(xbegin, _y); item->setZValue(_level); const auto color = child.node->block()->getColor(); const auto itemBrush = QBrush(QColor(profiler::colors::get_red(color), profiler::colors::get_green(color), profiler::colors::get_blue(color))); item->setBrush(itemBrush); - - addItem(item); + item->setPen(QPen(Qt::NoPen)); // Don't paint lines! There are display bugs if bounding lines are painted: vertical lines are very thick. ProfGraphicsTextItem* text = new ProfGraphicsTextItem(child.node->getBlockName(), item); - text->setPos(BASE_TEXT_SHIFT, _level * 5); + text->setPos(BASE_TEXT_SHIFT, 1); auto textBrush = text->brush(); textBrush.setColor(QRgb(0x00ffffff - itemBrush.color().rgb())); text->setBrush(textBrush); - setTreeInternal(child.children, _y, _level + 1); + const auto children_duration = setTreeInternal(child.children, _depth, _y + GRAPHICS_ROW_SIZE_FULL, _level + 1); + if (duration < children_duration) + { + duration = children_duration; + } + + item->setPolygon(QRectF(0, 0, duration, GRAPHICS_ROW_SIZE)); + addItem(item); + + total_duration += duration; } + + return total_duration; } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -241,6 +263,8 @@ void ProfGraphicsView::wheelEvent(QWheelEvent* _event) scale(scaleCoeff, 1);// scaleCoeff); m_scale *= scaleCoeff; + scene()->update(); + _event->accept(); //QGraphicsView::wheelEvent(_event); } @@ -281,10 +305,16 @@ void ProfGraphicsView::mouseMoveEvent(QMouseEvent* _event) void ProfGraphicsView::initMode() { - setCacheMode(QGraphicsView::CacheBackground); + // TODO: find mode with least number of bugs :) + // There are always some display bugs... + + //setCacheMode(QGraphicsView::CacheBackground); + setCacheMode(QGraphicsView::CacheNone); + setTransformationAnchor(QGraphicsView::AnchorUnderMouse); - //setTransformationAnchor(QGraphicsView::AnchorViewCenter); + setViewportUpdateMode(QGraphicsView::BoundingRectViewportUpdate); + //setViewportUpdateMode(QGraphicsView::FullViewportUpdate); } void ProfGraphicsView::setTree(const thread_blocks_tree_t& _blocksTree) diff --git a/profiler_gui/blocks_graphics_view.h b/profiler_gui/blocks_graphics_view.h index d9ff226..190da34 100644 --- a/profiler_gui/blocks_graphics_view.h +++ b/profiler_gui/blocks_graphics_view.h @@ -38,7 +38,7 @@ public: ProfGraphicsPolygonItem(bool _drawBorders, QGraphicsItem* _parent = nullptr); virtual ~ProfGraphicsPolygonItem(); - void paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget = Q_NULLPTR) override; + //void paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget = Q_NULLPTR) override; }; // END of class ProfGraphicsPolygonItem. @@ -82,7 +82,7 @@ private: void setTree(const thread_blocks_tree_t& _blocksTree); void setTreeInternal(const thread_blocks_tree_t& _blocksTree); - void setTreeInternal(const BlocksTree::children_t& _children, qreal _y, int _level = 0); + qreal setTreeInternal(const BlocksTree::children_t& _children, unsigned short& _depth, qreal _y, unsigned short _level); inline qreal time2position(const profiler::timestamp_t& _time) const { diff --git a/profiler_gui/blocks_tree_widget.cpp b/profiler_gui/blocks_tree_widget.cpp index b1eac09..58d9540 100644 --- a/profiler_gui/blocks_tree_widget.cpp +++ b/profiler_gui/blocks_tree_widget.cpp @@ -14,6 +14,7 @@ * : * 2016/06/27 Victor Zarubkin: Added possibility to colorize rows * : with profiler blocks' colors. * : Also added displaying frame statistics for blocks. +* : Disabled sorting by name. * : * * ----------------- : * license : TODO: add license text @@ -64,12 +65,12 @@ bool ProfTreeWidgetItem::operator < (const Parent& _other) const switch (col) { - case COL_UNKNOWN: - case COL_NAME: - { - // column 0 - Name - return Parent::operator < (_other); - } +// case COL_UNKNOWN: +// case COL_NAME: +// { +// // column 0 - Name +// return Parent::operator < (_other); +// } case COL_NCALLS_TOTAL: case COL_NCALLS: @@ -187,7 +188,7 @@ ProfTreeWidget::ProfTreeWidget(const unsigned int _blocksNumber, const thread_bl setTreeInternal(_blocksNumber, _blocksTree); setSortingEnabled(true); - sortByColumn(COL_NAME, Qt::AscendingOrder); + //sortByColumn(COL_NAME, Qt::AscendingOrder); sortByColumn(COL_BEGIN, Qt::AscendingOrder); connect(this, &Parent::itemExpanded, this, &This::onItemExpand); @@ -213,7 +214,7 @@ void ProfTreeWidget::setTree(const unsigned int _blocksNumber, const thread_bloc setTreeInternal(_blocksNumber, _blocksTree); setSortingEnabled(true); - sortByColumn(COL_NAME, Qt::AscendingOrder); + //sortByColumn(COL_NAME, Qt::AscendingOrder); sortByColumn(COL_BEGIN, Qt::AscendingOrder); connect(this, &Parent::itemExpanded, this, &This::onItemExpand); diff --git a/profiler_gui/main_window.cpp b/profiler_gui/main_window.cpp index aec267e..11c42df 100644 --- a/profiler_gui/main_window.cpp +++ b/profiler_gui/main_window.cpp @@ -95,7 +95,7 @@ void ProfMainWindow::onOpenFileClicked(bool) thread_blocks_tree_t prof_blocks; auto nblocks = fillTreesFromFile(stdfilename.c_str(), prof_blocks, true); - if (nblocks > 0) + if (nblocks != 0) { m_lastFile.swap(stdfilename); m_currentProf.swap(prof_blocks); @@ -116,7 +116,7 @@ void ProfMainWindow::onReloadFileClicked(bool) thread_blocks_tree_t prof_blocks; auto nblocks = fillTreesFromFile(m_lastFile.c_str(), prof_blocks, true); - if (nblocks > 0) + if (nblocks != 0) { m_currentProf.swap(prof_blocks); static_cast(m_treeWidget->widget())->setTree(nblocks, m_currentProf); diff --git a/reader/main.cpp b/reader/main.cpp index 1445274..7db3e6f 100644 --- a/reader/main.cpp +++ b/reader/main.cpp @@ -75,7 +75,7 @@ int main() auto start = std::chrono::system_clock::now(); - int blocks_counter = fillTreesFromFile("test.prof", threaded_trees, true); + auto blocks_counter = fillTreesFromFile("test.prof", threaded_trees, true); auto end = std::chrono::system_clock::now(); diff --git a/sample/main.cpp b/sample/main.cpp index b1c8176..949ca00 100644 --- a/sample/main.cpp +++ b/sample/main.cpp @@ -216,7 +216,7 @@ int main() std::cout << elapsed.count() << " usec" << std::endl; thread_blocks_tree_t threaded_trees; - int blocks_counter = fillTreesFromFile("test.prof", threaded_trees); + auto blocks_counter = fillTreesFromFile("test.prof", threaded_trees); std::cout << "Blocks count: " << blocks_counter << std::endl; char c; diff --git a/src/reader.cpp b/src/reader.cpp index 9d1977e..904bdcf 100644 --- a/src/reader.cpp +++ b/src/reader.cpp @@ -135,17 +135,17 @@ void update_statistics(StatsMap& _stats_map, ::profiler::SerilizedBlock* _curren ////////////////////////////////////////////////////////////////////////// extern "C"{ - int fillTreesFromFile(const char* filename, thread_blocks_tree_t& threaded_trees, bool gather_statistics) + unsigned int fillTreesFromFile(const char* filename, thread_blocks_tree_t& threaded_trees, bool gather_statistics) { std::ifstream inFile(filename, std::fstream::binary); if (!inFile.is_open()){ - return -1; + return 0; } StatsMap overall_statistics, frame_statistics; - int blocks_counter = 0; + unsigned int blocks_counter = 0; while (!inFile.eof()){ uint16_t sz = 0; @@ -165,22 +165,20 @@ extern "C"{ BlocksTree tree; tree.node = new profiler::SerilizedBlock(sz, data); - blocks_counter++; + ++blocks_counter; - if (root.children.empty()){ - root.children.push_back(std::move(tree)); - } - else{ - BlocksTree& back = root.children.back(); - auto t1 = back.node->block()->getEnd(); - auto mt0 = tree.node->block()->getBegin(); - if (mt0 < t1)//parent - starts earlier than last ends - { - auto lower = std::lower_bound(root.children.begin(), root.children.end(), tree); + if (!root.children.empty()) + { + BlocksTree& back = root.children.back(); + auto t1 = back.node->block()->getEnd(); + auto mt0 = tree.node->block()->getBegin(); + if (mt0 < t1)//parent - starts earlier than last ends + { + auto lower = std::lower_bound(root.children.begin(), root.children.end(), tree); - std::move(lower, root.children.end(), std::back_inserter(tree.children)); + std::move(lower, root.children.end(), std::back_inserter(tree.children)); - root.children.erase(lower, root.children.end()); + root.children.erase(lower, root.children.end()); if (gather_statistics) { @@ -195,11 +193,10 @@ extern "C"{ update_statistics(frame_statistics, child.node, child.frame_statistics); } } - } + } + } - root.children.push_back(std::move(tree)); - - } + root.children.push_back(std::move(tree)); //delete[] data; @@ -228,6 +225,6 @@ extern "C"{ // No need to delete BlockStatistics instances - they will be deleted on BlocksTree destructors - return blocks_counter; + return blocks_counter; } } \ No newline at end of file