From f0309c95e096fe0b4d803666c6547168500f4be9 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Thu, 6 Nov 2025 23:25:48 +0100 Subject: [PATCH 1/2] Add wxGLContext::ClearCurrent() This function allows to reset the current OpenGL context. Closes #25951. --- include/wx/glcanvas.h | 3 +++ interface/wx/glcanvas.h | 10 ++++++++++ src/msw/glcanvas.cpp | 6 ++++++ src/osx/cocoa/glcanvas.mm | 6 ++++++ src/qt/glcanvas.cpp | 8 ++++++++ src/unix/glegl.cpp | 7 +++++++ src/unix/glx11.cpp | 6 ++++++ 7 files changed, 46 insertions(+) diff --git a/include/wx/glcanvas.h b/include/wx/glcanvas.h index e67b49968f..2518d69f00 100644 --- a/include/wx/glcanvas.h +++ b/include/wx/glcanvas.h @@ -188,6 +188,9 @@ public: // set this context as the current one virtual bool SetCurrent(const wxGLCanvas& win) const = 0; + // unset any currently set context + static void ClearCurrent(); + bool IsOK() const { return m_isOk; } protected: diff --git a/interface/wx/glcanvas.h b/interface/wx/glcanvas.h index 1a63e72877..dcc0781059 100644 --- a/interface/wx/glcanvas.h +++ b/interface/wx/glcanvas.h @@ -535,6 +535,16 @@ public: equivalent, see wxGLCanvas::SetCurrent(). */ virtual bool SetCurrent(const wxGLCanvas& win) const; + + /** + Clears any currently set context. + + After calling this function, no OpenGL operations can be performed + until a new context is made current. + + @since 3.3.2 + */ + static void ClearCurrent(); }; /** diff --git a/src/msw/glcanvas.cpp b/src/msw/glcanvas.cpp index 21fb453622..360d842a2e 100644 --- a/src/msw/glcanvas.cpp +++ b/src/msw/glcanvas.cpp @@ -622,6 +622,12 @@ bool wxGLContext::SetCurrent(const wxGLCanvas& win) const return true; } +/* static */ +void wxGLContextBase::ClearCurrent() +{ + wglMakeCurrent(nullptr, nullptr); +} + // ============================================================================ // wxGLCanvas // ============================================================================ diff --git a/src/osx/cocoa/glcanvas.mm b/src/osx/cocoa/glcanvas.mm index 823109cd74..a7a1ff858f 100644 --- a/src/osx/cocoa/glcanvas.mm +++ b/src/osx/cocoa/glcanvas.mm @@ -207,4 +207,10 @@ bool wxGLContext::SetCurrent(const wxGLCanvas& win) const return true; } +/* static */ +void wxGLContextBase::ClearCurrent() +{ + [NSOpenGLContext clearCurrentContext]; +} + #endif // wxUSE_GLCANVAS diff --git a/src/qt/glcanvas.cpp b/src/qt/glcanvas.cpp index 854f0d2676..7e0fc8f52e 100644 --- a/src/qt/glcanvas.cpp +++ b/src/qt/glcanvas.cpp @@ -12,6 +12,7 @@ #include "wx/qt/private/winevent.h" #include "wx/glcanvas.h" +#include #include #include #include @@ -365,6 +366,13 @@ bool wxGLContext::SetCurrent(const wxGLCanvas& win) const return true; } +/* static */ +void wxGLContextBase::ClearCurrent() +{ + if (auto* const current = QOpenGLContext::currentContext()) + current->doneCurrent(); +} + //--------------------------------------------------------------------------- // PanGestureRecognizer - helper class for wxGLCanvas //--------------------------------------------------------------------------- diff --git a/src/unix/glegl.cpp b/src/unix/glegl.cpp index 0b774d2c9f..a4cdff2a52 100644 --- a/src/unix/glegl.cpp +++ b/src/unix/glegl.cpp @@ -327,6 +327,13 @@ bool wxGLContext::SetCurrent(const wxGLCanvas& win) const win.GetEGLSurface(), m_glContext); } +/* static */ +void wxGLContextBase::ClearCurrent() +{ + eglMakeCurrent(wxGLCanvasEGL::GetDisplay(), EGL_NO_SURFACE, + EGL_NO_SURFACE, EGL_NO_CONTEXT); +} + // ============================================================================ // wxGLCanvasEGL implementation // ============================================================================ diff --git a/src/unix/glx11.cpp b/src/unix/glx11.cpp index df18704f20..d516b2ffcc 100644 --- a/src/unix/glx11.cpp +++ b/src/unix/glx11.cpp @@ -580,6 +580,12 @@ bool wxGLContext::SetCurrent(const wxGLCanvas& win) const return MakeCurrent(xid, m_glContext); } +/* static */ +void wxGLContextBase::ClearCurrent() +{ + MakeCurrent(None, nullptr); +} + // wrapper around glXMakeContextCurrent/glXMakeCurrent depending on GLX // version static bool MakeCurrent(GLXDrawable drawable, GLXContext context) From 15a85fb319c281756f24c0f30851cdefccb5e36e Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Thu, 6 Nov 2025 23:29:35 +0100 Subject: [PATCH 2/2] Use ClearCurrent() in wxGLContext dtor in Unix implementations No real changes, just reuse the just added function for clarity instead of duplicating its (trivial) code in the dtor. --- src/unix/glegl.cpp | 3 +-- src/unix/glx11.cpp | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/unix/glegl.cpp b/src/unix/glegl.cpp index a4cdff2a52..78f8f3a6e0 100644 --- a/src/unix/glegl.cpp +++ b/src/unix/glegl.cpp @@ -312,8 +312,7 @@ wxGLContext::~wxGLContext() return; if ( m_glContext == eglGetCurrentContext() ) - eglMakeCurrent(wxGLCanvasEGL::GetDisplay(), EGL_NO_SURFACE, - EGL_NO_SURFACE, EGL_NO_CONTEXT); + ClearCurrent(); eglDestroyContext(wxGLCanvasEGL::GetDisplay(), m_glContext); } diff --git a/src/unix/glx11.cpp b/src/unix/glx11.cpp index d516b2ffcc..f867c0b053 100644 --- a/src/unix/glx11.cpp +++ b/src/unix/glx11.cpp @@ -564,7 +564,7 @@ wxGLContext::~wxGLContext() return; if ( m_glContext == glXGetCurrentContext() ) - MakeCurrent(None, nullptr); + ClearCurrent(); glXDestroyContext( wxGetX11Display(), m_glContext ); }