Improve GAL panel refresh logic.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/15041
This commit is contained in:
parent
55b31030c0
commit
7b5e725b98
|
@ -62,9 +62,11 @@ EDA_DRAW_PANEL_GAL::EDA_DRAW_PANEL_GAL( wxWindow* aParentWindow, wxWindowID aWin
|
|||
m_MouseCapturedLost( false ),
|
||||
m_parent( aParentWindow ),
|
||||
m_edaFrame( nullptr ),
|
||||
m_lastRepaint( 0 ),
|
||||
m_lastRepaintStart( 0 ),
|
||||
m_lastRepaintEnd( 0 ),
|
||||
m_drawing( false ),
|
||||
m_drawingEnabled( false ),
|
||||
m_needIdleRefresh( false ),
|
||||
m_gal( nullptr ),
|
||||
m_view( nullptr ),
|
||||
m_painter( nullptr ),
|
||||
|
@ -150,7 +152,7 @@ EDA_DRAW_PANEL_GAL::EDA_DRAW_PANEL_GAL( wxWindow* aParentWindow, wxWindowID aWin
|
|||
Connect( eventType, wxEventHandler( EDA_DRAW_PANEL_GAL::OnEvent ), nullptr,
|
||||
m_eventDispatcher );
|
||||
|
||||
// Set up timer that prevents too frequent redraw commands
|
||||
// Set up timer to detect when drawing starts
|
||||
m_refreshTimer.SetOwner( this );
|
||||
Connect( m_refreshTimer.GetId(), wxEVT_TIMER,
|
||||
wxTimerEventHandler( EDA_DRAW_PANEL_GAL::onRefreshTimer ), nullptr, this );
|
||||
|
@ -204,7 +206,7 @@ bool EDA_DRAW_PANEL_GAL::DoRePaint()
|
|||
if( m_drawing )
|
||||
return false;
|
||||
|
||||
m_lastRepaint = wxGetLocalTimeMillis();
|
||||
m_lastRepaintStart = wxGetLocalTimeMillis();
|
||||
|
||||
// Repaint the canvas, and fix scrollbar cursors
|
||||
// Usually called by a OnPaint event, but because it does not use a wxPaintDC,
|
||||
|
@ -334,6 +336,8 @@ bool EDA_DRAW_PANEL_GAL::DoRePaint()
|
|||
);
|
||||
}
|
||||
|
||||
m_lastRepaintEnd = wxGetLocalTimeMillis();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -378,26 +382,8 @@ void EDA_DRAW_PANEL_GAL::onSize( wxSizeEvent& aEvent )
|
|||
|
||||
void EDA_DRAW_PANEL_GAL::Refresh( bool aEraseBackground, const wxRect* aRect )
|
||||
{
|
||||
wxLongLong t = wxGetLocalTimeMillis();
|
||||
wxLongLong delta = t - m_lastRepaint;
|
||||
|
||||
int minRefreshPeriod = 13; // 77 FPS limit when v-sync not available.
|
||||
|
||||
if( m_gal && m_gal->IsInitialized() && m_gal->GetSwapInterval() != 0 )
|
||||
minRefreshPeriod = 3;
|
||||
|
||||
// If it has been too long since the last frame (possible depending on platform timer latency),
|
||||
// just do a refresh. Otherwise, start the refresh timer if it hasn't already been started.
|
||||
// This ensures that we will render often enough but not too often.
|
||||
if( delta >= minRefreshPeriod )
|
||||
{
|
||||
if( !DoRePaint() )
|
||||
m_refreshTimer.Start( minRefreshPeriod, true );
|
||||
}
|
||||
else if( !m_refreshTimer.IsRunning() )
|
||||
{
|
||||
m_refreshTimer.Start( ( minRefreshPeriod - delta ).ToLong(), true );
|
||||
}
|
||||
if( !DoRePaint() )
|
||||
m_needIdleRefresh = true;
|
||||
}
|
||||
|
||||
|
||||
|
@ -424,7 +410,10 @@ void EDA_DRAW_PANEL_GAL::StopDrawing()
|
|||
{
|
||||
m_refreshTimer.Stop();
|
||||
m_drawingEnabled = false;
|
||||
|
||||
Disconnect( wxEVT_PAINT, wxPaintEventHandler( EDA_DRAW_PANEL_GAL::onPaint ), nullptr, this );
|
||||
|
||||
Disconnect( wxEVT_IDLE, wxIdleEventHandler( EDA_DRAW_PANEL_GAL::onIdle ), nullptr, this );
|
||||
}
|
||||
|
||||
|
||||
|
@ -570,7 +559,16 @@ void EDA_DRAW_PANEL_GAL::OnEvent( wxEvent& aEvent )
|
|||
else
|
||||
m_eventDispatcher->DispatchWxEvent( aEvent );
|
||||
|
||||
Refresh();
|
||||
// Give events time to process, based on last render duration
|
||||
wxLongLong endDelta = wxGetLocalTimeMillis() - m_lastRepaintEnd;
|
||||
long long timeLimit = ( m_lastRepaintEnd - m_lastRepaintStart ).GetValue() / 5;
|
||||
|
||||
timeLimit = std::clamp( timeLimit, 3LL, 150LL );
|
||||
|
||||
if( endDelta > timeLimit )
|
||||
Refresh();
|
||||
else
|
||||
m_needIdleRefresh = true;
|
||||
}
|
||||
|
||||
|
||||
|
@ -599,6 +597,18 @@ void EDA_DRAW_PANEL_GAL::onLostFocus( wxFocusEvent& aEvent )
|
|||
}
|
||||
|
||||
|
||||
void EDA_DRAW_PANEL_GAL::onIdle( wxIdleEvent& aEvent )
|
||||
{
|
||||
if( m_needIdleRefresh )
|
||||
{
|
||||
m_needIdleRefresh = false;
|
||||
Refresh();
|
||||
}
|
||||
|
||||
aEvent.Skip();
|
||||
}
|
||||
|
||||
|
||||
void EDA_DRAW_PANEL_GAL::onRefreshTimer( wxTimerEvent& aEvent )
|
||||
{
|
||||
if( !m_drawingEnabled )
|
||||
|
@ -607,6 +617,9 @@ void EDA_DRAW_PANEL_GAL::onRefreshTimer( wxTimerEvent& aEvent )
|
|||
{
|
||||
Connect( wxEVT_PAINT, wxPaintEventHandler( EDA_DRAW_PANEL_GAL::onPaint ), nullptr,
|
||||
this );
|
||||
|
||||
Connect( wxEVT_IDLE, wxIdleEventHandler( EDA_DRAW_PANEL_GAL::onIdle ), nullptr, this );
|
||||
|
||||
m_drawingEnabled = true;
|
||||
}
|
||||
else
|
||||
|
|
|
@ -333,7 +333,7 @@ void EDA_DRAW_FRAME::CommonSettingsChanged( bool aEnvVarsChanged, bool aTextVars
|
|||
if( m_canvasType != GetCanvas()->GetBackend() )
|
||||
{
|
||||
// Try to switch (will automatically fallback if necessary)
|
||||
GetCanvas()->SwitchBackend( m_canvasType );
|
||||
SwitchCanvas( m_canvasType );
|
||||
EDA_DRAW_PANEL_GAL::GAL_TYPE newGAL = GetCanvas()->GetBackend();
|
||||
bool success = newGAL == m_canvasType;
|
||||
|
||||
|
|
|
@ -1020,9 +1020,6 @@ bool TOOL_MANAGER::ProcessEvent( const TOOL_EVENT& aEvent )
|
|||
|
||||
if( m_view && m_view->IsDirty() )
|
||||
{
|
||||
if( GetToolHolder() )
|
||||
GetToolHolder()->RefreshCanvas();
|
||||
|
||||
#if defined( __WXMAC__ )
|
||||
wxTheApp->ProcessPendingEvents(); // required for updating brightening behind a popup menu
|
||||
#endif
|
||||
|
|
|
@ -405,7 +405,6 @@ void WX_VIEW_CONTROLS::onWheel( wxMouseEvent& aEvent )
|
|||
// Do not skip this event, otherwise wxWidgets will fire
|
||||
// 3 wxEVT_SCROLLWIN_LINEUP or wxEVT_SCROLLWIN_LINEDOWN (normal wxWidgets behavior)
|
||||
// and we do not want that.
|
||||
m_parentPanel->Refresh();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -254,13 +254,15 @@ protected:
|
|||
void onSize( wxSizeEvent& aEvent );
|
||||
void onEnter( wxMouseEvent& aEvent );
|
||||
void onLostFocus( wxFocusEvent& aEvent );
|
||||
void onIdle( wxIdleEvent& aEvent );
|
||||
void onRefreshTimer( wxTimerEvent& aEvent );
|
||||
void onShowTimer( wxTimerEvent& aEvent );
|
||||
|
||||
wxWindow* m_parent; ///< Pointer to the parent window
|
||||
EDA_DRAW_FRAME* m_edaFrame; ///< Parent EDA_DRAW_FRAME (if available)
|
||||
|
||||
wxLongLong m_lastRepaint; ///< Timestamp of the last repaint start
|
||||
wxLongLong m_lastRepaintStart; ///< Timestamp of the last repaint start
|
||||
wxLongLong m_lastRepaintEnd; ///< Timestamp of the last repaint end
|
||||
wxTimer m_refreshTimer; ///< Timer to prevent too-frequent refreshing
|
||||
|
||||
std::mutex m_refreshMutex; ///< Blocks multiple calls to the draw
|
||||
|
@ -271,6 +273,9 @@ protected:
|
|||
/// Flag that determines if VIEW may use GAL for redrawing the screen.
|
||||
bool m_drawingEnabled;
|
||||
|
||||
/// True when canvas needs to be refreshed from idle handler
|
||||
bool m_needIdleRefresh;
|
||||
|
||||
/// Timer used to execute OnShow() when the window finally appears on the screen.
|
||||
wxTimer m_onShowTimer;
|
||||
|
||||
|
|
Loading…
Reference in New Issue