diff options
author | Laszlo Agocs <laszlo.agocs@theqtcompany.com> | 2016-02-13 19:52:57 +0100 |
---|---|---|
committer | Laszlo Agocs <laszlo.agocs@theqtcompany.com> | 2016-02-15 05:32:31 +0000 |
commit | 3b6ebe6338747b4b24558c9b5f2c9702f4cce1be (patch) | |
tree | b0186897ff0295f06bee3a1086dde3acc4a710f3 | |
parent | b6ff963362955f63ca35daa0268d8fde93229997 (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.pri | 1 | ||||
-rw-r--r-- | src/quick/scenegraph/adaptations/dummy/dummy.pri | 5 | ||||
-rw-r--r-- | src/quick/scenegraph/adaptations/dummy/qsgdummyadaptation.cpp | 90 | ||||
-rw-r--r-- | src/quick/scenegraph/adaptations/dummy/qsgdummyadaptation_p.h | 76 | ||||
-rw-r--r-- | src/quick/scenegraph/qsgcontextplugin.cpp | 120 | ||||
-rw-r--r-- | src/quick/scenegraph/scenegraph.pri | 3 |
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 |