Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
qsgcontextplugin.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
5#include <QtQuick/private/qsgcontext_p.h>
6#include <QtGui/qguiapplication.h>
7#include <QtCore/private/qfactoryloader_p.h>
8#include <QtCore/qlibraryinfo.h>
9
10// Built-in adaptations
11#include <QtQuick/private/qsgsoftwareadaptation_p.h>
12#include <QtQuick/private/qsgdefaultcontext_p.h>
13
14#include <QtGui/private/qguiapplication_p.h>
15#include <QtGui/qpa/qplatformintegration.h>
16
18
20
22 : QObject(parent)
23{
24}
25
29
30#if QT_CONFIG(library)
33#endif
34
50
52{
53 // Fill in the table with the built-in adaptations.
55}
56
61
62Q_GLOBAL_STATIC(QSGAdaptationBackendData, qsg_adaptation_data)
63
64// This only works when the backend is loaded (contextFactory() was called),
65// otherwise the return value is 0.
66//
67// Note that the default (OpenGL) implementation always results in 0, custom flags
68// can only be returned from the other (either compiled-in or plugin-based) backends.
70{
71 return qsg_adaptation_data()->flags;
72}
73
75{
76 QSGAdaptationBackendData *backendData = qsg_adaptation_data();
77
78 if (!backendData->tried) {
79 backendData->tried = true;
80
82 QString requestedBackend = backendData->quickWindowBackendRequest; // empty or set via QQuickWindow::setSceneGraphBackend()
83
84 for (int index = 0; index < args.size(); ++index) {
85 if (args.at(index).startsWith(QLatin1String("--device="))) {
86 requestedBackend = args.at(index).mid(9);
87 break;
88 }
89 }
90
91 if (requestedBackend.isEmpty())
92 requestedBackend = qEnvironmentVariable("QMLSCENE_DEVICE");
93
94 // A modern alternative. Scenegraph adaptations can represent backends
95 // for different graphics APIs as well, instead of being specific to
96 // some device or platform.
97 if (requestedBackend.isEmpty())
98 requestedBackend = qEnvironmentVariable("QT_QUICK_BACKEND");
99
100 // If this platform does not support OpenGL, Vulkan, D3D11, or Metal, and no
101 // backend has been set, default to the software renderer. We rely on the
102 // static, build time flags only. This is to prevent the inevitable confusion
103 // caused by run time hocus pocus. If one wants to use the software backend
104 // in a GL or Vulkan capable Qt build (or on Windows or Apple platforms), it
105 // has to be requested explicitly.
106#if !QT_CONFIG(opengl) && !QT_CONFIG(vulkan) && !QT_CONFIG(metal) && !defined(Q_OS_WIN)
107 if (requestedBackend.isEmpty())
108 requestedBackend = QLatin1String("software");
109#endif
110
111 // As an exception to the above, play nice with platform plugins like
112 // vnc or linuxfb: Trying to initialize a QRhi is futile on these, and
113 // Qt 5 had an explicit fallback to the software backend, based on the
114 // OpenGL capability. Replicate that behavior using the new
115 // RhiBasedRendering capability flag, which, on certain platforms,
116 // indicates that we should not even bother trying to initialize a QRhi
117 // as no 3D API can be expected work.
119 if (requestedBackend.isEmpty())
120 requestedBackend = QLatin1String("software");
121 }
122
123 // This is handy if some of the logic above goes wrong and we select
124 // e.g. the software backend when it is not desired.
125 if (requestedBackend == QLatin1String("rhi"))
126 requestedBackend.clear(); // empty = no custom backend to load
127
128 if (!requestedBackend.isEmpty()) {
129 qCDebug(QSG_LOG_INFO, "Loading backend %s", qUtf8Printable(requestedBackend));
130
131 // First look for a built-in adaptation.
132 for (QSGContextFactoryInterface *builtInBackend : std::as_const(backendData->builtIns)) {
133 if (builtInBackend->keys().contains(requestedBackend)) {
134 backendData->factory = builtInBackend;
135 backendData->name = requestedBackend;
136 backendData->flags = backendData->factory->flags(requestedBackend);
137 break;
138 }
139 }
140
141#if QT_CONFIG(library)
142 // Then try the plugins.
143 if (!backendData->factory) {
144 const int index = loader()->indexOf(requestedBackend);
145 if (index != -1)
146 backendData->factory = qobject_cast<QSGContextFactoryInterface*>(loader()->instance(index));
147 if (backendData->factory) {
148 backendData->name = requestedBackend;
149 backendData->flags = backendData->factory->flags(requestedBackend);
150 }
151 if (!backendData->factory) {
152 qWarning("Could not create scene graph context for backend '%s'"
153 " - check that plugins are installed correctly in %s",
154 qPrintable(requestedBackend),
156 }
157 }
158#endif // library
159 }
160 }
161
162 return backendData;
163}
164
165
166
174{
176 if (backendData->factory)
177 return backendData->factory->create(backendData->name);
178 return new QSGDefaultContext();
179}
180
181
182
191{
193 if (backendData->factory)
194 return backendData->factory->createTextureFactoryFromImage(image);
195 return nullptr;
196}
197
198
205{
207 if (backendData->factory)
208 return backendData->factory->createWindowManager();
209 return nullptr;
210}
211
212void QSGContext::setBackend(const QString &backend)
213{
214 QSGAdaptationBackendData *backendData = qsg_adaptation_data();
215 if (backendData->tried)
216 qWarning("Scenegraph already initialized, setBackend() request ignored");
217
218 backendData->quickWindowBackendRequest = backend;
219}
220
222{
223 QSGAdaptationBackendData *backendData = qsg_adaptation_data();
224 if (backendData->tried)
225 return backendData->name;
226
227 return backendData->quickWindowBackendRequest;
228}
229
231
232#include "moc_qsgcontextplugin_p.cpp"
static QStringList arguments()
static QPlatformIntegration * platformIntegration()
\inmodule QtGui
Definition qimage.h:37
static QString path(LibraryPath p)
Definition qlist.h:75
qsizetype size() const noexcept
Definition qlist.h:397
const_reference at(qsizetype i) const noexcept
Definition qlist.h:446
\inmodule QtCore
Definition qobject.h:103
The QQuickTextureFactory class provides an interface for loading custom textures from QML....
The QSGContext holds the scene graph entry points for one QML engine.
static QString backend()
static QQuickTextureFactory * createTextureFactoryFromImage(const QImage &image)
Calls into the scene graph adaptation if available and creates a texture factory.
static void setBackend(const QString &backend)
static QSGRenderLoop * createWindowManager()
Calls into the scene graph adaptation if available and creates a hardware specific window manager.
static QSGContext * createDefaultContext()
Creates a default scene graph context for the current hardware.
\inmodule QtCore
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:129
qDeleteAll(list.begin(), list.end())
Combined button and popup list for selecting options.
Definition image.cpp:4
Flags
#define Q_GLOBAL_STATIC_WITH_ARGS(TYPE, NAME, ARGS)
#define Q_GLOBAL_STATIC(TYPE, NAME,...)
#define qWarning
Definition qlogging.h:166
#define qCDebug(category,...)
#define Q_DECLARE_LOGGING_CATEGORY(name)
GLuint index
[2]
GLbitfield flags
GLuint name
QSGAdaptationBackendData * contextFactory()
QSGContextFactoryInterface::Flags qsg_backend_flags()
#define QSGContextFactoryInterface_iid
#define qUtf8Printable(string)
Definition qstring.h:1535
#define qPrintable(string)
Definition qstring.h:1531
QLatin1StringView QLatin1String
Definition qstringfwd.h:31
QString qEnvironmentVariable(const char *varName, const QString &defaultValue)
QJSValueList args
QVector< QSGContextFactoryInterface * > builtIns
QSGContextFactoryInterface * factory
virtual Flags flags(const QString &key) const =0