summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLaszlo Agocs <laszlo.agocs@qt.io>2021-11-17 18:23:21 +0100
committerLaszlo Agocs <laszlo.agocs@qt.io>2021-11-26 14:22:05 +0100
commitc1899ca310cbd3a4ce5e8454a01a22638beb8d73 (patch)
tree9a1d3997218fecb7a64aabb1d78db14d3c8e92bd /src
parent24022bc76080f1881755df839b41a1003a1ed125 (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.cpp34
-rw-r--r--src/gui/rhi/qrhigles2_p_p.h2
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 {