mirror of
https://github.com/yse/easy_profiler.git
synced 2024-12-27 08:41:02 +08:00
(profiler_gui) refactoring;
(ProfGraphicsView) Added separate background drawer item; Added timeline scale drawing;
This commit is contained in:
parent
d8ccff0788
commit
9f48bf6e21
@ -28,7 +28,7 @@
|
||||
#include <QWheelEvent>
|
||||
#include <QMouseEvent>
|
||||
#include <QScrollBar>
|
||||
#include <QVBoxLayout>
|
||||
#include <QGridLayout>
|
||||
#include <QFontMetrics>
|
||||
#include <math.h>
|
||||
#include <algorithm>
|
||||
@ -54,6 +54,8 @@ const unsigned short ROW_SPACING = 4;
|
||||
const QRgb BORDERS_COLOR = 0x00a07050;
|
||||
const QRgb BACKGROUND_1 = 0x00dddddd;
|
||||
const QRgb BACKGROUND_2 = 0x00ffffff;
|
||||
const QRgb TIMELINE_BACKGROUND = 0x20303030;
|
||||
const QRgb SELECTED_ITEM_COLOR = 0x000050a0;
|
||||
const QColor CHRONOMETER_COLOR2 = QColor::fromRgba(0x20408040);
|
||||
|
||||
const unsigned int TEST_PROGRESSION_BASE = 4;
|
||||
@ -77,29 +79,11 @@ inline T logn(T _value)
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
QRgb BG1();
|
||||
QRgb BG2();
|
||||
QRgb (*GetBackgroundColor)() = BG1;
|
||||
|
||||
QRgb BG1()
|
||||
{
|
||||
GetBackgroundColor = BG2;
|
||||
return BACKGROUND_1;
|
||||
}
|
||||
|
||||
QRgb BG2()
|
||||
{
|
||||
GetBackgroundColor = BG1;
|
||||
return BACKGROUND_2;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ProfGraphicsItem::ProfGraphicsItem() : ProfGraphicsItem(false)
|
||||
{
|
||||
}
|
||||
|
||||
ProfGraphicsItem::ProfGraphicsItem(bool _test) : QGraphicsItem(nullptr), m_bTest(_test), m_backgroundColor(0x00ffffff), m_pRoot(nullptr)
|
||||
ProfGraphicsItem::ProfGraphicsItem(bool _test) : QGraphicsItem(nullptr), m_bTest(_test), m_pRoot(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
@ -177,22 +161,6 @@ void ProfGraphicsItem::paint(QPainter* _painter, const QStyleOptionGraphicsItem*
|
||||
}
|
||||
|
||||
|
||||
// Draw background --------------------------
|
||||
if (!m_bTest && m_pRoot->thread_id == ::profiler_gui::EASY_GLOBALS.selected_thread && m_pRoot->thread_id != 0)
|
||||
{
|
||||
brush.setColor(::profiler_gui::SELECTED_THREAD_BACKGROUND);
|
||||
}
|
||||
else
|
||||
{
|
||||
brush.setColor(m_backgroundColor);
|
||||
}
|
||||
|
||||
_painter->setBrush(brush);
|
||||
_painter->setPen(Qt::NoPen);
|
||||
rect.setRect(0, m_boundingRect.top() - (ROW_SPACING >> 1), visibleSceneRect.width(), m_boundingRect.height() + ROW_SPACING);
|
||||
_painter->drawRect(rect);
|
||||
// END. Draw background. ~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
|
||||
// This is to make _painter->drawText() work properly
|
||||
// (it seems there is a bug in Qt5.6 when drawText called for big coordinates,
|
||||
@ -200,15 +168,21 @@ void ProfGraphicsItem::paint(QPainter* _painter, const QStyleOptionGraphicsItem*
|
||||
// works fine without using this additional shifting)
|
||||
auto dx = level0[m_levelsIndexes[0]].left() * currentScale;
|
||||
|
||||
|
||||
|
||||
// Shifting coordinates to current screen offset
|
||||
_painter->setTransform(QTransform::fromTranslate(dx - offset * currentScale, -y()), true);
|
||||
|
||||
|
||||
|
||||
if (::profiler_gui::EASY_GLOBALS.draw_graphics_items_borders)
|
||||
{
|
||||
previousPenStyle = Qt::SolidLine;
|
||||
_painter->setPen(BORDERS_COLOR);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Iterate through layers and draw visible items
|
||||
bool selectedItemsWasPainted = false;
|
||||
for (unsigned short l = 0; l < levelsNumber; ++l)
|
||||
@ -626,13 +600,6 @@ const ::profiler_gui::ProfBlockItem* ProfGraphicsItem::intersect(const QPointF&
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void ProfGraphicsItem::setBackgroundColor(QRgb _color)
|
||||
{
|
||||
m_backgroundColor = _color;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void ProfGraphicsItem::setBoundingRect(qreal x, qreal y, qreal w, qreal h)
|
||||
{
|
||||
m_boundingRect.setRect(x, y, w, h);
|
||||
@ -695,7 +662,7 @@ unsigned int ProfGraphicsItem::addItem(unsigned short _level)
|
||||
|
||||
ProfChronometerItem::ProfChronometerItem(bool _main) : QGraphicsItem(), m_font(QFont("CourierNew", 16, 2)), m_color(CHRONOMETER_COLOR), m_left(0), m_right(0), m_bMain(_main), m_bReverse(false), m_bHover(false)
|
||||
{
|
||||
setZValue(10);
|
||||
//setZValue(_main ? 10 : 9);
|
||||
m_indicator.reserve(3);
|
||||
}
|
||||
|
||||
@ -758,20 +725,15 @@ void ProfChronometerItem::paint(QPainter* _painter, const QStyleOptionGraphicsIt
|
||||
return;
|
||||
}
|
||||
|
||||
const auto selectedInterval = width();
|
||||
auto selectedInterval = width();
|
||||
QRectF rect((m_left - offset) * currentScale, visibleSceneRect.top(), ::std::max(selectedInterval * currentScale, 1.0), visibleSceneRect.height());
|
||||
selectedInterval = units2microseconds(selectedInterval);
|
||||
|
||||
QString text; // Displayed text
|
||||
if (selectedInterval < 1.0) // interval in nanoseconds
|
||||
text = ::std::move(QString("%1 ns").arg(selectedInterval * 1e3, 0, 'f', 1));
|
||||
else if (selectedInterval < 1e3) // interval in microseconds
|
||||
text = ::std::move(QString("%1 us").arg(selectedInterval, 0, 'f', 1));
|
||||
else if (selectedInterval < 1e6) // interval in milliseconds
|
||||
text = ::std::move(QString("%1 ms").arg(selectedInterval * 1e-3, 0, 'f', 1));
|
||||
else // interval in seconds
|
||||
text = ::std::move(QString("%1 sec").arg(selectedInterval * 1e-6, 0, 'f', 1));
|
||||
|
||||
const QString text = ::profiler_gui::timeStringReal(selectedInterval); // Displayed text
|
||||
const auto textRect = QFontMetrics(m_font).boundingRect(text); // Calculate displayed text boundingRect
|
||||
const auto rgb = m_color.rgb() & 0x00ffffff;
|
||||
|
||||
|
||||
|
||||
// Paint!--------------------------
|
||||
_painter->save();
|
||||
@ -784,9 +746,17 @@ void ProfChronometerItem::paint(QPainter* _painter, const QStyleOptionGraphicsIt
|
||||
_painter->setPen(Qt::NoPen);
|
||||
_painter->drawRect(rect);
|
||||
|
||||
// draw left and right borders
|
||||
_painter->setBrush(Qt::NoBrush);
|
||||
_painter->setPen(QColor::fromRgba(0xa0000000 | rgb));
|
||||
if (m_left > sceneLeft)
|
||||
_painter->drawLine(QPointF(rect.left(), rect.top()), QPointF(rect.left(), rect.bottom()));
|
||||
if (m_right < sceneRight)
|
||||
_painter->drawLine(QPointF(rect.right(), rect.top()), QPointF(rect.right(), rect.bottom()));
|
||||
|
||||
// draw text
|
||||
_painter->setCompositionMode(QPainter::CompositionMode_Difference); // This lets the text to be visible on every background
|
||||
_painter->setPen(0xffffffff - m_color.rgb());
|
||||
_painter->setPen(0xffffffff - rgb);
|
||||
_painter->setFont(m_font);
|
||||
|
||||
if (m_left < sceneLeft)
|
||||
@ -889,35 +859,108 @@ const ProfGraphicsView* ProfChronometerItem::view() const
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ProfGraphicsView::ProfGraphicsView(bool _test)
|
||||
: QGraphicsView()
|
||||
, m_beginTime(-1)
|
||||
, m_scale(1)
|
||||
, m_offset(0)
|
||||
, m_mouseButtons(Qt::NoButton)
|
||||
, m_pScrollbar(nullptr)
|
||||
, m_chronometerItem(nullptr)
|
||||
, m_chronometerItemAux(nullptr)
|
||||
, m_flickerSpeedX(0)
|
||||
, m_flickerSpeedY(0)
|
||||
, m_bDoubleClick(false)
|
||||
, m_bUpdatingRect(false)
|
||||
, m_bTest(_test)
|
||||
, m_bEmpty(true)
|
||||
void ProfBackgroundItem::paint(QPainter* _painter, const QStyleOptionGraphicsItem* _option, QWidget* _widget)
|
||||
{
|
||||
initMode();
|
||||
setScene(new QGraphicsScene(this));
|
||||
const auto sceneView = static_cast<const ProfGraphicsView*>(scene()->parent());
|
||||
const auto visibleSceneRect = sceneView->visibleSceneRect();
|
||||
const auto currentScale = sceneView->scale();
|
||||
const auto offset = sceneView->offset();
|
||||
const auto left = offset * currentScale;
|
||||
|
||||
if (_test)
|
||||
QRectF rect;
|
||||
|
||||
_painter->save();
|
||||
_painter->setTransform(QTransform::fromTranslate(-x(), -y()));
|
||||
|
||||
const auto& items = sceneView->getItems();
|
||||
if (!items.empty())
|
||||
{
|
||||
test(18000, 40000000, 2);
|
||||
static const auto OVERLAP = ROW_SPACING >> 1;
|
||||
static const QBrush brushes[2] = {QColor::fromRgb(BACKGROUND_1), QColor::fromRgb(BACKGROUND_2)};
|
||||
const bool isTest = (items.front()->items(0).front().block == nullptr);
|
||||
int i = -1;
|
||||
|
||||
// Draw background
|
||||
_painter->setPen(Qt::NoPen);
|
||||
for (auto item : items)
|
||||
{
|
||||
++i;
|
||||
|
||||
auto br = item->boundingRect();
|
||||
auto top = item->y() + br.top() - visibleSceneRect.top();
|
||||
auto bottom = top + br.height();
|
||||
|
||||
if (top > visibleSceneRect.height() || bottom < 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!isTest && item->threadId() == ::profiler_gui::EASY_GLOBALS.selected_thread)
|
||||
{
|
||||
_painter->setBrush(QBrush(QColor::fromRgb(::profiler_gui::SELECTED_THREAD_BACKGROUND)));
|
||||
}
|
||||
else
|
||||
{
|
||||
_painter->setBrush(brushes[i & 1]);
|
||||
}
|
||||
|
||||
rect.setRect(0, top - OVERLAP, visibleSceneRect.width(), br.height() + OVERLAP);
|
||||
_painter->drawRect(rect);
|
||||
}
|
||||
}
|
||||
|
||||
updateVisibleSceneRect();
|
||||
// Draw timeline scale marks ----------------
|
||||
//_painter->setBrush(Qt::NoBrush);
|
||||
//_painter->setPen(QColor::fromRgba(TIMELINE_BACKGROUND));
|
||||
_painter->setBrush(QColor::fromRgba(TIMELINE_BACKGROUND));
|
||||
|
||||
const auto step = sceneView->timelineStep() * currentScale;
|
||||
const auto steps = static_cast<int>(visibleSceneRect.width() / step);
|
||||
auto first = static_cast<quint64>(offset / sceneView->timelineStep());
|
||||
const int addend = (first & 1) ? 1 : 0;
|
||||
|
||||
for (qreal curr = (first - addend) * step, last = (first + steps + 2) * step; curr < last; curr += 2 * step)
|
||||
{
|
||||
auto x1 = curr - left;
|
||||
rect.setRect(x1, 0, step, visibleSceneRect.height());
|
||||
_painter->drawRect(rect);
|
||||
//_painter->drawLine(QPointF(x1, 0), QPointF(x1, visibleSceneRect.height()));
|
||||
}
|
||||
// END Draw timeline scale marks ~~~~~~~~~~~~
|
||||
|
||||
_painter->restore();
|
||||
}
|
||||
|
||||
ProfGraphicsView::ProfGraphicsView(const ::profiler::thread_blocks_tree_t& _blocksTree)
|
||||
: QGraphicsView()
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void ProfTimelineIndicatorItem::paint(QPainter* _painter, const QStyleOptionGraphicsItem* _option, QWidget* _widget)
|
||||
{
|
||||
const auto sceneView = static_cast<const ProfGraphicsView*>(scene()->parent());
|
||||
const auto visibleSceneRect = sceneView->visibleSceneRect();
|
||||
const auto step = sceneView->timelineStep() * sceneView->scale();
|
||||
const QString text = ::profiler_gui::timeStringInt(units2microseconds(sceneView->timelineStep())); // Displayed text
|
||||
|
||||
// Draw scale indicator
|
||||
_painter->save();
|
||||
_painter->setTransform(QTransform::fromTranslate(-x(), -y()));
|
||||
_painter->setCompositionMode(QPainter::CompositionMode_Difference);
|
||||
_painter->setBrush(Qt::white);
|
||||
_painter->setPen(Qt::NoPen);
|
||||
|
||||
QRectF rect(visibleSceneRect.width() - 10 - step, visibleSceneRect.height() - 25, step, 5);
|
||||
_painter->drawRect(rect);
|
||||
|
||||
rect.translate(0, 5);
|
||||
_painter->setPen(Qt::white);
|
||||
_painter->drawText(rect, Qt::AlignRight | Qt::TextDontClip, text);
|
||||
|
||||
_painter->restore();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ProfGraphicsView::ProfGraphicsView(QWidget* _parent)
|
||||
: QGraphicsView(_parent)
|
||||
, m_beginTime(-1)
|
||||
, m_scale(1)
|
||||
, m_offset(0)
|
||||
@ -934,7 +977,6 @@ ProfGraphicsView::ProfGraphicsView(const ::profiler::thread_blocks_tree_t& _bloc
|
||||
{
|
||||
initMode();
|
||||
setScene(new QGraphicsScene(this));
|
||||
setTree(_blocksTree);
|
||||
updateVisibleSceneRect();
|
||||
}
|
||||
|
||||
@ -982,7 +1024,7 @@ void ProfGraphicsView::fillTestChildren(ProfGraphicsItem* _item, const int _maxl
|
||||
}
|
||||
else
|
||||
{
|
||||
b.setRect(_x, _y, to_microseconds(10 + rand() % 190), GRAPHICS_ROW_SIZE);
|
||||
b.setRect(_x, _y, units2microseconds(10 + rand() % 190), GRAPHICS_ROW_SIZE);
|
||||
b.totalHeight = GRAPHICS_ROW_SIZE;
|
||||
b.children_begin = -1;
|
||||
}
|
||||
@ -1005,6 +1047,11 @@ void ProfGraphicsView::test(unsigned int _frames_number, unsigned int _total_ite
|
||||
const int max_depth = logn<TEST_PROGRESSION_BASE>(children_per_frame * (TEST_PROGRESSION_BASE - 1) * 0.5 + 1);
|
||||
const auto first_level_children_count = static_cast<unsigned int>(static_cast<double>(children_per_frame) * (1.0 - TEST_PROGRESSION_BASE) / (1.0 - pow(TEST_PROGRESSION_BASE, max_depth)) + 0.5);
|
||||
|
||||
|
||||
auto bgItem = new ProfBackgroundItem();
|
||||
scene()->addItem(bgItem);
|
||||
|
||||
|
||||
::std::vector<ProfGraphicsItem*> thread_items(_rows);
|
||||
for (int i = 0; i < _rows; ++i)
|
||||
{
|
||||
@ -1061,10 +1108,6 @@ void ProfGraphicsView::test(unsigned int _frames_number, unsigned int _total_ite
|
||||
|
||||
const auto h = item->getItem(0, 0).totalHeight;
|
||||
item->setBoundingRect(0, 0, x, h);
|
||||
if (_rows > 1)
|
||||
{
|
||||
item->setBackgroundColor(GetBackgroundColor());
|
||||
}
|
||||
|
||||
m_items.push_back(item);
|
||||
scene()->addItem(item);
|
||||
@ -1096,8 +1139,13 @@ void ProfGraphicsView::test(unsigned int _frames_number, unsigned int _total_ite
|
||||
|
||||
// Create new chronometer item (previous item was destroyed by scene on scene()->clear()).
|
||||
// It will be shown on mouse right button click.
|
||||
m_chronometerItem = createChronometer(true);
|
||||
m_chronometerItemAux = createChronometer(false);
|
||||
m_chronometerItem = createChronometer(true);
|
||||
|
||||
bgItem->setBoundingRect(scene()->sceneRect());
|
||||
auto indicator = new ProfTimelineIndicatorItem();
|
||||
indicator->setBoundingRect(scene()->sceneRect());
|
||||
scene()->addItem(indicator);
|
||||
|
||||
// Set necessary flags
|
||||
m_bTest = true;
|
||||
@ -1112,8 +1160,6 @@ void ProfGraphicsView::clearSilent()
|
||||
{
|
||||
const QSignalBlocker blocker(this), sceneBlocker(scene()); // block all scene signals (otherwise clear() would be extremely slow!)
|
||||
|
||||
GetBackgroundColor = BG1; // reset background color
|
||||
|
||||
// Stop flicking
|
||||
m_flickerTimer.stop();
|
||||
m_flickerSpeedX = 0;
|
||||
@ -1126,6 +1172,7 @@ void ProfGraphicsView::clearSilent()
|
||||
|
||||
m_beginTime = -1; // reset begin time
|
||||
m_scale = 1; // scale back to initial 100% scale
|
||||
m_timelineStep = 1;
|
||||
m_offset = 0; // scroll back to the beginning of the scene
|
||||
|
||||
// Reset necessary flags
|
||||
@ -1146,6 +1193,9 @@ void ProfGraphicsView::setTree(const ::profiler::thread_blocks_tree_t& _blocksTr
|
||||
return;
|
||||
}
|
||||
|
||||
auto bgItem = new ProfBackgroundItem();
|
||||
scene()->addItem(bgItem);
|
||||
|
||||
// set new blocks tree
|
||||
// calculate scene size and fill it with items
|
||||
|
||||
@ -1186,7 +1236,6 @@ void ProfGraphicsView::setTree(const ::profiler::thread_blocks_tree_t& _blocksTr
|
||||
const auto children_duration = setTree(item, tree.children, h, y, 0);
|
||||
|
||||
item->setBoundingRect(0, 0, children_duration + x, h);
|
||||
item->setBackgroundColor(GetBackgroundColor());
|
||||
m_items.push_back(item);
|
||||
scene()->addItem(item);
|
||||
|
||||
@ -1201,12 +1250,8 @@ void ProfGraphicsView::setTree(const ::profiler::thread_blocks_tree_t& _blocksTr
|
||||
// Calculating scene rect
|
||||
const qreal endX = time2position(finish) + 1500.0;
|
||||
scene()->setSceneRect(0, 0, endX, y);
|
||||
|
||||
// Stub! :O
|
||||
for (auto item : m_items)
|
||||
{
|
||||
item->setBoundingRect(0, 0, endX, item->boundingRect().height());
|
||||
}
|
||||
//for (auto item : m_items)
|
||||
// item->setBoundingRect(0, 0, endX, item->boundingRect().height());
|
||||
|
||||
// Center view on the beginning of the scene
|
||||
updateVisibleSceneRect();
|
||||
@ -1221,8 +1266,13 @@ void ProfGraphicsView::setTree(const ::profiler::thread_blocks_tree_t& _blocksTr
|
||||
|
||||
// Create new chronometer item (previous item was destroyed by scene on scene()->clear()).
|
||||
// It will be shown on mouse right button click.
|
||||
m_chronometerItem = createChronometer(true);
|
||||
m_chronometerItemAux = createChronometer(false);
|
||||
m_chronometerItem = createChronometer(true);
|
||||
|
||||
bgItem->setBoundingRect(0, 0, endX, y);
|
||||
auto indicator = new ProfTimelineIndicatorItem();
|
||||
indicator->setBoundingRect(0, 0, endX, y);
|
||||
scene()->addItem(indicator);
|
||||
|
||||
// Setting flags
|
||||
m_bTest = false;
|
||||
@ -1348,6 +1398,27 @@ void ProfGraphicsView::updateVisibleSceneRect()
|
||||
m_visibleSceneRect.setWidth(m_visibleSceneRect.width() - vbar->width() - 2);
|
||||
}
|
||||
|
||||
void ProfGraphicsView::updateTimelineStep(qreal _windowWidth)
|
||||
{
|
||||
const auto time = units2microseconds(_windowWidth);
|
||||
if (time < 100)
|
||||
m_timelineStep = 1e-2;
|
||||
else if (time < 10e3)
|
||||
m_timelineStep = 1;
|
||||
else if (time < 10e6)
|
||||
m_timelineStep = 1e3;
|
||||
else
|
||||
m_timelineStep = 1e6;
|
||||
|
||||
auto steps = time / m_timelineStep;
|
||||
while (steps > 50) {
|
||||
m_timelineStep *= 10;
|
||||
steps *= 0.1;
|
||||
}
|
||||
|
||||
m_timelineStep = microseconds2units(m_timelineStep);
|
||||
}
|
||||
|
||||
void ProfGraphicsView::updateScene()
|
||||
{
|
||||
scene()->update(m_visibleSceneRect);
|
||||
@ -1371,6 +1442,7 @@ void ProfGraphicsView::scaleTo(qreal _scale)
|
||||
const auto windowWidth = m_visibleSceneRect.width() / m_scale;
|
||||
m_pScrollbar->setSliderWidth(windowWidth);
|
||||
|
||||
updateTimelineStep(windowWidth);
|
||||
updateScene();
|
||||
}
|
||||
|
||||
@ -1406,6 +1478,7 @@ void ProfGraphicsView::wheelEvent(QWheelEvent* _event)
|
||||
m_pScrollbar->setValue(m_offset);
|
||||
m_bUpdatingRect = false;
|
||||
|
||||
updateTimelineStep(windowWidth);
|
||||
updateScene(); // repaint scene
|
||||
_event->accept();
|
||||
}
|
||||
@ -1821,19 +1894,10 @@ void ProfGraphicsView::onSelectedBlockChange(unsigned int _block_index)
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ProfGraphicsViewWidget::ProfGraphicsViewWidget(bool _test)
|
||||
: QWidget(nullptr)
|
||||
ProfGraphicsViewWidget::ProfGraphicsViewWidget(QWidget* _parent)
|
||||
: QWidget(_parent)
|
||||
, m_scrollbar(new ProfGraphicsScrollbar(nullptr))
|
||||
, m_view(new ProfGraphicsView(_test))
|
||||
//, m_threadWidget(new ProfThreadViewWidget(this,m_view))
|
||||
{
|
||||
initWidget();
|
||||
}
|
||||
|
||||
ProfGraphicsViewWidget::ProfGraphicsViewWidget(const ::profiler::thread_blocks_tree_t& _blocksTree)
|
||||
: QWidget(nullptr)
|
||||
, m_scrollbar(new ProfGraphicsScrollbar(nullptr))
|
||||
, m_view(new ProfGraphicsView(_blocksTree))
|
||||
, m_view(new ProfGraphicsView(nullptr))
|
||||
//, m_threadWidget(new ProfThreadViewWidget(this,m_view))
|
||||
{
|
||||
initWidget();
|
||||
@ -1843,12 +1907,13 @@ void ProfGraphicsViewWidget::initWidget()
|
||||
{
|
||||
auto lay = new QGridLayout(this);
|
||||
lay->setContentsMargins(1, 0, 1, 0);
|
||||
lay->addWidget(m_view,0,1);
|
||||
lay->addWidget(m_view, 0, 1);
|
||||
lay->setSpacing(1);
|
||||
lay->addWidget(m_scrollbar,1,1);
|
||||
lay->addWidget(m_scrollbar, 1, 1);
|
||||
//lay->setSpacing(1);
|
||||
//lay->addWidget(m_threadWidget,0,0);
|
||||
//lay->addWidget(m_threadWidget, 0, 0);
|
||||
setLayout(lay);
|
||||
|
||||
m_view->setScrollbar(m_scrollbar);
|
||||
}
|
||||
|
||||
|
@ -42,6 +42,22 @@
|
||||
|
||||
class ProfGraphicsView;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline qreal units2microseconds(qreal _value)
|
||||
{
|
||||
return _value;
|
||||
//return _value * 1e3;
|
||||
}
|
||||
|
||||
inline qreal microseconds2units(qreal _value)
|
||||
{
|
||||
return _value;
|
||||
//return _value * 1e-3;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class ProfGraphicsItem : public QGraphicsItem
|
||||
{
|
||||
typedef ::profiler_gui::ProfItems Children;
|
||||
@ -53,7 +69,6 @@ class ProfGraphicsItem : public QGraphicsItem
|
||||
|
||||
QRectF m_boundingRect; ///< boundingRect (see QGraphicsItem)
|
||||
const ::profiler::BlocksTreeRoot* m_pRoot; ///< Pointer to the root profiler block (thread block). Used by ProfTreeWidget to restore hierarchy.
|
||||
QRgb m_backgroundColor; ///< Background color (to enable AlternateColors behavior like in QTreeWidget)
|
||||
const bool m_bTest; ///< If true then we are running test()
|
||||
|
||||
public:
|
||||
@ -78,8 +93,6 @@ public:
|
||||
void setBoundingRect(qreal x, qreal y, qreal w, qreal h);
|
||||
void setBoundingRect(const QRectF& _rect);
|
||||
|
||||
void setBackgroundColor(QRgb _color);
|
||||
|
||||
::profiler::thread_id_t threadId() const;
|
||||
|
||||
///< Returns number of levels
|
||||
@ -214,6 +227,25 @@ private:
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define EASY_QGRAPHICSITEM(ClassName) \
|
||||
class ClassName : public QGraphicsItem { \
|
||||
QRectF m_boundingRect; \
|
||||
public: \
|
||||
ClassName() : QGraphicsItem() {} \
|
||||
virtual ~ClassName() {} \
|
||||
void paint(QPainter* _painter, const QStyleOptionGraphicsItem* _option, QWidget* _widget = nullptr) override; \
|
||||
QRectF boundingRect() const override { return m_boundingRect; } \
|
||||
void setBoundingRect(qreal x, qreal y, qreal w, qreal h) { m_boundingRect.setRect(x, y, w, h); } \
|
||||
void setBoundingRect(const QRectF& _rect) { m_boundingRect = _rect; } \
|
||||
}
|
||||
|
||||
EASY_QGRAPHICSITEM(ProfBackgroundItem);
|
||||
EASY_QGRAPHICSITEM(ProfTimelineIndicatorItem);
|
||||
|
||||
#undef EASY_QGRAPHICSITEM
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class ProfGraphicsView : public QGraphicsView
|
||||
{
|
||||
Q_OBJECT
|
||||
@ -230,6 +262,7 @@ private:
|
||||
::profiler::timestamp_t m_beginTime; ///< Begin time of profiler session. Used to reduce values of all begin and end times of profiler blocks.
|
||||
qreal m_scale; ///< Current scale
|
||||
qreal m_offset; ///< Have to use manual offset for all scene content instead of using scrollbars because QScrollBar::value is 32-bit integer :(
|
||||
qreal m_timelineStep; ///<
|
||||
QPoint m_mousePressPos; ///< Last mouse global position (used by mousePressEvent and mouseMoveEvent)
|
||||
QPoint m_mouseMovePath; ///< Mouse move path between press and release of any button
|
||||
Qt::MouseButtons m_mouseButtons; ///< Pressed mouse buttons
|
||||
@ -245,8 +278,7 @@ private:
|
||||
|
||||
public:
|
||||
|
||||
ProfGraphicsView(bool _test = false);
|
||||
ProfGraphicsView(const ::profiler::thread_blocks_tree_t& _blocksTree);
|
||||
ProfGraphicsView(QWidget* _parent = nullptr);
|
||||
virtual ~ProfGraphicsView();
|
||||
|
||||
// Public virtual methods
|
||||
@ -284,6 +316,7 @@ private:
|
||||
bool moveChrono(ProfChronometerItem* _chronometerItem, qreal _mouseX);
|
||||
void initMode();
|
||||
void updateVisibleSceneRect();
|
||||
void updateTimelineStep(qreal _windowWidth);
|
||||
void updateScene();
|
||||
void scaleTo(qreal _scale);
|
||||
qreal setTree(ProfGraphicsItem* _item, const ::profiler::BlocksTree::children_t& _children, qreal& _height, qreal _y, unsigned short _level);
|
||||
@ -318,6 +351,11 @@ public:
|
||||
return m_visibleSceneRect;
|
||||
}
|
||||
|
||||
inline qreal timelineStep() const
|
||||
{
|
||||
return m_timelineStep;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
// Private inline methods
|
||||
@ -334,18 +372,6 @@ private:
|
||||
//return PROF_FROM_MILLISECONDS(_pos);
|
||||
}
|
||||
|
||||
inline qreal to_microseconds(qreal _value) const
|
||||
{
|
||||
return _value;
|
||||
//return _value * 1e-3;
|
||||
}
|
||||
|
||||
inline qreal to_milliseconds(qreal _value) const
|
||||
{
|
||||
return _value * 1e3;
|
||||
//return _value;
|
||||
}
|
||||
|
||||
}; // END of class ProfGraphicsView.
|
||||
|
||||
class ProfThreadViewWidget : public QWidget
|
||||
@ -380,8 +406,7 @@ private:
|
||||
|
||||
public:
|
||||
|
||||
ProfGraphicsViewWidget(bool _test = false);
|
||||
ProfGraphicsViewWidget(const ::profiler::thread_blocks_tree_t& _blocksTree);
|
||||
ProfGraphicsViewWidget(QWidget* _parent = nullptr);
|
||||
virtual ~ProfGraphicsViewWidget();
|
||||
|
||||
ProfGraphicsView* view();
|
||||
|
@ -298,17 +298,6 @@ ProfTreeWidget::ProfTreeWidget(QWidget* _parent) : Parent(_parent), m_beginTime(
|
||||
loadSettings();
|
||||
}
|
||||
|
||||
ProfTreeWidget::ProfTreeWidget(const unsigned int _blocksNumber, const ::profiler::thread_blocks_tree_t& _blocksTree, QWidget* _parent) : This(_parent)
|
||||
{
|
||||
setTreeInternal(_blocksNumber, _blocksTree);
|
||||
|
||||
setSortingEnabled(true);
|
||||
sortByColumn(COL_BEGIN, Qt::AscendingOrder);
|
||||
resizeColumnToContents(COL_NAME);
|
||||
|
||||
connect(this, &Parent::itemExpanded, this, &This::onItemExpand);
|
||||
}
|
||||
|
||||
ProfTreeWidget::~ProfTreeWidget()
|
||||
{
|
||||
saveSettings();
|
||||
|
@ -121,7 +121,6 @@ protected:
|
||||
public:
|
||||
|
||||
ProfTreeWidget(QWidget* _parent = nullptr);
|
||||
ProfTreeWidget(const unsigned int _blocksNumber, const ::profiler::thread_blocks_tree_t& _blocksTree, QWidget* _parent = nullptr);
|
||||
virtual ~ProfTreeWidget();
|
||||
|
||||
void clearSilent(bool _global = false);
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include <vector>
|
||||
#include <unordered_map>
|
||||
#include <QRgb>
|
||||
#include <QString>
|
||||
#include "profiler/reader.h"
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
@ -156,6 +157,40 @@ struct ProfSelectedBlock final
|
||||
|
||||
typedef ::std::vector<ProfSelectedBlock> TreeBlocks;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline QString timeStringReal(qreal _interval, int _precision = 1)
|
||||
{
|
||||
if (_interval < 1) // interval in nanoseconds
|
||||
return QString("%1 ns").arg(_interval * 1e3, 0, 'f', _precision);
|
||||
|
||||
if (_interval < 1e3) // interval in microseconds
|
||||
return QString("%1 us").arg(_interval, 0, 'f', _precision);
|
||||
|
||||
if (_interval < 1e6) // interval in milliseconds
|
||||
return QString("%1 ms").arg(_interval * 1e-3, 0, 'f', _precision);
|
||||
|
||||
// interval in seconds
|
||||
return QString("%1 sec").arg(_interval * 1e-6, 0, 'f', _precision);
|
||||
}
|
||||
|
||||
inline QString timeStringInt(qreal _interval)
|
||||
{
|
||||
if (_interval < 1) // interval in nanoseconds
|
||||
return QString("%1 ns").arg(static_cast<int>(_interval * 1e3));
|
||||
|
||||
if (_interval < 1e3) // interval in microseconds
|
||||
return QString("%1 us").arg(static_cast<int>(_interval));
|
||||
|
||||
if (_interval < 1e6) // interval in milliseconds
|
||||
return QString("%1 ms").arg(static_cast<int>(_interval * 1e-3));
|
||||
|
||||
// interval in seconds
|
||||
return QString("%1 sec").arg(static_cast<int>(_interval * 1e-6));
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
} // END of namespace profiler_gui.
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
@ -43,7 +43,6 @@ namespace profiler_gui {
|
||||
const QColor CHRONOMETER_COLOR = QColor::fromRgba(0x202020c0);
|
||||
const QRgb SELECTED_THREAD_BACKGROUND = 0x00e0e060;
|
||||
const QRgb SELECTED_THREAD_FOREGROUND = 0x00ffffff - SELECTED_THREAD_BACKGROUND;
|
||||
const QRgb SELECTED_ITEM_COLOR = 0x000050a0;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
@ -2,9 +2,7 @@
|
||||
#include <QTreeView>
|
||||
#include <QFileSystemModel>
|
||||
#include <chrono>
|
||||
#include "treemodel.h"
|
||||
#include "blocks_graphics_view.h"
|
||||
#include "blocks_tree_widget.h"
|
||||
//#include "treemodel.h"
|
||||
#include "main_window.h"
|
||||
#include "profiler/reader.h"
|
||||
|
||||
@ -39,48 +37,8 @@ int main(int argc, char **argv)
|
||||
auto now = ::std::chrono::duration_cast<std::chrono::seconds>(::std::chrono::system_clock::now().time_since_epoch()).count() >> 1;
|
||||
srand((unsigned int)now);
|
||||
|
||||
int mode = 2;
|
||||
ProfMainWindow window;
|
||||
window.show();
|
||||
|
||||
switch (mode)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
const bool test = false;
|
||||
|
||||
if (test)
|
||||
{
|
||||
ProfGraphicsView gview(true);
|
||||
gview.show();
|
||||
return app.exec();
|
||||
}
|
||||
|
||||
::profiler::thread_blocks_tree_t threaded_trees;
|
||||
fillTreesFromFile("test.prof", threaded_trees, true);
|
||||
|
||||
ProfGraphicsView gview(threaded_trees);
|
||||
gview.show();
|
||||
|
||||
return app.exec();
|
||||
}
|
||||
|
||||
case 1:
|
||||
{
|
||||
::profiler::thread_blocks_tree_t threaded_trees;
|
||||
auto nblocks = fillTreesFromFile("test.prof", threaded_trees, true);
|
||||
|
||||
ProfTreeWidget view(nblocks, threaded_trees);
|
||||
view.show();
|
||||
|
||||
return app.exec();
|
||||
}
|
||||
|
||||
case 2:
|
||||
{
|
||||
ProfMainWindow window;
|
||||
window.show();
|
||||
return app.exec();
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
return app.exec();
|
||||
}
|
||||
|
@ -46,7 +46,7 @@ ProfMainWindow::ProfMainWindow() : QMainWindow(), m_treeWidget(nullptr), m_graph
|
||||
|
||||
setStatusBar(new QStatusBar());
|
||||
|
||||
auto graphicsView = new ProfGraphicsViewWidget(false);
|
||||
auto graphicsView = new ProfGraphicsViewWidget();
|
||||
m_graphicsView = new QDockWidget("Blocks diagram");
|
||||
m_graphicsView->setMinimumHeight(50);
|
||||
m_graphicsView->setAllowedAreas(Qt::AllDockWidgetAreas);
|
||||
|
Loading…
x
Reference in New Issue
Block a user