summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndre de la Rocha <andre.rocha@qt.io>2018-06-05 19:20:58 +0200
committerAndre de la Rocha <andre.rocha@qt.io>2018-06-06 08:55:00 +0000
commit94000dd2b17e64719df8614f25b8df4e0061a133 (patch)
treea80a41363e39f089c8463ab42b036d16afc1a1fb
parent247cd74b4cbe2769c189b29bcbbd68084de3fc18 (diff)
Fix data normalization in GLXYSeriesDataManager
GLXYSeriesDataManager::setPoints() has an optimized path when it detects a regular XY chart, which skips calculateGeometryPoints() and sets up a shader-based transform instead of normalizing vertex data. However, for some series data containing values far away from the origin, which are represented with less absolute precision as floating-point values, by the time the transform is used, precision was already lost in the conversion from double to float, destroying the chart. This change performs proper normalization inside the optimized path, while keeping the same level of performance as before. Task-number: QTBUG-59674 Change-Id: Idc57481815a409c19ca364e1721153483cbc2993 Reviewed-by: Andy Shaw <andy.shaw@qt.io> Reviewed-by: Miikka Heikkinen <miikka.heikkinen@qt.io>
-rw-r--r--src/charts/xychart/glxyseriesdata.cpp24
1 files changed, 15 insertions, 9 deletions
diff --git a/src/charts/xychart/glxyseriesdata.cpp b/src/charts/xychart/glxyseriesdata.cpp
index 54c533b2..8ec919b7 100644
--- a/src/charts/xychart/glxyseriesdata.cpp
+++ b/src/charts/xychart/glxyseriesdata.cpp
@@ -117,20 +117,26 @@ void GLXYSeriesDataManager::setPoints(QXYSeries *series, const AbstractDomain *d
data->min = QVector2D(0, 0);
data->delta = QVector2D(domain->size().width() / 2.0f, domain->size().height() / 2.0f);
} else {
- // Regular value axes, so we can do the math easily on shaders.
+ // Regular value axes, so we can optimize it a bit.
if (reverseX)
matrix.scale(-1.0, 1.0);
if (reverseY)
matrix.scale(1.0, -1.0);
- QVector<QPointF> seriesPoints = series->pointsVector();
- for (int i = 0; i < count; i++) {
- const QPointF &point = seriesPoints.at(i);
- array[index++] = float(point.x());
- array[index++] = float(point.y());
+
+ const qreal mx = domain->minX();
+ const qreal my = domain->minY();
+ const qreal xd = domain->maxX() - mx;
+ const qreal yd = domain->maxY() - my;
+
+ if (!qFuzzyIsNull(xd) && !qFuzzyIsNull(yd)) {
+ const QVector<QPointF> seriesPoints = series->pointsVector();
+ for (const QPointF &point : seriesPoints) {
+ array[index++] = float((point.x() - mx) / xd);
+ array[index++] = float((point.y() - my) / yd);
+ }
}
- data->min = QVector2D(domain->minX(), domain->minY());
- data->delta = QVector2D((domain->maxX() - domain->minX()) / 2.0f,
- (domain->maxY() - domain->minY()) / 2.0f);
+ data->min = QVector2D(0.0f, 0.0f);
+ data->delta = QVector2D(0.5f, 0.5f);
}
data->matrix = matrix;
data->dirty = true;