aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLaszlo Agocs <laszlo.agocs@theqtcompany.com>2016-02-13 19:52:57 +0100
committerLaszlo Agocs <laszlo.agocs@theqtcompany.com>2016-02-15 05:32:31 +0000
commit3b6ebe6338747b4b24558c9b5f2c9702f4cce1be (patch)
treeb0186897ff0295f06bee3a1086dde3acc4a710f3
parentb6ff963362955f63ca35daa0268d8fde93229997 (diff)
Make it possible to have built-in adaptations
In addition to QMLSCENE_DEVICE, start supporting an env var named QT_QUICK_BACKEND. This is more suitable for general use. Besides plugin-based adaptations, some built-in ones are anticipated as well. Therefore, add support for shipping custom contexts as part of the scenegraph. For test purposes, a dummy adaptation is provided that falls back to the default, OpenGL-based path for everything. This may be removed at some point later on, but is useful for testing the loading logic for now. Change-Id: I7e0a2cd3ef33ba910604fb4027af3b3711fcaf1e Reviewed-by: Andy Nichols <andy.nichols@theqtcompany.com>
-rw-r--r--src/quick/scenegraph/adaptations/adaptations.pri1
-rw-r--r--src/quick/scenegraph/adaptations/dummy/dummy.pri5
-rw-r--r--src/quick/scenegraph/adaptations/dummy/qsgdummyadaptation.cpp90
-rw-r--r--src/quick/scenegraph/adaptations/dummy/qsgdummyadaptation_p.h76
-rw-r--r--src/quick/scenegraph/qsgcontextplugin.cpp120
-rw-r--r--src/quick/scenegraph/scenegraph.pri3
6 files changed, 248 insertions, 47 deletions
diff --git a/src/quick/scenegraph/adaptations/adaptations.pri b/src/quick/scenegraph/adaptations/adaptations.pri
new file mode 100644
index 0000000000..3511971cac
--- /dev/null
+++ b/src/quick/scenegraph/adaptations/adaptations.pri
@@ -0,0 +1 @@
+include(dummy/dummy.pri)
diff --git a/src/quick/scenegraph/adaptations/dummy/dummy.pri b/src/quick/scenegraph/adaptations/dummy/dummy.pri
new file mode 100644
index 0000000000..f81655dcaa
--- /dev/null
+++ b/src/quick/scenegraph/adaptations/dummy/dummy.pri
@@ -0,0 +1,5 @@
+SOURCES += \
+ $$PWD/qsgdummyadaptation.cpp
+
+HEADERS += \
+ $$PWD/qsgdummyadaptation_p.h
diff --git a/src/quick/scenegraph/adaptations/dummy/qsgdummyadaptation.cpp b/src/quick/scenegraph/adaptations/dummy/qsgdummyadaptation.cpp
new file mode 100644
index 0000000000..98f6872533
--- /dev/null
+++ b/src/quick/scenegraph/adaptations/dummy/qsgdummyadaptation.cpp
@@ -0,0 +1,90 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part 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 The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://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 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qsgdummyadaptation_p.h"
+
+#include <private/qguiapplication_p.h>
+#include <qpa/qplatformintegration.h>
+
+QT_BEGIN_NAMESPACE
+
+class QSGDummyContext : public QSGContext
+{
+public:
+ QSGDummyContext(QObject *parent = 0) : QSGContext(parent) { }
+
+ QSGRenderContext *createRenderContext() override { return QSGContext::createRenderContext(); }
+ QSGRectangleNode *createRectangleNode() override { return QSGContext::createRectangleNode(); }
+ QSGImageNode *createImageNode() override { return QSGContext::createImageNode(); }
+ QSGPainterNode *createPainterNode(QQuickPaintedItem *item) override { return QSGContext::createPainterNode(item); }
+ QSGGlyphNode *createGlyphNode(QSGRenderContext *rc, bool preferNativeGlyphNode) override { return QSGContext::createGlyphNode(rc, preferNativeGlyphNode); }
+ QSGNinePatchNode *createNinePatchNode() override { return QSGContext::createNinePatchNode(); }
+ QSGLayer *createLayer(QSGRenderContext *rc) override { return QSGContext::createLayer(rc); }
+ QSurfaceFormat defaultSurfaceFormat() const override { return QSGContext::defaultSurfaceFormat(); }
+};
+
+QSGDummyAdaptation::QSGDummyAdaptation(QObject *parent)
+ : QSGContextPlugin(parent)
+{
+}
+
+QStringList QSGDummyAdaptation::keys() const
+{
+ return QStringList() << QLatin1String("dummy");
+}
+
+QSGContext *QSGDummyAdaptation::create(const QString &) const
+{
+ if (!contextInstance) {
+ qDebug("Creating OpenGL SG context via dummy");
+ contextInstance = new QSGDummyContext;
+ }
+
+ return contextInstance;
+}
+
+QSGRenderLoop *QSGDummyAdaptation::createWindowManager()
+{
+ qDebug("Creating default OpenGL render loop via dummy");
+ return nullptr;
+}
+
+QSGDummyContext *QSGDummyAdaptation::contextInstance = nullptr;
+
+QT_END_NAMESPACE
diff --git a/src/quick/scenegraph/adaptations/dummy/qsgdummyadaptation_p.h b/src/quick/scenegraph/adaptations/dummy/qsgdummyadaptation_p.h
new file mode 100644
index 0000000000..aa0599de79
--- /dev/null
+++ b/src/quick/scenegraph/adaptations/dummy/qsgdummyadaptation_p.h
@@ -0,0 +1,76 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part 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 The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://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 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QSGDUMMYADAPTATION_P_H
+#define QSGDUMMYADAPTATION_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <private/qsgcontext_p.h>
+#include <private/qsgcontextplugin_p.h>
+
+QT_BEGIN_NAMESPACE
+
+class QSGDummyContext;
+
+class QSGDummyAdaptation : public QSGContextPlugin
+{
+public:
+ QSGDummyAdaptation(QObject *parent = 0);
+
+ QStringList keys() const override;
+ QSGContext *create(const QString &key) const override;
+ QSGRenderLoop *createWindowManager() override;
+
+private:
+ static QSGDummyContext *contextInstance;
+};
+
+QT_END_NAMESPACE
+
+#endif // QSGDUMMYADAPTATION_P_H
diff --git a/src/quick/scenegraph/qsgcontextplugin.cpp b/src/quick/scenegraph/qsgcontextplugin.cpp
index f5c2b6880b..bc5d2a0a0d 100644
--- a/src/quick/scenegraph/qsgcontextplugin.cpp
+++ b/src/quick/scenegraph/qsgcontextplugin.cpp
@@ -43,8 +43,13 @@
#include <QtCore/private/qfactoryloader_p.h>
#include <QtCore/qlibraryinfo.h>
+// Built-in adaptations
+#include <QtQuick/private/qsgdummyadaptation_p.h>
+
QT_BEGIN_NAMESPACE
+Q_DECLARE_LOGGING_CATEGORY(QSG_LOG_INFO)
+
QSGContextPlugin::QSGContextPlugin(QObject *parent)
: QObject(parent)
{
@@ -59,61 +64,86 @@ Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, loader,
(QSGContextFactoryInterface_iid, QLatin1String("/scenegraph")))
#endif
-struct QSGAdaptionPluginData
+struct QSGAdaptionBackendData
{
- QSGAdaptionPluginData()
- : tried(false)
- , factory(0)
- {
- }
-
- ~QSGAdaptionPluginData()
- {
- }
+ QSGAdaptionBackendData();
bool tried;
QSGContextFactoryInterface *factory;
- QString deviceName;
+ QString name;
+
+ QVector<QSGContextFactoryInterface *> builtIns;
};
-Q_GLOBAL_STATIC(QSGAdaptionPluginData, qsg_adaptation_data)
+QSGAdaptionBackendData::QSGAdaptionBackendData()
+ : tried(false)
+ , factory(0)
+{
+ // Fill in the table with the built-in adaptations.
+ builtIns.append(new QSGDummyAdaptation);
+}
+
+Q_GLOBAL_STATIC(QSGAdaptionBackendData, qsg_adaptation_data)
-QSGAdaptionPluginData *contextFactory()
+QSGAdaptionBackendData *contextFactory()
{
- QSGAdaptionPluginData *plugin = qsg_adaptation_data();
- if (!plugin->tried) {
+ QSGAdaptionBackendData *backendData = qsg_adaptation_data();
+
+ if (!backendData->tried) {
+ backendData->tried = true;
- plugin->tried = true;
const QStringList args = QGuiApplication::arguments();
- QString device;
+ QString requestedBackend;
for (int index = 0; index < args.count(); ++index) {
if (args.at(index).startsWith(QLatin1String("--device="))) {
- device = args.at(index).mid(9);
+ requestedBackend = args.at(index).mid(9);
break;
}
}
- if (device.isEmpty())
- device = QString::fromLocal8Bit(qgetenv("QMLSCENE_DEVICE"));
-#ifndef QT_NO_LIBRARY
- if (!device.isEmpty()) {
- const int index = loader()->indexOf(device);
- if (index != -1)
- plugin->factory = qobject_cast<QSGContextFactoryInterface*>(loader()->instance(index));
- plugin->deviceName = device;
+ if (requestedBackend.isEmpty() && qEnvironmentVariableIsSet("QMLSCENE_DEVICE"))
+ requestedBackend = QString::fromLocal8Bit(qgetenv("QMLSCENE_DEVICE"));
+
+ // A modern alternative. Scenegraph adaptations can represent backends
+ // for different graphics APIs as well, instead of being specific to
+ // some device or platform.
+ if (requestedBackend.isEmpty() && qEnvironmentVariableIsSet("QT_QUICK_BACKEND"))
+ requestedBackend = QString::fromLocal8Bit(qgetenv("QT_QUICK_BACKEND"));
+
+ if (!requestedBackend.isEmpty()) {
#ifndef QT_NO_DEBUG
- if (!plugin->factory) {
- qWarning("Could not create scene graph context for device '%s'"
- " - check that plugins are installed correctly in %s",
- qPrintable(device),
- qPrintable(QLibraryInfo::location(QLibraryInfo::PluginsPath)));
- }
+ qCDebug(QSG_LOG_INFO) << "Loading backend" << requestedBackend;
#endif
- }
+ // First look for a built-in adaptation.
+ for (QSGContextFactoryInterface *builtInBackend : qAsConst(backendData->builtIns)) {
+ if (builtInBackend->keys().contains(requestedBackend)) {
+ backendData->factory = builtInBackend;
+ break;
+ }
+ }
+
+ // Then try the plugins.
+ if (!backendData->factory) {
+#ifndef QT_NO_LIBRARY
+ const int index = loader()->indexOf(requestedBackend);
+ if (index != -1)
+ backendData->factory = qobject_cast<QSGContextFactoryInterface*>(loader()->instance(index));
+ backendData->name = requestedBackend;
+#ifndef QT_NO_DEBUG
+ if (!backendData->factory) {
+ qWarning("Could not create scene graph context for backend '%s'"
+ " - check that plugins are installed correctly in %s",
+ qPrintable(requestedBackend),
+ qPrintable(QLibraryInfo::location(QLibraryInfo::PluginsPath)));
+ }
+#endif
+ }
#endif // QT_NO_LIBRARY
+ }
}
- return plugin;
+
+ return backendData;
}
@@ -126,9 +156,9 @@ QSGAdaptionPluginData *contextFactory()
*/
QSGContext *QSGContext::createDefaultContext()
{
- QSGAdaptionPluginData *plugin = contextFactory();
- if (plugin->factory)
- return plugin->factory->create(plugin->deviceName);
+ QSGAdaptionBackendData *backendData = contextFactory();
+ if (backendData->factory)
+ return backendData->factory->create(backendData->name);
return new QSGContext();
}
@@ -143,9 +173,9 @@ QSGContext *QSGContext::createDefaultContext()
QQuickTextureFactory *QSGContext::createTextureFactoryFromImage(const QImage &image)
{
- QSGAdaptionPluginData *plugin = contextFactory();
- if (plugin->factory)
- return plugin->factory->createTextureFactoryFromImage(image);
+ QSGAdaptionBackendData *backendData = contextFactory();
+ if (backendData->factory)
+ return backendData->factory->createTextureFactoryFromImage(image);
return 0;
}
@@ -157,14 +187,10 @@ QQuickTextureFactory *QSGContext::createTextureFactoryFromImage(const QImage &im
QSGRenderLoop *QSGContext::createWindowManager()
{
- QSGAdaptionPluginData *plugin = contextFactory();
- if (plugin->factory)
- return plugin->factory->createWindowManager();
+ QSGAdaptionBackendData *backendData = contextFactory();
+ if (backendData->factory)
+ return backendData->factory->createWindowManager();
return 0;
}
-
-
-
-
QT_END_NAMESPACE
diff --git a/src/quick/scenegraph/scenegraph.pri b/src/quick/scenegraph/scenegraph.pri
index 84cc2ba135..33f6dff8cf 100644
--- a/src/quick/scenegraph/scenegraph.pri
+++ b/src/quick/scenegraph/scenegraph.pri
@@ -100,6 +100,9 @@ SOURCES += \
$$PWD/qsgwindowsrenderloop.cpp \
$$PWD/qsgdefaultlayer.cpp
+# Built-in, non-plugin-based adaptations
+include(adaptations/adaptations.pri)
+
RESOURCES += \
$$PWD/scenegraph.qrc