From 5611b66c901867a2ea2855c90454c2267ef197dd Mon Sep 17 00:00:00 2001 From: Louai Al-Khanji Date: Wed, 23 Apr 2014 14:23:38 +0300 Subject: Direct2D QPA: Optimize Clipping Use axis aligned clips when possible instead of layer-clipping. This can be much faster when a lot of clipping operations take place. Change-Id: I6865d69fc917a7da858033b4c362b307724d9006 Reviewed-by: Risto Avila Reviewed-by: Friedemann Kleint Reviewed-by: Andrew Knight --- src/gui/painting/qpaintengine_raster.cpp | 33 +++++--------------------------- src/gui/painting/qvectorpath_p.h | 28 ++++++++++++++++++++++++++- 2 files changed, 32 insertions(+), 29 deletions(-) (limited to 'src/gui') diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp index bfcb24ae3a..ce8c1d1ca7 100644 --- a/src/gui/painting/qpaintengine_raster.cpp +++ b/src/gui/painting/qpaintengine_raster.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the QtGui module of the Qt Toolkit. @@ -235,21 +235,6 @@ static const QRectF boundingRect(const QPointF *points, int pointCount) } #endif -template static inline bool isRect(const T *pts, int elementCount) { - return (elementCount == 5 // 5-point polygon, check for closed rect - && pts[0] == pts[8] && pts[1] == pts[9] // last point == first point - && pts[0] == pts[6] && pts[2] == pts[4] // x values equal - && pts[1] == pts[3] && pts[5] == pts[7] // y values equal... - && pts[0] < pts[4] && pts[1] < pts[5] - ) || - (elementCount == 4 // 4-point polygon, check for unclosed rect - && pts[0] == pts[6] && pts[2] == pts[4] // x values equal - && pts[1] == pts[3] && pts[5] == pts[7] // y values equal... - && pts[0] < pts[4] && pts[1] < pts[5] - ); -} - - static void qt_ft_outline_move_to(qfixed x, qfixed y, void *data) { ((QOutlineMapper *) data)->moveTo(QPointF(qt_fixed_to_real(x), qt_fixed_to_real(y))); @@ -1193,22 +1178,14 @@ void QRasterPaintEngine::clip(const QVectorPath &path, Qt::ClipOperation op) Q_D(QRasterPaintEngine); QRasterPaintEngineState *s = state(); - const qreal *points = path.points(); - const QPainterPath::ElementType *types = path.elements(); - // There are some cases that are not supported by clip(QRect) if (op != Qt::IntersectClip || !s->clip || s->clip->hasRectClip || s->clip->hasRegionClip) { if (s->matrix.type() <= QTransform::TxScale - && ((path.shape() == QVectorPath::RectangleHint) - || (isRect(points, path.elementCount()) - && (!types || (types[0] == QPainterPath::MoveToElement - && types[1] == QPainterPath::LineToElement - && types[2] == QPainterPath::LineToElement - && types[3] == QPainterPath::LineToElement))))) { + && path.isRect()) { #ifdef QT_DEBUG_DRAW qDebug() << " --- optimizing vector clip to rect clip..."; #endif - + const qreal *points = path.points(); QRectF r(points[0], points[1], points[4]-points[0], points[5]-points[1]); if (setClipRectInDeviceCoords(s->matrix.mapRect(r).toRect(), op)) return; @@ -1939,7 +1916,7 @@ void QRasterPaintEngine::drawPolygon(const QPointF *points, int pointCount, Poly #endif Q_ASSERT(pointCount >= 2); - if (mode != PolylineMode && isRect((qreal *) points, pointCount)) { + if (mode != PolylineMode && QVectorPath::isRect((qreal *) points, pointCount)) { QRectF r(points[0], points[2]); drawRects(&r, 1); return; @@ -1980,7 +1957,7 @@ void QRasterPaintEngine::drawPolygon(const QPoint *points, int pointCount, Polyg qDebug() << " - " << points[i]; #endif Q_ASSERT(pointCount >= 2); - if (mode != PolylineMode && isRect((int *) points, pointCount)) { + if (mode != PolylineMode && QVectorPath::isRect((int *) points, pointCount)) { QRect r(points[0].x(), points[0].y(), points[2].x() - points[0].x(), diff --git a/src/gui/painting/qvectorpath_p.h b/src/gui/painting/qvectorpath_p.h index e97d6e1dce..ca95c32597 100644 --- a/src/gui/painting/qvectorpath_p.h +++ b/src/gui/painting/qvectorpath_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the QtGui module of the Qt Toolkit. @@ -167,6 +167,32 @@ public: return 0; } + template static inline bool isRect(const T *pts, int elementCount) { + return (elementCount == 5 // 5-point polygon, check for closed rect + && pts[0] == pts[8] && pts[1] == pts[9] // last point == first point + && pts[0] == pts[6] && pts[2] == pts[4] // x values equal + && pts[1] == pts[3] && pts[5] == pts[7] // y values equal... + && pts[0] < pts[4] && pts[1] < pts[5] + ) || + (elementCount == 4 // 4-point polygon, check for unclosed rect + && pts[0] == pts[6] && pts[2] == pts[4] // x values equal + && pts[1] == pts[3] && pts[5] == pts[7] // y values equal... + && pts[0] < pts[4] && pts[1] < pts[5] + ); + } + + inline bool isRect() const + { + const QPainterPath::ElementType * const types = elements(); + + return (shape() == QVectorPath::RectangleHint) + || (isRect(points(), elementCount()) + && (!types || (types[0] == QPainterPath::MoveToElement + && types[1] == QPainterPath::LineToElement + && types[2] == QPainterPath::LineToElement + && types[3] == QPainterPath::LineToElement))); + } + private: Q_DISABLE_COPY(QVectorPath) -- cgit v1.2.3