7
mirror of https://gitlab.com/kicad/code/kicad.git synced 2025-04-19 23:31:40 +00:00

Avoid GL ctx deadlock

Allow non-drawing routines to access error messages without dealocking
the load
This commit is contained in:
Seth Hillbrand 2024-09-06 13:34:07 -07:00
parent 304d9e0006
commit be2a52dd2b
3 changed files with 56 additions and 2 deletions
3d-viewer/3d_rendering/opengl
common
include/gal/opengl

View File

@ -32,6 +32,7 @@
#include "common_ogl/ogl_utils.h"
#include <board.h>
#include <footprint.h>
#include <gal/opengl/gl_context_mgr.h>
#include <3d_math.h>
#include <glm/geometric.hpp>
#include <lset.h>
@ -486,7 +487,13 @@ bool RENDER_3D_OPENGL::Redraw( bool aIsMoving, REPORTER* aStatusReporter,
if( aStatusReporter )
aStatusReporter->Report( _( "Loading..." ) );
reload( aStatusReporter, aWarningReporter );
// Careful here!
// We are in the middle of rendering and the reload method may show
// a dialog box that requires the opengl context for a redraw
GL_CONTEXT_MANAGER::Get().RunWithoutCtxLock( [this, aStatusReporter, aWarningReporter]()
{
reload( aStatusReporter, aWarningReporter );
} );
// generate a new 3D grid as the size of the board may had changed
m_lastGridType = static_cast<GRID3D_TYPE>( cfg.grid_type );

View File

@ -204,7 +204,7 @@ bool EDA_DRAW_PANEL_GAL::DoRePaint()
if( !m_drawingEnabled )
return false;
if( !m_gal->IsInitialized() || !m_gal->IsVisible() )
if( !m_gal->IsInitialized() || !m_gal->IsVisible() || m_gal->IsContextLocked() )
return false;
if( m_drawing )

View File

@ -86,6 +86,53 @@ public:
*/
void UnlockCtx( wxGLContext* aContext );
/**
* Get the currently bound GL context.
*
* @return the currently bound GL context.
*/
wxGLContext* GetCurrentCtx() const
{
return m_glCtx;
}
/**
* Get the currently bound GL canvas.
*
* @return the currently bound GL canvas.
*/
wxGLCanvas* GetCurrentCanvas() const
{
auto it = m_glContexts.find( m_glCtx );
return it != m_glContexts.end() ? it->second : nullptr;
}
/**
* Run the given function first releasing the GL context lock, then restoring it.
*
* @param aFunction is the function to be executed.
*/
template<typename Func, typename... Args>
auto RunWithoutCtxLock( Func&& aFunction, Args&&... args )
{
wxGLContext* currentCtx = GetCurrentCtx();
wxGLCanvas* currentCanvas = GetCurrentCanvas();
UnlockCtx( currentCtx );
if constexpr (std::is_void_v<decltype(aFunction(std::forward<Args>(args)...))>)
{
std::forward<Func>(aFunction)(std::forward<Args>(args)...);
LockCtx( currentCtx, currentCanvas );
return;
}
else
{
auto result = std::forward<Func>(aFunction)(std::forward<Args>(args)...);
LockCtx( currentCtx, currentCanvas );
return result;
}
}
private:
///< Map of GL contexts & their parent canvases.
std::map<wxGLContext*, wxGLCanvas*> m_glContexts;