QmlProfiler: Avoid numerical overflows in calculation of event width

We must not keep intermediate values in 32bit integers as they can
easily get too large for that. This change restores the behavior from
before change 10a14ced36, which coaxed
the compiler into using floats by stating the minimum constants as
"1.0".

Task-number: QTCREATORBUG-13391
Change-Id: Ie83337b7e2b09b37d94a31a07813de14b85152ee
Reviewed-by: Kai Koehne <kai.koehne@theqtcompany.com>
This commit is contained in:
Ulf Hermann
2014-11-11 15:52:17 +01:00
parent 673cc77dd0
commit fd3f544bb2

View File

@@ -112,22 +112,28 @@ void TimelineRenderer::swapSelections(int modelIndex1, int modelIndex2)
inline void TimelineRenderer::getItemXExtent(int modelIndex, int i, int &currentX, int &itemWidth) inline void TimelineRenderer::getItemXExtent(int modelIndex, int i, int &currentX, int &itemWidth)
{ {
qint64 start = m_profilerModelProxy->startTime(modelIndex, i) - m_startTime; qint64 start = m_profilerModelProxy->startTime(modelIndex, i) - m_startTime;
// avoid integer overflows by using floating point for width calculations. m_spacing is qreal,
// too, so for some intermediate calculations we have to use floats anyway.
qreal rawWidth;
if (start > 0) { if (start > 0) {
currentX = start * m_spacing; currentX = static_cast<int>(start * m_spacing);
itemWidth = m_profilerModelProxy->duration(modelIndex, i) * m_spacing; rawWidth = m_profilerModelProxy->duration(modelIndex, i) * m_spacing;
} else { } else {
currentX = -OutOfScreenMargin; currentX = -OutOfScreenMargin;
// Explicitly round the "start" part down, away from 0, to match the implicit rounding of // Explicitly round the "start" part down, away from 0, to match the implicit rounding of
// currentX in the > 0 case. If we don't do that we get glitches where a pixel is added if // currentX in the > 0 case. If we don't do that we get glitches where a pixel is added if
// the element starts outside the screen and subtracted if it starts inside the screen. // the element starts outside the screen and subtracted if it starts inside the screen.
itemWidth = m_profilerModelProxy->duration(modelIndex, i) * m_spacing + rawWidth = m_profilerModelProxy->duration(modelIndex, i) * m_spacing +
floor(start * m_spacing) + OutOfScreenMargin; floor(start * m_spacing) + OutOfScreenMargin;
} }
if (itemWidth < MinimumItemWidth) { if (rawWidth < MinimumItemWidth) {
currentX -= (MinimumItemWidth - itemWidth) / 2; currentX -= static_cast<int>((MinimumItemWidth - rawWidth) / 2);
itemWidth = MinimumItemWidth; itemWidth = MinimumItemWidth;
} else if (itemWidth > m_spacedDuration) { } else if (rawWidth > m_spacedDuration) {
itemWidth = m_spacedDuration; itemWidth = static_cast<int>(m_spacedDuration);
} else {
itemWidth = static_cast<int>(rawWidth);
} }
} }