From b5b743d9ad33228acdf0a1946bf475c6f22e0169 Mon Sep 17 00:00:00 2001 From: Victor Zarubkin Date: Mon, 13 Mar 2017 20:30:57 +0300 Subject: [PATCH] resolve #20 : You can now turn on an option "Automatically adjust histogram height" (in Settings/View) and histogram height will be adjusted automatically to the visible region (but this restricts you from adjusting manually in zoom mode) --- profiler_gui/easy_graphics_item.cpp | 4 +- profiler_gui/easy_graphics_scrollbar.cpp | 362 +++++++++++++++-------- profiler_gui/easy_graphics_scrollbar.h | 11 +- profiler_gui/globals.cpp | 3 +- profiler_gui/globals.h | 3 +- profiler_gui/globals_qobjects.h | 3 +- profiler_gui/main_window.cpp | 45 ++- profiler_gui/main_window.h | 1 - 8 files changed, 279 insertions(+), 153 deletions(-) diff --git a/profiler_gui/easy_graphics_item.cpp b/profiler_gui/easy_graphics_item.cpp index c11f2c1..ba2b0a9 100644 --- a/profiler_gui/easy_graphics_item.cpp +++ b/profiler_gui/easy_graphics_item.cpp @@ -1027,7 +1027,7 @@ void EasyGraphicsItem::paint(QPainter* _painter, const QStyleOptionGraphicsItem* - if (EASY_GLOBALS.enable_event_indicators && !m_pRoot->events.empty()) + if (EASY_GLOBALS.enable_event_markers && !m_pRoot->events.empty()) { const auto sceneView = view(); auto first = ::std::lower_bound(m_pRoot->events.begin(), m_pRoot->events.end(), p.offset, [&sceneView](::profiler::block_index_t _index, qreal _value) @@ -1192,7 +1192,7 @@ const ::profiler_gui::EasyBlock* EasyGraphicsItem::intersect(const QPointF& _pos { // The Y position is out of blocks range - if (EASY_GLOBALS.enable_event_indicators && !m_pRoot->events.empty()) + if (EASY_GLOBALS.enable_event_markers && !m_pRoot->events.empty()) { // If event indicators are enabled then try to intersect with one of event indicators diff --git a/profiler_gui/easy_graphics_scrollbar.cpp b/profiler_gui/easy_graphics_scrollbar.cpp index 9db9043..a500403 100644 --- a/profiler_gui/easy_graphics_scrollbar.cpp +++ b/profiler_gui/easy_graphics_scrollbar.cpp @@ -233,14 +233,16 @@ EasyHistogramItem::EasyHistogramItem() : Parent(nullptr) , m_threadProfiledTime(0) , m_threadWaitTime(0) , m_pSource(nullptr) - , m_temporaryImage(nullptr) + , m_workerImage(nullptr) , m_topDuration(0) , m_maxDuration(0) , m_minDuration(0) , m_imageOrigin(0) , m_imageScale(1) - , m_temporaryImageOrigin(0) - , m_temporaryImageScale(1) + , m_workerImageOrigin(0) + , m_workerImageScale(1) + , m_workerTopDuration(0) + , m_workerBottomDuration(0) , m_timer(::std::bind(&This::onTimeout, this)) , m_boundaryTimer([this](){ updateImage(); }, true) , m_pProfilerThread(nullptr) @@ -259,7 +261,7 @@ EasyHistogramItem::~EasyHistogramItem() m_bReady.store(true, ::std::memory_order_release); if (m_workerThread.joinable()) m_workerThread.join(); - delete m_temporaryImage; + delete m_workerImage; } QRectF EasyHistogramItem::boundingRect() const @@ -791,8 +793,8 @@ void EasyHistogramItem::setSource(::profiler::thread_id_t _thread_id, const ::pr if (m_workerThread.joinable()) m_workerThread.join(); - delete m_temporaryImage; - m_temporaryImage = nullptr; + delete m_workerImage; + m_workerImage = nullptr; m_imageOriginUpdate = m_imageOrigin = 0; m_imageScaleUpdate = m_imageScale = 1; @@ -829,18 +831,10 @@ void EasyHistogramItem::setSource(::profiler::thread_id_t _thread_id, const ::pr m_bReady.store(false, ::std::memory_order_release); m_workerThread = ::std::thread([this](const ::profiler_gui::EasyItems* _source) { - m_topDuration = m_maxDuration = 0; - m_bottomDuration = m_minDuration = 1e30; + m_maxDuration = 0; + m_minDuration = 1e30; - /* -#define median_window 3 -#define median_mid 1 -#define median_midmax 1 - - int windowIndex = 0; - float window[median_window] = {}; - float sortedWindow[median_window] = {}; - float windowSum = 0; + bool empty = true; for (const auto& item : *_source) { if (m_bReady.load(::std::memory_order_acquire)) @@ -849,33 +843,6 @@ void EasyHistogramItem::setSource(::profiler::thread_id_t _thread_id, const ::pr if (easyDescriptor(easyBlock(item.block).tree.node->id()).type() == ::profiler::BLOCK_TYPE_EVENT) continue; - const auto w = item.width(); - window[median_mid - windowIndex] = w; - window[median_mid + windowIndex] = w; - - if (++windowIndex == median_midmax) - break; - } - - for (auto w : window) windowSum += w; - memcpy(sortedWindow, window, sizeof(window)); - std::sort(sortedWindow, sortedWindow + median_window); - - windowIndex = 0; - size_t i = 0; - */ - - for (const auto& item : *_source) - { - if (m_bReady.load(::std::memory_order_acquire)) - return; - - if (easyDescriptor(easyBlock(item.block).tree.node->id()).type() == ::profiler::BLOCK_TYPE_EVENT) - { - //++i; - continue; - } - const auto w = item.width(); if (w > m_maxDuration) @@ -884,48 +851,35 @@ void EasyHistogramItem::setSource(::profiler::thread_id_t _thread_id, const ::pr if (w < m_minDuration) m_minDuration = w; - /*for (size_t j = i + 1; ; ++j) + empty = false; + } + + if ((m_maxDuration - m_minDuration) < 1e-3) + { + if (m_minDuration > 0.1) { - size_t k = j; - if (j >= _source->size()) - k = _source->size() - 1 - j + _source->size(); - - const auto& jtem = _source->operator[](k); - if (easyDescriptor(easyBlock(item.block).tree.node->id()).type() == ::profiler::BLOCK_TYPE_EVENT) - continue; - - windowSum -= window[windowIndex]; - window[windowIndex] = jtem.width(); - windowSum += window[windowIndex]; - break; + m_minDuration -= 0.1; } - - const bool applyFilter = (w > m_topDuration * 2 || w < m_bottomDuration * 0.5); - if (applyFilter) + else { - memcpy(sortedWindow, window, sizeof(window)); - std::sort(sortedWindow, sortedWindow + median_window); - w = sortedWindow[median_mid]; - //w = windowSum / median_window; + m_maxDuration = 0.1; + m_minDuration = 0; } - - if (w > m_topDuration) - m_topDuration = w; - - if (w < m_bottomDuration) - m_bottomDuration = w; - - if (++windowIndex == median_window) - windowIndex = 0; - - ++i;*/ } m_topDuration = m_maxDuration; m_bottomDuration = m_minDuration; - m_topDurationStr = ::profiler_gui::timeStringReal(m_timeUnits, m_topDuration, 3); - m_bottomDurationStr = ::profiler_gui::timeStringReal(m_timeUnits, m_bottomDuration, 3); + if (!empty) + { + m_topDurationStr = ::profiler_gui::timeStringReal(m_timeUnits, m_topDuration, 3); + m_bottomDurationStr = ::profiler_gui::timeStringReal(m_timeUnits, m_bottomDuration, 3); + } + else + { + m_topDurationStr.clear(); + m_bottomDurationStr.clear(); + } m_bReady.store(true, ::std::memory_order_release); @@ -965,8 +919,8 @@ void EasyHistogramItem::setSource(::profiler::thread_id_t _thread_id, ::profiler if (m_workerThread.joinable()) m_workerThread.join(); - delete m_temporaryImage; - m_temporaryImage = nullptr; + delete m_workerImage; + m_workerImage = nullptr; m_imageOriginUpdate = m_imageOrigin = 0; m_imageScaleUpdate = m_imageScale = 1; @@ -1068,10 +1022,26 @@ void EasyHistogramItem::setSource(::profiler::thread_id_t _thread_id, ::profiler { m_maxDuration *= 1e-3; m_minDuration *= 1e-3; + + if ((m_maxDuration - m_minDuration) < 1e-3) + { + if (m_minDuration > 0.1) + { + m_minDuration -= 0.1; + } + else + { + m_maxDuration = 0.1; + m_minDuration = 0; + } + } + m_topDurationStr = ::profiler_gui::timeStringReal(m_timeUnits, m_maxDuration, 3); m_bottomDurationStr = ::profiler_gui::timeStringReal(m_timeUnits, m_minDuration, 3); } + + m_topDuration = m_maxDuration; m_bottomDuration = m_minDuration; @@ -1129,12 +1099,21 @@ void EasyHistogramItem::onTimeout() if (m_workerThread.joinable()) m_workerThread.join(); - m_temporaryImage->swap(m_mainImage); - delete m_temporaryImage; - m_temporaryImage = nullptr; + m_workerImage->swap(m_mainImage); + delete m_workerImage; + m_workerImage = nullptr; - m_imageOriginUpdate = m_imageOrigin = m_temporaryImageOrigin; - m_imageScaleUpdate = m_imageScale = m_temporaryImageScale; + m_imageOriginUpdate = m_imageOrigin = m_workerImageOrigin; + m_imageScaleUpdate = m_imageScale = m_workerImageScale; + + if (EASY_GLOBALS.auto_adjust_histogram_height && !m_topDurationStr.isEmpty()) + { + m_topDuration = m_workerTopDuration; + m_bottomDuration = m_workerBottomDuration; + + m_topDurationStr = ::profiler_gui::timeStringReal(m_timeUnits, m_topDuration, 3); + m_bottomDurationStr = ::profiler_gui::timeStringReal(m_timeUnits, m_bottomDuration, 3); + } } } @@ -1145,7 +1124,7 @@ void EasyHistogramItem::onTimeout() void EasyHistogramItem::pickTopBoundary(qreal _y) { - if (m_bPermitImageUpdate && m_boundingRect.top() < _y && _y < m_boundingRect.bottom()) + if (m_bPermitImageUpdate && m_boundingRect.top() < _y && _y < m_boundingRect.bottom() && !m_topDurationStr.isEmpty()) { m_topDuration = m_bottomDuration + (m_topDuration - m_bottomDuration) * (m_boundingRect.bottom() - _y) / (m_boundingRect.height() - HIST_COLUMN_MIN_HEIGHT); m_topDurationStr = ::profiler_gui::timeStringReal(m_timeUnits, m_topDuration, 3); @@ -1157,7 +1136,7 @@ void EasyHistogramItem::pickTopBoundary(qreal _y) void EasyHistogramItem::increaseTopBoundary() { - if (m_bPermitImageUpdate && m_topDuration < m_maxDuration) + if (m_bPermitImageUpdate && m_topDuration < m_maxDuration && !m_topDurationStr.isEmpty()) { auto step = 0.05 * (m_maxDuration - m_bottomDuration); if (m_topDuration < (m_bottomDuration + 1.25 * step)) @@ -1175,7 +1154,7 @@ void EasyHistogramItem::increaseTopBoundary() void EasyHistogramItem::decreaseTopBoundary() { - if (m_bPermitImageUpdate && m_topDuration > m_bottomDuration) + if (m_bPermitImageUpdate && m_topDuration > m_bottomDuration && !m_topDurationStr.isEmpty()) { auto step = 0.05 * (m_maxDuration - m_bottomDuration); if (m_topDuration < (m_bottomDuration + 1.25 * step)) @@ -1197,7 +1176,7 @@ void EasyHistogramItem::decreaseTopBoundary() void EasyHistogramItem::pickBottomBoundary(qreal _y) { - if (m_bPermitImageUpdate && m_boundingRect.top() < _y && _y < m_boundingRect.bottom()) + if (m_bPermitImageUpdate && m_boundingRect.top() < _y && _y < m_boundingRect.bottom() && !m_bottomDurationStr.isEmpty()) { m_bottomDuration = m_bottomDuration + (m_topDuration - m_bottomDuration) * (m_boundingRect.bottom() - _y) / (m_boundingRect.height() - HIST_COLUMN_MIN_HEIGHT); m_bottomDurationStr = ::profiler_gui::timeStringReal(m_timeUnits, m_bottomDuration, 3); @@ -1209,7 +1188,7 @@ void EasyHistogramItem::pickBottomBoundary(qreal _y) void EasyHistogramItem::increaseBottomBoundary() { - if (m_bPermitImageUpdate && m_bottomDuration < m_topDuration) + if (m_bPermitImageUpdate && m_bottomDuration < m_topDuration && !m_bottomDurationStr.isEmpty()) { auto step = 0.05 * (m_topDuration - m_minDuration); if (m_bottomDuration > (m_topDuration - 1.25 * step)) @@ -1229,10 +1208,7 @@ void EasyHistogramItem::increaseBottomBoundary() void EasyHistogramItem::decreaseBottomBoundary() { - if (!m_bPermitImageUpdate) - return; - - if (m_bottomDuration > m_minDuration) + if (m_bPermitImageUpdate && m_bottomDuration > m_minDuration && !m_bottomDurationStr.isEmpty()) { auto step = 0.05 * (m_topDuration - m_minDuration); if (m_bottomDuration > (m_topDuration - 1.25 * step)) @@ -1256,10 +1232,10 @@ void EasyHistogramItem::setMouseY(qreal _mouseY) void EasyHistogramItem::pickFrameTime(qreal _y) const { - if (m_bPermitImageUpdate && m_boundingRect.top() < _y && _y < m_boundingRect.bottom()) + if (m_bPermitImageUpdate && m_boundingRect.top() < _y && _y < m_boundingRect.bottom() && !m_topDurationStr.isEmpty()) { EASY_GLOBALS.frame_time = m_bottomDuration + (m_topDuration - m_bottomDuration) * (m_boundingRect.bottom() - _y) / (m_boundingRect.height() - HIST_COLUMN_MIN_HEIGHT); - emit EASY_GLOBALS.events.timelineMarkerChanged(); + emit EASY_GLOBALS.events.expectedFrameTimeChanged(); } } @@ -1294,6 +1270,25 @@ void EasyHistogramItem::onValueChanged() ////////////////////////////////////////////////////////////////////////// +void EasyHistogramItem::onModeChanged() +{ + if (!m_bPermitImageUpdate) + return; + + const auto widget = static_cast(scene()->parent()); + + if (!widget->bindMode() && EASY_GLOBALS.auto_adjust_histogram_height) + { + m_topDuration = m_maxDuration; + m_bottomDuration = m_minDuration; + } + + m_boundaryTimer.stop(); + updateImage(); +} + +////////////////////////////////////////////////////////////////////////// + void EasyHistogramItem::cancelImageUpdate() { if (!m_bPermitImageUpdate) @@ -1304,8 +1299,8 @@ void EasyHistogramItem::cancelImageUpdate() m_workerThread.join(); m_bReady.store(false, ::std::memory_order_release); - delete m_temporaryImage; - m_temporaryImage = nullptr; + delete m_workerImage; + m_workerImage = nullptr; m_imageOriginUpdate = m_imageOrigin; m_imageScaleUpdate = m_imageScale; @@ -1325,20 +1320,20 @@ void EasyHistogramItem::updateImage() m_workerThread.join(); m_bReady.store(false, ::std::memory_order_release); - delete m_temporaryImage; - m_temporaryImage = nullptr; + delete m_workerImage; + m_workerImage = nullptr; m_imageScaleUpdate = widget->range() / widget->sliderWidth(); m_imageOriginUpdate = widget->bindMode() ? (widget->value() - widget->sliderWidth() * 3) : widget->minimum(); m_workerThread = ::std::thread([this](QRectF _boundingRect, HistRegime _regime, qreal _current_scale, qreal _minimum, qreal _maximum, qreal _range, qreal _value, qreal _width, qreal _top_duration, qreal _bottom_duration, - bool _bindMode, float _frame_time, ::profiler::timestamp_t _begin_time, qreal _origin) + bool _bindMode, float _frame_time, ::profiler::timestamp_t _begin_time, qreal _origin, bool _autoAdjustHist) { - updateImage(_boundingRect, _regime, _current_scale, _minimum, _maximum, _range, _value, _width, _top_duration, _bottom_duration, _bindMode, _frame_time, _begin_time, _origin); + updateImage(_boundingRect, _regime, _current_scale, _minimum, _maximum, _range, _value, _width, _top_duration, _bottom_duration, _bindMode, _frame_time, _begin_time, _origin, _autoAdjustHist); m_bReady.store(true, ::std::memory_order_release); }, m_boundingRect, m_regime, widget->getWindowScale(), widget->minimum(), widget->maximum(), widget->range(), widget->value(), widget->sliderWidth(), - m_topDuration, m_bottomDuration, widget->bindMode(), EASY_GLOBALS.frame_time, EASY_GLOBALS.begin_time, m_imageOriginUpdate); + m_topDuration, m_bottomDuration, widget->bindMode(), EASY_GLOBALS.frame_time, EASY_GLOBALS.begin_time, m_imageOriginUpdate, EASY_GLOBALS.auto_adjust_histogram_height); m_timeouts = 3; m_timer.start(WORKER_THREAD_CHECK_INTERVAL); @@ -1348,30 +1343,28 @@ void EasyHistogramItem::updateImage(QRectF _boundingRect, HistRegime _regime, qr qreal _minimum, qreal _maximum, qreal _range, qreal _value, qreal _width, qreal _top_duration, qreal _bottom_duration, bool _bindMode, float _frame_time, ::profiler::timestamp_t _begin_time, - qreal _origin) + qreal _origin, bool _autoAdjustHist) { const auto bottom = _boundingRect.height();//_boundingRect.bottom(); const auto screenWidth = _boundingRect.width() * _current_scale; - const auto dtime = _top_duration - _bottom_duration; const auto maxColumnHeight = _boundingRect.height(); - const auto coeff = (_boundingRect.height() - HIST_COLUMN_MIN_HEIGHT) / (dtime > 1e-3 ? dtime : 1.); const auto viewScale = _range / _width; if (_bindMode) { - m_temporaryImageScale = viewScale; - m_temporaryImageOrigin = _value - _width * 3; - m_temporaryImage = new QImage(screenWidth * 7 + 0.5, _boundingRect.height(), QImage::Format_ARGB32); + m_workerImageScale = viewScale; + m_workerImageOrigin = _value - _width * 3; + m_workerImage = new QImage(screenWidth * 7 + 0.5, _boundingRect.height(), QImage::Format_ARGB32); } else { - m_temporaryImageScale = 1; - m_temporaryImageOrigin = _minimum; - m_temporaryImage = new QImage(screenWidth + 0.5, _boundingRect.height(), QImage::Format_ARGB32); + m_workerImageScale = 1; + m_workerImageOrigin = _minimum; + m_workerImage = new QImage(screenWidth + 0.5, _boundingRect.height(), QImage::Format_ARGB32); } - m_temporaryImage->fill(0); - QPainter p(m_temporaryImage); + m_workerImage->fill(0); + QPainter p(m_workerImage); p.setPen(Qt::NoPen); QRectF rect; @@ -1404,8 +1397,8 @@ void EasyHistogramItem::updateImage(QRectF _boundingRect, HistRegime _regime, qr if (_bindMode) { - _minimum = m_temporaryImageOrigin; - _maximum = m_temporaryImageOrigin + _width * 7; + _minimum = m_workerImageOrigin; + _maximum = m_workerImageOrigin + _width * 7; realScale *= viewScale; offset = _minimum * realScale; @@ -1423,8 +1416,55 @@ void EasyHistogramItem::updateImage(QRectF _boundingRect, HistRegime _regime, qr { first = items.begin() + items.size() - 1; } + + if (_autoAdjustHist) + { + const auto maxVal = _value + _width; + decltype(_top_duration) maxDuration = 0; + decltype(_bottom_duration) minDuration = 1e30; + size_t iterations = 0; + for (auto it = first, end = items.end(); it != end; ++it) + { + // Draw rectangle + if (it->left() > maxVal) + break; + + if (it->right() < _value) + continue; + + if (maxDuration < it->width()) + maxDuration = it->width(); + + if (minDuration > it->width()) + minDuration = it->width(); + + ++iterations; + } + + if (iterations) + { + _top_duration = maxDuration; + _bottom_duration = minDuration; + + if ((_top_duration - _bottom_duration) < 1e-3) + { + if (_bottom_duration > 0.1) + { + _bottom_duration -= 0.1; + } + else + { + _top_duration = 0.1; + _bottom_duration = 0; + } + } + } + } } + const auto dtime = _top_duration - _bottom_duration; + const auto coeff = (_boundingRect.height() - HIST_COLUMN_MIN_HEIGHT) / (dtime > 1e-3 ? dtime : 1.); + for (auto it = first, end = items.end(); it != end; ++it) { // Draw rectangle @@ -1467,8 +1507,8 @@ void EasyHistogramItem::updateImage(QRectF _boundingRect, HistRegime _regime, qr if (_bindMode) { - _minimum = m_temporaryImageOrigin; - _maximum = m_temporaryImageOrigin + _width * 7; + _minimum = m_workerImageOrigin; + _maximum = m_workerImageOrigin + _width * 7; realScale *= viewScale; offset = _minimum * 1e3 * realScale; @@ -1486,10 +1526,67 @@ void EasyHistogramItem::updateImage(QRectF _boundingRect, HistRegime _regime, qr { first = m_selectedBlocks.begin() + m_selectedBlocks.size() - 1; } + + _minimum *= 1e3; + _maximum *= 1e3; + + if (_autoAdjustHist) + { + const auto minVal = _value * 1e3, maxVal = (_value + _width) * 1e3; + decltype(_top_duration) maxDuration = 0; + decltype(_bottom_duration) minDuration = 1e30; + size_t iterations = 0; + for (auto it = first, end = m_selectedBlocks.end(); it != end; ++it) + { + const auto item = easyBlock(*it).tree.node; + + const auto beginTime = item->begin() - _begin_time; + if (beginTime > maxVal) + break; + + const auto endTime = item->end() - _begin_time; + if (endTime < minVal) + continue; + + const qreal duration = item->duration() * 1e-3; + + if (maxDuration < duration) + maxDuration = duration; + + if (minDuration > duration) + minDuration = duration; + + ++iterations; + } + + if (iterations) + { + _top_duration = maxDuration; + _bottom_duration = minDuration; + + if ((_top_duration - _bottom_duration) < 1e-3) + { + if (_bottom_duration > 0.1) + { + _bottom_duration -= 0.1; + } + else + { + _top_duration = 0.1; + _bottom_duration = 0; + } + } + } + } + } + else + { + _minimum *= 1e3; + _maximum *= 1e3; } - _minimum *= 1e3; - _maximum *= 1e3; + const auto dtime = _top_duration - _bottom_duration; + const auto coeff = (_boundingRect.height() - HIST_COLUMN_MIN_HEIGHT) / (dtime > 1e-3 ? dtime : 1.); for (auto it = first, end = m_selectedBlocks.end(); it != end; ++it) { @@ -1532,6 +1629,9 @@ void EasyHistogramItem::updateImage(QRectF _boundingRect, HistRegime _regime, qr previous_h = h; } } + + m_workerTopDuration = _top_duration; + m_workerBottomDuration = _bottom_duration; } ////////////////////////////////////////////////////////////////////////// @@ -1587,19 +1687,28 @@ EasyGraphicsScrollbar::EasyGraphicsScrollbar(QWidget* _parent) selfScene->addItem(m_slider); m_slider->hide(); - connect(&EASY_GLOBALS.events, &::profiler_gui::EasyGlobalSignals::timelineMarkerChanged, [this]() + connect(&EASY_GLOBALS.events, &::profiler_gui::EasyGlobalSignals::expectedFrameTimeChanged, [this]() { if (m_histogramItem->isVisible()) + { m_histogramItem->updateImage(); - scene()->update(); + scene()->update(); + } + }); + + connect(&EASY_GLOBALS.events, &::profiler_gui::EasyGlobalSignals::autoAdjustHistogramChanged, [this]() + { + if (m_histogramItem->isVisible()) + m_histogramItem->onModeChanged(); }); connect(&EASY_GLOBALS.events, &::profiler_gui::EasyGlobalSignals::threadNameDecorationChanged, [this]() { - if (!m_histogramItem->isVisible()) - return; - m_histogramItem->validateName(); - scene()->update(); + if (m_histogramItem->isVisible()) + { + m_histogramItem->validateName(); + scene()->update(); + } }); centerOn(0, 0); @@ -1790,8 +1899,7 @@ void EasyGraphicsScrollbar::mousePressEvent(QMouseEvent* _event) { m_bBindMode = !m_bBindMode; if (m_histogramItem->isVisible()) - m_histogramItem->updateImage(); - scene()->update(); + m_histogramItem->onModeChanged(); } } diff --git a/profiler_gui/easy_graphics_scrollbar.h b/profiler_gui/easy_graphics_scrollbar.h index 30a452b..e14e7dc 100644 --- a/profiler_gui/easy_graphics_scrollbar.h +++ b/profiler_gui/easy_graphics_scrollbar.h @@ -143,8 +143,10 @@ class EasyHistogramItem : public QGraphicsItem qreal m_imageScale; qreal m_imageOriginUpdate; qreal m_imageScaleUpdate; - qreal m_temporaryImageOrigin; - qreal m_temporaryImageScale; + qreal m_workerImageOrigin; + qreal m_workerImageScale; + qreal m_workerTopDuration; + qreal m_workerBottomDuration; QString m_topDurationStr; QString m_bottomDurationStr; QString m_threadName; @@ -157,7 +159,7 @@ class EasyHistogramItem : public QGraphicsItem ::profiler::timestamp_t m_threadProfiledTime; ::profiler::timestamp_t m_threadWaitTime; const ::profiler_gui::EasyItems* m_pSource; - QImage* m_temporaryImage; + QImage* m_workerImage; const ::profiler::BlocksTreeRoot* m_pProfilerThread; ::profiler::thread_id_t m_threadId; ::profiler::block_index_t m_blockId; @@ -205,6 +207,7 @@ public: void pickFrameTime(qreal _y) const; void onValueChanged(); + void onModeChanged(); private: @@ -216,7 +219,7 @@ private: void updateImage(QRectF _boundingRect, HistRegime _regime, qreal _current_scale, qreal _minimum, qreal _maximum, qreal _range, qreal _value, qreal _width, qreal _top_duration, qreal _bottom_duration, bool _bindMode, - float _frame_time, ::profiler::timestamp_t _begin_time, qreal _origin); + float _frame_time, ::profiler::timestamp_t _begin_time, qreal _origin, bool _autoAdjustHist); }; // END of class EasyHistogramItem. diff --git a/profiler_gui/globals.cpp b/profiler_gui/globals.cpp index ec52df2..1d6741c 100644 --- a/profiler_gui/globals.cpp +++ b/profiler_gui/globals.cpp @@ -70,7 +70,7 @@ namespace profiler_gui { , time_units(TimeUnits_ms) , connected(false) , use_decorated_thread_name(true) - , enable_event_indicators(true) + , enable_event_markers(true) , enable_statistics(true) , enable_zero_length(true) , add_zero_blocks_to_hierarchy(false) @@ -83,6 +83,7 @@ namespace profiler_gui { , only_current_thread_hierarchy(false) , highlight_blocks_with_same_id(true) , selecting_block_changes_thread(true) + , auto_adjust_histogram_height(false) , bind_scene_and_tree_expand_status(true) { diff --git a/profiler_gui/globals.h b/profiler_gui/globals.h index c04f636..ad26ac7 100644 --- a/profiler_gui/globals.h +++ b/profiler_gui/globals.h @@ -149,7 +149,7 @@ namespace profiler_gui { TimeUnits time_units; ///< Units type for time (milliseconds, microseconds, nanoseconds or auto-definition) bool connected; ///< Is connected to source (to be able to capture profiling information) bool use_decorated_thread_name; ///< Add "Thread" to the name of each thread (if there is no one) - bool enable_event_indicators; ///< Enable event indicators painting (These are narrow rectangles at the bottom of each thread) + bool enable_event_markers; ///< Enable event indicators painting (These are narrow rectangles at the bottom of each thread) bool enable_statistics; ///< Enable gathering and using statistics (Disable if you want to consume less memory) bool enable_zero_length; ///< Enable zero length blocks (if true, then such blocks will have width == 1 pixel on each scale) bool add_zero_blocks_to_hierarchy; ///< Enable adding zero blocks into hierarchy tree @@ -162,6 +162,7 @@ namespace profiler_gui { bool only_current_thread_hierarchy; ///< Build hierarchy tree for current thread only bool highlight_blocks_with_same_id; ///< Highlight all blocks with same id on diagram bool selecting_block_changes_thread; ///< If true then current selected thread will change every time you select block + bool auto_adjust_histogram_height; ///< Automatically adjust histogram height to the visible region bool bind_scene_and_tree_expand_status; /** \brief If true then items on graphics scene and in the tree (blocks hierarchy) are binded on each other so expanding/collapsing items on scene also expands/collapse items in the tree. */ diff --git a/profiler_gui/globals_qobjects.h b/profiler_gui/globals_qobjects.h index 609e4ba..df40666 100644 --- a/profiler_gui/globals_qobjects.h +++ b/profiler_gui/globals_qobjects.h @@ -54,7 +54,8 @@ namespace profiler_gui { void blockStatusChanged(::profiler::block_id_t _id, ::profiler::EasyBlockStatus _status); void connectionChanged(bool _connected); void blocksRefreshRequired(bool); - void timelineMarkerChanged(); + void expectedFrameTimeChanged(); + void autoAdjustHistogramChanged(); void hierarchyFlagChanged(bool); void threadNameDecorationChanged(); void refreshRequired(); diff --git a/profiler_gui/main_window.cpp b/profiler_gui/main_window.cpp index f49f616..bdfe0de 100644 --- a/profiler_gui/main_window.cpp +++ b/profiler_gui/main_window.cpp @@ -334,11 +334,25 @@ EasyMainWindow::EasyMainWindow() : Parent(), m_lastAddress("localhost"), m_lastP action->setChecked(EASY_GLOBALS.selecting_block_changes_thread); connect(action, &QAction::triggered, [this](bool _checked){ EASY_GLOBALS.selecting_block_changes_thread = _checked; }); - action = submenu->addAction("Draw event indicators"); - action->setToolTip("Display event indicators under the blocks\n(even if event-blocks are not visible).\nThis slightly reduces performance."); + action = submenu->addAction("Draw event markers"); + action->setToolTip("Display event markers under the blocks\n(even if event-blocks are not visible).\nThis slightly reduces performance."); action->setCheckable(true); - action->setChecked(EASY_GLOBALS.enable_event_indicators); - connect(action, &QAction::triggered, this, &This::onEventIndicatorsChange); + action->setChecked(EASY_GLOBALS.enable_event_markers); + connect(action, &QAction::triggered, [this](bool _checked) + { + EASY_GLOBALS.enable_event_markers = _checked; + refreshDiagram(); + }); + + action = submenu->addAction("Automatically adjust histogram height"); + action->setToolTip("You do not need to adjust boundaries manually,\nbut this restricts you from adjusting boundaries at all (zoom mode).\nYou can still adjust boundaries in overview mode though."); + action->setCheckable(true); + action->setChecked(EASY_GLOBALS.auto_adjust_histogram_height); + connect(action, &QAction::triggered, [](bool _checked) + { + EASY_GLOBALS.auto_adjust_histogram_height = _checked; + emit EASY_GLOBALS.events.autoAdjustHistogramChanged(); + }); action = submenu->addAction("Use decorated thread names"); action->setToolTip("Add \'Thread\' word into thread name if there is no one already.\nExamples: \'Render\' will change to \'Render Thread\'\n\'WorkerThread\' will not change."); @@ -514,7 +528,7 @@ EasyMainWindow::EasyMainWindow() : Parent(), m_lastAddress("localhost"), m_lastP m_frameTimeEdit->setValidator(val); m_frameTimeEdit->setText(QString::number(EASY_GLOBALS.frame_time * 1e-3)); connect(m_frameTimeEdit, &QLineEdit::editingFinished, this, &This::onFrameTimeEditFinish); - connect(&EASY_GLOBALS.events, &::profiler_gui::EasyGlobalSignals::timelineMarkerChanged, this, &This::onFrameTimeChanged); + connect(&EASY_GLOBALS.events, &::profiler_gui::EasyGlobalSignals::expectedFrameTimeChanged, this, &This::onFrameTimeChanged); toolbar->addWidget(m_frameTimeEdit); lbl = new QLabel("ms", toolbar); @@ -790,12 +804,6 @@ void EasyMainWindow::onUnitsChanged(bool) EASY_GLOBALS.time_units = static_cast<::profiler_gui::TimeUnits>(_sender->data().toInt()); } -void EasyMainWindow::onEventIndicatorsChange(bool _checked) -{ - EASY_GLOBALS.enable_event_indicators = _checked; - refreshDiagram(); -} - void EasyMainWindow::onEnableDisableStatistics(bool _checked) { EASY_GLOBALS.enable_statistics = _checked; @@ -1028,7 +1036,11 @@ void EasyMainWindow::loadSettings() flag = settings.value("enable_event_indicators"); if (!flag.isNull()) - EASY_GLOBALS.enable_event_indicators = flag.toBool(); + EASY_GLOBALS.enable_event_markers = flag.toBool(); + + flag = settings.value("auto_adjust_histogram_height"); + if (!flag.isNull()) + EASY_GLOBALS.auto_adjust_histogram_height = flag.toBool(); flag = settings.value("use_decorated_thread_name"); if (!flag.isNull()) @@ -1089,7 +1101,8 @@ void EasyMainWindow::saveSettingsAndGeometry() settings.setValue("highlight_blocks_with_same_id", EASY_GLOBALS.highlight_blocks_with_same_id); settings.setValue("bind_scene_and_tree_expand_status", EASY_GLOBALS.bind_scene_and_tree_expand_status); settings.setValue("selecting_block_changes_thread", EASY_GLOBALS.selecting_block_changes_thread); - settings.setValue("enable_event_indicators", EASY_GLOBALS.enable_event_indicators); + settings.setValue("enable_event_indicators", EASY_GLOBALS.enable_event_markers); + settings.setValue("auto_adjust_histogram_height", EASY_GLOBALS.auto_adjust_histogram_height); settings.setValue("use_decorated_thread_name", EASY_GLOBALS.use_decorated_thread_name); settings.setValue("enable_statistics", EASY_GLOBALS.enable_statistics); settings.setValue("encoding", QTextCodec::codecForLocale()->name()); @@ -1436,9 +1449,9 @@ void EasyMainWindow::onFrameTimeEditFinish() EASY_GLOBALS.frame_time = text.toFloat() * 1e3f; - disconnect(&EASY_GLOBALS.events, &::profiler_gui::EasyGlobalSignals::timelineMarkerChanged, this, &This::onFrameTimeChanged); - emit EASY_GLOBALS.events.timelineMarkerChanged(); - connect(&EASY_GLOBALS.events, &::profiler_gui::EasyGlobalSignals::timelineMarkerChanged, this, &This::onFrameTimeChanged); + disconnect(&EASY_GLOBALS.events, &::profiler_gui::EasyGlobalSignals::expectedFrameTimeChanged, this, &This::onFrameTimeChanged); + emit EASY_GLOBALS.events.expectedFrameTimeChanged(); + connect(&EASY_GLOBALS.events, &::profiler_gui::EasyGlobalSignals::expectedFrameTimeChanged, this, &This::onFrameTimeChanged); } void EasyMainWindow::onFrameTimeChanged() diff --git a/profiler_gui/main_window.h b/profiler_gui/main_window.h index 2afd750..49b404b 100644 --- a/profiler_gui/main_window.h +++ b/profiler_gui/main_window.h @@ -237,7 +237,6 @@ protected slots: void onEncodingChanged(bool); void onChronoTextPosChanged(bool); void onUnitsChanged(bool); - void onEventIndicatorsChange(bool); void onEnableDisableStatistics(bool); void onCollapseItemsAfterCloseChanged(bool); void onAllItemsExpandedByDefaultChange(bool);