From 3d785b9b6869f18f449f42f112129fd9ca16f5a0 Mon Sep 17 00:00:00 2001 From: baldurk Date: Tue, 14 Sep 2021 17:54:48 +0100 Subject: [PATCH] Try to rebind user DC first when pushing/popping GL contexts. Refs #2361 * In the old codepath for a valid existing window we'd create a cloned DC and use that to pop with. However that DC is then released so we have created the 'stale DC' situation. This can cause problems with subsequent context activations when we try to push/pop to populate GL hooks and fail to pop properly as the queried DC is invalid. --- renderdoc/driver/gl/wgl_hooks.cpp | 10 +++++++++- renderdoc/driver/gl/wgl_platform.cpp | 14 ++++++++++---- 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/renderdoc/driver/gl/wgl_hooks.cpp b/renderdoc/driver/gl/wgl_hooks.cpp index 21b901182..df03e886f 100644 --- a/renderdoc/driver/gl/wgl_hooks.cpp +++ b/renderdoc/driver/gl/wgl_hooks.cpp @@ -101,7 +101,15 @@ void WGLHook::PopulateFromContext(HDC dc, HGLRC rc) }); // restore DC/context - WGL.wglMakeCurrent(prevDC, prevContext); + if(!WGL.wglMakeCurrent(prevDC, prevContext)) + { + RDCWARN( + "Couldn't restore prev context %p with prev DC %p - possibly stale. Using new DC %p to " + "ensure context is rebound properly", + prevContext, prevDC, dc); + + WGL.wglMakeCurrent(dc, prevContext); + } } } diff --git a/renderdoc/driver/gl/wgl_platform.cpp b/renderdoc/driver/gl/wgl_platform.cpp index 752fa1c96..173867206 100644 --- a/renderdoc/driver/gl/wgl_platform.cpp +++ b/renderdoc/driver/gl/wgl_platform.cpp @@ -70,10 +70,16 @@ class WGLPlatform : public GLPlatform virtual void PopChildContext(GLWindowingData existing, GLWindowingData newChild, GLWindowingData saved) { - MakeContextCurrent(saved); - // release the DC now, if we didn't use our own because theirs was invalid - if(saved.DC != newChild.DC) - ::ReleaseDC(saved.wnd, saved.DC); + // if possible we want to use the existing DC so that we have a valid DC for further work (the + // cloned one we're making is going to be destroyed). First try to rebind the existing as-is, + // and only if that fails - e.g. due to a stale DC - use our cloned one to rebind the context + if(!MakeContextCurrent(existing)) + { + MakeContextCurrent(saved); + // release the DC now, if we didn't use our own because theirs was invalid + if(saved.DC != newChild.DC) + ::ReleaseDC(saved.wnd, saved.DC); + } } GLWindowingData CloneTemporaryContext(GLWindowingData share) {