/**************************************************************************** ** ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** ** This file is part of the test suite of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions ** contained in the either Technology Preview License Agreement or the ** Beta Release License Agreement. ** ** 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 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain ** additional rights. These rights are described in the Nokia Qt LGPL ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this ** package. ** ** GNU General Public License Usage ** Alternatively, this file may be used under the terms of the GNU ** General Public License version 3.0 as published by the Free Software ** Foundation and appearing in the file LICENSE.GPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU General Public License version 3.0 requirements will be ** met: http://www.gnu.org/copyleft/gpl.html. ** ** If you are unsure which license is appropriate for your use, please ** contact the sales department at qt-sales@nokia.com. ** $QT_END_LICENSE$ ** ****************************************************************************/ #include #include #include #include class OpenGLBench : public QObject { Q_OBJECT private slots: void initTestCase(); void cleanupTestCase(); void imageDrawing_data(); void imageDrawing(); void pathDrawing_data(); void pathDrawing(); void painterOverhead(); void startupCost_data(); void startupCost(); void lineDrawing(); void textDrawing_data(); void textDrawing(); void clippedPainting_data(); void clippedPainting(); void gradients_data(); void gradients(); private: QGLPixelBuffer *pb; }; void OpenGLBench::initTestCase() { pb = new QGLPixelBuffer(512, 512); QPainter p(pb); p.setRenderHint(QPainter::Antialiasing); p.setRenderHint(QPainter::HighQualityAntialiasing); p.drawImage(0, 0, QImage(256, 256, QImage::Format_ARGB32_Premultiplied)); } void OpenGLBench::cleanupTestCase() { delete pb; } void OpenGLBench::imageDrawing_data() { QTest::addColumn("smoothPixmapTransform"); QTest::addColumn("highQualityAntialiasing"); QTest::addColumn("pixmap"); for (int i = 0; i < (1 << 3); ++i) { bool smoothPixmapTransform = i & 1; bool highQualityAntialiasing = i & 2; bool pixmap = i & 4; QTest::newRow(QString("pixmap=%1 highQualityAntialiasing=%2 smoothPixmapTransform=%3") .arg(pixmap).arg(highQualityAntialiasing).arg(smoothPixmapTransform).toAscii().data()) << pixmap << highQualityAntialiasing << smoothPixmapTransform; } } void OpenGLBench::imageDrawing() { QFETCH(bool, smoothPixmapTransform); QFETCH(bool, highQualityAntialiasing); QFETCH(bool, pixmap); QImage img; QPixmap pm; if (pixmap) pm = QPixmap(800, 800); else img = QImage(800, 800, QImage::Format_ARGB32_Premultiplied); QPainter p(pb); p.setRenderHint(QPainter::SmoothPixmapTransform, smoothPixmapTransform); p.setRenderHint(QPainter::Antialiasing, highQualityAntialiasing); p.setRenderHint(QPainter::HighQualityAntialiasing, highQualityAntialiasing); QBENCHMARK { if (pixmap) { pm.detach(); p.drawPixmap(0, 0, pm); } else { img.detach(); p.drawImage(0, 0, img); } } } Q_DECLARE_METATYPE(QPainterPath) void OpenGLBench::pathDrawing_data() { QTest::addColumn("path"); QTest::addColumn("highQualityAntialiasing"); QList > paths; { QPainterPath path; path.addRect(-100, -100, 200, 200); paths << qMakePair(path, QLatin1String("plain rect")); } { QPainterPath path; path.addRoundedRect(-100, -100, 200, 200, 50, 50); paths << qMakePair(path, QLatin1String("rounded rect")); } { QPainterPath path; path.addEllipse(-100, -100, 200, 200); paths << qMakePair(path, QLatin1String("ellipse")); } for (int j = 0; j < (1 << 1); ++j) { bool highQualityAntialiasing = j & 1; for (int i = 0; i < paths.size(); ++i) { QTest::newRow(QString("path=%1 highQualityAntialiasing=%2") .arg(paths[i].second).arg(highQualityAntialiasing).toAscii().data()) << paths[i].first << highQualityAntialiasing; } } } void OpenGLBench::pathDrawing() { QFETCH(QPainterPath, path); QFETCH(bool, highQualityAntialiasing); // warm-up { QPainterPath dummy; dummy.addRect(-1, -1, 2, 2); QPainter p(pb); p.setRenderHint(QPainter::Antialiasing, highQualityAntialiasing); p.setRenderHint(QPainter::HighQualityAntialiasing, highQualityAntialiasing); p.translate(pb->width() / 2, pb->height() / 2); p.rotate(30); p.drawPath(dummy); p.end(); } QPainter p(pb); p.setPen(Qt::NoPen); p.setBrush(Qt::black); p.translate(pb->width() / 2, pb->height() / 2); QBENCHMARK { p.setRenderHint(QPainter::Antialiasing, highQualityAntialiasing); p.setRenderHint(QPainter::HighQualityAntialiasing, highQualityAntialiasing); p.rotate(0.01); p.drawPath(path); } } void OpenGLBench::painterOverhead() { QBENCHMARK { QPainter p(pb); } } void OpenGLBench::startupCost_data() { QTest::addColumn("highQualityAntialiasing"); QTest::newRow("highQualityAntialiasing=0") << false; QTest::newRow("highQualityAntialiasing=1") << true; } void OpenGLBench::startupCost() { QFETCH(bool, highQualityAntialiasing); QPainterPath path; path.addRoundedRect(-100, -100, 200, 200, 20, 20); QBENCHMARK { QGLPixelBuffer buffer(512, 512); QPainter p(&buffer); p.setRenderHint(QPainter::Antialiasing, highQualityAntialiasing); p.setRenderHint(QPainter::HighQualityAntialiasing, highQualityAntialiasing); p.translate(buffer.width() / 2, buffer.height() / 2); p.drawPath(path); } } void OpenGLBench::lineDrawing() { QPainter p(pb); QBENCHMARK { p.drawLine(10, 10, 500, 500); } } void OpenGLBench::textDrawing_data() { QTest::addColumn("lines"); int lines[] = { 1, 2, 4, 8, 16, 32, 64, 128 }; QTest::newRow("text lines=1 (warmup run)") << 1; for (unsigned int i = 0; i < sizeof(lines) / sizeof(int); ++i) QTest::newRow(QString("text lines=%0").arg(lines[i]).toAscii().data()) << lines[i]; } void OpenGLBench::textDrawing() { QPainter p(pb); QFETCH(int, lines); p.translate(0, 16); QBENCHMARK { for (int i = 0; i < lines; ++i) p.drawText(0, i, "Hello World!"); } } void OpenGLBench::clippedPainting_data() { QTest::addColumn("path"); QRectF rect = QRectF(0, 0, pb->width(), pb->height()).adjusted(5, 5, -5, -5); { QPainterPath path; path.addRect(rect); QTest::newRow("rect path") << path; } { QPainterPath path; path.addRoundedRect(rect, 5, 5); QTest::newRow("rounded rect path") << path; } { QPainterPath path; path.addEllipse(rect); QTest::newRow("ellipse path") << path; } } void OpenGLBench::clippedPainting() { QFETCH(QPainterPath, path); QBENCHMARK { QPainter p(pb); p.setPen(Qt::NoPen); p.setBrush(Qt::black); p.setClipPath(path); p.drawRect(0, 0, pb->width(), pb->height()); } } Q_DECLARE_METATYPE(QGradient::Type) void OpenGLBench::gradients_data() { QTest::addColumn("gradientType"); QTest::addColumn("objectBoundingMode"); QTest::newRow("warmup run") << QGradient::LinearGradient << false; QTest::newRow("linear gradient") << QGradient::LinearGradient << false; QTest::newRow("radial gradient") << QGradient::RadialGradient << false; QTest::newRow("conical gradient") << QGradient::ConicalGradient << false; QTest::newRow("linear gradient, object bounding mode") << QGradient::LinearGradient << true; QTest::newRow("radial gradient, object bounding mode") << QGradient::RadialGradient << true; QTest::newRow("conical gradient, object bounding mode") << QGradient::ConicalGradient << true; } void OpenGLBench::gradients() { QFETCH(QGradient::Type, gradientType); QFETCH(bool, objectBoundingMode); QPointF a; QPointF b = objectBoundingMode ? QPointF(1, 1) : QPointF(pb->width(), pb->height()); QGradient gradient; switch (gradientType) { case QGradient::LinearGradient: gradient = QLinearGradient(a, b); break; case QGradient::RadialGradient: gradient = QRadialGradient(a, b.x() / 2, b); break; case QGradient::ConicalGradient: gradient = QConicalGradient((a + b)/2, 0); break; default: break; } if (objectBoundingMode) gradient.setCoordinateMode(QGradient::ObjectBoundingMode); gradient.setColorAt(0, Qt::red); gradient.setColorAt(0.2, Qt::blue); gradient.setColorAt(0.4, Qt::transparent); gradient.setColorAt(0.6, Qt::green); gradient.setColorAt(0.8, Qt::black); gradient.setColorAt(1, Qt::white); QPainter p(pb); QBENCHMARK { p.fillRect(0, 0, pb->width(), pb->height(), gradient); glFinish(); } } QTEST_MAIN(OpenGLBench) #include "main.moc"