aboutsummaryrefslogtreecommitdiffstats
path: root/tests/auto/quick/qquickframebufferobject
diff options
context:
space:
mode:
authorGunnar Sletta <gunnar.sletta@digia.com>2013-09-23 09:53:58 +0200
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-09-25 16:16:15 +0200
commitf2233c725078d49f6b185e642325dacb47b33240 (patch)
tree7e612d02f2d4c84882bc5294640ecb99333f139d /tests/auto/quick/qquickframebufferobject
parent0e62896fdcbad014177ba11d88bbe46eb496ab2d (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')
-rw-r--r--tests/auto/quick/qquickframebufferobject/data/testStuff.qml56
-rw-r--r--tests/auto/quick/qquickframebufferobject/qquickframebufferobject.pro15
-rw-r--r--tests/auto/quick/qquickframebufferobject/tst_qquickframebufferobject.cpp255
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"