[graphics/krita] /: OpenGL: increase minimum to ES3 / 3.3 Compatibility / 4.1 Core

L. E. Segovia null at kde.org
Wed Feb 1 18:16:46 GMT 2023


Git commit 2aef8841276ceffaa18221ac29e427c4d31efb6b by L. E. Segovia.
Committed on 01/02/2023 at 17:31.
Pushed by merge-service into branch 'master'.

OpenGL: increase minimum to ES3 / 3.3 Compatibility / 4.1 Core

This is the second attempt of commit
ca645e71a09e1ee81dc0f7ef153b00304af058de. For this one, I've ported Qt's
dynamic OpenGL module detection (which we cannot run at this time due to
QGuiApplication having not yet been instanced), and split the minimum
version per-operating system flavor.

For all OpenGL ES users, the new version will be fixed to 3.0 +
QSurfaceFormat::NoProfile (already the default-- CompatibilityProfile
and DeprecatedFunctions are no-ops).

For desktop GL users not on macOS, the new version will be fixed to 3.3
Compatibility. While testing, I found that it was easy to induce a
"crash" (in fact, forced process exit by X11) by asking NVIDIA's GLX
implementation to instantiate a 4.x surface if it was set to GLES
(whether by setRenderableType or by using NoProfile). For that reason
I've kept the Compatibility profile but without DeprecatedFunctions--
that way the display driver returns the maximum supported version.

For all desktop OpenGL users on a Mac, we use the Apple default and sole
supported version, 4.1 Core.

This reverts commit fa671d407fd6d89c87c15c67d486e5dd1c7b0301.

BUG:464255
CCMAIL:kimageshop at kde.org

Part-of: <https://invent.kde.org/graphics/krita/-/merge_requests/1726>

M  +5    -0    krita/main.cc
M  +7    -9    libs/ui/opengl/KisOpenGLModeProber.h
M  +71   -8    libs/ui/opengl/kis_opengl.cpp
M  +13   -14   libs/ui/opengl/kis_opengl_shader_loader.cpp

https://invent.kde.org/graphics/krita/commit/2aef8841276ceffaa18221ac29e427c4d31efb6b

diff --git a/krita/main.cc b/krita/main.cc
index 79e136dec7..5112077f1f 100644
--- a/krita/main.cc
+++ b/krita/main.cc
@@ -233,6 +233,11 @@ extern "C" MAIN_EXPORT int MAIN_FN(int argc, char **argv)
 
 #if defined HAVE_X11
     qputenv("QT_QPA_PLATFORM", "xcb");
+    // NOTE: this is necessary on Ubuntu to skip a crash with NVIDIA
+    // GLX when requesting a core or > 3.0 context.
+    // But in 5.15 it will break Qt Quick:
+    // https://bugreports.qt.io/browse/QTBUG-91698
+    // qputenv("QT_XCB_GL_INTEGRATION", "xcb_egl");
 #endif
 
     // Workaround a bug in QNetworkManager
diff --git a/libs/ui/opengl/KisOpenGLModeProber.h b/libs/ui/opengl/KisOpenGLModeProber.h
index fe84673e7e..1305358cb6 100644
--- a/libs/ui/opengl/KisOpenGLModeProber.h
+++ b/libs/ui/opengl/KisOpenGLModeProber.h
@@ -1,11 +1,11 @@
 /*
  *  SPDX-FileCopyrightText: 2017 Alvin Wong <alvinhochun at gmail.com>
  *  SPDX-FileCopyrightText: 2019 Dmitry Kazakov <dimula73 at gmail.com>
+ *  SPDX-FileCopyrightText: 2023 L. E. Segovia <amy at amyspark.me>
  *
  *  SPDX-License-Identifier: GPL-2.0-or-later
  */
 
-
 #ifndef KISOPENGLMODEPROBER_H
 #define KISOPENGLMODEPROBER_H
 
@@ -76,14 +76,12 @@ public:
     }
 
     bool isSupportedVersion() const {
-        return
-#ifdef Q_OS_MACOS
-                ((m_glMajorVersion * 100 + m_glMinorVersion) >= 302)
-#else
-                (m_glMajorVersion >= 3 && (m_supportsDeprecatedFunctions || m_isOpenGLES)) ||
-                ((m_glMajorVersion * 100 + m_glMinorVersion) == 201)
-#endif
-                ;
+        // Technically we could support GLES2 (I added the extensions for
+        // floating point surfaces). But given that Dmitry required VAOs
+        // on GLES, I've kept the check mostly as-is.
+        // Note:
+        //  - we've not supported OpenGL 2.1 for a Long time (commit e0d9a4feba0d4b5e70dddece8b76f38a6043fc88)
+        return (m_isOpenGLES && m_glMajorVersion >= 3) || ((m_glMajorVersion * 100 + m_glMinorVersion) >= 303);
     }
 
     bool supportsLoD() const {
diff --git a/libs/ui/opengl/kis_opengl.cpp b/libs/ui/opengl/kis_opengl.cpp
index c4864e6206..c85f024ca1 100644
--- a/libs/ui/opengl/kis_opengl.cpp
+++ b/libs/ui/opengl/kis_opengl.cpp
@@ -1,9 +1,11 @@
 /*
  *  SPDX-FileCopyrightText: 2007 Adrian Page <adrian at pagenet.plus.com>
+ *  SPDX-FileCopyrightText: 2023 L. E. Segovia <amy at amyspark.me>
  *
  *  SPDX-License-Identifier: GPL-2.0-or-later
  */
 
+#include <qopenglcontext.h>
 #include <tuple>
 
 #include <boost/optional.hpp>
@@ -534,6 +536,47 @@ RendererInfo getRendererInfo(KisOpenGL::OpenGLRenderer renderer)
     return info;
 }
 
+QOpenGLContext::OpenGLModuleType determineOpenGLImplementation(const RendererInfo &info)
+{
+    switch (info.first) {
+    case QSurfaceFormat::OpenGLES:
+#if defined(Q_OS_WINDOWS)
+        // https://invent.kde.org/szaman/qtbase/-/blob/krita/5.15/src/plugins/platforms/windows/qwindowsintegration.cpp#L425
+        switch (info.second) {
+        case KisOpenGL::AngleRendererD3d11:
+        case KisOpenGL::AngleRendererD3d9:
+        case KisOpenGL::AngleRendererD3d11Warp:
+            return QOpenGLContext::LibGLES;
+        // Assume system OpenGL -- QOpenGLStaticContext
+        default:
+            break;
+        }
+        return QOpenGLContext::LibGL;
+#else
+        // At least Manjaro Qt can perfectly call up a ES context,
+        // while Qt says via macros that it doesn't support that...
+        return QOpenGLContext::LibGLES;
+#endif
+    case QSurfaceFormat::DefaultRenderableType:
+#ifdef Q_OS_WIN
+    // https://invent.kde.org/szaman/qtbase/-/blob/krita/5.15/src/plugins/platforms/windows/qwindowsglcontext.cpp#L1117
+        return QOpenGLContext::LibGL;
+#else
+    // https://invent.kde.org/szaman/qtbase/-/blob/krita/5.15/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qglxintegration.cpp#L246
+#if defined(QT_OPENGL_ES_2)
+    return QOpenGLContext::LibGLES;
+#else
+    return QOpenGLContext::LibGL;
+#endif
+#endif
+    case QSurfaceFormat::OpenGL:
+    default:
+        // https://invent.kde.org/szaman/qtbase/-/blob/krita/5.15/src/plugins/platforms/windows/qwindowsglcontext.cpp#L1117
+        KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE(info.first != QSurfaceFormat::OpenVG, QOpenGLContext::LibGL);
+        // https://invent.kde.org/szaman/qtbase/-/blob/krita/5.15/src/gui/kernel/qplatformintegration.cpp#L547
+        return QOpenGLContext::LibGL;
+    };
+}
 
 KisOpenGL::RendererConfig generateSurfaceConfig(KisOpenGL::OpenGLRenderer renderer,
                                                 KisConfig::RootSurfaceFormat rootSurfaceFormat,
@@ -544,16 +587,36 @@ KisOpenGL::RendererConfig generateSurfaceConfig(KisOpenGL::OpenGLRenderer render
     KisOpenGL::RendererConfig config;
     config.angleRenderer = info.second;
 
+    dbgOpenGL << "Requesting configuration for" << info.first << info.second;
+
     QSurfaceFormat &format = config.format;
-#ifdef Q_OS_MACOS
-    format.setVersion(3, 2);
-    format.setProfile(QSurfaceFormat::CoreProfile);
-#elif !defined(Q_OS_ANDROID)
-    // XXX This can be removed once we move to Qt5.7
-    format.setVersion(3, 0);
-    format.setProfile(QSurfaceFormat::CompatibilityProfile);
-    format.setOptions(QSurfaceFormat::DeprecatedFunctions);
+    const auto openGLModuleType = determineOpenGLImplementation(info);
+    switch (openGLModuleType) {
+    case QOpenGLContext::LibGL:
+#if defined Q_OS_MACOS
+        format.setVersion(4, 1);
+        format.setProfile(QSurfaceFormat::CoreProfile);
+#else
+        // If asked for 3.0 "Core", Qt will instead request
+        // an OpenGL ES context.
+        // NVIDIA's GLX implementation will not allow that and results
+        // in a forced process exit through X11 (NVIDIA bug #3959482).
+        // Alternatively (if NoProfile or Core), it will cause the
+        // AppImage to crash because we don't ship GLES support.
+        format.setVersion(3, 3);
+        // Make sure to request a Compatibility profile to have NVIDIA
+        // return the maximum supported GL version.
+        format.setProfile(QSurfaceFormat::CompatibilityProfile);
 #endif
+        break;
+    case QOpenGLContext::LibGLES:
+        format.setVersion(3, 0);
+        format.setProfile(QSurfaceFormat::NoProfile);
+        break;
+    }
+
+    dbgOpenGL << "Version selected:" << openGLModuleType << format.version();
+
     format.setDepthBufferSize(24);
     format.setStencilBufferSize(8);
 
diff --git a/libs/ui/opengl/kis_opengl_shader_loader.cpp b/libs/ui/opengl/kis_opengl_shader_loader.cpp
index 2dd5d5b61a..bec43f0b19 100644
--- a/libs/ui/opengl/kis_opengl_shader_loader.cpp
+++ b/libs/ui/opengl/kis_opengl_shader_loader.cpp
@@ -1,5 +1,6 @@
 /* This file is part of the KDE project
  * SPDX-FileCopyrightText: 2016 Julian Thijssen <julianthijssen at gmail.com>
+ * SPDX-FileCopyrightText: 2023 L. E. Segovia <amy at amyspark.me>
  *
  *  SPDX-License-Identifier: GPL-2.0-or-later
  */
@@ -50,18 +51,17 @@ KisShaderProgram *KisOpenGLShaderLoader::loadShader(QString vertPath, QString fr
     // Load vertex shader
     QByteArray vertSource;
 
-// XXX Check can be removed and set to the MAC version after we move to Qt5.7
-#ifdef Q_OS_MACOS
-    vertSource.append(KisOpenGL::hasOpenGL3() ? "#version 150 core\n" : "#version 120\n");
-    vertSource.append("#define texture2D texture\n");
-    vertSource.append("#define texture3D texture\n");
-#else
     if (KisOpenGL::hasOpenGLES()) {
         vertSource.append("#version 300 es\n");
     } else {
+#ifdef Q_OS_MACOS
+        vertSource.append(KisOpenGL::hasOpenGL3() ? "#version 150 core\n" : "#version 120\n");
+        vertSource.append("#define texture2D texture\n");
+        vertSource.append("#define texture3D texture\n");
+#else
         vertSource.append(KisOpenGL::supportsLoD() ? "#version 130\n" : "#version 120\n");
-    }
 #endif
+    }
     vertSource.append(vertHeader);
     QFile vertexShaderFile(":/" + vertPath);
     vertexShaderFile.open(QIODevice::ReadOnly);
@@ -74,12 +74,6 @@ KisShaderProgram *KisOpenGLShaderLoader::loadShader(QString vertPath, QString fr
     // Load fragment shader
     QByteArray fragSource;
 
-// XXX Check can be removed and set to the MAC version after we move to Qt5.7
-#ifdef Q_OS_MACOS
-    fragSource.append(KisOpenGL::hasOpenGL3() ? "#version 150 core\n" : "#version 120\n");
-    fragSource.append("#define texture2D texture\n");
-    fragSource.append("#define texture3D texture\n");
-#else
     if (KisOpenGL::hasOpenGLES()) {
         fragSource.append("#version 300 es\n");
         if (KisOpenGL::supportsLoD()) {
@@ -100,9 +94,14 @@ KisShaderProgram *KisOpenGLShaderLoader::loadShader(QString vertPath, QString fr
             );
         }
     } else {
+#ifdef Q_OS_MACOS
+        fragSource.append(KisOpenGL::hasOpenGL3() ? "#version 150 core\n" : "#version 120\n");
+        fragSource.append("#define texture2D texture\n");
+        fragSource.append("#define texture3D texture\n");
+#else
         fragSource.append(KisOpenGL::supportsLoD() ? "#version 130\n" : "#version 120\n");
-    }
 #endif
+    }
     fragSource.append(fragHeader);
     QFile fragmentShaderFile(":/" + fragPath);
     fragmentShaderFile.open(QIODevice::ReadOnly);


More information about the kimageshop mailing list