diff options
author | Gunnar Sletta <gunnar.sletta@digia.com> | 2013-09-23 09:53:58 +0200 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2013-09-25 16:16:15 +0200 |
commit | f2233c725078d49f6b185e642325dacb47b33240 (patch) | |
tree | 7e612d02f2d4c84882bc5294640ecb99333f139d /tests/auto/quick/qquickframebufferobject | |
parent | 0e62896fdcbad014177ba11d88bbe46eb496ab2d (diff) |
Convenience class for FBO rendering in Qt Quick
Change-Id: I5712bbfa0cde9f2fe5fddc35c4cc23597717065c
Reviewed-by: Lars Knoll <lars.knoll@digia.com>
Diffstat (limited to 'tests/auto/quick/qquickframebufferobject')
3 files changed, 326 insertions, 0 deletions
diff --git a/tests/auto/quick/qquickframebufferobject/data/testStuff.qml b/tests/auto/quick/qquickframebufferobject/data/testStuff.qml new file mode 100644 index 0000000000..b4ac4e81eb --- /dev/null +++ b/tests/auto/quick/qquickframebufferobject/data/testStuff.qml @@ -0,0 +1,56 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the tests of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** 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 Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/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 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, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, 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. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.0 +import FBOItem 1.0 + +Item { + width: 400 + height: 400 + + FBOItem { + objectName: "fbo" + color: "red" + width: 100 + height: 100 + } + +} diff --git a/tests/auto/quick/qquickframebufferobject/qquickframebufferobject.pro b/tests/auto/quick/qquickframebufferobject/qquickframebufferobject.pro new file mode 100644 index 0000000000..612b6f7283 --- /dev/null +++ b/tests/auto/quick/qquickframebufferobject/qquickframebufferobject.pro @@ -0,0 +1,15 @@ +CONFIG += testcase +TARGET = tst_qquickframebufferobject +SOURCES += tst_qquickframebufferobject.cpp + +TESTDATA = data/* +include(../../shared/util.pri) + +macx:CONFIG -= app_bundle + +CONFIG += parallel_test +QT += quick testlib + +OTHER_FILES += \ + data/testStuff.qml + diff --git a/tests/auto/quick/qquickframebufferobject/tst_qquickframebufferobject.cpp b/tests/auto/quick/qquickframebufferobject/tst_qquickframebufferobject.cpp new file mode 100644 index 0000000000..b7b58c6d3d --- /dev/null +++ b/tests/auto/quick/qquickframebufferobject/tst_qquickframebufferobject.cpp @@ -0,0 +1,255 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** 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 Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/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 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, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, 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. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <qtest.h> + +#include <QtQuick/qquickitem.h> +#include <QtQuick/qquickview.h> +#include <QtGui/qopenglcontext.h> +#include <QtGui/qopenglframebufferobject.h> + +#include <QtQuick/QQuickFramebufferObject> + +#include "../../shared/util.h" + +#ifndef GL_MAX_SAMPLES +#define GL_MAX_SAMPLES 0x8D57 +#endif + +struct FrameInfo { + int renderCount; + int createFBOCount; + bool msaaSupported; + bool msaaEnabled; + QSize fboSize; +} frameInfo; + +class ColorRenderer : public QQuickFramebufferObject::Renderer +{ +public: + void render(); + void synchronize(QQuickFramebufferObject *item); + QOpenGLFramebufferObject *createFramebufferObject(const QSize &size); + + QSize textureSize; + QColor color; + bool msaa; +}; + +class FBOItem : public QQuickFramebufferObject +{ + Q_OBJECT + + Q_PROPERTY(bool msaa READ msaa WRITE setMsaa NOTIFY msaaChanged) + Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged) + + Q_PROPERTY(QSize textureSize READ textureSize WRITE setTextureSize NOTIFY textureSizeChanged) + +public: + Renderer *createRenderer() const { return new ColorRenderer(); } + + void setColor(const QColor &color) { m_color = color; colorChanged(m_color); } + QColor color() const { return m_color; } + + void setMsaa(bool msaa) { m_msaa = msaa; msaaChanged(m_msaa); } + bool msaa() const { return m_msaa; } + + void setTextureSize(const QSize &size) { m_textureSize = size; textureSizeChanged(m_textureSize); } + QSize textureSize() const { return m_textureSize; } + +signals: + void colorChanged(const QColor &color); + void msaaChanged(bool msaa); + void textureSizeChanged(const QSize &size); + +public: + bool m_msaa; + QColor m_color; + QSize m_textureSize; + +}; + +void ColorRenderer::render() +{ + glClearColor(color.redF(), color.greenF(), color.blueF(), color.alphaF()); + glClear(GL_COLOR_BUFFER_BIT); + + int maxSamples = 0; + glGetIntegerv(GL_MAX_SAMPLES, &maxSamples); + + QByteArray extensions((const char *) glGetString(GL_EXTENSIONS)); + frameInfo.msaaSupported = maxSamples > 0 + && extensions.contains("GL_EXT_framebuffer_multisample") + && extensions.contains("GL_EXT_framebuffer_blit"); + + int samples; + glGetIntegerv(GL_SAMPLES, &samples); + frameInfo.msaaEnabled = samples > 0; + + frameInfo.fboSize = framebufferObject()->size(); + + frameInfo.renderCount++; +} + +void ColorRenderer::synchronize(QQuickFramebufferObject *item) +{ + FBOItem *fboItem = qobject_cast<FBOItem *>(item); + color = fboItem->color(); + msaa = fboItem->msaa(); + if (textureSize != fboItem->textureSize()) { + textureSize = fboItem->textureSize(); + invalidateFramebufferObject(); + } +} + +QOpenGLFramebufferObject *ColorRenderer::createFramebufferObject(const QSize &size) +{ + frameInfo.createFBOCount++; + QOpenGLFramebufferObjectFormat format; + if (msaa) + format.setSamples(4); + QSize s = textureSize.isValid() ? textureSize : size; + return new QOpenGLFramebufferObject(s, format); +} + +class tst_QQuickFramebufferObject: public QQmlDataTest +{ + Q_OBJECT +public: +private slots: + void testThatStuffWorks_data(); + void testThatStuffWorks(); + + void testInvalidate(); +}; + +void tst_QQuickFramebufferObject::testThatStuffWorks_data() +{ + QTest::addColumn<uint>("color"); + QTest::addColumn<bool>("msaa"); + QTest::addColumn<QSize>("textureSize"); + + QTest::newRow("red, !aa, item-size") << 0xffff0000 << false << QSize(); + QTest::newRow("green, !aa, 80x80") << 0xff00ff00 << false << QSize(80, 80); + QTest::newRow("blue, aa, item-size") << 0xff0000ff << true << QSize(); + QTest::newRow("pink, aa, 80x80") << 0xffff00ff << true << QSize(80, 80); +} + +void tst_QQuickFramebufferObject::testThatStuffWorks() +{ + QFETCH(uint, color); + QFETCH(bool, msaa); + QFETCH(QSize, textureSize); + + frameInfo.renderCount = 0; + frameInfo.msaaEnabled = false; + frameInfo.msaaSupported = false; + frameInfo.fboSize = QSize(); + + qmlRegisterType<FBOItem>("FBOItem", 1, 0, "FBOItem"); + + QQuickView view; + view.setSource(QUrl::fromLocalFile("data/testStuff.qml")); + + FBOItem *item = view.rootObject()->findChild<FBOItem *>("fbo"); + + item->setColor(color); + if (textureSize.isValid()) { + item->setTextureFollowsItemSize(false); + item->setTextureSize(textureSize); + } + item->setMsaa(msaa); + + view.show(); + QTest::qWaitForWindowExposed(&view); + + QImage result = view.grabWindow(); + + QCOMPARE(frameInfo.renderCount, 1); + QCOMPARE(result.pixel(0, 0), color); + if (textureSize.isValid()) + QCOMPARE(frameInfo.fboSize, textureSize); + else + QCOMPARE(frameInfo.fboSize, QSize(item->width(), item->height()) * view.devicePixelRatio()); + if (frameInfo.msaaSupported && msaa) + QVERIFY(frameInfo.msaaEnabled); + + // Resize the item and grab again + item->setSize(QSize(200, 200)); + result = view.grabWindow(); + + QCOMPARE(frameInfo.renderCount, 2); + QCOMPARE(result.pixel(150, 150), color); + if (textureSize.isValid()) + QCOMPARE(frameInfo.fboSize, textureSize); + else + QCOMPARE(frameInfo.fboSize, QSize(item->width(), item->height()) * view.devicePixelRatio()); + if (frameInfo.msaaSupported && msaa) + QVERIFY(frameInfo.msaaEnabled); +} + +void tst_QQuickFramebufferObject::testInvalidate() +{ + qmlRegisterType<FBOItem>("FBOItem", 1, 0, "FBOItem"); + + QQuickView view; + view.setSource(QUrl::fromLocalFile("data/testStuff.qml")); + + FBOItem *item = view.rootObject()->findChild<FBOItem *>("fbo"); + item->setTextureFollowsItemSize(false); + item->setTextureSize(QSize(200, 200)); + + view.show(); + QTest::qWaitForWindowExposed(&view); + + QCOMPARE(frameInfo.fboSize, QSize(200, 200)); + + frameInfo.createFBOCount = 0; + item->setTextureSize(QSize(300, 300)); + item->update(); + + QTRY_COMPARE(frameInfo.createFBOCount, 1); + QCOMPARE(frameInfo.fboSize, QSize(300, 300)); +} + +QTEST_MAIN(tst_QQuickFramebufferObject) + +#include "tst_qquickframebufferobject.moc" |