~ruther/guix-local

ref: next-master guix-local/gnu/packages/patches/qtwebengine-revert-egl.patch -rw-r--r-- 8.6 KiB
b989e013 — Andy Tai gnu: koboldcpp: Update to 1.106.2. 30 days ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
https://codereview.qt-project.org/c/qt/qtwebengine/+/675112
From 3cc88e0f85113e38ccb1bfdadb7d150c2389b1bc Mon Sep 17 00:00:00 2001
From: Moss Heim <moss.heim@qt.io>
Date: Thu, 11 Sep 2025 13:47:04 +0200
Subject: [PATCH] Return to supporting eglCreateImage in EGLHelper::queryDmaBuf

eglCreateDRMImageMESA was removed in mesa 25.2.
Keep using it where we can since this fixes support for
panthor/panfrost, otherwise fall back to the old use of EGL API.

Includes a revert of the following commits:
Revert "Create EGLImage with eglCreateDRMImageMESA() for exporting dma_buf"
This reverts commit 2ed5f9632292c6e531f353dae800cb12274af91a.
Revert "Remove leftover QOffscreenSurface from EGLHelper"
This reverts commit bcee2dbf412cc655c1b467091b581c696d234e3f.

Pick-to: 6.9 6.10 6.10.0
Task-number: QTBUG-136257
Task-number: QTBUG-139424
Change-Id: Ie115bd6373ce0a80651781aa568405477010ee25
Reviewed-by: Peter Varga <pvarga@inf.u-szeged.hu>
---
 src/core/ozone/egl_helper.cpp | 142 +++++++++++++++++++++++++++++++---
 src/core/ozone/egl_helper.h   |   4 +
 2 files changed, 134 insertions(+), 12 deletions(-)

diff --git a/src/core/ozone/egl_helper.cpp b/src/core/ozone/egl_helper.cpp
index 76e1c2a4663..68e45ffd446 100644
--- a/src/core/ozone/egl_helper.cpp
+++ b/src/core/ozone/egl_helper.cpp
@@ -3,10 +3,14 @@
 // Qt-Security score:significant reason:default
 
 #include "egl_helper.h"
+
+#include "compositor/compositor.h"
 #include "ozone_util_qt.h"
 #include "web_engine_context.h"
 
+#include <QtCore/qthread.h>
 #include <QtGui/qguiapplication.h>
+#include <QtGui/qoffscreensurface.h>
 #include <QtGui/qopenglcontext.h>
 #include <QtGui/qopenglfunctions.h>
 #include <qpa/qplatformnativeinterface.h>
@@ -57,6 +61,84 @@ static const char *getEGLErrorString(uint32_t error)
 
 QT_BEGIN_NAMESPACE
 
+class ScopedGLContext
+{
+public:
+    ScopedGLContext(QOffscreenSurface *surface, EGLHelper::EGLFunctions *eglFun)
+        : m_context(new QOpenGLContext()), m_eglFun(eglFun)
+    {
+        if ((m_previousEGLContext = m_eglFun->eglGetCurrentContext())) {
+            m_previousEGLDrawSurface = m_eglFun->eglGetCurrentSurface(EGL_DRAW);
+            m_previousEGLReadSurface = m_eglFun->eglGetCurrentSurface(EGL_READ);
+            m_previousEGLDisplay = m_eglFun->eglGetCurrentDisplay();
+        }
+
+        if (!m_context->create()) {
+            qWarning("Failed to create OpenGL context.");
+            return;
+        }
+
+        Q_ASSERT(surface->isValid());
+        if (!m_context->makeCurrent(surface)) {
+            qWarning("Failed to make OpenGL context current.");
+            return;
+        }
+    }
+
+    ~ScopedGLContext()
+    {
+        if (!m_textures.empty()) {
+            auto *glFun = m_context->functions();
+            glFun->glDeleteTextures(m_textures.size(), m_textures.data());
+        }
+
+        if (m_previousEGLContext) {
+            // Make sure the scoped context is not current when restoring the previous
+            // EGL context otherwise the QOpenGLContext destructor resets the restored
+            // current context.
+            m_context->doneCurrent();
+
+            m_eglFun->eglMakeCurrent(m_previousEGLDisplay, m_previousEGLDrawSurface,
+                                     m_previousEGLReadSurface, m_previousEGLContext);
+            if (m_eglFun->eglGetError() != EGL_SUCCESS)
+                qWarning("Failed to restore EGL context.");
+        }
+    }
+
+    bool isValid() const { return m_context->isValid() && (m_context->surface() != nullptr); }
+
+    EGLContext eglContext() const
+    {
+        QNativeInterface::QEGLContext *nativeInterface =
+                m_context->nativeInterface<QNativeInterface::QEGLContext>();
+        return nativeInterface->nativeContext();
+    }
+
+    uint createTexture(int width, int height)
+    {
+        auto *glFun = m_context->functions();
+
+        uint glTexture;
+        glFun->glGenTextures(1, &glTexture);
+        glFun->glBindTexture(GL_TEXTURE_2D, glTexture);
+        glFun->glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE,
+                            NULL);
+        glFun->glBindTexture(GL_TEXTURE_2D, 0);
+
+        m_textures.push_back(glTexture);
+        return glTexture;
+    }
+
+private:
+    QScopedPointer<QOpenGLContext> m_context;
+    EGLHelper::EGLFunctions *m_eglFun;
+    EGLContext m_previousEGLContext = nullptr;
+    EGLSurface m_previousEGLDrawSurface = nullptr;
+    EGLSurface m_previousEGLReadSurface = nullptr;
+    EGLDisplay m_previousEGLDisplay = nullptr;
+    std::vector<uint> m_textures;
+};
+
 EGLHelper::EGLFunctions::EGLFunctions()
 {
     QOpenGLContext *context = OzoneUtilQt::getQOpenGLContext();
@@ -117,8 +199,23 @@ EGLHelper::EGLHelper()
         const char *displayExtensions = m_functions->eglQueryString(m_eglDisplay, EGL_EXTENSIONS);
         m_isDmaBufSupported = strstr(displayExtensions, "EGL_EXT_image_dma_buf_import")
                 && strstr(displayExtensions, "EGL_EXT_image_dma_buf_import_modifiers")
-                && strstr(displayExtensions, "EGL_MESA_drm_image")
                 && strstr(displayExtensions, "EGL_MESA_image_dma_buf_export");
+        m_isCreateDRMImageMesaSupported = strstr(displayExtensions, "EGL_MESA_drm_image");
+        if (!m_isDmaBufSupported) {
+            qCDebug(QtWebEngineCore::lcWebEngineCompositor,
+                    "EGL: MESA extensions not found, will not use dma-buf");
+        } else if (!m_isCreateDRMImageMesaSupported) {
+            qCDebug(QtWebEngineCore::lcWebEngineCompositor,
+                    "EGL: MESA extensions found but missing EGL_MESA_drm_image, will use dma-buf, "
+                    "some older graphics cards may not be supported");
+            m_offscreenSurface.reset(new QOffscreenSurface());
+            Q_ASSERT(QThread::currentThread() == qApp->thread());
+            m_offscreenSurface->create();
+        } else {
+            qCDebug(QtWebEngineCore::lcWebEngineCompositor,
+                    "EGL: MESA extensions and EGL_MESA_drm_image found, will use dma-buf with GEM "
+                    "buffer allocation");
+        }
     }
 
     // Try to create dma-buf.
@@ -138,17 +235,38 @@ void EGLHelper::queryDmaBuf(const int width, const int height, int *fd, int *str
     if (!m_isDmaBufSupported)
         return;
 
-    // clang-format off
-    EGLint attribs[] = {
-        EGL_WIDTH, width,
-        EGL_HEIGHT, height,
-        EGL_DRM_BUFFER_FORMAT_MESA, EGL_DRM_BUFFER_FORMAT_ARGB32_MESA,
-        EGL_DRM_BUFFER_USE_MESA, EGL_DRM_BUFFER_USE_SHARE_MESA,
-        EGL_NONE
-    };
-    // clang-format on
-
-    EGLImage eglImage = m_functions->eglCreateDRMImageMESA(m_eglDisplay, attribs);
+    EGLImage eglImage = EGL_NO_IMAGE;
+    // Probably doesn't need to live to the end of the function, but just in case.
+    std::unique_ptr<ScopedGLContext> glContext;
+    if (m_isCreateDRMImageMesaSupported) {
+        // This approach is slightly worse for security and no longer supported in mesa 25.2,
+        // but it allows us to keep support for the Panthor driver prior to that mesa version.
+        // clang-format off
+        EGLint attribs[] = {
+            EGL_WIDTH, width,
+            EGL_HEIGHT, height,
+            EGL_DRM_BUFFER_FORMAT_MESA, EGL_DRM_BUFFER_FORMAT_ARGB32_MESA,
+            EGL_DRM_BUFFER_USE_MESA, EGL_DRM_BUFFER_USE_SHARE_MESA,
+            EGL_NONE
+        };
+        // clang-format on
+        eglImage = m_functions->eglCreateDRMImageMESA(m_eglDisplay, attribs);
+    } else {
+        glContext = std::make_unique<ScopedGLContext>(m_offscreenSurface.get(), m_functions.get());
+        if (!glContext->isValid())
+            return;
+
+        EGLContext eglContext = glContext->eglContext();
+        if (!eglContext) {
+            qWarning("EGL: No EGLContext.");
+            return;
+        }
+
+        uint64_t textureId = glContext->createTexture(width, height);
+        eglImage = m_functions->eglCreateImage(m_eglDisplay, eglContext, EGL_GL_TEXTURE_2D,
+                                                    (EGLClientBuffer)textureId, NULL);
+    }
+
     if (eglImage == EGL_NO_IMAGE) {
         qWarning("EGL: Failed to create EGLImage: %s", getLastEGLErrorString());
         return;
diff --git a/src/core/ozone/egl_helper.h b/src/core/ozone/egl_helper.h
index 6233ef87e4d..6e059baecb4 100644
--- a/src/core/ozone/egl_helper.h
+++ b/src/core/ozone/egl_helper.h
@@ -25,6 +25,8 @@
 
 QT_BEGIN_NAMESPACE
 
+class QOffscreenSurface;
+
 class EGLHelper
 {
 public:
@@ -59,7 +61,9 @@ class EGLHelper
 
     EGLDisplay m_eglDisplay = EGL_NO_DISPLAY;
     QScopedPointer<EGLFunctions> m_functions;
+    QScopedPointer<QOffscreenSurface> m_offscreenSurface;
     bool m_isDmaBufSupported = false;
+    bool m_isCreateDRMImageMesaSupported = false;
 };
 
 QT_END_NAMESPACE