tests/benchmarks/qgraphicsview/tst_qgraphicsview.cpp
changeset 0 1918ee327afb
child 3 41300fa6a67c
equal deleted inserted replaced
-1:000000000000 0:1918ee327afb
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
       
     6 **
       
     7 ** This file is part of the test suite of the Qt Toolkit.
       
     8 **
       
     9 ** $QT_BEGIN_LICENSE:LGPL$
       
    10 ** No Commercial Usage
       
    11 ** This file contains pre-release code and may not be distributed.
       
    12 ** You may use this file in accordance with the terms and conditions
       
    13 ** contained in the Technology Preview License Agreement accompanying
       
    14 ** this package.
       
    15 **
       
    16 ** GNU Lesser General Public License Usage
       
    17 ** Alternatively, this file may be used under the terms of the GNU Lesser
       
    18 ** General Public License version 2.1 as published by the Free Software
       
    19 ** Foundation and appearing in the file LICENSE.LGPL included in the
       
    20 ** packaging of this file.  Please review the following information to
       
    21 ** ensure the GNU Lesser General Public License version 2.1 requirements
       
    22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
       
    23 **
       
    24 ** In addition, as a special exception, Nokia gives you certain additional
       
    25 ** rights.  These rights are described in the Nokia Qt LGPL Exception
       
    26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
       
    27 **
       
    28 ** If you have questions regarding the use of this file, please contact
       
    29 ** Nokia at qt-info@nokia.com.
       
    30 **
       
    31 **
       
    32 **
       
    33 **
       
    34 **
       
    35 **
       
    36 **
       
    37 **
       
    38 ** $QT_END_LICENSE$
       
    39 **
       
    40 ****************************************************************************/
       
    41 
       
    42 #include <qtest.h>
       
    43 #include <QDebug>
       
    44 #include <QGraphicsItem>
       
    45 #include <QGraphicsScene>
       
    46 #include <QGraphicsView>
       
    47 #include <QImage>
       
    48 #ifdef Q_WS_X11
       
    49 QT_BEGIN_NAMESPACE
       
    50 extern void qt_x11_wait_for_window_manager(QWidget *);
       
    51 QT_END_NAMESPACE
       
    52 #endif
       
    53 #include "chiptester/chiptester.h"
       
    54 //#define CALLGRIND_DEBUG
       
    55 #ifdef CALLGRIND_DEBUG
       
    56 #include "valgrind/callgrind.h"
       
    57 #endif
       
    58 
       
    59 //TESTED_FILES=
       
    60 
       
    61 class QEventWaiter : public QEventLoop
       
    62 {
       
    63 public:
       
    64     QEventWaiter(QObject *receiver, QEvent::Type type)
       
    65 	: waiting(false), t(type)
       
    66     {
       
    67 	receiver->installEventFilter(this);
       
    68     }
       
    69 
       
    70     void wait()
       
    71     {
       
    72 	waiting = true;
       
    73 	exec();
       
    74     }
       
    75 
       
    76     bool eventFilter(QObject *receiver, QEvent *event)
       
    77     {
       
    78 	Q_UNUSED(receiver);
       
    79 	if (waiting && event->type() == t) {
       
    80 	    waiting = false;
       
    81 	    exit();
       
    82 	}
       
    83 	return false;
       
    84     }
       
    85 
       
    86 private:
       
    87     bool waiting;
       
    88     QEvent::Type t;
       
    89 };
       
    90 
       
    91 class tst_QGraphicsView : public QObject
       
    92 {
       
    93     Q_OBJECT
       
    94 
       
    95 public:
       
    96     tst_QGraphicsView();
       
    97     virtual ~tst_QGraphicsView();
       
    98 
       
    99 public slots:
       
   100     void init();
       
   101     void cleanup();
       
   102 
       
   103 private slots:
       
   104     void construct();
       
   105     void paintSingleItem();
       
   106     void paintDeepStackingItems();
       
   107     void paintDeepStackingItems_clipped();
       
   108     void moveSingleItem();
       
   109     void mapPointToScene_data();
       
   110     void mapPointToScene();
       
   111     void mapPointFromScene_data();
       
   112     void mapPointFromScene();
       
   113     void mapRectToScene_data();
       
   114     void mapRectToScene();
       
   115     void mapRectFromScene_data();
       
   116     void mapRectFromScene();
       
   117     void chipTester_data();
       
   118     void chipTester();
       
   119     void deepNesting_data();
       
   120     void deepNesting();
       
   121     void imageRiver_data();
       
   122     void imageRiver();
       
   123     void textRiver_data();
       
   124     void textRiver();
       
   125     void moveItemCache_data();
       
   126     void moveItemCache();
       
   127     void paintItemCache_data();
       
   128     void paintItemCache();
       
   129 };
       
   130 
       
   131 tst_QGraphicsView::tst_QGraphicsView()
       
   132 {
       
   133 }
       
   134 
       
   135 tst_QGraphicsView::~tst_QGraphicsView()
       
   136 {
       
   137 }
       
   138 
       
   139 void tst_QGraphicsView::init()
       
   140 {
       
   141 }
       
   142 
       
   143 void tst_QGraphicsView::cleanup()
       
   144 {
       
   145 }
       
   146 
       
   147 void tst_QGraphicsView::construct()
       
   148 {
       
   149     QBENCHMARK {
       
   150         QGraphicsView view;
       
   151     }
       
   152 }
       
   153 
       
   154 void tst_QGraphicsView::paintSingleItem()
       
   155 {
       
   156     QGraphicsScene scene(0, 0, 100, 100);
       
   157     scene.addRect(0, 0, 10, 10);
       
   158 
       
   159     QGraphicsView view(&scene);
       
   160     view.show();
       
   161     view.resize(100, 100);
       
   162 #ifdef Q_WS_X11
       
   163     qt_x11_wait_for_window_manager(&view);
       
   164 #endif
       
   165 
       
   166     QImage image(100, 100, QImage::Format_ARGB32_Premultiplied);
       
   167     QPainter painter(&image);
       
   168     QBENCHMARK {
       
   169 	view.viewport()->render(&painter);
       
   170     }
       
   171 }
       
   172 
       
   173 void tst_QGraphicsView::paintDeepStackingItems()
       
   174 {
       
   175     QGraphicsScene scene(0, 0, 100, 100);
       
   176     QGraphicsRectItem *item = scene.addRect(0, 0, 10, 10);
       
   177     QGraphicsRectItem *lastRect = item;
       
   178     for (int i = 0; i < 1000; ++i) {
       
   179 	QGraphicsRectItem *rect = scene.addRect(0, 0, 10, 10);
       
   180 	rect->setPos(1, 1);
       
   181 	rect->setParentItem(lastRect);	
       
   182 	lastRect = rect;
       
   183     }
       
   184 
       
   185     QGraphicsView view(&scene);
       
   186     view.show();
       
   187     view.resize(100, 100);
       
   188 #ifdef Q_WS_X11
       
   189     qt_x11_wait_for_window_manager(&view);
       
   190 #endif
       
   191 
       
   192     QImage image(100, 100, QImage::Format_ARGB32_Premultiplied);
       
   193     QPainter painter(&image);
       
   194     QBENCHMARK {
       
   195 	view.viewport()->render(&painter);
       
   196     }
       
   197 }
       
   198 
       
   199 void tst_QGraphicsView::paintDeepStackingItems_clipped()
       
   200 {
       
   201     QGraphicsScene scene(0, 0, 100, 100);
       
   202     QGraphicsRectItem *item = scene.addRect(0, 0, 10, 10);
       
   203     item->setFlag(QGraphicsItem::ItemClipsChildrenToShape);
       
   204     QGraphicsRectItem *lastRect = item;
       
   205     for (int i = 0; i < 1000; ++i) {
       
   206 	QGraphicsRectItem *rect = scene.addRect(0, 0, 10, 10);
       
   207 	rect->setPos(1, 1);
       
   208 	rect->setParentItem(lastRect);	
       
   209 	lastRect = rect;
       
   210     }
       
   211 
       
   212     QGraphicsView view(&scene);
       
   213     view.show();
       
   214     view.resize(100, 100);
       
   215 #ifdef Q_WS_X11
       
   216     qt_x11_wait_for_window_manager(&view);
       
   217 #endif
       
   218 
       
   219     QImage image(100, 100, QImage::Format_ARGB32_Premultiplied);
       
   220     QPainter painter(&image);
       
   221     QBENCHMARK {
       
   222 	view.viewport()->render(&painter);
       
   223     }
       
   224 }
       
   225 
       
   226 void tst_QGraphicsView::moveSingleItem()
       
   227 {
       
   228     QGraphicsScene scene(0, 0, 100, 100);
       
   229     QGraphicsRectItem *item = scene.addRect(0, 0, 10, 10);
       
   230 
       
   231     QGraphicsView view(&scene);
       
   232     view.show();
       
   233     view.resize(100, 100);
       
   234 #ifdef Q_WS_X11
       
   235     qt_x11_wait_for_window_manager(&view);
       
   236 #endif
       
   237 
       
   238     QEventWaiter waiter(view.viewport(), QEvent::Paint);
       
   239     int n = 1;
       
   240     QBENCHMARK {
       
   241         item->setPos(25 * n, 25 * n);
       
   242 	waiter.wait();
       
   243 	n = n ? 0 : 1;
       
   244     }
       
   245 }
       
   246 
       
   247 void tst_QGraphicsView::mapPointToScene_data()
       
   248 {
       
   249     QTest::addColumn<QTransform>("transform");
       
   250     QTest::addColumn<QPoint>("point");
       
   251 
       
   252     QTest::newRow("null") << QTransform() << QPoint();
       
   253     QTest::newRow("identity  QPoint(100, 100)") << QTransform() << QPoint(100, 100);
       
   254     QTest::newRow("rotate    QPoint(100, 100)") << QTransform().rotate(90) << QPoint(100, 100);
       
   255     QTest::newRow("scale     QPoint(100, 100)") << QTransform().scale(5, 5) << QPoint(100, 100);
       
   256     QTest::newRow("translate QPoint(100, 100)") << QTransform().translate(5, 5) << QPoint(100, 100);
       
   257     QTest::newRow("shear     QPoint(100, 100)") << QTransform().shear(1.5, 1.5) << QPoint(100, 100);
       
   258     QTest::newRow("perspect  QPoint(100, 100)") << QTransform().rotate(45, Qt::XAxis) << QPoint(100, 100);
       
   259 }
       
   260 
       
   261 void tst_QGraphicsView::mapPointToScene()
       
   262 {
       
   263     QFETCH(QTransform, transform);
       
   264     QFETCH(QPoint, point);
       
   265 
       
   266     QGraphicsView view;
       
   267     view.setTransform(transform);
       
   268     QBENCHMARK {
       
   269         view.mapToScene(point);
       
   270     }
       
   271 }
       
   272 
       
   273 void tst_QGraphicsView::mapPointFromScene_data()
       
   274 {
       
   275     QTest::addColumn<QTransform>("transform");
       
   276     QTest::addColumn<QPointF>("point");
       
   277 
       
   278     QTest::newRow("null") << QTransform() << QPointF();
       
   279     QTest::newRow("identity  QPointF(100, 100)") << QTransform() << QPointF(100, 100);
       
   280     QTest::newRow("rotate    QPointF(100, 100)") << QTransform().rotate(90) << QPointF(100, 100);
       
   281     QTest::newRow("scale     QPointF(100, 100)") << QTransform().scale(5, 5) << QPointF(100, 100);
       
   282     QTest::newRow("translate QPointF(100, 100)") << QTransform().translate(5, 5) << QPointF(100, 100);
       
   283     QTest::newRow("shear     QPointF(100, 100)") << QTransform().shear(1.5, 1.5) << QPointF(100, 100);
       
   284     QTest::newRow("perspect  QPointF(100, 100)") << QTransform().rotate(45, Qt::XAxis) << QPointF(100, 100);
       
   285 }
       
   286 
       
   287 void tst_QGraphicsView::mapPointFromScene()
       
   288 {
       
   289     QFETCH(QTransform, transform);
       
   290     QFETCH(QPointF, point);
       
   291 
       
   292     QGraphicsView view;
       
   293     view.setTransform(transform);
       
   294     QBENCHMARK {
       
   295         view.mapFromScene(point);
       
   296     }
       
   297 }
       
   298 
       
   299 void tst_QGraphicsView::mapRectToScene_data()
       
   300 {
       
   301     QTest::addColumn<QTransform>("transform");
       
   302     QTest::addColumn<QRect>("rect");
       
   303 
       
   304     QTest::newRow("null") << QTransform() << QRect();
       
   305     QTest::newRow("identity  QRect(0, 0, 100, 100)") << QTransform() << QRect(0, 0, 100, 100);
       
   306     QTest::newRow("rotate    QRect(0, 0, 100, 100)") << QTransform().rotate(90) << QRect(0, 0, 100, 100);
       
   307     QTest::newRow("scale     QRect(0, 0, 100, 100)") << QTransform().scale(5, 5) << QRect(0, 0, 100, 100);
       
   308     QTest::newRow("translate QRect(0, 0, 100, 100)") << QTransform().translate(5, 5) << QRect(0, 0, 100, 100);
       
   309     QTest::newRow("shear     QRect(0, 0, 100, 100)") << QTransform().shear(1.5, 1.5) << QRect(0, 0, 100, 100);
       
   310     QTest::newRow("perspect  QRect(0, 0, 100, 100)") << QTransform().rotate(45, Qt::XAxis) << QRect(0, 0, 100, 100);
       
   311 }
       
   312 
       
   313 void tst_QGraphicsView::mapRectToScene()
       
   314 {
       
   315     QFETCH(QTransform, transform);
       
   316     QFETCH(QRect, rect);
       
   317 
       
   318     QGraphicsView view;
       
   319     view.setTransform(transform);
       
   320     QBENCHMARK {
       
   321         view.mapToScene(rect);
       
   322     }
       
   323 }
       
   324 
       
   325 void tst_QGraphicsView::mapRectFromScene_data()
       
   326 {
       
   327     QTest::addColumn<QTransform>("transform");
       
   328     QTest::addColumn<QRectF>("rect");
       
   329 
       
   330     QTest::newRow("null") << QTransform() << QRectF();
       
   331     QTest::newRow("identity  QRectF(0, 0, 100, 100)") << QTransform() << QRectF(0, 0, 100, 100);
       
   332     QTest::newRow("rotate    QRectF(0, 0, 100, 100)") << QTransform().rotate(90) << QRectF(0, 0, 100, 100);
       
   333     QTest::newRow("scale     QRectF(0, 0, 100, 100)") << QTransform().scale(5, 5) << QRectF(0, 0, 100, 100);
       
   334     QTest::newRow("translate QRectF(0, 0, 100, 100)") << QTransform().translate(5, 5) << QRectF(0, 0, 100, 100);
       
   335     QTest::newRow("shear     QRectF(0, 0, 100, 100)") << QTransform().shear(1.5, 1.5) << QRectF(0, 0, 100, 100);
       
   336     QTest::newRow("perspect  QRectF(0, 0, 100, 100)") << QTransform().rotate(45, Qt::XAxis) << QRectF(0, 0, 100, 100);
       
   337 }
       
   338 
       
   339 void tst_QGraphicsView::mapRectFromScene()
       
   340 {
       
   341     QFETCH(QTransform, transform);
       
   342     QFETCH(QRectF, rect);
       
   343 
       
   344     QGraphicsView view;
       
   345     view.setTransform(transform);
       
   346     QBENCHMARK {
       
   347         view.mapFromScene(rect);
       
   348     }
       
   349 }
       
   350 
       
   351 void tst_QGraphicsView::chipTester_data()
       
   352 {
       
   353     QTest::addColumn<bool>("antialias");
       
   354     QTest::addColumn<bool>("opengl");
       
   355     QTest::addColumn<int>("operation");
       
   356     QTest::newRow("rotate, normal") << false << false << 0;
       
   357     QTest::newRow("rotate, normal, antialias") << true << false << 0;
       
   358     QTest::newRow("rotate, opengl") << false << true << 0;
       
   359     QTest::newRow("rotate, opengl, antialias") << true << true << 0;
       
   360     QTest::newRow("zoom, normal") << false << false << 1;
       
   361     QTest::newRow("zoom, normal, antialias") << true << false << 1;
       
   362     QTest::newRow("zoom, opengl") << false << true << 1;
       
   363     QTest::newRow("zoom, opengl, antialias") << true << true << 1;
       
   364     QTest::newRow("translate, normal") << false << false << 2;
       
   365     QTest::newRow("translate, normal, antialias") << true << false << 2;
       
   366     QTest::newRow("translate, opengl") << false << true << 2;
       
   367     QTest::newRow("translate, opengl, antialias") << true << true << 2;
       
   368 }
       
   369 
       
   370 void tst_QGraphicsView::chipTester()
       
   371 {
       
   372     QFETCH(bool, antialias);
       
   373     QFETCH(bool, opengl);
       
   374     QFETCH(int, operation);
       
   375 
       
   376     ChipTester tester;
       
   377     tester.show();
       
   378 #ifdef Q_WS_X11
       
   379     qt_x11_wait_for_window_manager(&tester);
       
   380 #endif
       
   381     tester.setAntialias(antialias);
       
   382     tester.setOpenGL(opengl);
       
   383     tester.setOperation(ChipTester::Operation(operation));
       
   384     QBENCHMARK {
       
   385 	tester.runBenchmark();
       
   386     }
       
   387 }
       
   388 
       
   389 static void addChildHelper(QGraphicsItem *parent, int n, bool rotate)
       
   390 {
       
   391     if (!n)
       
   392 	return;
       
   393     QGraphicsRectItem *item = new QGraphicsRectItem(QRectF(0, 0, 50, 50), parent);
       
   394     item->setPos(10, 10);
       
   395     if (rotate)
       
   396 	item->rotate(10);
       
   397     addChildHelper(item, n - 1, rotate);
       
   398 }
       
   399 
       
   400 void tst_QGraphicsView::deepNesting_data()
       
   401 {
       
   402     QTest::addColumn<bool>("rotate");
       
   403     QTest::addColumn<bool>("sortCache");
       
   404     QTest::addColumn<bool>("bsp");
       
   405 
       
   406     QTest::newRow("bsp, no transform") << false << false << true;
       
   407     QTest::newRow("bsp, rotation") << true << false << true;
       
   408     QTest::newRow("bsp, no transform, sort cache") << false << true << true;
       
   409     QTest::newRow("bsp, rotation, sort cache") << true << true << true;
       
   410     QTest::newRow("no transform") << false << false << false;
       
   411     QTest::newRow("rotation") << true << false << false;
       
   412     QTest::newRow("no transform, sort cache") << false << true << false;
       
   413     QTest::newRow("rotation, sort cache") << true << true << false;
       
   414 }
       
   415 
       
   416 void tst_QGraphicsView::deepNesting()
       
   417 {
       
   418     QFETCH(bool, rotate);
       
   419     QFETCH(bool, sortCache);
       
   420     QFETCH(bool, bsp);
       
   421 
       
   422     QGraphicsScene scene;
       
   423     for (int y = 0; y < 15; ++y) {
       
   424 	for (int x = 0; x < 15; ++x) {
       
   425 	    QGraphicsItem *item1 = scene.addRect(QRectF(0, 0, 50, 50));
       
   426 	    if (rotate) item1->rotate(10);
       
   427 	    item1->setPos(x * 25, y * 25);
       
   428 	    addChildHelper(item1, 30, rotate);
       
   429 	}
       
   430     }
       
   431     scene.setItemIndexMethod(bsp ? QGraphicsScene::BspTreeIndex : QGraphicsScene::NoIndex);
       
   432     scene.setSortCacheEnabled(sortCache);
       
   433 
       
   434     QGraphicsView view(&scene);
       
   435     view.setRenderHint(QPainter::Antialiasing);
       
   436     view.show();
       
   437 #ifdef Q_WS_X11
       
   438     qt_x11_wait_for_window_manager(&view);
       
   439 #endif
       
   440     QTest::qWait(250);
       
   441 
       
   442     QBENCHMARK {
       
   443 #ifdef CALLGRIND_DEBUG
       
   444 	CALLGRIND_START_INSTRUMENTATION
       
   445 #endif
       
   446 	view.viewport()->repaint();
       
   447 #ifdef CALLGRIND_DEBUG
       
   448 	CALLGRIND_STOP_INSTRUMENTATION
       
   449 #endif
       
   450     }
       
   451 }
       
   452 
       
   453 class AnimatedPixmapItem : public QGraphicsPixmapItem
       
   454 {
       
   455 public:
       
   456     AnimatedPixmapItem(int x, int y, bool rot, bool scal, QGraphicsItem *parent = 0)
       
   457         : QGraphicsPixmapItem(parent), rotateFactor(0), scaleFactor(0)
       
   458     {
       
   459 	rotate = rot;
       
   460 	scale = scal;
       
   461 	xspeed = x;
       
   462 	yspeed = y;
       
   463     }
       
   464 
       
   465 protected:
       
   466     void advance(int i)
       
   467     { 
       
   468 	if (!i)
       
   469 	    return;
       
   470 	int x = int(pos().x()) + pixmap().width();
       
   471 	x += xspeed;
       
   472 	x = (x % (300 + pixmap().width() * 2)) - pixmap().width();
       
   473 	int y = int(pos().y()) + pixmap().width();
       
   474 	y += yspeed;
       
   475 	y = (y % (300 + pixmap().width() * 2)) - pixmap().width();
       
   476 	setPos(x, y);
       
   477 
       
   478 	int rot = rotateFactor;
       
   479 	int sca = scaleFactor;
       
   480         if (rotate)
       
   481 	    rotateFactor = 1 + (rot + xspeed) % 360;
       
   482         if (scale)
       
   483 	    scaleFactor = 1 + (sca + yspeed) % 50;
       
   484 
       
   485 	if (rotate || scale) {
       
   486 	    qreal s = 0.5 + scaleFactor / 50.0;
       
   487 	    setTransform(QTransform().rotate(rotateFactor).scale(s, s));
       
   488 	}
       
   489     }
       
   490 
       
   491 private:
       
   492     int xspeed;
       
   493     int yspeed;
       
   494     int rotateFactor;
       
   495     int scaleFactor;
       
   496     bool rotate;
       
   497     bool scale;
       
   498 };
       
   499 
       
   500 class CountPaintEventView : public QGraphicsView
       
   501 {
       
   502 public:
       
   503     CountPaintEventView(QGraphicsScene *scene = 0)
       
   504         : QGraphicsView(scene), count(0)
       
   505     { }
       
   506 
       
   507     int count;
       
   508 
       
   509 protected:
       
   510     void paintEvent(QPaintEvent *event)
       
   511     {
       
   512         ++count;
       
   513         QGraphicsView::paintEvent(event);
       
   514     };
       
   515 };
       
   516 
       
   517 void tst_QGraphicsView::imageRiver_data()
       
   518 {
       
   519     QTest::addColumn<int>("direction");
       
   520     QTest::addColumn<bool>("rotation");
       
   521     QTest::addColumn<bool>("scale");
       
   522     QTest::newRow("horizontal") << 0 << false << false;
       
   523     QTest::newRow("vertical") << 1 << false << false;
       
   524     QTest::newRow("both") << 2 << false << false;
       
   525     QTest::newRow("horizontal rot") << 0 << true << false;
       
   526     QTest::newRow("horizontal scale") << 0 << false << true;
       
   527     QTest::newRow("horizontal rot + scale") << 0 << true << true;
       
   528 }
       
   529 
       
   530 void tst_QGraphicsView::imageRiver()
       
   531 {
       
   532     QFETCH(int, direction);
       
   533     QFETCH(bool, rotation);
       
   534     QFETCH(bool, scale);
       
   535 
       
   536     QGraphicsScene scene(0, 0, 300, 300);
       
   537 
       
   538     CountPaintEventView view(&scene);
       
   539     view.resize(300, 300);
       
   540     view.setFrameStyle(0);
       
   541     view.setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
       
   542     view.setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
       
   543     view.show();
       
   544 
       
   545     QPixmap pix(":/images/designer.png");
       
   546     QVERIFY(!pix.isNull());   
       
   547 
       
   548     QList<QGraphicsItem *> items;
       
   549     QFile file(":/random.data");
       
   550     QVERIFY(file.open(QIODevice::ReadOnly));
       
   551     QDataStream str(&file);
       
   552     for (int i = 0; i < 100; ++i) {
       
   553 	AnimatedPixmapItem *item;
       
   554 	if (direction == 0) item = new AnimatedPixmapItem((i % 4) + 1, 0, rotation, scale);
       
   555 	if (direction == 1) item = new AnimatedPixmapItem(0, (i % 4) + 1, rotation, scale);
       
   556 	if (direction == 2) item = new AnimatedPixmapItem((i % 4) + 1, (i % 4) + 1, rotation, scale);
       
   557 	item->setPixmap(pix);
       
   558         int rnd1, rnd2;
       
   559         str >> rnd1 >> rnd2;
       
   560 	item->setPos(-pix.width() + rnd1 % (view.width() + pix.width()),
       
   561 		     -pix.height() + rnd2 % (view.height() + pix.height()));
       
   562 	scene.addItem(item);
       
   563     }
       
   564 
       
   565     view.count = 0;
       
   566 
       
   567     QBENCHMARK {
       
   568 #ifdef CALLGRIND_DEBUG
       
   569 	CALLGRIND_START_INSTRUMENTATION
       
   570 #endif
       
   571 	for (int i = 0; i < 100; ++i) {
       
   572 	    scene.advance();
       
   573 	    while (view.count < (i+1))
       
   574 		qApp->processEvents();
       
   575 	}
       
   576 #ifdef CALLGRIND_DEBUG
       
   577 	CALLGRIND_STOP_INSTRUMENTATION
       
   578 #endif
       
   579     }
       
   580 }
       
   581 
       
   582 class AnimatedTextItem : public QGraphicsSimpleTextItem
       
   583 {
       
   584 public:
       
   585     AnimatedTextItem(int x, int y, bool rot, bool scal, QGraphicsItem *parent = 0)
       
   586         : QGraphicsSimpleTextItem(parent), rotateFactor(0), scaleFactor(25)
       
   587     {
       
   588 	setText("River of text");
       
   589 	rotate = rot;
       
   590 	scale = scal;
       
   591 	xspeed = x;
       
   592 	yspeed = y;
       
   593     }
       
   594 
       
   595 protected:
       
   596     void advance(int i)
       
   597     { 
       
   598 	if (!i)
       
   599 	    return;
       
   600 	QRect r = boundingRect().toRect();
       
   601 	int x = int(pos().x()) + r.width();
       
   602 	x += xspeed;
       
   603 	x = (x % (300 + r.width() * 2)) - r.width();
       
   604 	int y = int(pos().y()) + r.width();
       
   605 	y += yspeed;
       
   606 	y = (y % (300 + r.width() * 2)) - r.width();
       
   607 	setPos(x, y);
       
   608 
       
   609 	int rot = rotateFactor;
       
   610 	int sca = scaleFactor;
       
   611         if (rotate)
       
   612 	    rotateFactor = 1 + (rot + xspeed) % 360;
       
   613         if (scale)
       
   614 	    scaleFactor = 1 + (sca + yspeed) % 50;
       
   615 
       
   616 	if (rotate || scale) {
       
   617 	    qreal s = 0.5 + scaleFactor / 50.0;
       
   618 	    setTransform(QTransform().rotate(rotateFactor).scale(s, s));
       
   619 	}
       
   620     }
       
   621 
       
   622 private:
       
   623     int xspeed;
       
   624     int yspeed;
       
   625     int rotateFactor;
       
   626     int scaleFactor;
       
   627     bool rotate;
       
   628     bool scale;
       
   629 };
       
   630 
       
   631 void tst_QGraphicsView::textRiver_data()
       
   632 {
       
   633     QTest::addColumn<int>("direction");
       
   634     QTest::addColumn<bool>("rotation");
       
   635     QTest::addColumn<bool>("scale");
       
   636     QTest::newRow("horizontal") << 0 << false << false;
       
   637     QTest::newRow("vertical") << 1 << false << false;
       
   638     QTest::newRow("both") << 2 << false << false;
       
   639     QTest::newRow("horizontal rot") << 0 << true << false;
       
   640     QTest::newRow("horizontal scale") << 0 << false << true;
       
   641     QTest::newRow("horizontal rot + scale") << 0 << true << true;
       
   642 }
       
   643 
       
   644 void tst_QGraphicsView::textRiver()
       
   645 {
       
   646     QFETCH(int, direction);
       
   647     QFETCH(bool, rotation);
       
   648     QFETCH(bool, scale);
       
   649 
       
   650     QGraphicsScene scene(0, 0, 300, 300);
       
   651 
       
   652     CountPaintEventView view(&scene);
       
   653     view.resize(300, 300);
       
   654     view.setFrameStyle(0);
       
   655     view.setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
       
   656     view.setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
       
   657     view.show();
       
   658 
       
   659     QPixmap pix(":/images/designer.png");
       
   660     QVERIFY(!pix.isNull());   
       
   661 
       
   662     QList<QGraphicsItem *> items;
       
   663     QFile file(":/random.data");
       
   664     QVERIFY(file.open(QIODevice::ReadOnly));
       
   665     QDataStream str(&file);
       
   666     for (int i = 0; i < 100; ++i) {
       
   667 	AnimatedTextItem *item;
       
   668 	if (direction == 0) item = new AnimatedTextItem((i % 4) + 1, 0, rotation, scale);
       
   669 	if (direction == 1) item = new AnimatedTextItem(0, (i % 4) + 1, rotation, scale);
       
   670 	if (direction == 2) item = new AnimatedTextItem((i % 4) + 1, (i % 4) + 1, rotation, scale);
       
   671         int rnd1, rnd2;
       
   672         str >> rnd1 >> rnd2;
       
   673 	item->setPos(-pix.width() + rnd1 % (view.width() + pix.width()),
       
   674 		     -pix.height() + rnd2 % (view.height() + pix.height()));
       
   675 	scene.addItem(item);
       
   676     }
       
   677 
       
   678     view.count = 0;
       
   679 
       
   680     QBENCHMARK {
       
   681 #ifdef CALLGRIND_DEBUG
       
   682 	CALLGRIND_START_INSTRUMENTATION
       
   683 #endif
       
   684 	for (int i = 0; i < 100; ++i) {
       
   685 	    scene.advance();
       
   686 	    while (view.count < (i+1))
       
   687 		qApp->processEvents();
       
   688 	}
       
   689 #ifdef CALLGRIND_DEBUG
       
   690 	CALLGRIND_STOP_INSTRUMENTATION
       
   691 #endif
       
   692     }
       
   693 }
       
   694 
       
   695 class AnimatedPixmapCacheItem : public QGraphicsPixmapItem
       
   696 {
       
   697 public:
       
   698     AnimatedPixmapCacheItem(int x, int y, QGraphicsItem *parent = 0)
       
   699         : QGraphicsPixmapItem(parent)
       
   700     {
       
   701         xspeed = x;
       
   702         yspeed = y;
       
   703     }
       
   704 
       
   705     void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0)
       
   706     {
       
   707         QGraphicsPixmapItem::paint(painter,option,widget);
       
   708         //We just want to wait, and we don't want to process the event loop with qWait
       
   709         QTest::qSleep(3);
       
   710     }
       
   711 protected:
       
   712     void advance(int i)
       
   713     {
       
   714         if (!i)
       
   715             return;
       
   716         int x = int(pos().x()) + pixmap().width();
       
   717         x += xspeed;
       
   718         x = (x % (300 + pixmap().width() * 2)) - pixmap().width();
       
   719         int y = int(pos().y()) + pixmap().width();
       
   720         y += yspeed;
       
   721         y = (y % (300 + pixmap().width() * 2)) - pixmap().width();
       
   722         setPos(x, y);
       
   723     }
       
   724 
       
   725 private:
       
   726     int xspeed;
       
   727     int yspeed;
       
   728 };
       
   729 
       
   730 void tst_QGraphicsView::moveItemCache_data()
       
   731 {
       
   732     QTest::addColumn<int>("direction");
       
   733     QTest::addColumn<bool>("rotation");
       
   734     QTest::addColumn<int>("cacheMode");
       
   735     QTest::newRow("Horizontal movement : ItemCoordinate Cache") << 0 << false << (int)QGraphicsItem::ItemCoordinateCache;
       
   736     QTest::newRow("Horizontal movement : DeviceCoordinate Cache") << 0 << false << (int)QGraphicsItem::DeviceCoordinateCache;
       
   737     QTest::newRow("Horizontal movement : No Cache") << 0 << false << (int)QGraphicsItem::NoCache;
       
   738     QTest::newRow("Vertical +  Horizontal movement : ItemCoordinate Cache") << 2 << false <<  (int)QGraphicsItem::ItemCoordinateCache;
       
   739     QTest::newRow("Vertical +  Horizontal movement : DeviceCoordinate Cache") << 2 << false <<  (int)QGraphicsItem::DeviceCoordinateCache;
       
   740     QTest::newRow("Vertical +  Horizontal movement : No Cache") << 2 << false << (int)QGraphicsItem::NoCache;
       
   741     QTest::newRow("Horizontal movement + Rotation : ItemCoordinate Cache") << 0 << true << (int)QGraphicsItem::ItemCoordinateCache;
       
   742     QTest::newRow("Horizontal movement + Rotation : DeviceCoordinate Cache") << 0 << true << (int)QGraphicsItem::DeviceCoordinateCache;
       
   743     QTest::newRow("Horizontal movement + Rotation : No Cache") << 0 << true << (int)QGraphicsItem::NoCache;
       
   744 }
       
   745 
       
   746 void tst_QGraphicsView::moveItemCache()
       
   747 {
       
   748     QFETCH(int, direction);
       
   749     QFETCH(bool, rotation);
       
   750     QFETCH(int, cacheMode);
       
   751 
       
   752     QGraphicsScene scene(0, 0, 300, 300);
       
   753 
       
   754     CountPaintEventView view(&scene);
       
   755     view.resize(600, 600);
       
   756     view.setFrameStyle(0);
       
   757     view.setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
       
   758     view.setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
       
   759     view.show();
       
   760 
       
   761     QPixmap pix(":/images/wine.jpeg");
       
   762     QVERIFY(!pix.isNull());
       
   763 
       
   764     QList<QGraphicsItem *> items;
       
   765     QFile file(":/random.data");
       
   766     QVERIFY(file.open(QIODevice::ReadOnly));
       
   767     QDataStream str(&file);
       
   768     for (int i = 0; i < 50; ++i) {
       
   769         AnimatedPixmapCacheItem *item;
       
   770         if (direction == 0) item = new AnimatedPixmapCacheItem((i % 4) + 1, 0);
       
   771         if (direction == 1) item = new AnimatedPixmapCacheItem(0, (i % 4) + 1);
       
   772         if (direction == 2) item = new AnimatedPixmapCacheItem((i % 4) + 1, (i % 4) + 1);
       
   773         item->setPixmap(pix);
       
   774         item->setCacheMode((QGraphicsItem::CacheMode)cacheMode);
       
   775         if (rotation)
       
   776             item->setTransform(QTransform().rotate(45));
       
   777         int rnd1, rnd2;
       
   778         str >> rnd1 >> rnd2;
       
   779         item->setPos(-pix.width() + rnd1 % (view.width() + pix.width()),
       
   780                      -pix.height() + rnd2 % (view.height() + pix.height()));
       
   781         scene.addItem(item);
       
   782     }
       
   783 
       
   784     view.count = 0;
       
   785 
       
   786     QBENCHMARK {
       
   787 #ifdef CALLGRIND_DEBUG
       
   788         CALLGRIND_START_INSTRUMENTATION
       
   789 #endif
       
   790         for (int i = 0; i < 100; ++i) {
       
   791             scene.advance();
       
   792             while (view.count < (i+1))
       
   793                 qApp->processEvents();
       
   794         }
       
   795 #ifdef CALLGRIND_DEBUG
       
   796         CALLGRIND_STOP_INSTRUMENTATION
       
   797 #endif
       
   798     }
       
   799 }
       
   800 
       
   801 class UpdatedPixmapCacheItem : public QGraphicsPixmapItem
       
   802 {
       
   803 public:
       
   804     UpdatedPixmapCacheItem(bool partial, QGraphicsItem *parent = 0)
       
   805         : QGraphicsPixmapItem(parent), partial(partial)
       
   806     {
       
   807     }
       
   808 
       
   809     void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0)
       
   810     {
       
   811         QGraphicsPixmapItem::paint(painter,option,widget);
       
   812     }
       
   813 protected:
       
   814     void advance(int i)
       
   815     {
       
   816         if (partial)
       
   817             update(QRectF(boundingRect().center().x(), boundingRect().center().x(), 30, 30));
       
   818         else
       
   819             update();
       
   820     }
       
   821 
       
   822 private:
       
   823     bool partial;
       
   824 };
       
   825 
       
   826 void tst_QGraphicsView::paintItemCache_data()
       
   827 {
       
   828     QTest::addColumn<bool>("updatePartial");
       
   829     QTest::addColumn<bool>("rotation");
       
   830     QTest::addColumn<int>("cacheMode");
       
   831     QTest::newRow("Partial Update : ItemCoordinate Cache") << true << false << (int)QGraphicsItem::ItemCoordinateCache;
       
   832     QTest::newRow("Partial Update : DeviceCoordinate Cache") << true << false << (int)QGraphicsItem::DeviceCoordinateCache;
       
   833     QTest::newRow("Partial Update : No Cache") << true << false << (int)QGraphicsItem::NoCache;
       
   834     QTest::newRow("Full Update : ItemCoordinate Cache") << false << false << (int)QGraphicsItem::ItemCoordinateCache;
       
   835     QTest::newRow("Full Update : DeviceCoordinate Cache") << false << false << (int)QGraphicsItem::DeviceCoordinateCache;
       
   836     QTest::newRow("Full Update : No Cache") << false << false << (int)QGraphicsItem::NoCache;
       
   837     QTest::newRow("Partial Update : ItemCoordinate Cache item rotated") << true << true << (int)QGraphicsItem::ItemCoordinateCache;
       
   838     QTest::newRow("Partial Update : DeviceCoordinate Cache item rotated") << true << true << (int)QGraphicsItem::DeviceCoordinateCache;
       
   839     QTest::newRow("Partial Update : No Cache item rotated") << true << true << (int)QGraphicsItem::NoCache;
       
   840     QTest::newRow("Full Update : ItemCoordinate Cache item rotated") << false  << true << (int)QGraphicsItem::ItemCoordinateCache;
       
   841     QTest::newRow("Full Update : DeviceCoordinate Cache item rotated") << false << true << (int)QGraphicsItem::DeviceCoordinateCache;
       
   842     QTest::newRow("Full Update : No Cache item rotated") << false << true <<(int)QGraphicsItem::NoCache;
       
   843 }
       
   844 
       
   845 void tst_QGraphicsView::paintItemCache()
       
   846 {
       
   847     QFETCH(bool, updatePartial);
       
   848     QFETCH(bool, rotation);
       
   849     QFETCH(int, cacheMode);
       
   850 
       
   851     QGraphicsScene scene(0, 0, 300, 300);
       
   852 
       
   853     CountPaintEventView view(&scene);
       
   854     view.resize(600, 600);
       
   855     view.setFrameStyle(0);
       
   856     view.setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
       
   857     view.setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
       
   858     view.show();
       
   859 
       
   860     QPixmap pix(":/images/wine.jpeg");
       
   861     QVERIFY(!pix.isNull());
       
   862 
       
   863     QList<QGraphicsItem *> items;
       
   864     QFile file(":/random.data");
       
   865     QVERIFY(file.open(QIODevice::ReadOnly));
       
   866     QDataStream str(&file);
       
   867     UpdatedPixmapCacheItem *item = new UpdatedPixmapCacheItem(updatePartial);
       
   868     item->setPixmap(pix);
       
   869     item->setCacheMode((QGraphicsItem::CacheMode)cacheMode);
       
   870     if (rotation)
       
   871         item->setTransform(QTransform().rotate(45));
       
   872     item->setPos(-100, -100);
       
   873     scene.addItem(item);
       
   874 
       
   875     QPixmap pix2(":/images/wine-big.jpeg");
       
   876     item = new UpdatedPixmapCacheItem(updatePartial);
       
   877     item->setPixmap(pix2);
       
   878     item->setCacheMode((QGraphicsItem::CacheMode)cacheMode);
       
   879     if (rotation)
       
   880         item->setTransform(QTransform().rotate(45));
       
   881     item->setPos(0, 0);
       
   882     scene.addItem(item);
       
   883 
       
   884     view.count = 0;
       
   885 
       
   886     QBENCHMARK {
       
   887 #ifdef CALLGRIND_DEBUG
       
   888         CALLGRIND_START_INSTRUMENTATION
       
   889 #endif
       
   890         for (int i = 0; i < 50; ++i) {
       
   891             scene.advance();
       
   892             while (view.count < (i+1))
       
   893                 qApp->processEvents();
       
   894         }
       
   895 #ifdef CALLGRIND_DEBUG
       
   896         CALLGRIND_STOP_INSTRUMENTATION
       
   897 #endif
       
   898     }
       
   899 }
       
   900 
       
   901 QTEST_MAIN(tst_QGraphicsView)
       
   902 #include "tst_qgraphicsview.moc"