From 4bc295241994409a77b9227943650e59d95ef3d0 Mon Sep 17 00:00:00 2001 From: reuk Date: Wed, 23 Oct 2024 19:17:53 +0100 Subject: [PATCH] OpenGL: Set up context sharing on the GL thread, rather than the main thread wglShareLists will only succeed when the shared context is not currently active on another thread, but it is difficult to ensure that the GL thread is paused/inactive at any given time - in particular, it's very easy to accidentally introduce deadlocks where the main thread waits for the render thread's lock while the render thread waits for the messagemanager lock. The simplest way to ensure that no other thread has activated the shared context is to share the contexts directly on the render thread itself. --- .../juce_opengl/native/juce_OpenGL_windows.h | 25 ++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/modules/juce_opengl/native/juce_OpenGL_windows.h b/modules/juce_opengl/native/juce_OpenGL_windows.h index 4c8ef365c1..47faf717d2 100644 --- a/modules/juce_opengl/native/juce_OpenGL_windows.h +++ b/modules/juce_opengl/native/juce_OpenGL_windows.h @@ -47,6 +47,7 @@ public: void* contextToShareWithIn, bool /*useMultisampling*/, OpenGLVersion version) + : sharedContext (contextToShareWithIn) { placeholderComponent.reset (new PlaceholderComponent (*this)); createNativeWindow (component); @@ -84,9 +85,6 @@ public: } } - if (contextToShareWithIn != nullptr) - wglShareLists ((HGLRC) contextToShareWithIn, renderContext.get()); - component.getTopLevelComponent()->repaint(); component.repaint(); } @@ -107,6 +105,26 @@ public: { threadAwarenessSetter = std::make_unique (nativeWindow->getNativeHandle()); context = &c; + + if (sharedContext != nullptr) + { + if (! wglShareLists ((HGLRC) sharedContext, renderContext.get())) + { + TCHAR messageBuffer[256] = {}; + + FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, + nullptr, + GetLastError(), + MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT), + messageBuffer, + (DWORD) numElementsInArray (messageBuffer) - 1, + nullptr); + + DBG (messageBuffer); + jassertfalse; + } + } + return InitResult::success; } @@ -405,6 +423,7 @@ private: std::unique_ptr, RenderContextDeleter> renderContext; std::unique_ptr, DeviceContextDeleter> dc; OpenGLContext* context = nullptr; + void* sharedContext = nullptr; double nativeScaleFactor = 1.0; //==============================================================================