From 7432c7c08a6709a12a143d48fbaa9927962edae8 Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Tue, 7 Apr 2015 11:20:08 +0200 Subject: Cleanup and optimization of qimage smoothscale Cleaning up smoothscale code. Upscaling is improved using existing optimized interpolation methods, and downscale is given SSE4.1 optimized versions. Change-Id: I7cdc256c26850948aef7dae26fda1622be6b8179 Reviewed-by: Gunnar Sletta --- tests/benchmarks/gui/image/image.pro | 1 + .../gui/image/qimagescale/qimagescale.pro | 4 + .../gui/image/qimagescale/tst_qimagescale.cpp | 140 +++++++++++++++++++++ 3 files changed, 145 insertions(+) create mode 100644 tests/benchmarks/gui/image/qimagescale/qimagescale.pro create mode 100644 tests/benchmarks/gui/image/qimagescale/tst_qimagescale.cpp (limited to 'tests/benchmarks/gui') diff --git a/tests/benchmarks/gui/image/image.pro b/tests/benchmarks/gui/image/image.pro index 71228f4499..89008290fc 100644 --- a/tests/benchmarks/gui/image/image.pro +++ b/tests/benchmarks/gui/image/image.pro @@ -3,6 +3,7 @@ SUBDIRS = \ blendbench \ qimageconversion \ qimagereader \ + qimagescale \ qpixmap \ qpixmapcache diff --git a/tests/benchmarks/gui/image/qimagescale/qimagescale.pro b/tests/benchmarks/gui/image/qimagescale/qimagescale.pro new file mode 100644 index 0000000000..a576e2c9aa --- /dev/null +++ b/tests/benchmarks/gui/image/qimagescale/qimagescale.pro @@ -0,0 +1,4 @@ +TEMPLATE = app +TARGET = tst_bench_imageScale +QT += testlib +SOURCES += tst_qimagescale.cpp diff --git a/tests/benchmarks/gui/image/qimagescale/tst_qimagescale.cpp b/tests/benchmarks/gui/image/qimagescale/tst_qimagescale.cpp new file mode 100644 index 0000000000..58abfdf4da --- /dev/null +++ b/tests/benchmarks/gui/image/qimagescale/tst_qimagescale.cpp @@ -0,0 +1,140 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include + +class tst_QImageScale : public QObject +{ + Q_OBJECT +private slots: + void scaleRgb32_data(); + void scaleRgb32(); + + void scaleArgb32pm_data(); + void scaleArgb32pm(); + +private: + QImage generateImageRgb32(int width, int height); + QImage generateImageArgb32(int width, int height); +}; + +void tst_QImageScale::scaleRgb32_data() +{ + QTest::addColumn("inputImage"); + QTest::addColumn("outputSize"); + + QImage image = generateImageRgb32(1000, 1000); + QTest::newRow("1000x1000 -> 2000x2000") << image << QSize(2000, 2000); + QTest::newRow("1000x1000 -> 2000x1000") << image << QSize(2000, 1000); + QTest::newRow("1000x1000 -> 1000x2000") << image << QSize(1000, 2000); + QTest::newRow("1000x1000 -> 2000x500") << image << QSize(2000, 500); + QTest::newRow("1000x1000 -> 500x2000") << image << QSize(500, 2000); + QTest::newRow("1000x1000 -> 500x500") << image << QSize(500, 500); + QTest::newRow("1000x1000 -> 200x200") << image << QSize(200, 200); +} + +void tst_QImageScale::scaleRgb32() +{ + QFETCH(QImage, inputImage); + QFETCH(QSize, outputSize); + + QBENCHMARK { + volatile QImage output = inputImage.scaled(outputSize, Qt::IgnoreAspectRatio, Qt::SmoothTransformation); + // we need the volatile and the following to make sure the compiler does not do + // anything stupid :) + (void)output; + } +} + +void tst_QImageScale::scaleArgb32pm_data() +{ + QTest::addColumn("inputImage"); + QTest::addColumn("outputSize"); + + QImage image = generateImageArgb32(1000, 1000).convertToFormat(QImage::Format_ARGB32_Premultiplied); + QTest::newRow("1000x1000 -> 2000x2000") << image << QSize(2000, 2000); + QTest::newRow("1000x1000 -> 2000x1000") << image << QSize(2000, 1000); + QTest::newRow("1000x1000 -> 1000x2000") << image << QSize(1000, 2000); + QTest::newRow("1000x1000 -> 2000x500") << image << QSize(2000, 500); + QTest::newRow("1000x1000 -> 500x2000") << image << QSize(500, 2000); + QTest::newRow("1000x1000 -> 500x500") << image << QSize(500, 500); + QTest::newRow("1000x1000 -> 200x200") << image << QSize(200, 200); +} + +void tst_QImageScale::scaleArgb32pm() +{ + QFETCH(QImage, inputImage); + QFETCH(QSize, outputSize); + + QBENCHMARK { + volatile QImage output = inputImage.scaled(outputSize, Qt::IgnoreAspectRatio, Qt::SmoothTransformation); + // we need the volatile and the following to make sure the compiler does not do + // anything stupid :) + (void)output; + } +} + +/* + Fill a RGB32 image with "random" pixel values. + */ +QImage tst_QImageScale::generateImageRgb32(int width, int height) +{ + QImage image(width, height, QImage::Format_RGB32); + + for (int y = 0; y < image.height(); ++y) { + QRgb *scanline = (QRgb*)image.scanLine(y); + for (int x = 0; x < width; ++x) + scanline[x] = qRgb(x, y, x ^ y); + } + return image; +} + +/* + Fill a ARGB32 image with "random" pixel values. + */ +QImage tst_QImageScale::generateImageArgb32(int width, int height) +{ + QImage image(width, height, QImage::Format_ARGB32); + const int byteWidth = width * 4; + + for (int y = 0; y < image.height(); ++y) { + uchar *scanline = image.scanLine(y); + for (int x = 0; x < byteWidth; ++x) + scanline[x] = x ^ y; + } + return image; +} + +QTEST_MAIN(tst_QImageScale) +#include "tst_qimagescale.moc" -- cgit v1.2.3