summaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
authorMartin Jones <martin.jones@nokia.com>2010-08-19 00:29:51 (GMT)
committerMartin Jones <martin.jones@nokia.com>2010-08-19 00:29:51 (GMT)
commite5893ababec6c58207c8066908e21bff3d746356 (patch)
treeb4800e3a1fd5fa209b39e2f2d627081ed72bed38 /tests
parent2abbc5fc400dfa8ad26397cc39f49f9b3a4304c9 (diff)
parentceb068261e326f38b4049becd75c7160a6b84f87 (diff)
downloadQt-e5893ababec6c58207c8066908e21bff3d746356.zip
Qt-e5893ababec6c58207c8066908e21bff3d746356.tar.gz
Qt-e5893ababec6c58207c8066908e21bff3d746356.tar.bz2
Merge branch '4.7' of scm.dev.nokia.troll.no:qt/qt-qml into 4.7
Diffstat (limited to 'tests')
-rw-r--r--tests/auto/declarative/qdeclarativetextinput/tst_qdeclarativetextinput.cpp16
-rw-r--r--tests/auto/macnativeevents/tst_macnativeevents.cpp81
-rw-r--r--tests/auto/qdatastream/tst_qdatastream.cpp2
-rw-r--r--tests/auto/qmake/testdata/substitutes/sub/test2.in1
-rw-r--r--tests/auto/qmake/testdata/substitutes/test.in2
-rw-r--r--tests/auto/qmake/testdata/substitutes/test.pro2
-rw-r--r--tests/auto/qmake/testdata/substitutes_build/README1
-rw-r--r--tests/auto/qmake/tst_qmake.cpp16
-rw-r--r--tests/auto/qtreeview/tst_qtreeview.cpp125
-rw-r--r--tests/auto/qwidget/tst_qwidget.cpp75
-rw-r--r--tests/benchmarks/README81
-rw-r--r--tests/benchmarks/gui/image/blendbench/main.cpp43
12 files changed, 443 insertions, 2 deletions
diff --git a/tests/auto/declarative/qdeclarativetextinput/tst_qdeclarativetextinput.cpp b/tests/auto/declarative/qdeclarativetextinput/tst_qdeclarativetextinput.cpp
index a5c2dda..7450d35 100644
--- a/tests/auto/declarative/qdeclarativetextinput/tst_qdeclarativetextinput.cpp
+++ b/tests/auto/declarative/qdeclarativetextinput/tst_qdeclarativetextinput.cpp
@@ -98,6 +98,7 @@ private slots:
void validators();
void inputMethods();
+ void passwordCharacter();
void cursorDelegate();
void navigation();
void copyAndPaste();
@@ -768,6 +769,21 @@ void tst_qdeclarativetextinput::copyAndPaste() {
#endif
}
+void tst_qdeclarativetextinput::passwordCharacter()
+{
+ QString componentStr = "import Qt 4.7\nTextInput { text: \"Hello world!\"; font.family: \"Helvetica\"; echoMode: TextInput.Password }";
+ QDeclarativeComponent textInputComponent(&engine);
+ textInputComponent.setData(componentStr.toLatin1(), QUrl());
+ QDeclarativeTextInput *textInput = qobject_cast<QDeclarativeTextInput*>(textInputComponent.create());
+ QVERIFY(textInput != 0);
+
+ textInput->setPasswordCharacter("X");
+ QSize contentsSize = textInput->contentsSize();
+ textInput->setPasswordCharacter(".");
+ // QTBUG-12383 content is updated and redrawn
+ QVERIFY(contentsSize != textInput->contentsSize());
+}
+
void tst_qdeclarativetextinput::cursorDelegate()
{
QDeclarativeView* view = createView(SRCDIR "/data/cursorTest.qml");
diff --git a/tests/auto/macnativeevents/tst_macnativeevents.cpp b/tests/auto/macnativeevents/tst_macnativeevents.cpp
index ffd0596..d582417 100644
--- a/tests/auto/macnativeevents/tst_macnativeevents.cpp
+++ b/tests/auto/macnativeevents/tst_macnativeevents.cpp
@@ -67,6 +67,11 @@ private slots:
void testDragWindow();
void testMouseEnter();
void testChildDialogInFrontOfModalParent();
+#ifdef QT_MAC_USE_COCOA
+ void testChildWindowInFrontOfParentWindow();
+// void testChildToolWindowInFrontOfChildNormalWindow();
+ void testChildWindowInFrontOfStaysOnTopParentWindow();
+#endif
void testKeyPressOnToplevel();
};
@@ -308,6 +313,82 @@ void tst_MacNativeEvents::testChildDialogInFrontOfModalParent()
QVERIFY(!child.isVisible());
}
+#ifdef QT_MAC_USE_COCOA
+void tst_MacNativeEvents::testChildWindowInFrontOfParentWindow()
+{
+ // Test that a child window always stacks in front of its parent window.
+ // Do this by first click on the parent, then on the child window button.
+ QWidget parent;
+ QPushButton child("a button", &parent);
+ child.setWindowFlags(Qt::Window);
+ connect(&child, SIGNAL(clicked()), &child, SLOT(close()));
+ parent.show();
+ child.show();
+
+ QPoint parent_p = parent.geometry().bottomLeft() + QPoint(20, -20);
+ QPoint child_p = child.geometry().center();
+
+ NativeEventList native;
+ native.append(new QNativeMouseButtonEvent(parent_p, Qt::LeftButton, 1, Qt::NoModifier));
+ native.append(new QNativeMouseButtonEvent(parent_p, Qt::LeftButton, 0, Qt::NoModifier));
+ native.append(new QNativeMouseButtonEvent(child_p, Qt::LeftButton, 1, Qt::NoModifier));
+ native.append(new QNativeMouseButtonEvent(child_p, Qt::LeftButton, 0, Qt::NoModifier));
+
+ native.play();
+ QTest::qWait(100);
+ QVERIFY(!child.isVisible());
+}
+
+/* This test can be enabled once setStackingOrder has been fixed in qwidget_mac.mm
+void tst_MacNativeEvents::testChildToolWindowInFrontOfChildNormalWindow()
+{
+ // Test that a child tool window always stacks in front of normal sibling windows.
+ // Do this by first click on the sibling, then on the tool window button.
+ QWidget parent;
+ QWidget normalChild(&parent, Qt::Window);
+ QPushButton toolChild("a button", &parent);
+ toolChild.setWindowFlags(Qt::Tool);
+ connect(&toolChild, SIGNAL(clicked()), &toolChild, SLOT(close()));
+ parent.show();
+ normalChild.show();
+ toolChild.show();
+
+ QPoint normalChild_p = normalChild.geometry().bottomLeft() + QPoint(20, -20);
+ QPoint toolChild_p = toolChild.geometry().center();
+
+ NativeEventList native;
+ native.append(new QNativeMouseButtonEvent(normalChild_p, Qt::LeftButton, 1, Qt::NoModifier));
+ native.append(new QNativeMouseButtonEvent(normalChild_p, Qt::LeftButton, 0, Qt::NoModifier));
+ native.append(new QNativeMouseButtonEvent(toolChild_p, Qt::LeftButton, 1, Qt::NoModifier));
+ native.append(new QNativeMouseButtonEvent(toolChild_p, Qt::LeftButton, 0, Qt::NoModifier));
+
+ native.play();
+ QTest::qWait(100);
+ QVERIFY(!toolChild.isVisible());
+}
+*/
+void tst_MacNativeEvents::testChildWindowInFrontOfStaysOnTopParentWindow()
+{
+ // Test that a child window stacks on top of a stays-on-top parent.
+ QWidget parent(0, Qt::WindowStaysOnTopHint);
+ QPushButton button("close", &parent);
+ button.setWindowFlags(Qt::Window);
+ connect(&button, SIGNAL(clicked()), &button, SLOT(close()));
+ parent.show();
+ button.show();
+ QPoint inside = button.geometry().center();
+
+ // Post a click on the button to close the child dialog:
+ NativeEventList native;
+ native.append(new QNativeMouseButtonEvent(inside, Qt::LeftButton, 1, Qt::NoModifier));
+ native.append(new QNativeMouseButtonEvent(inside, Qt::LeftButton, 0, Qt::NoModifier));
+
+ native.play();
+ QTest::qWait(100);
+ QVERIFY(!button.isVisible());
+}
+#endif
+
void tst_MacNativeEvents::testKeyPressOnToplevel()
{
// Check that we receive keyevents for
diff --git a/tests/auto/qdatastream/tst_qdatastream.cpp b/tests/auto/qdatastream/tst_qdatastream.cpp
index 31e12fe..c03bc71 100644
--- a/tests/auto/qdatastream/tst_qdatastream.cpp
+++ b/tests/auto/qdatastream/tst_qdatastream.cpp
@@ -1820,7 +1820,7 @@ void tst_QDataStream::stream_QPixmap()
#ifdef Q_OS_WINCE
QSKIP("Test depends on more memory than available on Qt/CE", SkipAll);
#endif
- STREAM_IMPL(QIcon);
+ STREAM_IMPL(QPixmap);
}
void tst_QDataStream::stream_QIcon_data()
diff --git a/tests/auto/qmake/testdata/substitutes/sub/test2.in b/tests/auto/qmake/testdata/substitutes/sub/test2.in
new file mode 100644
index 0000000..78a6069
--- /dev/null
+++ b/tests/auto/qmake/testdata/substitutes/sub/test2.in
@@ -0,0 +1 @@
+heya
diff --git a/tests/auto/qmake/testdata/substitutes/test.in b/tests/auto/qmake/testdata/substitutes/test.in
new file mode 100644
index 0000000..2fa05e0
--- /dev/null
+++ b/tests/auto/qmake/testdata/substitutes/test.in
@@ -0,0 +1,2 @@
+test
+tst
diff --git a/tests/auto/qmake/testdata/substitutes/test.pro b/tests/auto/qmake/testdata/substitutes/test.pro
new file mode 100644
index 0000000..5bce312
--- /dev/null
+++ b/tests/auto/qmake/testdata/substitutes/test.pro
@@ -0,0 +1,2 @@
+QMAKE_SUBSTITUTES += test.in
+# doesn't work for the time being: sub/test2.in
diff --git a/tests/auto/qmake/testdata/substitutes_build/README b/tests/auto/qmake/testdata/substitutes_build/README
new file mode 100644
index 0000000..81dc596
--- /dev/null
+++ b/tests/auto/qmake/testdata/substitutes_build/README
@@ -0,0 +1 @@
+Placeholder file to ensure this directory exists
diff --git a/tests/auto/qmake/tst_qmake.cpp b/tests/auto/qmake/tst_qmake.cpp
index 5efe714..1a3f843 100644
--- a/tests/auto/qmake/tst_qmake.cpp
+++ b/tests/auto/qmake/tst_qmake.cpp
@@ -90,6 +90,7 @@ private slots:
void bundle_spaces();
#endif
void includefunction();
+ void substitutes();
private:
TestCompiler test_compiler;
@@ -477,6 +478,21 @@ void tst_qmake::includefunction()
QVERIFY(test_compiler.commandOutput().contains(warningMsg));
}
+void tst_qmake::substitutes()
+{
+ QString workDir = base_path + "/testdata/substitutes";
+ QVERIFY( test_compiler.qmake( workDir, "test" ));
+ QVERIFY( test_compiler.exists( workDir, "test", Plain, "" ));
+ //QVERIFY( test_compiler.exists( workDir, "sub/test2", Plain, "" ));
+ QVERIFY( test_compiler.makeDistClean( workDir ));
+
+ QString buildDir = base_path + "/testdata/substitutes_build";
+ QVERIFY( test_compiler.qmake( workDir, "test", buildDir ));
+ QVERIFY( test_compiler.exists( buildDir, "test", Plain, "" ));
+ //QVERIFY( test_compiler.exists( buildDir, "sub/test2", Plain, "" ));
+ QVERIFY( test_compiler.makeDistClean( buildDir ));
+}
+
QTEST_MAIN(tst_qmake)
#include "tst_qmake.moc"
diff --git a/tests/auto/qtreeview/tst_qtreeview.cpp b/tests/auto/qtreeview/tst_qtreeview.cpp
index 75a4c62..7e2e800 100644
--- a/tests/auto/qtreeview/tst_qtreeview.cpp
+++ b/tests/auto/qtreeview/tst_qtreeview.cpp
@@ -239,6 +239,7 @@ private slots:
void doubleClickedWithSpans();
void taskQTBUG_6450_selectAllWith1stColumnHidden();
void taskQTBUG_9216_setSizeAndUniformRowHeightsWrongRepaint();
+ void taskQTBUG_11466_keyboardNavigationRegression();
};
class QtTestModel: public QAbstractItemModel
@@ -3785,5 +3786,129 @@ void tst_QTreeView::keyboardNavigationWithDisabled()
QCOMPARE(view.currentIndex(), model.index(6, 0));
}
+class Model_11466 : public QAbstractItemModel
+{
+ Q_OBJECT
+public:
+ Model_11466(QObject *parent) :
+ m_block(false)
+ {
+ // set up the model to have two top level items and a few others
+ m_selectionModel = new QItemSelectionModel(this, this); // owned by this
+
+ connect(m_selectionModel, SIGNAL(currentChanged(const QModelIndex &,const QModelIndex &)),
+ this, SLOT(slotCurrentChanged(const QModelIndex &,const QModelIndex &)));
+ };
+
+ int rowCount(const QModelIndex &parent) const
+ {
+ if (parent.isValid())
+ return (parent.internalId() == 0) ? 4 : 0;
+ return 2; // two top level items
+ }
+
+ int columnCount(const QModelIndex &parent) const
+ {
+ return 2;
+ }
+
+ QVariant data(const QModelIndex &index, int role) const
+ {
+ if (role == Qt::DisplayRole && index.isValid()) {
+ qint64 parentRowPlusOne = index.internalId();
+ QString str;
+ QTextStream stream(&str);
+ if (parentRowPlusOne > 0)
+ stream << parentRowPlusOne << " -> " << index.row() << " : " << index.column();
+ else
+ stream << index.row() << " : " << index.column();
+ return QVariant(str);
+ }
+ return QVariant();
+ }
+
+ QModelIndex parent(const QModelIndex &index) const
+ {
+ if (index.isValid()) {
+ qint64 parentRowPlusOne = index.internalId();
+ if (parentRowPlusOne > 0) {
+ int row = static_cast<int>(parentRowPlusOne - 1);
+ return createIndex(row, 0, (quint32)0);
+ }
+ }
+ return QModelIndex();
+ }
+
+ void bindView(QTreeView *view)
+ {
+ // sets the view to this model with a shared selection model
+ QItemSelectionModel *oldModel = view->selectionModel();
+ if (oldModel != m_selectionModel)
+ delete oldModel;
+ view->setModel(this); // this creates a new selection model for the view, but we dont want it either ...
+ oldModel = view->selectionModel();
+ view->setSelectionModel(m_selectionModel);
+ delete oldModel;
+ }
+
+ QModelIndex index(int row, int column, const QModelIndex &parent) const
+ {
+ return createIndex(row, column, parent.isValid() ? (quint32)(parent.row() + 1) : (quint32)0);
+ }
+
+public slots:
+ void slotCurrentChanged(const QModelIndex &current,const QModelIndex &)
+ {
+ if (m_block)
+ return;
+
+ if (current.isValid()) {
+ int selectedRow = current.row();
+ quint32 parentRowPlusOne = static_cast<quint32>(current.internalId());
+
+ for (int i = 0; i < 2; ++i) {
+ // announce the removal of all non top level items
+ beginRemoveRows(createIndex(i, 0, 0), 0, 3);
+ // nothing to actually do for the removal
+ endRemoveRows();
+
+ // put them back in again
+ beginInsertRows(createIndex(i, 0, 0), 0, 3);
+ // nothing to actually do for the insertion
+ endInsertRows();
+ }
+ // reselect the current item ...
+ QModelIndex selectedIndex = createIndex(selectedRow, 0, parentRowPlusOne);
+
+ m_block = true; // recursion block
+ m_selectionModel->select(selectedIndex, QItemSelectionModel::ClearAndSelect|QItemSelectionModel::Current|QItemSelectionModel::Rows);
+ m_selectionModel->setCurrentIndex(selectedIndex, QItemSelectionModel::NoUpdate);
+ m_block = false;
+ } else {
+ m_selectionModel->clear();
+ }
+ }
+
+private:
+ bool m_block;
+ QItemSelectionModel *m_selectionModel;
+};
+
+void tst_QTreeView::taskQTBUG_11466_keyboardNavigationRegression()
+{
+ QTreeView treeView;
+ treeView.setSelectionBehavior(QAbstractItemView::SelectRows);
+ treeView.setSelectionMode(QAbstractItemView::SingleSelection);
+ Model_11466 model(&treeView);
+ model.bindView(&treeView);
+ treeView.expandAll();
+ treeView.show();
+ QTest::qWaitForWindowShown(&treeView);
+
+ QTest::keyPress(treeView.viewport(), Qt::Key_Down);
+ QTest::qWait(10);
+ QTRY_COMPARE(treeView.currentIndex(), treeView.selectionModel()->selection().indexes().first());
+}
+
QTEST_MAIN(tst_QTreeView)
#include "tst_qtreeview.moc"
diff --git a/tests/auto/qwidget/tst_qwidget.cpp b/tests/auto/qwidget/tst_qwidget.cpp
index f722f89..ef05b91 100644
--- a/tests/auto/qwidget/tst_qwidget.cpp
+++ b/tests/auto/qwidget/tst_qwidget.cpp
@@ -9742,7 +9742,6 @@ void tst_QWidget::destroyBackingStoreWhenHidden()
QVERIFY(0 != backingStore(child));
// Parent is obscured, therefore its backing store should be destroyed
- QEXPECT_FAIL("", "QTBUG-12406", Continue);
QVERIFY(0 == backingStore(parent));
// Disable full screen
@@ -9758,6 +9757,80 @@ void tst_QWidget::destroyBackingStoreWhenHidden()
QVERIFY(0 != backingStore(parent));
QVERIFY(0 == backingStore(child));
}
+
+ // 6. Partial reveal followed by full reveal
+ {
+ QWidget upper;
+ upper.setAutoFillBackground(true);
+ upper.setPalette(Qt::red);
+ upper.setGeometry(50, 50, 100, 100);
+
+ QWidget lower;
+ lower.setAutoFillBackground(true);
+ lower.setPalette(Qt::green);
+ lower.setGeometry(50, 50, 100, 100);
+
+ lower.show();
+ QTest::qWaitForWindowShown(&lower);
+ upper.show();
+ QTest::qWaitForWindowShown(&upper);
+ upper.raise();
+
+ QVERIFY(0 != backingStore(upper));
+ QVERIFY(0 == backingStore(lower));
+
+ // Check that upper obscures lower
+ QVERIFY(lower.visibleRegion().subtracted(upper.visibleRegion()).isEmpty());
+
+ // Partially reveal lower
+ upper.move(100, 100);
+
+ // Completely reveal lower
+ upper.hide();
+
+ // Hide lower widget - this should cause its backing store to be deleted
+ lower.hide();
+
+ // Check that backing store was deleted
+ WAIT_AND_VERIFY(0 == backingStore(lower));
+ }
+
+ // 7. Reparenting of visible native child widget
+ {
+ QWidget parent1;
+ parent1.setAutoFillBackground(true);
+ parent1.setPalette(Qt::green);
+ parent1.setGeometry(50, 50, 100, 100);
+
+ QWidget *child = new QWidget(&parent1);
+ child->winId();
+ child->setAutoFillBackground(true);
+ child->setPalette(Qt::red);
+ child->setGeometry(10, 10, 30, 30);
+
+ QWidget parent2;
+ parent2.setAutoFillBackground(true);
+ parent2.setPalette(Qt::blue);
+ parent2.setGeometry(150, 150, 100, 100);
+
+ parent1.show();
+ QTest::qWaitForWindowShown(&parent1);
+ QVERIFY(0 != backingStore(parent1));
+
+ parent2.show();
+ QTest::qWaitForWindowShown(&parent2);
+ QVERIFY(0 != backingStore(parent2));
+
+ child->setParent(&parent2);
+ child->setGeometry(10, 10, 30, 30);
+ child->show();
+
+ parent1.hide();
+ WAIT_AND_VERIFY(0 == backingStore(parent1));
+
+ parent2.hide();
+ WAIT_AND_VERIFY(0 == backingStore(parent2));
+ }
}
#undef WAIT_AND_VERIFY
diff --git a/tests/benchmarks/README b/tests/benchmarks/README
new file mode 100644
index 0000000..d437299
--- /dev/null
+++ b/tests/benchmarks/README
@@ -0,0 +1,81 @@
+The most reliable way of running benchmarks is to do it in an otherwise idle
+system. On a busy system, the results will vary according to the other tasks
+demanding attention in the system.
+
+We have managed to obtain quite reliable results by doing the following on
+Linux (and you need root):
+
+ - switching the scheduler to a Real-Time mode
+ - setting the processor affinity to one single processor
+ - disabling the other thread of the same core
+
+This should work rather well for CPU-intensive tasks. A task that is in Real-
+Time mode will simply not be preempted by the OS. But if you make OS syscalls,
+especially I/O ones, your task will be de-scheduled. Note that this includes
+page faults, so if you can, make sure your benchmark's warmup code paths touch
+most of the data.
+
+To do this you need a tool called schedtool (package schedtool), from
+http://freequaos.host.sk/schedtool/
+
+From this point on, we are using CPU0 for all tasks:
+
+If you have a Hyperthreaded multi-core processor (Core-i5 and Core-i7), you
+have to disable the other thread of the same core as CPU0. To discover which
+one it is:
+
+$ cat /sys/devices/system/cpu/cpu0/topology/thread_siblings_list
+
+This will print something like 0,4, meaning that CPUs 0 and 4 are sibling
+threads on the same core. So we'll turn CPU 4 off:
+
+(as root)
+# echo 0 > /sys/devices/system/cpu/cpu4/online
+
+To turn it back on, echo 1 into the same file.
+
+To run a task on CPU 0 exclusively, using FIFO RT priority 10, you run the
+following:
+
+(as root)
+# schedtool -F -p 10 -a 1 -e ./taskname
+
+For example:
+# schedtool -F -p 10 -a 1 -e ./tst_bench_qstring -tickcounter
+
+Warning: if your task livelocks or takes far too long to complete, your system
+may be unusable for a long time, especially if you don't have other cores to
+run stuff on. To prevent that, run it before schedtool and time it.
+
+You can also limit the CPU time that the task is allowed to take. Run in the
+same shell as you'll run schedtool:
+
+$ ulimit -s 300
+To limit to 300 seconds (5 minutes)
+
+If your task runs away, it will get a SIGXCPU after consuming 5 minutes of CPU
+time (5 minutes running at 100%).
+
+If your app is multithreaded, you may want to give it more CPUs, like CPU0 and
+CPU1 with -a 3 (it's a bitmask).
+
+For best results, you should disable ALL other cores and threads of the same
+processor. The new Core-i7 have one processor with 4 cores,
+each core can run 2 threads; the older Mac Pros have two processors with 4
+cores each. So on those Mac Pros, you'd disable cores 1, 2 and 3, while on the
+Core-i7, you'll need to disable all other CPUs.
+
+However, disabling just the sibling thread seems to produce very reliable
+results for me already, with variance often below 0.5% (even though there are
+some measurable spikes).
+
+Other things to try:
+
+Running the benchmark with highest priority, i.e. "sudo nice -19"
+usually produces stable results on some machines. If the benchmark also
+involves displaying something on the screen (on X11), running it with
+"-sync" is a must. Though, in that case the "real" cost is not correct,
+but it is useful to discover regressions.
+
+Also; not many people know about ionice (1)
+ ionice - get/set program io scheduling class and priority
diff --git a/tests/benchmarks/gui/image/blendbench/main.cpp b/tests/benchmarks/gui/image/blendbench/main.cpp
index f53654b..d420d6c 100644
--- a/tests/benchmarks/gui/image/blendbench/main.cpp
+++ b/tests/benchmarks/gui/image/blendbench/main.cpp
@@ -106,6 +106,9 @@ private slots:
void blendBenchAlpha_data();
void blendBenchAlpha();
+
+ void unalignedBlendArgb32_data();
+ void unalignedBlendArgb32();
};
void BlendBench::blendBench_data()
@@ -179,6 +182,46 @@ void BlendBench::blendBenchAlpha()
}
}
+void BlendBench::unalignedBlendArgb32_data()
+{
+ // The performance of blending can depend of the alignment of the data
+ // on 16 bytes. Some SIMD instruction set have significantly better
+ // memory access when the memory is aligned on 16 bytes boundary.
+
+ // offset in 32 bits words
+ QTest::addColumn<int>("offset");
+ QTest::newRow("aligned on 16 bytes") << 0;
+ QTest::newRow("unaligned by 4 bytes") << 1;
+ QTest::newRow("unaligned by 8 bytes") << 2;
+ QTest::newRow("unaligned by 12 bytes") << 3;
+}
+
+void BlendBench::unalignedBlendArgb32()
+{
+ const int dimension = 1024;
+
+ // We use dst aligned by design. We don't want to test all the combination of alignemnt for src and dst.
+ // Moreover, it make sense for us to align dst in the implementation because it is accessed more often.
+ uchar *dstMemory = static_cast<uchar*>(qMallocAligned((dimension * dimension * sizeof(quint32)), 16));
+ QImage destination(dstMemory, dimension, dimension, QImage::Format_ARGB32_Premultiplied);
+ destination.fill(0x12345678); // avoid special cases of alpha
+
+ uchar *srcMemory = static_cast<uchar*>(qMallocAligned((dimension * dimension * sizeof(quint32)) + 16, 16));
+ QFETCH(int, offset);
+ srcMemory += (offset * sizeof(quint32));
+
+ QImage src(srcMemory, dimension, dimension, QImage::Format_ARGB32_Premultiplied);
+ src.fill(0x87654321);
+
+ QPainter painter(&destination);
+ QBENCHMARK {
+ painter.drawImage(QPoint(), src);
+ }
+
+ qFreeAligned(srcMemory);
+ qFreeAligned(dstMemory);
+}
+
QTEST_MAIN(BlendBench)
#include "main.moc"