From 5502bd0b0eb1f928f93795dbcf7cad2be46adec3 Mon Sep 17 00:00:00 2001 From: Jere Tuliniemi Date: Thu, 10 Oct 2024 13:15:14 +0300 Subject: [PATCH] Optimize AreaRenderer MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use QPainterPath method from PointRenderer to improve AreaRenderer performance. Also fixes bugged lower spline behavior. Task-number: QTBUG-129768 Change-Id: I738abeecd620ed4897e2f77301bc9e47dc0d39e8 Reviewed-by: Tomi Korpipää Reviewed-by: Owais Akhtar (cherry picked from commit 6c643a7d4172f20a70980f88492ab63addcc7666) --- src/graphs2d/qsgrenderer/arearenderer.cpp | 116 +++++----------------- src/graphs2d/qsgrenderer/arearenderer_p.h | 3 +- 2 files changed, 27 insertions(+), 92 deletions(-) diff --git a/src/graphs2d/qsgrenderer/arearenderer.cpp b/src/graphs2d/qsgrenderer/arearenderer.cpp index fd17d999..5bff8551 100644 --- a/src/graphs2d/qsgrenderer/arearenderer.cpp +++ b/src/graphs2d/qsgrenderer/arearenderer.cpp @@ -76,27 +76,10 @@ void AreaRenderer::handlePolish(QAreaSeries *series) auto group = m_groups.value(series); - if (upper->points().count() < 2) { - auto pathElements = group->shapePath->pathElements(); - pathElements.clear(&pathElements); - - for (auto path : group->paths) - path->deleteLater(); - - group->paths.clear(); - - return; - } - - if (lower && lower->points().count() < 2) { - auto pathElements = group->shapePath->pathElements(); - pathElements.clear(&pathElements); - - for (auto path : group->paths) - path->deleteLater(); - - group->paths.clear(); - + if (upper->points().count() < 2 || (lower && lower->points().count() < 2)) { + auto painterPath = group->painterPath; + painterPath.clear(); + group->shapePath->setPath(painterPath); return; } @@ -116,42 +99,8 @@ void AreaRenderer::handlePolish(QAreaSeries *series) / m_graph->m_axisRenderer->m_axisHorizontalValueRange) * m_areaWidth; - qsizetype pointCount = upper->points().size(); - qsizetype currentSize = group->paths.size(); - qsizetype extraCount = lower ? lower->points().size() : 2; - for (qsizetype i = currentSize; i < pointCount + extraCount; ++i) { - QQuickCurve *path = nullptr; - - if (!lower || (lower && i < pointCount - 1)) { - if (upper->type() == QAbstractSeries::SeriesType::Line || (!lower && i >= pointCount - 1)) - path = new QQuickPathLine(group->shapePath); - else if (upper->type() == QAbstractSeries::SeriesType::Spline) - path = new QQuickPathCubic(group->shapePath); - } else if (lower && (i == pointCount - 1 || i == pointCount + extraCount - 1)) { - path = new QQuickPathLine(group->shapePath); - } else { - if (lower->type() == QAbstractSeries::SeriesType::Line) - path = new QQuickPathLine(group->shapePath); - else if (lower->type() == QAbstractSeries::SeriesType::Spline) - path = new QQuickPathCubic(group->shapePath); - } - - if (path && series->isVisible()) { - auto pathElements = group->shapePath->pathElements(); - pathElements.append(&pathElements, path); - group->paths << path; - } - } - - auto pathElements = group->shapePath->pathElements(); - if (!series->isVisible() && pathElements.count(&pathElements) > 0) { - pathElements.clear(&pathElements); - - for (auto path : group->paths) - path->deleteLater(); - - group->paths.clear(); - } + auto &painterPath = group->painterPath; + painterPath.clear(); if (group->colorIndex < 0) { group->colorIndex = m_graph->graphSeriesCount(); @@ -204,15 +153,10 @@ void AreaRenderer::handlePolish(QAreaSeries *series) calculateRenderCoordinates(upperPoints[i].x(), upperPoints[i].y(), &x, &y); if (i == 0) { - group->shapePath->setStartX(x); - group->shapePath->setStartY(y); + painterPath.moveTo(x, y); } else { - group->paths[i - 1]->setX(x); - group->paths[i - 1]->setY(y); - - auto *cubicPath = qobject_cast(group->paths[i - 1]); - - if (cubicPath) { + if (i < upper->points().size() + && upper->type() == QAbstractSeries::SeriesType::Spline) { qreal x1, y1, x2, y2; calculateRenderCoordinates(fittedPoints[j - 1].x(), fittedPoints[j - 1].y(), @@ -220,12 +164,10 @@ void AreaRenderer::handlePolish(QAreaSeries *series) &y1); calculateRenderCoordinates(fittedPoints[j].x(), fittedPoints[j].y(), &x2, &y2); + painterPath.cubicTo(x1, y1, x2, y2, x, y); ++j; - - cubicPath->setControl2X(x2); - cubicPath->setControl1X(x1); - cubicPath->setControl2Y(y2); - cubicPath->setControl1Y(y1); + } else { + painterPath.lineTo(x, y); } } } @@ -234,8 +176,8 @@ void AreaRenderer::handlePolish(QAreaSeries *series) if (lower && series->isVisible()) { auto &&lowerPoints = lower->points(); QList fittedPoints; - if (upper->type() == QAbstractSeries::SeriesType::Spline) - fittedPoints = qobject_cast(upper)->getControlPoints(); + if (lower->type() == QAbstractSeries::SeriesType::Spline) + fittedPoints = qobject_cast(lower)->getControlPoints(); for (int i = 0, j = 0; i < lowerPoints.size(); ++i, ++j) { qreal x, y; @@ -244,13 +186,7 @@ void AreaRenderer::handlePolish(QAreaSeries *series) &x, &y); - group->paths[upperPoints.size() + i - 1]->setX(x); - group->paths[upperPoints.size() + i - 1]->setY(y); - - auto *cubicPath = qobject_cast( - group->paths[upperPoints.size() + i - 1]); - - if (cubicPath) { + if (i > 0 && lower->type() == QAbstractSeries::SeriesType::Spline) { qreal x1, y1, x2, y2; calculateRenderCoordinates(fittedPoints[fittedPoints.size() - 1 - j + 1].x(), fittedPoints[fittedPoints.size() - 1 - j + 1].y(), @@ -261,21 +197,20 @@ void AreaRenderer::handlePolish(QAreaSeries *series) &x2, &y2); + painterPath.cubicTo(x1, y1, x2, y2, x, y); ++j; - - cubicPath->setControl2X(x2); - cubicPath->setControl1X(x1); - cubicPath->setControl2Y(y2); - cubicPath->setControl1Y(y1); + } else { + painterPath.lineTo(x, y); } } qreal x, y; calculateRenderCoordinates(upperPoints[0].x(), upperPoints[0].y(), &x, &y); - - group->paths[upperPoints.size() + lowerPoints.size() - 1]->setX(x); - group->paths[upperPoints.size() + lowerPoints.size() - 1]->setY(y); + painterPath.lineTo(x, y); } + + group->shapePath->setPath(painterPath); + QList legendDataList = {{color, borderColor, series->name()}}; series->d_func()->setLegendData(legendDataList); } @@ -287,10 +222,9 @@ void AreaRenderer::afterPolish(QList &cleanupSeries) if (areaSeries && m_groups.contains(areaSeries)) { auto group = m_groups.value(areaSeries); - if (group->shapePath) { - auto pathElements = group->shapePath->pathElements(); - pathElements.clear(&pathElements); - } + auto painterPath = group->painterPath; + painterPath.clear(); + group->shapePath->setPath(painterPath); delete group; m_groups.remove(areaSeries); diff --git a/src/graphs2d/qsgrenderer/arearenderer_p.h b/src/graphs2d/qsgrenderer/arearenderer_p.h index ea933761..0df4f4e0 100644 --- a/src/graphs2d/qsgrenderer/arearenderer_p.h +++ b/src/graphs2d/qsgrenderer/arearenderer_p.h @@ -14,6 +14,7 @@ // // We mean it. +#include #include #include @@ -45,7 +46,7 @@ private: { QAreaSeries *series = nullptr; QQuickShapePath *shapePath = nullptr; - QList paths; + QPainterPath painterPath; qsizetype colorIndex = -1; qsizetype borderColorIndex = -1; bool hover = false;