diff options
author | Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io> | 2021-10-01 08:02:20 +0200 |
---|---|---|
committer | Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io> | 2021-12-08 21:08:04 +0100 |
commit | ee7573f61fe16ece4f07e7f48e0f47272ecdd535 (patch) | |
tree | c84880595769db74384dbfb889b2957b499bfdff | |
parent | b393370ebb5f983a92afbac419d49fb28b884010 (diff) |
Callbacks for begin/end of a frame on OpenGL
The background for this is that when running Wayland, the
Mesa driver has an issue which makes it crash if we call
eglDestroySurface() while we are rendering to it. This is
not according to the documentation, and it only seems to
happen on Mesa and only on Wayland, so it is probably
related to something in the Wayland implementation in the
driver.
Since this driver is very popular, we want to work around it,
which can easily be done using existing locking mechanisms
in the Qt Wayland QPA plugin. But in order to do so, we need
reliable callbacks for the start and end of a frame. The RHI
already has this, so we just need to channel the information
to the QPA plugin.
Having beginFrame/endFrame hooks in the QPlatformOpenGLContext
could be useful in other cases as well, especially knowing that
there are OpenGL implementations that require some extra thread
protection.
QPlatformSurface would be a more general location for these
hooks, but since the issue is only seen on OpenGL and
multi-threading is handled more explicitly in other APIs,
we don't want to expose this API in a more general location
than necessary.
Task-number: QTBUG-92249
Change-Id: I97ce7d4f744c4b28eec457e919d1c9652ff00079
Reviewed-by: Laszlo Agocs <laszlo.agocs@qt.io>
Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
-rw-r--r-- | src/gui/kernel/qplatformopenglcontext.cpp | 16 | ||||
-rw-r--r-- | src/gui/kernel/qplatformopenglcontext.h | 3 | ||||
-rw-r--r-- | src/gui/rhi/qrhigles2.cpp | 6 |
3 files changed, 25 insertions, 0 deletions
diff --git a/src/gui/kernel/qplatformopenglcontext.cpp b/src/gui/kernel/qplatformopenglcontext.cpp index 839ec008aa..048cbc6a4a 100644 --- a/src/gui/kernel/qplatformopenglcontext.cpp +++ b/src/gui/kernel/qplatformopenglcontext.cpp @@ -165,4 +165,20 @@ bool QPlatformOpenGLContext::parseOpenGLVersion(const QByteArray &versionString, return (majorOk && minorOk); } +/*! + Called when the RHI begins rendering a new frame in the context. Will always be paired with a + call to \l endFrame(). +*/ +void QPlatformOpenGLContext::beginFrame() +{ +} + +/*! + Called when the RHI ends rendering a in the context. Is always preceded by a call to + \l beginFrame(). +*/ +void QPlatformOpenGLContext::endFrame() +{ +} + QT_END_NAMESPACE diff --git a/src/gui/kernel/qplatformopenglcontext.h b/src/gui/kernel/qplatformopenglcontext.h index 034462e5f3..76cc992944 100644 --- a/src/gui/kernel/qplatformopenglcontext.h +++ b/src/gui/kernel/qplatformopenglcontext.h @@ -84,6 +84,9 @@ public: virtual bool makeCurrent(QPlatformSurface *surface) = 0; virtual void doneCurrent() = 0; + virtual void beginFrame(); + virtual void endFrame(); + virtual bool isSharing() const { return false; } virtual bool isValid() const { return true; } diff --git a/src/gui/rhi/qrhigles2.cpp b/src/gui/rhi/qrhigles2.cpp index aa1144a996..f0b97ce36a 100644 --- a/src/gui/rhi/qrhigles2.cpp +++ b/src/gui/rhi/qrhigles2.cpp @@ -43,6 +43,7 @@ #include <QOpenGLContext> #include <QtGui/private/qopenglextensions_p.h> #include <QtGui/private/qopenglprogrambinarycache_p.h> +#include <qpa/qplatformopenglcontext.h> #include <qmath.h> QT_BEGIN_NAMESPACE @@ -1769,6 +1770,8 @@ QRhi::FrameOpResult QRhiGles2::beginFrame(QRhiSwapChain *swapChain, QRhi::BeginF if (!ensureContext(swapChainD->surface)) return contextLost ? QRhi::FrameOpDeviceLost : QRhi::FrameOpError; + ctx->handle()->beginFrame(); + currentSwapChain = swapChainD; QRhiProfilerPrivate *rhiP = profilerPrivateOrNull(); @@ -1807,6 +1810,9 @@ QRhi::FrameOpResult QRhiGles2::endFrame(QRhiSwapChain *swapChain, QRhi::EndFrame swapChainD->frameCount += 1; currentSwapChain = nullptr; + + ctx->handle()->endFrame(); + return QRhi::FrameOpSuccess; } |