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>
This commit is contained in:
parent
24022bc760
commit
c1899ca310
@ -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();
|
||||
}
|
||||
|
@ -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 {
|
||||
|
Loading…
x
Reference in New Issue
Block a user