From 3257b2e4c53478a496d3279951d930f2799453fa Mon Sep 17 00:00:00 2001 From: Fatih Uzunoglu <fuzun54@outlook.com> Date: Wed, 19 Mar 2025 18:58:12 +0200 Subject: [PATCH 1/2] qt: relax made current assertions in `CompositorX11UISurface` Rather than having an assertion regarding the context became current, we can simply early return in these functions. If the context could not be made current, it is likely that we are in some sort of transitional phase and `resizeFbo()` would be called later when the state is stable either directly or indirectly. `render()`, on the other is periodically called anyway. It should be fine to simply return early instead of triggering assertion failure. When the context can be made current, it can do its job. --- .../maininterface/compositor_x11_uisurface.cpp | 16 +++++++++++----- .../maininterface/compositor_x11_uisurface.hpp | 4 ++-- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/modules/gui/qt/maininterface/compositor_x11_uisurface.cpp b/modules/gui/qt/maininterface/compositor_x11_uisurface.cpp index 63ea2ecbb47b..f36b9b736a5a 100644 --- a/modules/gui/qt/maininterface/compositor_x11_uisurface.cpp +++ b/modules/gui/qt/maininterface/compositor_x11_uisurface.cpp @@ -204,15 +204,16 @@ void CompositorX11UISurface::destroyFbo() } } -void CompositorX11UISurface::render() +bool CompositorX11UISurface::render() { if (!isExposed()) - return; + return false; if (m_context) { const bool current = m_context->makeCurrent(this); - assert(current); + if (!current) + return false; m_uiRenderControl->beginFrame(); } @@ -250,6 +251,8 @@ void CompositorX11UISurface::render() emit m_uiWindow->frameSwapped(); emit updated(); + + return true; } void CompositorX11UISurface::updateSizes() @@ -411,18 +414,21 @@ bool CompositorX11UISurface::eventFilter(QObject*, QEvent *event) return false; } -void CompositorX11UISurface::resizeFbo() +bool CompositorX11UISurface::resizeFbo() { if (m_rootItem) { const bool current = m_context->makeCurrent(this); - assert(current); + if (!current) + return false; destroyFbo(); createFbo(); m_context->doneCurrent(); updateSizes(); render(); + return true; } + return false; } void CompositorX11UISurface::applyNvidiaWorkaround(QSurfaceFormat &format) diff --git a/modules/gui/qt/maininterface/compositor_x11_uisurface.hpp b/modules/gui/qt/maininterface/compositor_x11_uisurface.hpp index 308b5796c6e3..30225a2869cd 100644 --- a/modules/gui/qt/maininterface/compositor_x11_uisurface.hpp +++ b/modules/gui/qt/maininterface/compositor_x11_uisurface.hpp @@ -57,7 +57,7 @@ public: explicit CompositorX11UISurface(QWindow* window, QScreen *screen = nullptr); ~CompositorX11UISurface(); - virtual void render(); + virtual bool render(); bool handleWindowEvent(QEvent *event); @@ -91,7 +91,7 @@ protected: void createFbo(); void destroyFbo(); - void resizeFbo(); + bool resizeFbo(); private: static void applyNvidiaWorkaround(QSurfaceFormat& format); -- GitLab From 99162581a3fc00a9d3f9917ad4fd2bedf649a6ce Mon Sep 17 00:00:00 2001 From: Fatih Uzunoglu <fuzun54@outlook.com> Date: Wed, 19 Mar 2025 19:01:55 +0200 Subject: [PATCH 2/2] qt: make context current before calling `::createFbo()` and `::destroyFbo()` in `CompositorX11UISurface` The reason these methods don't make the context current themselves is because they are called together in `resizeFbo()` where the context is already made current. This makes it possible to make current once instead of twice (with accompanying done current in these methods). --- .../maininterface/compositor_x11_uisurface.cpp | 17 +++++++++++++++-- .../maininterface/compositor_x11_uisurface.hpp | 3 +++ 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/modules/gui/qt/maininterface/compositor_x11_uisurface.cpp b/modules/gui/qt/maininterface/compositor_x11_uisurface.cpp index f36b9b736a5a..2e82cc8d68f5 100644 --- a/modules/gui/qt/maininterface/compositor_x11_uisurface.cpp +++ b/modules/gui/qt/maininterface/compositor_x11_uisurface.cpp @@ -89,8 +89,21 @@ CompositorX11UISurface::CompositorX11UISurface(QWindow* window, QScreen* screen) if (m_context) { - connect(m_uiWindow, &QQuickWindow::sceneGraphInitialized, this, &CompositorX11UISurface::createFbo); - connect(m_uiWindow, &QQuickWindow::sceneGraphInvalidated, this, &CompositorX11UISurface::destroyFbo); + connect(m_uiWindow, &QQuickWindow::sceneGraphInitialized, this, [this]() { + assert(m_context); + const bool ret = m_context->makeCurrent(this); + assert(ret); // initial fbo creation must succeed + createFbo(); + m_context->doneCurrent(); + }); + connect(m_uiWindow, &QQuickWindow::sceneGraphInvalidated, this, [this]() { + assert(m_context); + if (Q_LIKELY(m_context->makeCurrent(this))) + { + destroyFbo(); + m_context->doneCurrent(); + } + }); } connect(m_uiWindow, &QQuickWindow::beforeRendering, this, &CompositorX11UISurface::beforeRendering); diff --git a/modules/gui/qt/maininterface/compositor_x11_uisurface.hpp b/modules/gui/qt/maininterface/compositor_x11_uisurface.hpp index 30225a2869cd..ad9f359e62cb 100644 --- a/modules/gui/qt/maininterface/compositor_x11_uisurface.hpp +++ b/modules/gui/qt/maininterface/compositor_x11_uisurface.hpp @@ -89,8 +89,11 @@ protected: void updateSizes(); + // WARNING: The OpenGL context must be made current against this window before calling these methods: void createFbo(); void destroyFbo(); + + // NOTE: This method attempts to make the OpenGL context current against this window: bool resizeFbo(); private: -- GitLab