File indexing completed on 2024-11-24 05:00:56
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 return ok; 0046 } 0047 0048 void initializeRendererSessions() 0049 { 0050 // This is loaded via Q_COREAPP_STARTUP_FUNCTION 0051 0052 // Due to a quirk this gets called twice, see QTBUG-54479 0053 0054 // The order of events is: 0055 // Q*Application constructor starts 0056 // We load the QPA 0057 // We load the QPT (The first arguably incorrect invocation triggers) 0058 // QPA gets initalised 0059 // QCoreApplication constructor ends 0060 // Second (correct) invocation 0061 // it's important that we run after the QPA is initalised' 0062 0063 static bool firstCall = true; 0064 if (firstCall) { 0065 firstCall = false; 0066 return; 0067 } 0068 0069 PlasmaQtQuickSettings::RendererSettings s; 0070 QOpenGLContext checkContext; 0071 0072 QSGRendererInterface::GraphicsApi graphicsApi = QSGRendererInterface::Unknown; 0073 0074 switch (s.sceneGraphBackend()) { 0075 case PlasmaQtQuickSettings::RendererSettings::software: 0076 graphicsApi = QSGRendererInterface::Software; 0077 break; 0078 case PlasmaQtQuickSettings::RendererSettings::opengl: 0079 graphicsApi = QSGRendererInterface::OpenGL; 0080 break; 0081 default: 0082 if (!checkBackend(checkContext)) { 0083 qWarning("Warning: fallback to QtQuick software backend."); 0084 graphicsApi = QSGRendererInterface::Software; 0085 } 0086 } 0087 0088 if (graphicsApi != QSGRendererInterface::Unknown) { 0089 QQuickWindow::setSceneGraphBackend(graphicsApi); 0090 } 0091 0092 if (!qEnvironmentVariableIsSet("QSG_RENDER_LOOP")) { 0093 if (s.renderLoop() == PlasmaQtQuickSettings::RendererSettings::basic) { 0094 qputenv("QSG_RENDER_LOOP", "basic"); 0095 } else if (QGuiApplication::platformName() == QLatin1String("wayland")) { 0096 #if QT_CONFIG(opengl) 0097 // Workaround for Bug 432062 / QTBUG-95817 0098 QOffscreenSurface surface; 0099 surface.create(); 0100 if (checkContext.makeCurrent(&surface)) { 0101 const char *vendor = reinterpret_cast<const char *>(checkContext.functions()->glGetString(GL_VENDOR)); 0102 if (qstrcmp(vendor, "NVIDIA Corporation") == 0) { 0103 // Otherwise Qt Quick Windows break when resized 0104 qputenv("QSG_RENDER_LOOP", "basic"); 0105 } 0106 } 0107 #endif 0108 } 0109 } 0110 } 0111 0112 // Because this file gets loaded in the platform plugin, the QGuiApplication already exists 0113 Q_COREAPP_STARTUP_FUNCTION(initializeRendererSessions)