tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/main.cpp
branchRCL_3
changeset 7 3f74d0d4af4c
equal deleted inserted replaced
6:dee5afe5301f 7:3f74d0d4af4c
       
     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 
       
    43 #include <QtTest/QtTest>
       
    44 #include <QtGui/qgraphicsview.h>
       
    45 #include <QtGui/qpixmapcache.h>
       
    46 #include <QtGui/qdesktopwidget.h>
       
    47 
       
    48 #include "mainview.h"
       
    49 #include "dummydatagen.h"
       
    50 #include "simplelist.h"
       
    51 #include "itemrecyclinglist.h"
       
    52 #include "simplelist.h"
       
    53 #include "theme.h"
       
    54 #include "commandline.h"
       
    55 
       
    56 class tst_GraphicsViewBenchmark : public QObject
       
    57 {
       
    58     Q_OBJECT
       
    59 public:
       
    60     enum ListType {
       
    61         Simple,
       
    62         Recycling,
       
    63         None
       
    64     };
       
    65 
       
    66     enum ScrollStep {
       
    67         Slow = 2,
       
    68         Normal = 8,
       
    69         Fast = 64
       
    70     };
       
    71 
       
    72     tst_GraphicsViewBenchmark(Settings *settings)
       
    73         : mSettings(settings), mMainView(0), currentListSize(-1), currentListType(None) {}
       
    74     ~tst_GraphicsViewBenchmark() {}
       
    75 
       
    76 public slots:
       
    77     void initTestCase();
       
    78     void cleanupTestCase();
       
    79     void init();
       
    80 
       
    81 private slots:
       
    82     // Benchmarks:
       
    83     void createAndFillList_data();
       
    84     void createAndFillList();
       
    85     void add100ItemsToBeginningOfList_data();
       
    86     void add100ItemsToBeginningOfList();
       
    87     void remove100ItemsFromBeginningOfList_data();
       
    88     void remove100ItemsFromBeginningOfList();
       
    89     void deleteList_data();
       
    90     void deleteList();
       
    91     void themeChange_data();
       
    92     void themeChange();
       
    93     void update_data();
       
    94     void update();
       
    95     void scroll_data();
       
    96     void scroll();
       
    97 
       
    98 private:
       
    99     Settings *mSettings;
       
   100     MainView *mMainView;
       
   101     DummyDataGenerator mDataGenerator;
       
   102     int currentListSize;
       
   103     ListType currentListType;
       
   104 
       
   105     void resetView();
       
   106     void ensureListSizeAndType(int listSize, ListType listType);
       
   107     void ensureTheme(Theme::Themes theme);
       
   108     void ensureRotationAngle(int rotation);
       
   109     void ensureSubtreeCache(bool enable);
       
   110     void ensureImageBasedRendering(bool enable);
       
   111     void insertListData();
       
   112     inline void setTestWidget(QGraphicsWidget *widget, int listSize, ListType listType)
       
   113     {
       
   114         currentListSize = listSize;
       
   115         currentListType = listType;
       
   116         mMainView->setTestWidget(widget);
       
   117     }
       
   118 };
       
   119 
       
   120 Q_DECLARE_METATYPE(tst_GraphicsViewBenchmark::ListType)
       
   121 Q_DECLARE_METATYPE(Theme::Themes)
       
   122 Q_DECLARE_METATYPE(tst_GraphicsViewBenchmark::ScrollStep)
       
   123 
       
   124 const int AddRemoveCount = 100;
       
   125 
       
   126 static ListItem *newSimpleListItem(DummyDataGenerator &dataGenerator, const int id)
       
   127 {
       
   128     ListItem *item = new ListItem();
       
   129     item->setText(dataGenerator.randomName(), ListItem::FirstPos );
       
   130     item->setText(dataGenerator.randomPhoneNumber(QString("%1").arg(id)), ListItem::SecondPos );
       
   131     item->setIcon(new IconItem(dataGenerator.randomIconItem(), item), ListItem::LeftIcon );
       
   132     item->setIcon(new IconItem(dataGenerator.randomStatusItem(), item), ListItem::RightIcon);
       
   133     item->setFont(Theme::p()->font(Theme::ContactName), ListItem::FirstPos);
       
   134     item->setFont(Theme::p()->font(Theme::ContactNumber), ListItem::SecondPos);
       
   135     item->setBorderPen(Theme::p()->listItemBorderPen());
       
   136     item->setRounding(Theme::p()->listItemRounding());
       
   137     item->icon(ListItem::LeftIcon)->setRotation(Theme::p()->iconRotation(ListItem::LeftIcon));
       
   138     item->icon(ListItem::RightIcon)->setRotation(Theme::p()->iconRotation(ListItem::RightIcon));
       
   139     item->icon(ListItem::LeftIcon)->setSmoothTransformationEnabled(Theme::p()->isIconSmoothTransformationEnabled(ListItem::LeftIcon));
       
   140     item->icon(ListItem::RightIcon)->setSmoothTransformationEnabled(Theme::p()->isIconSmoothTransformationEnabled(ListItem::RightIcon));
       
   141     item->icon(ListItem::LeftIcon)->setOpacityEffectEnabled(Theme::p()->isIconOpacityEffectEnabled(ListItem::LeftIcon));
       
   142     item->icon(ListItem::RightIcon)->setOpacityEffectEnabled(Theme::p()->isIconOpacityEffectEnabled(ListItem::RightIcon));
       
   143     return item;
       
   144 }
       
   145 
       
   146 static RecycledListItem *newRecyclingListItem(DummyDataGenerator &dataGenerator, const int id)
       
   147 {
       
   148     RecycledListItem *item = new RecycledListItem();
       
   149     item->item()->setText(dataGenerator.randomName(), ListItem::FirstPos );
       
   150     item->item()->setText(dataGenerator.randomPhoneNumber(QString("%1").arg(id)), ListItem::SecondPos );
       
   151     item->item()->setIcon(new IconItem(dataGenerator.randomIconItem()), ListItem::LeftIcon );
       
   152     item->item()->setIcon(new IconItem(dataGenerator.randomStatusItem()), ListItem::RightIcon);
       
   153     item->item()->setFont(Theme::p()->font(Theme::ContactName), ListItem::FirstPos);
       
   154     item->item()->setFont(Theme::p()->font(Theme::ContactNumber), ListItem::SecondPos);
       
   155     item->item()->setBorderPen(Theme::p()->listItemBorderPen());
       
   156     item->item()->setRounding(Theme::p()->listItemRounding());
       
   157     item->item()->icon(ListItem::LeftIcon)->setRotation(Theme::p()->iconRotation(ListItem::LeftIcon));
       
   158     item->item()->icon(ListItem::RightIcon)->setRotation(Theme::p()->iconRotation(ListItem::RightIcon));
       
   159     item->item()->icon(ListItem::LeftIcon)->setSmoothTransformationEnabled(Theme::p()->isIconSmoothTransformationEnabled(ListItem::LeftIcon));
       
   160     item->item()->icon(ListItem::RightIcon)->setSmoothTransformationEnabled(Theme::p()->isIconSmoothTransformationEnabled(ListItem::RightIcon));
       
   161     item->item()->icon(ListItem::LeftIcon)->setOpacityEffectEnabled(Theme::p()->isIconOpacityEffectEnabled(ListItem::LeftIcon));
       
   162     item->item()->icon(ListItem::RightIcon)->setOpacityEffectEnabled(Theme::p()->isIconOpacityEffectEnabled(ListItem::RightIcon));
       
   163     return item;
       
   164 }
       
   165 
       
   166 static void fillList(DummyDataGenerator &dataGenerator, int itemCount, QGraphicsWidget *list)
       
   167 {
       
   168     if (SimpleList *simpleList = qobject_cast<SimpleList *>(list)) {
       
   169         for (int i = 0; i < itemCount; ++i)
       
   170             simpleList->addItem(newSimpleListItem(dataGenerator, i));
       
   171     } else if (ItemRecyclingList *recyclingList = qobject_cast<ItemRecyclingList *>(list)) {
       
   172         for (int i = 0; i < itemCount; ++i)
       
   173             recyclingList->addItem(newRecyclingListItem(dataGenerator, i));
       
   174     } else {
       
   175         qFatal("fillList: internal error");
       
   176     }
       
   177 }
       
   178 
       
   179 void tst_GraphicsViewBenchmark::resetView()
       
   180 {
       
   181     if (QGraphicsWidget *widget = mMainView->takeTestWidget()) {
       
   182         delete widget;
       
   183         currentListSize = -1;
       
   184         currentListType = None;
       
   185         QTest::qWait(50);
       
   186     } else {
       
   187         if (currentListSize != -1)
       
   188             qFatal("tst_GraphicsViewBenchmark::resetView: internal error: wrong list size");
       
   189         if (currentListType != None)
       
   190             qFatal("tst_GraphicsViewBenchmark::resetView: internal error: wrong list type");
       
   191     }
       
   192     ensureTheme(Theme::Blue);
       
   193     ensureRotationAngle(0);
       
   194     ensureSubtreeCache(false);
       
   195     ensureImageBasedRendering(false);
       
   196 }
       
   197 
       
   198 void tst_GraphicsViewBenchmark::ensureListSizeAndType(int listSize, ListType listType)
       
   199 {
       
   200     if (currentListSize != listSize || currentListType != listType) {
       
   201         resetView();
       
   202         if (listType == Simple) {
       
   203             SimpleList *list = new SimpleList;
       
   204             fillList(mDataGenerator, listSize, list);
       
   205             setTestWidget(list, listSize, listType);
       
   206         } else if (listType == Recycling) {
       
   207             ItemRecyclingList *list = new ItemRecyclingList;
       
   208             fillList(mDataGenerator, listSize, list);
       
   209             setTestWidget(list, listSize, listType);
       
   210         }
       
   211         QTest::qWait(50);
       
   212         return;
       
   213     }
       
   214 
       
   215     // Okay, we're supposed to have the right list type and size. Make sure we actually have it.
       
   216     QGraphicsWidget *widget = mMainView->testWidget();
       
   217     if (!widget) {
       
   218         if (currentListType != None || currentListSize != -1)
       
   219             qFatal("tst_GraphicsViewBenchmark::ensureListSizeAndType: internal error: no test widget");
       
   220         return;
       
   221     }
       
   222 
       
   223     if (listType == Simple) {
       
   224         SimpleList *list = qobject_cast<SimpleList *>(widget);
       
   225         if (!list)
       
   226             qFatal("tst_GraphicsViewBenchmark::ensureListSizeAndType: internal error: wrong list type");
       
   227         if (list->itemCount() != listSize)
       
   228             qFatal("tst_GraphicsViewBenchmark::ensureListSizeAndType: internal error: wrong list size");
       
   229     } else if (listType == Recycling){
       
   230         ItemRecyclingList *list = qobject_cast<ItemRecyclingList *>(widget);
       
   231         if (!list)
       
   232             qFatal("tst_GraphicsViewBenchmark::ensureListSizeAndType: internal error: wrong list type");
       
   233         if (list->rows() != listSize)
       
   234             qFatal("tst_GraphicsViewBenchmark::ensureListSizeAndType: internal error: wrong list size");
       
   235     }
       
   236 }
       
   237 
       
   238 void tst_GraphicsViewBenchmark::ensureTheme(Theme::Themes theme)
       
   239 {
       
   240     if (Theme::p()->theme() != theme) {
       
   241         Theme::p()->setTheme(theme);
       
   242         // The theme change itself can take a lot of time, so make
       
   243         // sure we give it a little bit time to stabilize *after*
       
   244         // the changes, hence sendPostedEvents(); qWait();
       
   245         QApplication::sendPostedEvents();
       
   246         QTest::qWait(50);
       
   247     }
       
   248 }
       
   249 
       
   250 void tst_GraphicsViewBenchmark::ensureRotationAngle(int angle)
       
   251 {
       
   252     const bool useTwoColumns = angle != 0;
       
   253     bool wait = false;
       
   254     if (mMainView->rotationAngle() != angle) {
       
   255         mMainView->rotateContent(-mMainView->rotationAngle() + angle);
       
   256         wait = true;
       
   257     }
       
   258     if (QGraphicsWidget *widget = mMainView->testWidget()) {
       
   259         if (SimpleList *list = qobject_cast<SimpleList *>(widget)) {
       
   260             if (list->twoColumns() != useTwoColumns) {
       
   261                 list->setTwoColumns(useTwoColumns);
       
   262                 wait = true;
       
   263             }
       
   264         } else if (ItemRecyclingList *list = qobject_cast<ItemRecyclingList *>(widget)) {
       
   265             if (list->twoColumns() != useTwoColumns) {
       
   266                 list->setTwoColumns(useTwoColumns);
       
   267                 wait = true;
       
   268             }
       
   269         }
       
   270     }
       
   271     if (wait)
       
   272         QTest::qWait(50);
       
   273 }
       
   274 
       
   275 void tst_GraphicsViewBenchmark::ensureSubtreeCache(bool enable)
       
   276 {
       
   277     QGraphicsWidget *widget = mMainView->testWidget();
       
   278     if (!widget)
       
   279         return;
       
   280 
       
   281     if (SimpleList *list = qobject_cast<SimpleList *>(widget)) {
       
   282         if (list->listItemCaching() != enable) {
       
   283             list->setListItemCaching(enable);
       
   284             QTest::qWait(50);
       
   285         }
       
   286     } else if (ItemRecyclingList *list = qobject_cast<ItemRecyclingList *>(widget)) {
       
   287         if (list->listItemCaching() != enable) {
       
   288             list->setListItemCaching(enable);
       
   289             QTest::qWait(50);
       
   290         }
       
   291     }
       
   292     QPixmapCache::clear();
       
   293 }
       
   294 
       
   295 void tst_GraphicsViewBenchmark::ensureImageBasedRendering(bool enable)
       
   296 {
       
   297     if (mMainView->imageBasedRendering() != enable) {
       
   298         mMainView->setImageBasedRendering(enable);
       
   299         QTest::qWait(50);
       
   300     }
       
   301 }
       
   302 
       
   303 void tst_GraphicsViewBenchmark::insertListData()
       
   304 {
       
   305     QTest::addColumn<int>("listSize");
       
   306     QTest::addColumn<ListType>("listType");
       
   307 
       
   308     QTest::newRow("Simple list containing 10 items") << 10 << Simple;
       
   309     QTest::newRow("Recycling list containing 10 items") << 10 << Recycling;
       
   310     QTest::newRow("Simple list containing 50 items") << 50 << Simple;
       
   311     QTest::newRow("Recycling list containing 50 items") << 50 << Recycling;
       
   312     QTest::newRow("Simple list containing 500 items") << 500 << Simple;
       
   313     QTest::newRow("Recycling list containing 500 items") << 500 << Recycling;
       
   314 }
       
   315 
       
   316 void tst_GraphicsViewBenchmark::initTestCase()
       
   317 {
       
   318     mMainView = new MainView(mSettings->options() & Settings::UseOpenGL,
       
   319                              mSettings->options() & Settings::OutputFps);
       
   320 
       
   321     if (mSettings->size().width() > 0 && mSettings->size().height() > 0) {
       
   322         mMainView->resize(mSettings->size().width(), mSettings->size().height());
       
   323         mMainView->show();
       
   324     } else {
       
   325 #if defined(Q_OS_SYMBIAN) || defined(Q_WS_MAEMO_5)
       
   326         mMainView->showFullScreen();
       
   327 #else
       
   328         if (QApplication::desktop()->width() < 360 || QApplication::desktop()->height() < 640) {
       
   329             mMainView->showFullScreen();
       
   330         } else {
       
   331             mMainView->resize(360, 640);
       
   332             mMainView->show();
       
   333         }
       
   334 #endif
       
   335     }
       
   336 
       
   337     mDataGenerator.Reset();
       
   338     SimpleList *list = new SimpleList;
       
   339     list->setListItemCaching(false);
       
   340     mMainView->setTestWidget(list);
       
   341     fillList(mDataGenerator, 5, list);
       
   342     mMainView->takeTestWidget();
       
   343     delete list;
       
   344 
       
   345     currentListSize = -1;
       
   346     currentListType = None;
       
   347 
       
   348     QTest::qWaitForWindowShown(mMainView);
       
   349 }
       
   350 
       
   351 void tst_GraphicsViewBenchmark::cleanupTestCase()
       
   352 {
       
   353     delete mMainView;
       
   354     mMainView = 0;
       
   355 }
       
   356 
       
   357 void tst_GraphicsViewBenchmark::init()
       
   358 {
       
   359     // Make sure we don't have pending events in the queue.
       
   360     // Yes, each test run takes a little bit longer, but the results are more stable.
       
   361     QTest::qWait(150);
       
   362 }
       
   363 
       
   364 void tst_GraphicsViewBenchmark::createAndFillList_data()
       
   365 {
       
   366     insertListData();
       
   367 }
       
   368 
       
   369 void tst_GraphicsViewBenchmark::createAndFillList()
       
   370 {
       
   371     QFETCH(int, listSize);
       
   372     QFETCH(ListType, listType);
       
   373 
       
   374     resetView();
       
   375 
       
   376     if (listType == Simple) {
       
   377         QBENCHMARK {
       
   378             SimpleList *list = new SimpleList;
       
   379             setTestWidget(list, listSize, listType);
       
   380             fillList(mDataGenerator, listSize, list);
       
   381         }
       
   382     } else {
       
   383         QBENCHMARK {
       
   384             ItemRecyclingList *list = new ItemRecyclingList;
       
   385             setTestWidget(list, listSize, listType);
       
   386             fillList(mDataGenerator, listSize, list);
       
   387         }
       
   388     }
       
   389 
       
   390     resetView();
       
   391 }
       
   392 
       
   393 void tst_GraphicsViewBenchmark::add100ItemsToBeginningOfList_data()
       
   394 {
       
   395     insertListData();
       
   396 }
       
   397 
       
   398 void tst_GraphicsViewBenchmark::add100ItemsToBeginningOfList()
       
   399 {
       
   400     QFETCH(int, listSize);
       
   401     QFETCH(ListType, listType);
       
   402 
       
   403     resetView();
       
   404 
       
   405     if (listType == Simple) {
       
   406         SimpleList *list = new SimpleList;
       
   407         fillList(mDataGenerator, listSize, list);
       
   408         setTestWidget(list, listSize, listType);
       
   409         QTest::qWait(50);
       
   410         QBENCHMARK {
       
   411             for (int i = 0; i < AddRemoveCount; ++i)
       
   412                 list->insertItem(0, newSimpleListItem(mDataGenerator, i));
       
   413         }
       
   414     } else {
       
   415         ItemRecyclingList *list = new ItemRecyclingList;
       
   416         fillList(mDataGenerator, listSize, list);
       
   417         setTestWidget(list, listSize, listType);
       
   418         QTest::qWait(50);
       
   419         QBENCHMARK {
       
   420             for (int i = 0; i < AddRemoveCount; ++i)
       
   421                 list->insertItem(0, newRecyclingListItem(mDataGenerator, i));
       
   422         }
       
   423     }
       
   424 
       
   425     resetView();
       
   426 }
       
   427 
       
   428 void tst_GraphicsViewBenchmark::remove100ItemsFromBeginningOfList_data()
       
   429 {
       
   430     insertListData();
       
   431 }
       
   432 
       
   433 void tst_GraphicsViewBenchmark::remove100ItemsFromBeginningOfList()
       
   434 {
       
   435     QFETCH(int, listSize);
       
   436     QFETCH(ListType, listType);
       
   437 
       
   438     resetView();
       
   439 
       
   440     if (listType == Simple) {
       
   441         SimpleList *list = new SimpleList;
       
   442         fillList(mDataGenerator, listSize, list);
       
   443         setTestWidget(list, listSize, listType);
       
   444         QTest::qWait(50);
       
   445         QBENCHMARK {
       
   446             for (int i = 0; i < AddRemoveCount; ++i)
       
   447                 delete list->takeItem(0);
       
   448         }
       
   449     } else {
       
   450         ItemRecyclingList *list = new ItemRecyclingList;
       
   451         fillList(mDataGenerator, listSize, list);
       
   452         setTestWidget(list, listSize, listType);
       
   453         QTest::qWait(50);
       
   454         QBENCHMARK {
       
   455             for (int i = 0; i < AddRemoveCount; ++i)
       
   456                 delete list->takeItem(0);
       
   457         }
       
   458     }
       
   459 
       
   460     resetView();
       
   461 }
       
   462 
       
   463 void tst_GraphicsViewBenchmark::deleteList_data()
       
   464 {
       
   465     insertListData();
       
   466     QTest::newRow("Simple list containing 1000 items") << 1000 << Simple;
       
   467     QTest::newRow("Recycling list containing 1000 items") << 1000 << Recycling;
       
   468 }
       
   469 
       
   470 void tst_GraphicsViewBenchmark::deleteList()
       
   471 {
       
   472     QFETCH(int, listSize);
       
   473     QFETCH(ListType, listType);
       
   474 
       
   475     if (listSize < 500)
       
   476         return; // Too small to measure.
       
   477 
       
   478     QGraphicsWidget *list = 0;
       
   479     if (listType == Simple)
       
   480         list = new SimpleList;
       
   481     else
       
   482         list = new ItemRecyclingList;
       
   483     fillList(mDataGenerator, listSize, list);
       
   484     QTest::qWait(20);
       
   485 
       
   486     QBENCHMARK_ONCE {
       
   487         delete list;
       
   488     }
       
   489 }
       
   490 
       
   491 void tst_GraphicsViewBenchmark::themeChange_data()
       
   492 {
       
   493     QTest::addColumn<int>("listSize");
       
   494     QTest::addColumn<ListType>("listType");
       
   495     QTest::addColumn<Theme::Themes>("fromTheme");
       
   496     QTest::addColumn<Theme::Themes>("toTheme");
       
   497 
       
   498     QTest::newRow("From Blue to Lime, simple list containing 10 items") << 10 << Simple << Theme::Blue << Theme::Lime;
       
   499     QTest::newRow("From Lime to Blue, simple list containing 10 items") << 10 << Simple << Theme::Lime << Theme::Blue;
       
   500 
       
   501     QTest::newRow("From Blue to Lime, recycling list containing 10 items") << 10 << Recycling << Theme::Blue << Theme::Lime;
       
   502     QTest::newRow("From Lime to Blue, recycling list containing 10 items") << 10 << Recycling << Theme::Lime << Theme::Blue;
       
   503 
       
   504     QTest::newRow("From Blue to Lime, simple list containing 50 items") << 50 << Simple << Theme::Blue << Theme::Lime;
       
   505     QTest::newRow("From Lime to Blue, simple list containing 50 items") << 50 << Simple << Theme::Lime << Theme::Blue;
       
   506 
       
   507     QTest::newRow("From Blue to Lime, recycling list containing 50 items") << 50 << Recycling << Theme::Blue << Theme::Lime;
       
   508     QTest::newRow("From Lime to Blue, recycling list containing 50 items") << 50 << Recycling << Theme::Lime << Theme::Blue;
       
   509 
       
   510     QTest::newRow("From Blue to Lime, simple list containing 500 items") << 500 << Simple << Theme::Blue << Theme::Lime;
       
   511     QTest::newRow("From Lime to Blue, simple list containing 500 items") << 500 << Simple << Theme::Lime << Theme::Blue;
       
   512 
       
   513     QTest::newRow("From Blue to Lime, recycling list containing 500 items") << 500 << Recycling << Theme::Blue << Theme::Lime;
       
   514     QTest::newRow("From Lime to Blue, recycling list containing 500 items") << 500 << Recycling << Theme::Lime << Theme::Blue;
       
   515 }
       
   516 
       
   517 void tst_GraphicsViewBenchmark::themeChange()
       
   518 {
       
   519     QFETCH(int, listSize);
       
   520     QFETCH(ListType, listType);
       
   521     QFETCH(Theme::Themes, fromTheme);
       
   522     QFETCH(Theme::Themes, toTheme);
       
   523 
       
   524     if (fromTheme == toTheme)
       
   525         qFatal("tst_GraphicsViewBenchmark::themeChange: to and from theme is the same");
       
   526 
       
   527     ensureListSizeAndType(listSize, listType);
       
   528     ensureTheme(fromTheme);
       
   529 
       
   530     QBENCHMARK {
       
   531         Theme::p()->setTheme(toTheme);
       
   532     }
       
   533 }
       
   534 
       
   535 static inline QLatin1String stringForTheme(Theme::Themes theme)
       
   536 {
       
   537     if (theme == Theme::Blue)
       
   538         return QLatin1String("Blue");
       
   539     return QLatin1String("Lime");
       
   540 }
       
   541 
       
   542 static inline QLatin1String stringForListType(tst_GraphicsViewBenchmark::ListType type)
       
   543 {
       
   544     if (type == tst_GraphicsViewBenchmark::Simple)
       
   545         return QLatin1String("Simple");
       
   546     if (type == tst_GraphicsViewBenchmark::Recycling)
       
   547         return QLatin1String("Recycling");
       
   548     return QLatin1String("None");
       
   549 }
       
   550 
       
   551 static inline QLatin1String stringForScrollStep(tst_GraphicsViewBenchmark::ScrollStep step)
       
   552 {
       
   553     if (step == tst_GraphicsViewBenchmark::Slow)
       
   554         return QLatin1String("Slow");
       
   555     if (step == tst_GraphicsViewBenchmark::Normal)
       
   556         return QLatin1String("Normal");
       
   557     return QLatin1String("Fast");
       
   558 }
       
   559 
       
   560 static inline QString rowString(int listSize, tst_GraphicsViewBenchmark::ListType listType,
       
   561                                 Theme::Themes theme, int toImage, int cache, int angle)
       
   562 {
       
   563     return QString("Items=%1, List=%2, Theme=%3, RenderToImage=%4, Cache=%5, RotAngle=%6")
       
   564            .arg(QString::number(listSize)).arg(stringForListType(listType))
       
   565            .arg(stringForTheme(theme)).arg(QString::number(toImage))
       
   566            .arg(QString::number(cache)).arg(QString::number(angle));
       
   567 }
       
   568 
       
   569 static inline QString rowString(int listSize, tst_GraphicsViewBenchmark::ListType listType,
       
   570                                 Theme::Themes theme, int cache, int angle,
       
   571                                 tst_GraphicsViewBenchmark::ScrollStep step)
       
   572 {
       
   573     return QString("Items=%1, List=%2, Theme=%3, Cache=%4, RotAngle=%5, Speed=%6")
       
   574            .arg(QString::number(listSize)).arg(stringForListType(listType))
       
   575            .arg(stringForTheme(theme)).arg(QString::number(cache))
       
   576            .arg(QString::number(angle)).arg(stringForScrollStep(step));
       
   577 }
       
   578 
       
   579 void tst_GraphicsViewBenchmark::update_data()
       
   580 {
       
   581     QTest::addColumn<int>("listSize");
       
   582     QTest::addColumn<ListType>("listType");
       
   583     QTest::addColumn<Theme::Themes>("theme");
       
   584     QTest::addColumn<bool>("renderToImage");
       
   585     QTest::addColumn<bool>("subtreeCache");
       
   586     QTest::addColumn<int>("rotationAngle");
       
   587 
       
   588     QList<ListType> listTypes;
       
   589     listTypes << Simple << Recycling;
       
   590 
       
   591     QList<int> listSizes;
       
   592     listSizes << 10 << 50 << 500;
       
   593 
       
   594     QList<Theme::Themes> themes;
       
   595     themes << Theme::Blue << Theme::Lime;
       
   596 
       
   597     QList<int> rotationAngles;
       
   598     rotationAngles << 0 << 90;
       
   599 
       
   600     // Generate rows:
       
   601     foreach (ListType listType, listTypes) {
       
   602         foreach (int listSize, listSizes) {
       
   603             foreach (int angle, rotationAngles) {
       
   604                 foreach (Theme::Themes theme, themes) {
       
   605                     for (int toImage = 0; toImage < 2; ++toImage) {
       
   606                         for (int cache = 0; cache < 2; ++cache) {
       
   607                             QString string = rowString(listSize, listType, theme, toImage, cache, angle);
       
   608                             QTest::newRow(string.toLatin1()) << listSize << listType << theme << bool(toImage)
       
   609                                                              << bool(cache) << angle;
       
   610                         }
       
   611                     }
       
   612                 }
       
   613             }
       
   614         }
       
   615     }
       
   616 }
       
   617 
       
   618 void tst_GraphicsViewBenchmark::update()
       
   619 {
       
   620     QFETCH(int, listSize);
       
   621     QFETCH(ListType, listType);
       
   622     QFETCH(Theme::Themes, theme);
       
   623     QFETCH(bool, renderToImage);
       
   624     QFETCH(bool, subtreeCache);
       
   625     QFETCH(int, rotationAngle);
       
   626 
       
   627     mMainView->viewport()->setUpdatesEnabled(false);
       
   628 
       
   629     ensureListSizeAndType(listSize, listType);
       
   630     ensureTheme(theme);
       
   631     ensureRotationAngle(rotationAngle);
       
   632     ensureSubtreeCache(subtreeCache);
       
   633     ensureImageBasedRendering(renderToImage);
       
   634 
       
   635     QEventLoop loop;
       
   636     QObject::connect(mMainView, SIGNAL(repainted()), &loop, SLOT(quit()));
       
   637     QTimer::singleShot(4000, &loop, SLOT(quit()));
       
   638     // Dry run (especially important when cache is enabled).
       
   639     // NB! setUpdatesEnabled triggers an update().
       
   640     mMainView->viewport()->setUpdatesEnabled(true);
       
   641     loop.exec(QEventLoop::AllEvents | QEventLoop::ExcludeUserInputEvents| QEventLoop::ExcludeSocketNotifiers);
       
   642     QTest::qWait(50);
       
   643 
       
   644     QTimer::singleShot(4000, &loop, SLOT(quit()));
       
   645     QBENCHMARK {
       
   646         mMainView->viewport()->update();
       
   647         loop.exec(QEventLoop::AllEvents | QEventLoop::ExcludeUserInputEvents| QEventLoop::ExcludeSocketNotifiers);
       
   648     }
       
   649 }
       
   650 
       
   651 void tst_GraphicsViewBenchmark::scroll_data()
       
   652 {
       
   653     QTest::addColumn<int>("listSize");
       
   654     QTest::addColumn<ListType>("listType");
       
   655     QTest::addColumn<Theme::Themes>("theme");
       
   656     QTest::addColumn<bool>("subtreeCache");
       
   657     QTest::addColumn<int>("rotationAngle");
       
   658     QTest::addColumn<ScrollStep>("scrollStep");
       
   659 
       
   660     QList<ListType> listTypes;
       
   661     listTypes << Simple << Recycling;
       
   662 
       
   663     QList<int> listSizes;
       
   664     listSizes << 10 << 50 << 500;
       
   665 
       
   666     QList<Theme::Themes> themes;
       
   667     themes << Theme::Blue << Theme::Lime;
       
   668 
       
   669     QList<int> rotationAngles;
       
   670     rotationAngles << 0 << 90;
       
   671 
       
   672     QList<ScrollStep> scrollSteps;
       
   673     scrollSteps << Slow << Normal << Fast;
       
   674 
       
   675     // Generate rows:
       
   676     foreach (ListType listType, listTypes) {
       
   677         foreach (int listSize, listSizes) {
       
   678             foreach (int angle, rotationAngles) {
       
   679                 foreach (ScrollStep step, scrollSteps) {
       
   680                     foreach (Theme::Themes theme, themes) {
       
   681                         for (int cache = 0; cache < 2; ++cache) {
       
   682                             QString string = rowString(listSize, listType, theme, cache, angle, step);
       
   683                             QTest::newRow(string.toLatin1()) << listSize << listType << theme
       
   684                                                              << bool(cache) << angle << step;
       
   685                         }
       
   686                     }
       
   687                 }
       
   688             }
       
   689         }
       
   690     }
       
   691 }
       
   692 
       
   693 void tst_GraphicsViewBenchmark::scroll()
       
   694 {
       
   695     QFETCH(int, listSize);
       
   696     QFETCH(ListType, listType);
       
   697     QFETCH(Theme::Themes, theme);
       
   698     QFETCH(bool, subtreeCache);
       
   699     QFETCH(int, rotationAngle);
       
   700     QFETCH(ScrollStep, scrollStep);
       
   701 
       
   702     mMainView->viewport()->setUpdatesEnabled(false);
       
   703 
       
   704     ensureListSizeAndType(listSize, listType);
       
   705     ensureTheme(theme);
       
   706     ensureRotationAngle(rotationAngle);
       
   707     ensureSubtreeCache(subtreeCache);
       
   708     ensureImageBasedRendering(false);
       
   709 
       
   710     ScrollBar *sb = 0;
       
   711     if (listType == Simple)
       
   712         sb = static_cast<SimpleList *>(mMainView->testWidget())->verticalScrollBar();
       
   713     else
       
   714         sb = static_cast<ItemRecyclingList *>(mMainView->testWidget())->verticalScrollBar();
       
   715     const qreal sliderStart = sb->sliderSize() / qreal(2.0);
       
   716     const qreal sliderTarget = sliderStart + qreal(scrollStep);
       
   717     sb->setSliderPosition(sliderStart);
       
   718 
       
   719     QEventLoop loop;
       
   720     QObject::connect(mMainView, SIGNAL(repainted()), &loop, SLOT(quit()));
       
   721     QTimer::singleShot(4000, &loop, SLOT(quit()));
       
   722     // Dry run (especially important when cache is enabled).
       
   723     // NB! setUpdatesEnabled triggers an update().
       
   724     mMainView->viewport()->setUpdatesEnabled(true);
       
   725     loop.exec(QEventLoop::AllEvents | QEventLoop::ExcludeUserInputEvents| QEventLoop::ExcludeSocketNotifiers);
       
   726     QTest::qWait(50);
       
   727 
       
   728     QTimer::singleShot(4000, &loop, SLOT(quit()));
       
   729     QBENCHMARK {
       
   730         sb->setSliderPosition(sliderTarget);
       
   731         loop.exec(QEventLoop::AllEvents | QEventLoop::ExcludeUserInputEvents| QEventLoop::ExcludeSocketNotifiers);
       
   732     }
       
   733 }
       
   734 
       
   735 int main(int argc, char *argv[])
       
   736 {
       
   737     Settings settings;
       
   738     if (!readSettingsFromCommandLine(argc, argv, settings))
       
   739         return 1;
       
   740 
       
   741     // Eat command line arguments.
       
   742     int aargc = 0;
       
   743     for (int i = 0; i < argc; ++i) {
       
   744         if (argv[i])
       
   745             ++aargc;
       
   746     }
       
   747     char **aargv = new char*[aargc];
       
   748     aargc = 0;
       
   749     for (int i = 0; i < argc; ++i) {
       
   750         if (argv[i])
       
   751             aargv[aargc++] = argv[i];
       
   752     }
       
   753 
       
   754     QApplication app(aargc, aargv);
       
   755 
       
   756     int returnValue = 0;
       
   757     if (settings.options() & Settings::ManualTest) {
       
   758         MainView view(settings.options() & Settings::UseOpenGL, settings.options() & Settings::OutputFps);
       
   759 
       
   760         DummyDataGenerator dataGenerator;
       
   761         dataGenerator.Reset();
       
   762 
       
   763         SimpleList *list = new SimpleList;
       
   764         if (settings.options() & Settings::UseListItemCache)
       
   765             list->setListItemCaching(true);
       
   766         else
       
   767             list->setListItemCaching(false);
       
   768 
       
   769         if (settings.listItemCount())
       
   770             fillList(dataGenerator, settings.listItemCount(), list);
       
   771         else
       
   772             fillList(dataGenerator, 500, list);
       
   773 
       
   774         view.setTestWidget(list);
       
   775 
       
   776         if ((settings.angle() % 360) != 0)
       
   777             view.rotateContent(settings.angle());
       
   778 
       
   779         if (settings.size().width() > 0 && settings.size().height() > 0) {
       
   780             view.resize(settings.size().width(), settings.size().height());
       
   781             view.show();
       
   782         } else {
       
   783 #if defined(Q_OS_SYMBIAN) || defined(Q_WS_MAEMO_5)
       
   784             view.showFullScreen();
       
   785 #else
       
   786             if (QApplication::desktop()->width() < 360 || QApplication::desktop()->height() < 640) {
       
   787                 view.showFullScreen();
       
   788             } else {
       
   789                 view.resize(360, 640);
       
   790                 view.show();
       
   791             }
       
   792 #endif
       
   793         }
       
   794         returnValue = app.exec();
       
   795     } else {
       
   796         QTEST_DISABLE_KEYPAD_NAVIGATION
       
   797         tst_GraphicsViewBenchmark tc(&settings);
       
   798         returnValue = QTest::qExec(&tc, aargc, aargv);
       
   799     }
       
   800 
       
   801     delete [] aargv;
       
   802     return returnValue;
       
   803 }
       
   804 
       
   805 #include "main.moc"