diff options
author | Tor Arne Vestbø <[email protected]> | 2025-05-05 14:35:48 +0200 |
---|---|---|
committer | Tor Arne Vestbø <[email protected]> | 2025-05-23 17:42:46 +0200 |
commit | 4a7ccb65f0065e878c5762db05eca9c5cd6731e5 (patch) | |
tree | e737796f54e0dc655185820f3ceed08f0a8f66d7 | |
parent | 868fc456acba412f5a1d4a39fa504fc890fda205 (diff) |
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.cpp | 1 | ||||
-rw-r--r-- | src/gui/kernel/qguiapplication.cpp | 14 | ||||
-rw-r--r-- | src/gui/kernel/qguiapplication_p.h | 6 | ||||
-rw-r--r-- | src/gui/kernel/qopenglcontext.cpp | 12 | ||||
-rw-r--r-- | src/gui/kernel/qsurfaceformat.cpp | 12 | ||||
-rw-r--r-- | src/gui/painting/qbackingstorerhisupport.cpp | 2 | ||||
-rw-r--r-- | src/gui/rhi/qrhigles2.cpp | 2 | ||||
-rw-r--r-- | src/opengl/qopenglwindow.cpp | 2 | ||||
-rw-r--r-- | src/openglwidgets/qopenglwidget.cpp | 2 | ||||
-rw-r--r-- | src/plugins/platforms/eglfs/api/qeglfswindow.cpp | 6 | ||||
-rw-r--r-- | tests/auto/gui/kernel/qguiapplication/tst_qguiapplication.cpp | 12 |
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, ¶ms, 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 |