Don't crash when getting multiple wx calls

Multiple size calls will assert trying to re-lock the GAL context.  Just
skip the second one.
This commit is contained in:
Seth Hillbrand 2021-01-09 12:13:46 -08:00
parent 751fdbf278
commit ffb3748cfc
4 changed files with 29 additions and 11 deletions

View File

@ -257,6 +257,10 @@ void EDA_DRAW_PANEL_GAL::DoRePaint()
void EDA_DRAW_PANEL_GAL::onSize( wxSizeEvent& aEvent ) void EDA_DRAW_PANEL_GAL::onSize( wxSizeEvent& aEvent )
{ {
// If we get a second wx update call before the first finishes, don't crash
if( m_gal->IsContextLocked() )
return;
KIGFX::GAL_CONTEXT_LOCKER locker( m_gal ); KIGFX::GAL_CONTEXT_LOCKER locker( m_gal );
wxSize clientSize = GetClientSize(); wxSize clientSize = GetClientSize();
WX_INFOBAR* infobar = GetParentEDAFrame() ? GetParentEDAFrame()->GetInfoBar() : nullptr; WX_INFOBAR* infobar = GetParentEDAFrame() ? GetParentEDAFrame()->GetInfoBar() : nullptr;
@ -617,4 +621,4 @@ void EDA_DRAW_PANEL_GAL::ClearDebugOverlay()
m_view->Remove( m_debugOverlay.get() ); m_view->Remove( m_debugOverlay.get() );
m_debugOverlay = nullptr; m_debugOverlay = nullptr;
} }
} }

View File

@ -207,7 +207,7 @@ OPENGL_GAL::OPENGL_GAL( GAL_DISPLAY_OPTIONS& aDisplayOptions, wxWindow* aParent,
overlayManager( nullptr ), overlayManager( nullptr ),
mainBuffer( 0 ), mainBuffer( 0 ),
overlayBuffer( 0 ), overlayBuffer( 0 ),
isContextLocked( false ), m_isContextLocked( false ),
lockClientCookie( 0 ) lockClientCookie( 0 )
{ {
if( glMainContext == NULL ) if( glMainContext == NULL )
@ -412,7 +412,7 @@ void OPENGL_GAL::beginDrawing()
PROF_COUNTER totalRealTime( "OPENGL_GAL::beginDrawing()", true ); PROF_COUNTER totalRealTime( "OPENGL_GAL::beginDrawing()", true );
#endif /* __WXDEBUG__ */ #endif /* __WXDEBUG__ */
wxASSERT_MSG( isContextLocked, "GAL_DRAWING_CONTEXT RAII object should have locked context. " wxASSERT_MSG( m_isContextLocked, "GAL_DRAWING_CONTEXT RAII object should have locked context. "
"Calling GAL::beginDrawing() directly is not allowed." ); "Calling GAL::beginDrawing() directly is not allowed." );
wxASSERT_MSG( IsVisible(), "GAL::beginDrawing() must not be entered when GAL is not visible. " wxASSERT_MSG( IsVisible(), "GAL::beginDrawing() must not be entered when GAL is not visible. "
@ -556,7 +556,7 @@ void OPENGL_GAL::beginDrawing()
void OPENGL_GAL::endDrawing() void OPENGL_GAL::endDrawing()
{ {
wxASSERT_MSG( isContextLocked, "What happened to the context lock?" ); wxASSERT_MSG( m_isContextLocked, "What happened to the context lock?" );
#ifdef __WXDEBUG__ #ifdef __WXDEBUG__
PROF_COUNTER totalRealTime( "OPENGL_GAL::endDrawing()", true ); PROF_COUNTER totalRealTime( "OPENGL_GAL::endDrawing()", true );
@ -595,8 +595,8 @@ void OPENGL_GAL::endDrawing()
void OPENGL_GAL::lockContext( int aClientCookie ) void OPENGL_GAL::lockContext( int aClientCookie )
{ {
wxASSERT_MSG( !isContextLocked, "Context already locked." ); wxASSERT_MSG( !m_isContextLocked, "Context already locked." );
isContextLocked = true; m_isContextLocked = true;
lockClientCookie = aClientCookie; lockClientCookie = aClientCookie;
GL_CONTEXT_MANAGER::Get().LockCtx( glPrivContext, this ); GL_CONTEXT_MANAGER::Get().LockCtx( glPrivContext, this );
@ -605,13 +605,13 @@ void OPENGL_GAL::lockContext( int aClientCookie )
void OPENGL_GAL::unlockContext( int aClientCookie ) void OPENGL_GAL::unlockContext( int aClientCookie )
{ {
wxASSERT_MSG( isContextLocked, "Context not locked. A GAL_CONTEXT_LOCKER RAII object must " wxASSERT_MSG( m_isContextLocked, "Context not locked. A GAL_CONTEXT_LOCKER RAII object must "
"be stacked rather than making separate lock/unlock calls." ); "be stacked rather than making separate lock/unlock calls." );
wxASSERT_MSG( lockClientCookie == aClientCookie, "Context was locked by a different client. " wxASSERT_MSG( lockClientCookie == aClientCookie, "Context was locked by a different client. "
"Should not be possible with RAII objects." ); "Should not be possible with RAII objects." );
isContextLocked = false; m_isContextLocked = false;
GL_CONTEXT_MANAGER::Get().UnlockCtx( glPrivContext ); GL_CONTEXT_MANAGER::Get().UnlockCtx( glPrivContext );
} }
@ -619,7 +619,7 @@ void OPENGL_GAL::unlockContext( int aClientCookie )
void OPENGL_GAL::beginUpdate() void OPENGL_GAL::beginUpdate()
{ {
wxASSERT_MSG( isContextLocked, "GAL_UPDATE_CONTEXT RAII object should have locked context. " wxASSERT_MSG( m_isContextLocked, "GAL_UPDATE_CONTEXT RAII object should have locked context. "
"Calling this from anywhere else is not allowed." ); "Calling this from anywhere else is not allowed." );
wxASSERT_MSG( IsVisible(), "GAL::beginUpdate() must not be entered when GAL is not visible. " wxASSERT_MSG( IsVisible(), "GAL::beginUpdate() must not be entered when GAL is not visible. "
@ -2099,7 +2099,7 @@ void OPENGL_GAL::init()
wxASSERT( IsShownOnScreen() ); wxASSERT( IsShownOnScreen() );
wxASSERT_MSG( isContextLocked, "This should only be called from within a locked context." ); wxASSERT_MSG( m_isContextLocked, "This should only be called from within a locked context." );
// IsDisplayAttr() handles WX_GL_{MAJOR,MINOR}_VERSION correctly only in 3.0.4 // IsDisplayAttr() handles WX_GL_{MAJOR,MINOR}_VERSION correctly only in 3.0.4
// starting with 3.1.0 one should use wxGLContext::IsOk() (done by GL_CONTEXT_MANAGER) // starting with 3.1.0 one should use wxGLContext::IsOk() (done by GL_CONTEXT_MANAGER)

View File

@ -1016,6 +1016,15 @@ public:
virtual void EnableDepthTest( bool aEnabled = false ) {}; virtual void EnableDepthTest( bool aEnabled = false ) {};
/**
* Checks the state of the context lock
* @return True if the context is currently locked
*/
virtual bool IsContextLocked()
{
return false;
}
protected: protected:
/// Private: use GAL_CONTEXT_LOCKER RAII object /// Private: use GAL_CONTEXT_LOCKER RAII object
virtual void lockContext( int aClientCookie ) {} virtual void lockContext( int aClientCookie ) {}

View File

@ -270,6 +270,11 @@ public:
void EnableDepthTest( bool aEnabled = false ) override; void EnableDepthTest( bool aEnabled = false ) override;
bool IsContextLocked() override
{
return m_isContextLocked;
}
///< Parameters passed to the GLU tesselator ///< Parameters passed to the GLU tesselator
typedef struct typedef struct
{ {
@ -320,7 +325,7 @@ private:
bool isInitialized; ///< Basic initialization flag, has to be done bool isInitialized; ///< Basic initialization flag, has to be done
///< when the window is visible ///< when the window is visible
bool isGrouping; ///< Was a group started? bool isGrouping; ///< Was a group started?
bool isContextLocked; ///< Used for assertion checking bool m_isContextLocked; ///< Used for assertion checking
int lockClientCookie; int lockClientCookie;
GLint ufm_worldPixelSize; GLint ufm_worldPixelSize;
GLint ufm_screenPixelSize; GLint ufm_screenPixelSize;