summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTor Arne Vestbø <[email protected]>2025-05-05 14:35:48 +0200
committerTor Arne Vestbø <[email protected]>2025-05-23 17:42:46 +0200
commit4a7ccb65f0065e878c5762db05eca9c5cd6731e5 (patch)
treee737796f54e0dc655185820f3ceed08f0a8f66d7
parent868fc456acba412f5a1d4a39fa504fc890fda205 (diff)
Lazily create global share context when Qt::AA_ShareOpenGLContexts is setHEADdev
The requirement to set Qt::AA_ShareOpenGLContexts before creating QGuiApp was forcing users to also set the default surface format before QGuiApp, which prevents us from initializing a default surface format based on the platform integration. By creating the global share context lazily when requested via the Qt::AA_ShareOpenGLContext application attribute we open up this possibility. Change-Id: I958639c997e96321013b1080c31e2533a36c13ff Reviewed-by: Allan Sandfeld Jensen <[email protected]>
-rw-r--r--src/corelib/kernel/qcoreapplication.cpp1
-rw-r--r--src/gui/kernel/qguiapplication.cpp14
-rw-r--r--src/gui/kernel/qguiapplication_p.h6
-rw-r--r--src/gui/kernel/qopenglcontext.cpp12
-rw-r--r--src/gui/kernel/qsurfaceformat.cpp12
-rw-r--r--src/gui/painting/qbackingstorerhisupport.cpp2
-rw-r--r--src/gui/rhi/qrhigles2.cpp2
-rw-r--r--src/opengl/qopenglwindow.cpp2
-rw-r--r--src/openglwidgets/qopenglwidget.cpp2
-rw-r--r--src/plugins/platforms/eglfs/api/qeglfswindow.cpp6
-rw-r--r--tests/auto/gui/kernel/qguiapplication/tst_qguiapplication.cpp12
11 files changed, 35 insertions, 36 deletions
diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp
index 180b8955906..38db0a0f39e 100644
--- a/src/corelib/kernel/qcoreapplication.cpp
+++ b/src/corelib/kernel/qcoreapplication.cpp
@@ -1013,7 +1013,6 @@ void QCoreApplication::setAttribute(Qt::ApplicationAttribute attribute, bool on)
case Qt::AA_UseDesktopOpenGL:
case Qt::AA_UseOpenGLES:
case Qt::AA_UseSoftwareOpenGL:
- case Qt::AA_ShareOpenGLContexts:
#ifdef QT_BOOTSTRAPPED
qWarning("Attribute %d must be set before QCoreApplication is created.",
attribute);
diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp
index 3a494d6406a..7e448aa6ae1 100644
--- a/src/gui/kernel/qguiapplication.cpp
+++ b/src/gui/kernel/qguiapplication.cpp
@@ -727,8 +727,7 @@ QGuiApplication::~QGuiApplication()
QGuiApplicationPrivate::QGuiApplicationPrivate(int &argc, char **argv)
: QCoreApplicationPrivate(argc, argv),
inputMethod(nullptr),
- lastTouchType(QEvent::TouchEnd),
- ownGlobalShareContext(false)
+ lastTouchType(QEvent::TouchEnd)
{
self = this;
application_type = QCoreApplicationPrivate::Gui;
@@ -1740,17 +1739,6 @@ void Q_TRACE_INSTRUMENT(qtgui) QGuiApplicationPrivate::init()
qRegisterGuiGetInterpolator();
#endif
- // set a global share context when enabled unless there is already one
-#ifndef QT_NO_OPENGL
- if (qApp->testAttribute(Qt::AA_ShareOpenGLContexts) && !qt_gl_global_share_context()) {
- QOpenGLContext *ctx = new QOpenGLContext;
- ctx->setFormat(QSurfaceFormat::defaultFormat());
- ctx->create();
- qt_gl_set_global_share_context(ctx);
- ownGlobalShareContext = true;
- }
-#endif
-
QWindowSystemInterfacePrivate::eventTime.start();
is_app_running = true;
diff --git a/src/gui/kernel/qguiapplication_p.h b/src/gui/kernel/qguiapplication_p.h
index 7ce270b1354..cb4702b5f7e 100644
--- a/src/gui/kernel/qguiapplication_p.h
+++ b/src/gui/kernel/qguiapplication_p.h
@@ -342,6 +342,10 @@ public:
static QThreadPool *qtGuiThreadPool();
+#ifndef QT_NO_OPENGL
+ bool ownGlobalShareContext = false;
+#endif
+
protected:
virtual void handleThemeChanged();
@@ -366,8 +370,6 @@ private:
#endif
std::shared_ptr<QColorTrcLut> m_a32ColorProfile;
- bool ownGlobalShareContext;
-
static QInputDeviceManager *m_inputDeviceManager;
// Cache the maximum device pixel ratio, to iterate through the screen list
diff --git a/src/gui/kernel/qopenglcontext.cpp b/src/gui/kernel/qopenglcontext.cpp
index 1bf84edf8e9..fa6572300b2 100644
--- a/src/gui/kernel/qopenglcontext.cpp
+++ b/src/gui/kernel/qopenglcontext.cpp
@@ -959,10 +959,6 @@ bool QOpenGLContext::supportsThreadedOpenGL()
This is useful if you need to upload OpenGL objects (buffers, textures,
etc.) before creating or showing a QOpenGLWidget or QQuickWidget.
- \note You must set the Qt::AA_ShareOpenGLContexts flag on QGuiApplication
- before creating the QGuiApplication object, otherwise Qt may not create a
- global shared context.
-
\warning Do not attempt to make the context returned by this function
current on any surface. Instead, you can create a new context which shares
with the global one, and then make the new context current.
@@ -972,6 +968,14 @@ bool QOpenGLContext::supportsThreadedOpenGL()
QOpenGLContext *QOpenGLContext::globalShareContext()
{
Q_ASSERT(qGuiApp);
+ // Lazily create a global share context when enabled unless there is already one
+ if (!qt_gl_global_share_context() && qGuiApp->testAttribute(Qt::AA_ShareOpenGLContexts)) {
+ QOpenGLContext *ctx = new QOpenGLContext;
+ ctx->setFormat(QSurfaceFormat::defaultFormat());
+ ctx->create();
+ qt_gl_set_global_share_context(ctx);
+ QGuiApplicationPrivate::instance()->ownGlobalShareContext = true;
+ }
return qt_gl_global_share_context();
}
diff --git a/src/gui/kernel/qsurfaceformat.cpp b/src/gui/kernel/qsurfaceformat.cpp
index 4d2dcab924a..59c469ae6b6 100644
--- a/src/gui/kernel/qsurfaceformat.cpp
+++ b/src/gui/kernel/qsurfaceformat.cpp
@@ -9,6 +9,10 @@
#include <QtGui/qcolorspace.h>
#include <QtGui/qguiapplication.h>
+#ifndef QT_NO_OPENGL
+#include <QtGui/private/qopenglcontext_p.h>
+#endif
+
#ifdef major
#undef major
#endif
@@ -807,12 +811,6 @@ Q_GLOBAL_STATIC(QSurfaceFormat, qt_default_surface_format)
and surfaces, even the ones created internally by Qt, will use the same
format.
- \note When setting Qt::AA_ShareOpenGLContexts, it is strongly recommended to
- place the call to this function before the construction of the
- QGuiApplication or QApplication. Otherwise \a format will not be applied to
- the global share context and therefore issues may arise with context sharing
- afterwards.
-
\since 5.4
\sa defaultFormat()
*/
@@ -820,7 +818,7 @@ void QSurfaceFormat::setDefaultFormat(const QSurfaceFormat &format)
{
#ifndef QT_NO_OPENGL
if (qApp) {
- QOpenGLContext *globalContext = QOpenGLContext::globalShareContext();
+ QOpenGLContext *globalContext = qt_gl_global_share_context();
if (globalContext && globalContext->isValid()) {
qWarning("Warning: Setting a new default format with a different version or profile "
"after the global shared context is created may cause issues with context "
diff --git a/src/gui/painting/qbackingstorerhisupport.cpp b/src/gui/painting/qbackingstorerhisupport.cpp
index 62932111f82..8136424b984 100644
--- a/src/gui/painting/qbackingstorerhisupport.cpp
+++ b/src/gui/painting/qbackingstorerhisupport.cpp
@@ -74,7 +74,7 @@ bool QBackingStoreRhiSupport::create()
params.fallbackSurface = surface;
params.window = m_window;
params.format = m_format;
- params.shareContext = qt_gl_global_share_context();
+ params.shareContext = QOpenGLContext::globalShareContext();
rhi = QRhi::create(QRhi::OpenGLES2, &params, flags);
}
#endif
diff --git a/src/gui/rhi/qrhigles2.cpp b/src/gui/rhi/qrhigles2.cpp
index 8d2002f68a0..8f89e6b48d2 100644
--- a/src/gui/rhi/qrhigles2.cpp
+++ b/src/gui/rhi/qrhigles2.cpp
@@ -771,7 +771,7 @@ bool QRhiGles2::create(QRhi::Flags flags)
if (maybeShareContext) {
ctx->setShareContext(maybeShareContext);
ctx->setScreen(maybeShareContext->screen());
- } else if (QOpenGLContext *shareContext = qt_gl_global_share_context()) {
+ } else if (QOpenGLContext *shareContext = QOpenGLContext::globalShareContext()) {
ctx->setShareContext(shareContext);
ctx->setScreen(shareContext->screen());
} else if (maybeWindow) {
diff --git a/src/opengl/qopenglwindow.cpp b/src/opengl/qopenglwindow.cpp
index 6b74aaedd70..05330dda0a4 100644
--- a/src/opengl/qopenglwindow.cpp
+++ b/src/opengl/qopenglwindow.cpp
@@ -161,7 +161,7 @@ public:
, shareContext(shareContext)
{
if (!shareContext)
- this->shareContext = qt_gl_global_share_context();
+ this->shareContext = QOpenGLContext::globalShareContext();
}
~QOpenGLWindowPrivate();
diff --git a/src/openglwidgets/qopenglwidget.cpp b/src/openglwidgets/qopenglwidget.cpp
index cf70e169903..fa8e59bc0cf 100644
--- a/src/openglwidgets/qopenglwidget.cpp
+++ b/src/openglwidgets/qopenglwidget.cpp
@@ -856,7 +856,7 @@ void QOpenGLWidgetPrivate::initialize()
context = new QOpenGLContext;
context->setFormat(requestedFormat);
- QOpenGLContext *shareContext = contextFromRhi ? contextFromRhi : qt_gl_global_share_context();
+ QOpenGLContext *shareContext = contextFromRhi ? contextFromRhi : QOpenGLContext::globalShareContext();
if (shareContext) {
context->setShareContext(shareContext);
context->setScreen(shareContext->screen());
diff --git a/src/plugins/platforms/eglfs/api/qeglfswindow.cpp b/src/plugins/platforms/eglfs/api/qeglfswindow.cpp
index 1e8c1a963e9..eddce2f55de 100644
--- a/src/plugins/platforms/eglfs/api/qeglfswindow.cpp
+++ b/src/plugins/platforms/eglfs/api/qeglfswindow.cpp
@@ -108,14 +108,14 @@ void QEglFSWindow::setBackingStore(QOpenGLCompositorBackingStore *backingStore)
#ifndef QT_NO_OPENGL
if (!m_rasterCompositingContext) {
m_rasterCompositingContext = new QOpenGLContext;
- m_rasterCompositingContext->setShareContext(qt_gl_global_share_context());
+ m_rasterCompositingContext->setShareContext(QOpenGLContext::globalShareContext());
m_rasterCompositingContext->setFormat(m_format);
m_rasterCompositingContext->setScreen(window()->screen());
if (Q_UNLIKELY(!m_rasterCompositingContext->create()))
qFatal("EGLFS: Failed to create compositing context");
// If there is a "root" window into which raster and QOpenGLWidget content is
// composited, all other contexts must share with its context.
- if (!qt_gl_global_share_context())
+ if (!QOpenGLContext::globalShareContext())
qt_gl_set_global_share_context(m_rasterCompositingContext);
}
QOpenGLCompositor *compositor = QOpenGLCompositor::instance();
@@ -145,7 +145,7 @@ void QEglFSWindow::destroy()
if (compositor->windows().isEmpty()) {
compositor->destroy();
- if (qt_gl_global_share_context() == m_rasterCompositingContext)
+ if (QOpenGLContext::globalShareContext() == m_rasterCompositingContext)
qt_gl_set_global_share_context(nullptr);
delete m_rasterCompositingContext;
} else {
diff --git a/tests/auto/gui/kernel/qguiapplication/tst_qguiapplication.cpp b/tests/auto/gui/kernel/qguiapplication/tst_qguiapplication.cpp
index d1a50e3d694..c6bf6c650c3 100644
--- a/tests/auto/gui/kernel/qguiapplication/tst_qguiapplication.cpp
+++ b/tests/auto/gui/kernel/qguiapplication/tst_qguiapplication.cpp
@@ -1273,7 +1273,7 @@ void tst_QGuiApplication::globalShareContext()
int argc = 1;
char *argv[] = { const_cast<char*>("tst_qguiapplication") };
QScopedPointer<QGuiApplication> app(new QGuiApplication(argc, argv));
- QOpenGLContext *ctx = qt_gl_global_share_context();
+ QOpenGLContext *ctx = QOpenGLContext::globalShareContext();
QVERIFY(ctx);
app.reset();
ctx = qt_gl_global_share_context();
@@ -1282,8 +1282,16 @@ void tst_QGuiApplication::globalShareContext()
// Test that there is no global share context by default.
QCoreApplication::setAttribute(Qt::AA_ShareOpenGLContexts, false);
app.reset(new QGuiApplication(argc, argv));
- ctx = qt_gl_global_share_context();
+ ctx = QOpenGLContext::globalShareContext();
QVERIFY(!ctx);
+
+ // Test that setting AA_ShareOpenGLContexts can happen after creating
+ // QGuiApplication.
+ app.reset();
+ app.reset(new QGuiApplication(argc, argv));
+ QCoreApplication::setAttribute(Qt::AA_ShareOpenGLContexts, true);
+ ctx = QOpenGLContext::globalShareContext();
+ QVERIFY(ctx);
#else
QSKIP("No OpenGL support");
#endif