File indexing completed on 2024-05-05 17:42:26
0001 /* 0002 SPDX-FileCopyrightText: 2016 David Edmundson <davidedmundson@kde.org> 0003 SPDX-FileCopyrightText: 2020 Piotr Henryk Dabrowski <phd@phd.re> 0004 SPDX-FileCopyrightText: 2021 David Redondo <kde@david-redondo.de> 0005 0006 SPDX-License-Identifier: LGPL-2.0-or-later 0007 */ 0008 0009 #include "renderersettings.h" 0010 0011 #include <QGuiApplication> 0012 #include <QLibraryInfo> 0013 #include <QOffscreenSurface> 0014 #include <QOpenGLContext> 0015 #include <QOpenGLFunctions> 0016 #include <QQuickWindow> 0017 #include <QSurfaceFormat> 0018 #include <QVersionNumber> 0019 0020 /** 0021 * If QtQuick is configured (QQuickWindow::sceneGraphBackend()) to use the OpenGL backend, 0022 * check if it is supported or otherwise reconfigure QtQuick to fallback to software mode. 0023 * This function is called by init(). 0024 * 0025 * @returns true if the selected backend is supported, false on fallback to software mode. 0026 */ 0027 static bool checkBackend(QOpenGLContext &checkContext) 0028 { 0029 if (!QQuickWindow::sceneGraphBackend().isEmpty()) { 0030 return true; // QtQuick is not configured to use the OpenGL backend 0031 } 0032 0033 // kwin wayland has it's own QPA, it is unable to create a GL context at this point. 0034 // KF6 TODO, drop this . The issue will be resolved in future kwin releases. 0035 QString platformName = qApp->platformName(); 0036 if (platformName == QLatin1String("wayland-org.kde.kwin.qpa")) { 0037 return true; 0038 } 0039 0040 #ifdef QT_NO_OPENGL 0041 bool ok = false; 0042 #else 0043 bool ok = checkContext.create(); 0044 #endif 0045 if (!ok) { 0046 qWarning("Warning: fallback to QtQuick software backend."); 0047 QQuickWindow::setSceneGraphBackend(QStringLiteral("software")); 0048 } 0049 return ok; 0050 } 0051 0052 void initializeRendererSessions() 0053 { 0054 // This is loaded via Q_COREAPP_STARTUP_FUNCTION 0055 0056 // Due to a quirk this gets called twice, see QTBUG-54479 0057 0058 // The order of events is: 0059 // Q*Application constructor starts 0060 // We load the QPA 0061 // We load the QPT (The first arguably incorrect invocation triggers) 0062 // QPA gets initalised 0063 // QCoreApplication constructor ends 0064 // Second (correct) invocation 0065 // it's important that we run after the QPA is initalised' 0066 0067 static bool firstCall = true; 0068 if (firstCall) { 0069 firstCall = false; 0070 return; 0071 } 0072 0073 PlasmaQtQuickSettings::RendererSettings s; 0074 QOpenGLContext checkContext; 0075 if (!s.sceneGraphBackend().isEmpty()) { 0076 QQuickWindow::setSceneGraphBackend(s.sceneGraphBackend()); 0077 } else { 0078 QQuickWindow::setSceneGraphBackend(QStringLiteral("")); 0079 checkBackend(checkContext); 0080 } 0081 0082 if (!qEnvironmentVariableIsSet("QSG_RENDER_LOOP")) { 0083 if (!s.renderLoop().isEmpty()) { 0084 qputenv("QSG_RENDER_LOOP", s.renderLoop().toLatin1()); 0085 } else if (QGuiApplication::platformName() == QLatin1String("wayland")) { 0086 #if QT_CONFIG(opengl) 0087 // Workaround for Bug 432062 / QTBUG-95817 0088 QOffscreenSurface surface; 0089 surface.create(); 0090 if (checkContext.makeCurrent(&surface)) { 0091 const char *vendor = reinterpret_cast<const char *>(checkContext.functions()->glGetString(GL_VENDOR)); 0092 if (qstrcmp(vendor, "NVIDIA Corporation") == 0) { 0093 // Otherwise Qt Quick Windows break when resized 0094 qputenv("QSG_RENDER_LOOP", "basic"); 0095 } 0096 } 0097 #endif 0098 } 0099 } 0100 } 0101 0102 // Because this file gets loaded in the platform plugin, the QGuiApplication already exists 0103 Q_COREAPP_STARTUP_FUNCTION(initializeRendererSessions)