File indexing completed on 2024-05-05 16:07:16

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 "qtquicksettings.h"
0010 
0011 #if QUICKADDONS_BUILD_DEPRECATED_SINCE(5, 93)
0012 #include "renderersettings.h"
0013 
0014 #include <QGuiApplication>
0015 #include <QLibraryInfo>
0016 #include <QOffscreenSurface>
0017 #include <QOpenGLContext>
0018 #include <QOpenGLFunctions>
0019 #include <QQuickWindow>
0020 #include <QSurfaceFormat>
0021 #include <QVersionNumber>
0022 
0023 /**
0024  * If QtQuick is configured (QQuickWindow::sceneGraphBackend()) to use the OpenGL backend,
0025  * check if it is supported or otherwise reconfigure QtQuick to fallback to software mode.
0026  * This function is called by init().
0027  *
0028  * @returns true if the selected backend is supported, false on fallback to software mode.
0029  */
0030 static bool checkBackend(QOpenGLContext *checkContext)
0031 {
0032     if (!QQuickWindow::sceneGraphBackend().isEmpty()) {
0033         return true; // QtQuick is not configured to use the OpenGL backend
0034     }
0035 
0036     // kwin wayland has it's own QPA, it is unable to create a GL context at this point.
0037     // KF6 TODO, drop this . The issue will be resolved in future kwin releases.
0038     QString platformName = qApp->platformName();
0039     if (platformName == QLatin1String("wayland-org.kde.kwin.qpa")) {
0040         return true;
0041     }
0042 
0043 #if !QT_CONFIG(opengl)
0044     Q_UNUSED(checkContext)
0045     bool ok = false;
0046 #else
0047     bool ok = checkContext->create();
0048 #endif
0049     if (!ok) {
0050         qWarning("Warning: fallback to QtQuick software backend.");
0051         QQuickWindow::setSceneGraphBackend(QStringLiteral("software"));
0052     }
0053     return ok;
0054 }
0055 
0056 void KQuickAddons::QtQuickSettings::init()
0057 {
0058     if (!(qobject_cast<QGuiApplication *> qApp)) {
0059         qWarning("Error: cannot call KQuickAddons::QtQuickSettings::init() before QGuiApplication is created.");
0060         return;
0061     }
0062 
0063     PlasmaQtQuickSettings::RendererSettings s;
0064 #if !QT_CONFIG(opengl)
0065     QOpenGLContext *pCheckContext = nullptr;
0066 #else
0067     QOpenGLContext checkContext, *pCheckContext = &checkContext;
0068 #endif
0069     if (!s.sceneGraphBackend().isEmpty()) {
0070         QQuickWindow::setSceneGraphBackend(s.sceneGraphBackend());
0071     } else {
0072         QQuickWindow::setSceneGraphBackend(QStringLiteral(""));
0073         checkBackend(pCheckContext);
0074     }
0075 
0076     if (!qEnvironmentVariableIsSet("QSG_RENDER_LOOP")) {
0077         if (!s.renderLoop().isEmpty()) {
0078             qputenv("QSG_RENDER_LOOP", s.renderLoop().toLatin1());
0079         } else if (QGuiApplication::platformName() == QLatin1String("wayland")) {
0080 #if QT_CONFIG(opengl)
0081             // Workaround for Bug 432062 / QTBUG-95817
0082             QOffscreenSurface surface;
0083             surface.create();
0084             if (checkContext.makeCurrent(&surface)) {
0085                 const char *vendor = reinterpret_cast<const char *>(checkContext.functions()->glGetString(GL_VENDOR));
0086                 if (qstrcmp(vendor, "NVIDIA Corporation") == 0) {
0087                     // Otherwise Qt Quick Windows break when resized
0088                     qputenv("QSG_RENDER_LOOP", "basic");
0089                 }
0090             }
0091 #endif
0092         }
0093     }
0094 
0095     auto format = QSurfaceFormat::defaultFormat();
0096     if (s.forceGlCoreProfile()) {
0097         format.setVersion(3, 2);
0098         format.setProfile(QSurfaceFormat::CoreProfile);
0099     }
0100     // Before Qt 5.12.2 this setting was somewhat unstable
0101     // it was opt-in to find bugs both in KDE and Qt
0102     // For 5.13 with modern plasma it should be fine
0103     if (s.graphicsResetNotifications() || QLibraryInfo::version() >= QVersionNumber(5, 13, 0)) {
0104         format.setOption(QSurfaceFormat::ResetNotification);
0105     }
0106     QSurfaceFormat::setDefaultFormat(format);
0107 }
0108 #endif