aboutsummaryrefslogtreecommitdiffstats
path: root/src/quick/util
diff options
context:
space:
mode:
authorKaj Grönholm <kgronholm@gmail.com>2017-12-16 12:00:07 +0200
committerTony Sarajärvi <tony.sarajarvi@qt.io>2018-02-01 06:39:24 +0000
commitf5abe488f1e7c9c31badd0622b7374648bea943a (patch)
tree4ba5c8c2fdc3af666917cced5937c767bdd5e6ef /src/quick/util
parent07f9ca1759e35f1eb497fe2f1ad4b7ba71b69b5c (diff)
Add optimized path for QML ShapePath
Improve performance of QML ShapePath, especially with more complex animating paths. Testing revealed that considerable amount of time is used for calculating QPainterPath::length(). QML ShapePath doesn't support QQuickPathAttribute or QQuickPathPercent, so it can have a fast-path for creating the path without calculating length or attributes. This gave heavy bezier lines rendering test ~7x performance boost. Task-number: QTBUG-64951 Change-Id: I5240ed3516b5eafb0391790ac96835e70f88e540 Reviewed-by: Robin Burchell <robin.burchell@crimson.no> Reviewed-by: Michael Brasser <michael.brasser@live.com> Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
Diffstat (limited to 'src/quick/util')
-rw-r--r--src/quick/util/qquickpath.cpp43
-rw-r--r--src/quick/util/qquickpath_p.h1
-rw-r--r--src/quick/util/qquickpath_p_p.h3
3 files changed, 45 insertions, 2 deletions
diff --git a/src/quick/util/qquickpath.cpp b/src/quick/util/qquickpath.cpp
index 0323dc9286..1ae9b78669 100644
--- a/src/quick/util/qquickpath.cpp
+++ b/src/quick/util/qquickpath.cpp
@@ -397,7 +397,12 @@ void QQuickPath::processPath()
d->_pointCache.clear();
d->prevBez.isValid = false;
- d->_path = createPath(QPointF(), QPointF(), d->_attributes, d->pathLength, d->_attributePoints, &d->closed);
+ if (d->isShapePath) {
+ // This path is a ShapePath, so avoid extra overhead
+ d->_path = createShapePath(QPointF(), QPointF(), d->pathLength, &d->closed);
+ } else {
+ d->_path = createPath(QPointF(), QPointF(), d->_attributes, d->pathLength, d->_attributePoints, &d->closed);
+ }
emit changed();
}
@@ -493,6 +498,42 @@ QPainterPath QQuickPath::createPath(const QPointF &startPoint, const QPointF &en
return path;
}
+QPainterPath QQuickPath::createShapePath(const QPointF &startPoint, const QPointF &endPoint, qreal &pathLength, bool *closed)
+{
+ Q_D(QQuickPath);
+
+ if (!d->componentComplete)
+ return QPainterPath();
+
+ QPainterPath path;
+
+ qreal startX = d->startX.isValid() ? d->startX.value : startPoint.x();
+ qreal startY = d->startY.isValid() ? d->startY.value : startPoint.y();
+ path.moveTo(startX, startY);
+
+ int index = 0;
+ for (QQuickCurve *curve : qAsConst(d->_pathCurves)) {
+ QQuickPathData data;
+ data.index = index;
+ data.endPoint = endPoint;
+ data.curves = d->_pathCurves;
+ curve->addToPath(path, data);
+ ++index;
+ }
+
+ if (closed) {
+ QPointF end = path.currentPosition();
+ *closed = startX == end.x() && startY == end.y();
+ }
+
+ // Note: Length of paths inside ShapePath is not used, so currently
+ // length is always 0. This avoids potentially heavy path.length()
+ //pathLength = path.length();
+ pathLength = 0;
+
+ return path;
+}
+
void QQuickPath::classBegin()
{
Q_D(QQuickPath);
diff --git a/src/quick/util/qquickpath_p.h b/src/quick/util/qquickpath_p.h
index d5474e2d30..a49403fd0e 100644
--- a/src/quick/util/qquickpath_p.h
+++ b/src/quick/util/qquickpath_p.h
@@ -522,6 +522,7 @@ private:
public:
QPainterPath createPath(const QPointF &startPoint, const QPointF &endPoint, const QStringList &attributes, qreal &pathLength, QList<AttributePoint> &attributePoints, bool *closed = 0);
+ QPainterPath createShapePath(const QPointF &startPoint, const QPointF &endPoint, qreal &pathLength, bool *closed = 0);
static QPointF sequentialPointAt(const QPainterPath &path, const qreal &pathLength, const QList<AttributePoint> &attributePoints, QQuickCachedBezier &prevBez, qreal p, qreal *angle = 0);
};
diff --git a/src/quick/util/qquickpath_p_p.h b/src/quick/util/qquickpath_p_p.h
index 8ce85dbf0f..f5c9664223 100644
--- a/src/quick/util/qquickpath_p_p.h
+++ b/src/quick/util/qquickpath_p_p.h
@@ -72,7 +72,7 @@ public:
static QQuickPathPrivate* get(QQuickPath *path) { return path->d_func(); }
static const QQuickPathPrivate* get(const QQuickPath *path) { return path->d_func(); }
- QQuickPathPrivate() : pathLength(0), closed(false), componentComplete(true) { }
+ QQuickPathPrivate() : pathLength(0), closed(false), componentComplete(true), isShapePath(false) { }
QPainterPath _path;
QList<QQuickPathElement*> _pathElements;
@@ -86,6 +86,7 @@ public:
qreal pathLength;
bool closed;
bool componentComplete;
+ bool isShapePath;
};
QT_END_NAMESPACE