From ad70622193f8a34c28b6536521f8612e0b500fbf Mon Sep 17 00:00:00 2001
From: Michael Brasser <michael.brasser@nokia.com>
Date: Tue, 16 Mar 2010 09:05:06 +1000
Subject: Optimize  QRegion::intersects(QRect).

Further optimize for the common case where numRects == 1. Benchmarks
included.

Reviewed-by: Samuel
---
 src/gui/painting/qregion.cpp                   | 36 ++++++++++---------
 tests/benchmarks/gui/painting/qregion/main.cpp | 50 ++++++++++++++++++++++++++
 2 files changed, 70 insertions(+), 16 deletions(-)

diff --git a/src/gui/painting/qregion.cpp b/src/gui/painting/qregion.cpp
index bea2b6e..bfeef72 100644
--- a/src/gui/painting/qregion.cpp
+++ b/src/gui/painting/qregion.cpp
@@ -704,28 +704,13 @@ bool QRegion::intersects(const QRegion &region) const
 }
 
 /*!
+    \fn bool QRegion::intersects(const QRect &rect) const
     \since 4.2
 
     Returns true if this region intersects with \a rect, otherwise
     returns false.
 */
-bool QRegion::intersects(const QRect &rect) const
-{
-    if (isEmpty() || rect.isNull())
-        return false;
 
-    const QRect r = rect.normalized();
-    if (!rect_intersects(boundingRect(), r))
-        return false;
-    if (rectCount() == 1)
-        return true;
-
-    const QVector<QRect> myRects = rects();
-    for (QVector<QRect>::const_iterator it = myRects.constBegin(); it < myRects.constEnd(); ++it)
-        if (rect_intersects(r, *it))
-            return true;
-    return false;
-}
 
 #if !defined (Q_OS_UNIX) && !defined (Q_WS_WIN)
 /*!
@@ -4349,5 +4334,24 @@ bool QRegion::operator==(const QRegion &r) const
         return EqualRegion(d->qt_rgn, r.d->qt_rgn);
 }
 
+bool QRegion::intersects(const QRect &rect) const
+{
+    if (isEmptyHelper(d->qt_rgn) || rect.isNull())
+        return false;
+
+    const QRect r = rect.normalized();
+    if (!rect_intersects(d->qt_rgn->extents, r))
+        return false;
+    if (d->qt_rgn->numRects == 1)
+        return true;
+
+    const QVector<QRect> myRects = rects();
+    for (QVector<QRect>::const_iterator it = myRects.constBegin(); it < myRects.constEnd(); ++it)
+        if (rect_intersects(r, *it))
+            return true;
+    return false;
+}
+
+
 #endif
 QT_END_NAMESPACE
diff --git a/tests/benchmarks/gui/painting/qregion/main.cpp b/tests/benchmarks/gui/painting/qregion/main.cpp
index 3d16e41..1d19854 100644
--- a/tests/benchmarks/gui/painting/qregion/main.cpp
+++ b/tests/benchmarks/gui/painting/qregion/main.cpp
@@ -49,6 +49,9 @@ class tst_qregion : public QObject
 private slots:
     void map_data();
     void map();
+
+    void intersects_data();
+    void intersects();
 };
 
 
@@ -84,6 +87,53 @@ void tst_qregion::map()
     }
 }
 
+void tst_qregion::intersects_data()
+{
+    QTest::addColumn<QRegion>("region");
+    QTest::addColumn<QRect>("rect");
+
+    QRegion region(0, 0, 100, 100);
+    QRegion complexRegion;
+    complexRegion = complexRegion.united(QRect(0, 0, 100, 100));
+    complexRegion = complexRegion.united(QRect(120, 20, 100, 100));
+
+    {
+        QRect rect(0, 0, 100, 100);
+        QTest::newRow("same -- simple") << region << rect;
+    }
+    {
+        QRect rect(10, 10, 10, 10);
+        QTest::newRow("inside -- simple") << region << rect;
+    }
+    {
+        QRect rect(110, 110, 10, 10);
+        QTest::newRow("outside -- simple") << region << rect;
+    }
+
+    {
+        QRect rect(0, 0, 100, 100);
+        QTest::newRow("same -- complex") << complexRegion << rect;
+    }
+    {
+        QRect rect(10, 10, 10, 10);
+        QTest::newRow("inside -- complex") << complexRegion << rect;
+    }
+    {
+        QRect rect(110, 110, 10, 10);
+        QTest::newRow("outside -- complex") << complexRegion << rect;
+    }
+}
+
+void tst_qregion::intersects()
+{
+    QFETCH(QRegion, region);
+    QFETCH(QRect, rect);
+
+    QBENCHMARK {
+        region.intersects(rect);
+    }
+}
+
 QTEST_MAIN(tst_qregion)
 
 #include "main.moc"
-- 
cgit v0.12