From ce8bff4b31f109c701d09ce587ca3e55939806dc Mon Sep 17 00:00:00 2001 From: Ulf Hermann Date: Wed, 10 Aug 2016 19:01:13 +0200 Subject: [PATCH] Timeline: Calculate minimum event distances only when we have to ... and not on every single frame. Task-number: QTCREATORBUG-14983 Change-Id: Id0724d3362ceca222cfdaaba60987b1269c8a5ae Reviewed-by: Milian Wolff Reviewed-by: Christian Kandeler Reviewed-by: Ulf Hermann --- src/libs/timeline/timelineitemsrenderpass.cpp | 82 +++++++++++-------- 1 file changed, 46 insertions(+), 36 deletions(-) diff --git a/src/libs/timeline/timelineitemsrenderpass.cpp b/src/libs/timeline/timelineitemsrenderpass.cpp index 235a3388168..b35497047a9 100644 --- a/src/libs/timeline/timelineitemsrenderpass.cpp +++ b/src/libs/timeline/timelineitemsrenderpass.cpp @@ -112,6 +112,7 @@ private: float selectionId; }; + void calculateDistances(); int updateVertices(TimelineItemsGeometry &geometry, const QVarLengthArray &distances, qint64 minDistance, float itemTop, int i) const; void addEvent(TimelineItemsGeometry &geometry, const QVarLengthArray &distances, @@ -397,9 +398,12 @@ TimelineRenderPass::State *TimelineItemsRenderPass::update(const TimelineAbstrac state->updateCollapsedRowMaterial(spacing / parentState->scale(), selectedItem, selectionColor); - NodeUpdater updater(model, parentState, state, indexFrom, indexTo); - updater.run(); - + if (state->indexFrom() < state->indexTo()) { + if (indexFrom < state->indexFrom() || indexTo > state->indexTo()) + NodeUpdater(model, parentState, state, indexFrom, indexTo).run(); + } else if (indexFrom < indexTo) { + NodeUpdater(model, parentState, state, indexFrom, indexTo).run(); + } if (model->expanded()) { for (int row = 0; row < model->expandedRowCount(); ++row) { @@ -565,45 +569,48 @@ void TimelineItemsRenderPassState::updateCollapsedRowMaterial(float xScale, int NodeUpdater::NodeUpdater(const TimelineModel *model, const TimelineRenderState *parentState, TimelineItemsRenderPassState *state, int indexFrom, int indexTo) : m_model(model), m_parentState(parentState), m_indexFrom(indexFrom), m_indexTo(indexTo), - m_state(state) + m_state(state), m_minCollapsedDistance(0), m_minExpandedDistance(0) +{ +} + +void NodeUpdater::calculateDistances() { int numItems = m_indexTo - m_indexFrom; - if (numItems > s_maxNumItems) { - m_collapsedDistances.resize(numItems); - m_expandedDistances.resize(numItems); - QVarLengthArray startsPerExpandedRow(m_model->expandedRowCount()); - QVarLengthArray startsPerCollapsedRow(m_model->collapsedRowCount()); - memset(startsPerCollapsedRow.data(), 0xff, startsPerCollapsedRow.size()); - memset(startsPerExpandedRow.data(), 0xff, startsPerExpandedRow.size()); - for (int i = m_indexFrom; i < m_indexTo; ++i) { - // Add some "random" factor. Distances below 256ns cannot be properly displayed - // anyway and if all events have the same distance from one another, then we'd merge - // them all together otherwise. - qint64 start = startTime(m_model, m_parentState, i) + (i % 256); - qint64 end = endTime(m_model, m_parentState, i) + (i % 256); - if (start > end) { - m_collapsedDistances[i - m_indexFrom] = m_expandedDistances[i - m_indexFrom] = 0; - continue; - } - qint64 &collapsedStart = startsPerCollapsedRow[m_model->collapsedRow(i)]; - m_collapsedDistances[i - m_indexFrom] = (collapsedStart != s_invalidTimestamp) ? - end - collapsedStart : std::numeric_limits::max(); - collapsedStart = start; - - qint64 &expandedStart = startsPerExpandedRow[m_model->expandedRow(i)]; - m_expandedDistances[i - m_indexFrom] = (expandedStart != s_invalidTimestamp) ? - end - expandedStart : std::numeric_limits::max(); - expandedStart = start; + m_collapsedDistances.resize(numItems); + m_expandedDistances.resize(numItems); + QVarLengthArray startsPerExpandedRow(m_model->expandedRowCount()); + QVarLengthArray startsPerCollapsedRow(m_model->collapsedRowCount()); + memset(startsPerCollapsedRow.data(), 0xff, startsPerCollapsedRow.size()); + memset(startsPerExpandedRow.data(), 0xff, startsPerExpandedRow.size()); + for (int i = m_indexFrom; i < m_indexTo; ++i) { + // Add some "random" factor. Distances below 256ns cannot be properly displayed + // anyway and if all events have the same distance from one another, then we'd merge + // them all together otherwise. + qint64 start = startTime(m_model, m_parentState, i) + (i % 256); + qint64 end = endTime(m_model, m_parentState, i) + (i % 256); + if (start > end) { + m_collapsedDistances[i - m_indexFrom] = m_expandedDistances[i - m_indexFrom] = 0; + continue; } - QVarLengthArray sorted = m_collapsedDistances; - std::sort(sorted.begin(), sorted.end()); - m_minCollapsedDistance = sorted[numItems - s_maxNumItems]; - sorted = m_expandedDistances; - std::sort(sorted.begin(), sorted.end()); - m_minExpandedDistance = sorted[numItems - s_maxNumItems]; + qint64 &collapsedStart = startsPerCollapsedRow[m_model->collapsedRow(i)]; + m_collapsedDistances[i - m_indexFrom] = (collapsedStart != s_invalidTimestamp) ? + end - collapsedStart : std::numeric_limits::max(); + collapsedStart = start; + + qint64 &expandedStart = startsPerExpandedRow[m_model->expandedRow(i)]; + m_expandedDistances[i - m_indexFrom] = (expandedStart != s_invalidTimestamp) ? + end - expandedStart : std::numeric_limits::max(); + expandedStart = start; } + + QVarLengthArray sorted = m_collapsedDistances; + std::sort(sorted.begin(), sorted.end()); + m_minCollapsedDistance = sorted[numItems - s_maxNumItems]; + sorted = m_expandedDistances; + std::sort(sorted.begin(), sorted.end()); + m_minExpandedDistance = sorted[numItems - s_maxNumItems]; } int NodeUpdater::updateVertices(TimelineItemsGeometry &geometry, @@ -733,6 +740,9 @@ int NodeUpdater::updateNodes(const int from, const int to) const void NodeUpdater::run() { + if (m_indexTo - m_indexFrom > s_maxNumItems) + calculateDistances(); + if (m_state->indexFrom() < m_state->indexTo()) { if (m_indexFrom < m_state->indexFrom()) { for (int i = m_indexFrom; i < m_state->indexFrom();)