aboutsummaryrefslogtreecommitdiffstats
path: root/src/quick
diff options
context:
space:
mode:
authorEirik Aavitsland <eirik.aavitsland@qt.io>2024-03-27 18:18:02 +0100
committerEirik Aavitsland <eirik.aavitsland@qt.io>2024-04-03 21:08:44 +0000
commit076711dbaab97e93348d4a1579cfcc9435359689 (patch)
tree44fc1da6e90a208fb8a53dfe0e8fb709939f9b73 /src/quick
parent1314d046f043bfcb29c44163e113b810c7764aed (diff)
Curve renderer: Use a common QQuadPath iterator function
For code simplification, replace a couple of ad-hoc QQuadPath iteration implementations with calls to QQuadPath's own iterateElements() function. To make that possible, extend iterateElements() to pass the element index too to the lambda function. Pick-to: 6.7 Change-Id: I2e6697b5d1404c7ed4fa1c247e18f93856394fa1 Reviewed-by: Paul Olav Tvete <paul.tvete@qt.io>
Diffstat (limited to 'src/quick')
-rw-r--r--src/quick/scenegraph/qsgcurveprocessor.cpp85
-rw-r--r--src/quick/scenegraph/util/qquadpath.cpp6
-rw-r--r--src/quick/scenegraph/util/qquadpath_p.h14
3 files changed, 45 insertions, 60 deletions
diff --git a/src/quick/scenegraph/qsgcurveprocessor.cpp b/src/quick/scenegraph/qsgcurveprocessor.cpp
index 801cf32826..3cefb8c39c 100644
--- a/src/quick/scenegraph/qsgcurveprocessor.cpp
+++ b/src/quick/scenegraph/qsgcurveprocessor.cpp
@@ -56,18 +56,6 @@ static inline float testSideOfLineByNormal(QVector2D a, QVector2D n, QVector2D p
return dot;
};
-template<typename Func>
-void iteratePath(const QQuadPath &path, int index, Func &&lambda)
-{
- const auto &element = path.elementAt(index);
- if (element.childCount() == 0) {
- lambda(element, index);
- } else {
- for (int i = 0; i < element.childCount(); ++i)
- iteratePath(path, element.indexOfChild(i), lambda);
- }
-}
-
static inline float determinant(const QVector2D &p1, const QVector2D &p2, const QVector2D &p3)
{
return p1.x() * (p2.y() - p3.y())
@@ -438,7 +426,8 @@ QList<TriangleData> simplePointTriangulator(const QList<QVector2D> &pts, const Q
return ret;
}
-static bool needsSplit(const QQuadPath::Element &el)
+
+inline bool needsSplit(const QQuadPath::Element &el)
{
Q_ASSERT(!el.isLine());
const auto v1 = el.controlPoint() - el.startPoint();
@@ -446,28 +435,24 @@ static bool needsSplit(const QQuadPath::Element &el)
float cos = QVector2D::dotProduct(v1, v2) / (v1.length() * v2.length());
return cos < 0.9;
}
-static void splitElementIfNecessary(QQuadPath &path, int index)
-{
- auto &e = path.elementAt(index);
- if (e.isLine())
- return;
- if (e.childCount() == 0) {
- if (needsSplit(e))
- path.splitElementAt(index);
- } else {
- const int childCount = e.childCount();
- for (int i = 0; i < childCount; ++i)
- splitElementIfNecessary(path, path.indexOfChildAt(index, i));
+
+
+inline void splitElementIfNecessary(QQuadPath *path, int index, int level) {
+ if (level > 0 && needsSplit(path->elementAt(index))) {
+ path->splitElementAt(index);
+ splitElementIfNecessary(path, path->indexOfChildAt(index, 0), level - 1);
+ splitElementIfNecessary(path, path->indexOfChildAt(index, 1), level - 1);
}
}
static QQuadPath subdivide(const QQuadPath &path, int subdivisions)
{
QQuadPath newPath = path;
+ newPath.iterateElements([&](QQuadPath::Element &e, int index) {
+ if (!e.isLine())
+ splitElementIfNecessary(&newPath, index, subdivisions);
+ });
- for (int i = 0; i < subdivisions; ++i)
- for (int j = 0; j < newPath.elementCount(); j++)
- splitElementIfNecessary(newPath, j);
return newPath;
}
@@ -1692,34 +1677,32 @@ void QSGCurveProcessor::processFill(const QQuadPath &fillPath,
[&uv](QVector2D) { return uv; });
};
- for (int i = 0; i < fillPath.elementCount(); ++i) {
- iteratePath(fillPath, i, [&](const QQuadPath::Element &element, int index) {
- QVector2D sp(element.startPoint());
- QVector2D cp(element.controlPoint());
- QVector2D ep(element.endPoint());
- QVector2D rsp = roundVec2D(sp);
-
- if (element.isSubpathStart())
- internalHull.moveTo(sp.toPointF());
- if (element.isLine()) {
+ fillPath.iterateElements([&](const QQuadPath::Element &element, int index) {
+ QVector2D sp(element.startPoint());
+ QVector2D cp(element.controlPoint());
+ QVector2D ep(element.endPoint());
+ QVector2D rsp = roundVec2D(sp);
+
+ if (element.isSubpathStart())
+ internalHull.moveTo(sp.toPointF());
+ if (element.isLine()) {
+ internalHull.lineTo(ep.toPointF());
+ pointHash.insert(rsp, index);
+ } else {
+ QVector2D rep = roundVec2D(ep);
+ QVector2D rcp = roundVec2D(cp);
+ if (element.isConvex()) {
internalHull.lineTo(ep.toPointF());
+ addTriangleForConvex(element, rsp, rep, rcp);
pointHash.insert(rsp, index);
} else {
- QVector2D rep = roundVec2D(ep);
- QVector2D rcp = roundVec2D(cp);
- if (element.isConvex()) {
- internalHull.lineTo(ep.toPointF());
- addTriangleForConvex(element, rsp, rep, rcp);
- pointHash.insert(rsp, index);
- } else {
- internalHull.lineTo(cp.toPointF());
- internalHull.lineTo(ep.toPointF());
+ internalHull.lineTo(cp.toPointF());
+ internalHull.lineTo(ep.toPointF());
addTriangleForConcave(element, rsp, rep, rcp);
- pointHash.insert(rcp, index);
- }
+ pointHash.insert(rcp, index);
}
- });
- }
+ }
+ });
// Points in p are already rounded do 1/32
// Returns false if the triangle needs to be split. Adds the triangle to the graphics buffers and returns true otherwise.
diff --git a/src/quick/scenegraph/util/qquadpath.cpp b/src/quick/scenegraph/util/qquadpath.cpp
index 1f77cd0185..8c9986c2ac 100644
--- a/src/quick/scenegraph/util/qquadpath.cpp
+++ b/src/quick/scenegraph/util/qquadpath.cpp
@@ -611,7 +611,7 @@ QRectF QQuadPath::controlPointRect() const
int QQuadPath::elementCountRecursive() const
{
int count = 0;
- iterateElements([&](const QQuadPath::Element &) { count++; });
+ iterateElements([&](const QQuadPath::Element &, int) { count++; });
return count;
}
@@ -704,7 +704,7 @@ QQuadPath QQuadPath::flattened() const
{
QQuadPath res;
res.reserve(elementCountRecursive());
- iterateElements([&](const QQuadPath::Element &element) { res.m_elements.append(element); });
+ iterateElements([&](const QQuadPath::Element &elem, int) { res.m_elements.append(elem); });
res.setPathHints(pathHints());
res.setFillRule(fillRule());
return res;
@@ -941,7 +941,7 @@ QDebug operator<<(QDebug stream, const QQuadPath &path)
<< path.elementCountRecursive() << " leaf elements, "
<< (path.fillRule() == Qt::OddEvenFill ? "OddEven" : "Winding") << Qt::endl;
int count = 0;
- path.iterateElements([&](const QQuadPath::Element &e) {
+ path.iterateElements([&](const QQuadPath::Element &e, int) {
stream << " " << count++ << (e.isSubpathStart() ? " >" : " ");
printElement(stream, e);
stream << Qt::endl;
diff --git a/src/quick/scenegraph/util/qquadpath_p.h b/src/quick/scenegraph/util/qquadpath_p.h
index 6037c6e736..98ef5b664c 100644
--- a/src/quick/scenegraph/util/qquadpath_p.h
+++ b/src/quick/scenegraph/util/qquadpath_p.h
@@ -248,7 +248,7 @@ public:
if (c.childCount() > 0)
iterateChildrenOf(c, lambda);
else
- lambda(c);
+ lambda(c, -(i + 1));
}
}
@@ -261,29 +261,31 @@ public:
if (c.childCount() > 0)
iterateChildrenOf(c, lambda);
else
- lambda(c);
+ lambda(c, -(i + 1));
}
}
template<typename Func>
void iterateElements(Func &&lambda)
{
- for (auto &e : m_elements) {
+ for (int i = 0; i < m_elements.size(); i++) {
+ Element &e = m_elements[i];
if (e.childCount() > 0)
iterateChildrenOf(e, lambda);
else
- lambda(e);
+ lambda(e, i);
}
}
template<typename Func>
void iterateElements(Func &&lambda) const
{
- for (auto &e : m_elements) {
+ for (int i = 0; i < m_elements.size(); i++) {
+ const Element &e = m_elements[i];
if (e.childCount() > 0)
iterateChildrenOf(e, lambda);
else
- lambda(e);
+ lambda(e, i);
}
}