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