diff options
author | Samuel Rødal <sroedal@trolltech.com> | 2009-10-07 12:59:34 (GMT) |
---|---|---|
committer | Samuel Rødal <sroedal@trolltech.com> | 2009-10-07 16:15:45 (GMT) |
commit | 14a8f1fb7414885cc3868b1d27699b5a0d59e7ee (patch) | |
tree | cd5527e8aec4c38a561d6bc81fac098491a334e7 /src/opengl/gl2paintengineex/qgl2pexvertexarray.cpp | |
parent | 57209cf902f9d0c9bea5b599b54fa4bdc015d2b5 (diff) | |
download | Qt-14a8f1fb7414885cc3868b1d27699b5a0d59e7ee.zip Qt-14a8f1fb7414885cc3868b1d27699b5a0d59e7ee.tar.gz Qt-14a8f1fb7414885cc3868b1d27699b5a0d59e7ee.tar.bz2 |
Optimized rasterizing of paths using stencil method in GL 2 engine.
Making the triangle fan of each sub path start at the sub path's
centroid will on average improve performance for complex paths, because
less pixels that are outside the path need to be touched. The centroid
is a more balanced choice than just picking the first element of the
sub path as triangle fan origin.
A performance improvement of 20 % was measured for star formed paths.
Reviewed-by: Trond
Diffstat (limited to 'src/opengl/gl2paintengineex/qgl2pexvertexarray.cpp')
-rw-r--r-- | src/opengl/gl2paintengineex/qgl2pexvertexarray.cpp | 37 |
1 files changed, 36 insertions, 1 deletions
diff --git a/src/opengl/gl2paintengineex/qgl2pexvertexarray.cpp b/src/opengl/gl2paintengineex/qgl2pexvertexarray.cpp index 866d1a2..1fe3999 100644 --- a/src/opengl/gl2paintengineex/qgl2pexvertexarray.cpp +++ b/src/opengl/gl2paintengineex/qgl2pexvertexarray.cpp @@ -67,7 +67,30 @@ void QGL2PEXVertexArray::addRect(const QRectF &rect) << rect.bottomRight() << rect.bottomLeft() << rect.topLeft(); } -void QGL2PEXVertexArray::addPath(const QVectorPath &path, GLfloat curveInverseScale) +void QGL2PEXVertexArray::addClosingLine(int index) +{ + if (QPointF(vertexArray.at(index)) != QPointF(vertexArray.last())) + vertexArray.add(vertexArray.at(index)); +} + +void QGL2PEXVertexArray::addCentroid(const QVectorPath &path, int subPathIndex) +{ + const QPointF *const points = reinterpret_cast<const QPointF *>(path.points()); + const QPainterPath::ElementType *const elements = path.elements(); + + QPointF sum = points[subPathIndex]; + int count = 1; + + for (int i = subPathIndex + 1; i < path.elementCount() && (!elements || elements[i] != QPainterPath::MoveToElement); ++i) { + sum += points[i]; + ++count; + } + + const QPointF centroid = sum / qreal(count); + vertexArray.add(centroid); +} + +void QGL2PEXVertexArray::addPath(const QVectorPath &path, GLfloat curveInverseScale, bool outline) { const QPointF* const points = reinterpret_cast<const QPointF*>(path.points()); const QPainterPath::ElementType* const elements = path.elements(); @@ -78,6 +101,10 @@ void QGL2PEXVertexArray::addPath(const QVectorPath &path, GLfloat curveInverseSc boundingRectDirty = false; } + if (!outline) + addCentroid(path, 0); + + int lastMoveTo = vertexArray.size(); vertexArray.add(points[0]); // The first element is always a moveTo do { @@ -96,8 +123,14 @@ void QGL2PEXVertexArray::addPath(const QVectorPath &path, GLfloat curveInverseSc const QPainterPath::ElementType elementType = elements[i]; switch (elementType) { case QPainterPath::MoveToElement: + if (!outline) + addClosingLine(lastMoveTo); // qDebug("element[%d] is a MoveToElement", i); vertexArrayStops.append(vertexArray.size()); + if (!outline) { + addCentroid(path, i); + lastMoveTo = vertexArray.size(); + } lineToArray(points[i].x(), points[i].y()); // Add the moveTo as a new vertex break; case QPainterPath::LineToElement: @@ -115,6 +148,8 @@ void QGL2PEXVertexArray::addPath(const QVectorPath &path, GLfloat curveInverseSc } } while (0); + if (!outline) + addClosingLine(lastMoveTo); vertexArrayStops.append(vertexArray.size()); } |