diff options
author | Laszlo Agocs <laszlo.agocs@qt.io> | 2021-11-17 18:23:21 +0100 |
---|---|---|
committer | Laszlo Agocs <laszlo.agocs@qt.io> | 2021-11-26 14:22:05 +0100 |
commit | c1899ca310cbd3a4ce5e8454a01a22638beb8d73 (patch) | |
tree | 9a1d3997218fecb7a64aabb1d78db14d3c8e92bd /src | |
parent | 24022bc76080f1881755df839b41a1003a1ed125 (diff) |
rhi: gl: Optimize context/surface changes
When there is a context with a surface current, keep on using
that whenever ensureContext() is called without specifying a
QWindow.
Consider the following sequence:
<component A>
beginOffscreenFrame
render to texture 1
endOffscreenFrame
<component B>
beginOffscreenFrame
render to texture 2
endOffscreenFrame
<component C>
beginFrame (with swapchain)
render something using texture 1 and 2
endFrame
repeat all over again, continuously
(in practice this is what a top level widget with QOpenGLWidgets
and/or QQuickWidgets in it would lead to with the QRhi migration
in place)
Besides being more readable, the new version recognizes that resource
and offscreen operations do not need one specific surface (like the
one QOffscreenSurface every GL backend of QRhi has), but are functional
with any surface (or with surfaceless even) as long as the context is
correct. Thus with the above example we can work with only ever making
the one QWindow current.
Change-Id: I633071cae88f02e1d45e445ee55c8a58f9ec5a8c
Pick-to: 6.2
Fixes: QTBUG-96405
Reviewed-by: Andy Nichols <andy.nichols@qt.io>
Diffstat (limited to 'src')
-rw-r--r-- | src/gui/rhi/qrhigles2.cpp | 34 | ||||
-rw-r--r-- | src/gui/rhi/qrhigles2_p_p.h | 2 |
2 files changed, 24 insertions, 12 deletions
diff --git a/src/gui/rhi/qrhigles2.cpp b/src/gui/rhi/qrhigles2.cpp index 4512acb969..aa1144a996 100644 --- a/src/gui/rhi/qrhigles2.cpp +++ b/src/gui/rhi/qrhigles2.cpp @@ -501,21 +501,33 @@ QRhiGles2::QRhiGles2(QRhiGles2InitParams *params, QRhiGles2NativeHandles *import } } +static inline QSurface *currentSurfaceForCurrentContext(QOpenGLContext *ctx) +{ + if (QOpenGLContext::currentContext() != ctx) + return nullptr; + + QSurface *currentSurface = ctx->surface(); + if (!currentSurface) + return nullptr; + + if (currentSurface->surfaceClass() == QSurface::Window && !currentSurface->surfaceHandle()) + return nullptr; + + return currentSurface; +} + bool QRhiGles2::ensureContext(QSurface *surface) const { - bool nativeWindowGone = false; - if (surface && surface->surfaceClass() == QSurface::Window && !surface->surfaceHandle()) { + if (!surface) { + if (currentSurfaceForCurrentContext(ctx)) + return true; surface = fallbackSurface; - nativeWindowGone = true; - } - - if (!surface) + } else if (surface->surfaceClass() == QSurface::Window && !surface->surfaceHandle()) { surface = fallbackSurface; - - if (needsMakeCurrent) - needsMakeCurrent = false; - else if (!nativeWindowGone && QOpenGLContext::currentContext() == ctx && (surface == fallbackSurface || ctx->surface() == surface)) + } else if (!needsMakeCurrentDueToSwap && currentSurfaceForCurrentContext(ctx) == surface) { return true; + } + needsMakeCurrentDueToSwap = false; if (!ctx->makeCurrent(surface)) { if (ctx->isValid()) { @@ -1788,7 +1800,7 @@ QRhi::FrameOpResult QRhiGles2::endFrame(QRhiSwapChain *swapChain, QRhi::EndFrame if (swapChainD->surface && !flags.testFlag(QRhi::SkipPresent)) { ctx->swapBuffers(swapChainD->surface); - needsMakeCurrent = true; + needsMakeCurrentDueToSwap = true; } else { f->glFlush(); } diff --git a/src/gui/rhi/qrhigles2_p_p.h b/src/gui/rhi/qrhigles2_p_p.h index c3297f488d..6ee6af8fc5 100644 --- a/src/gui/rhi/qrhigles2_p_p.h +++ b/src/gui/rhi/qrhigles2_p_p.h @@ -902,7 +902,7 @@ public: QSurface *fallbackSurface = nullptr; QWindow *maybeWindow = nullptr; QOpenGLContext *maybeShareContext = nullptr; - mutable bool needsMakeCurrent = false; + mutable bool needsMakeCurrentDueToSwap = false; QOpenGLExtensions *f = nullptr; uint vao = 0; struct Caps { |