GAL: improve redraw handling, allowing higher refresh rates.
minRefreshPeriod can't be set in SwitchBackend because OpenGL isn't initialized yet.
This commit is contained in:
parent
ef6866757e
commit
940f92a44f
|
@ -62,8 +62,7 @@ EDA_DRAW_PANEL_GAL::EDA_DRAW_PANEL_GAL( wxWindow* aParentWindow, wxWindowID aWin
|
|||
m_MouseCapturedLost( false ),
|
||||
m_parent( aParentWindow ),
|
||||
m_edaFrame( nullptr ),
|
||||
m_lastRefresh( 0 ),
|
||||
m_pendingRefresh( false ),
|
||||
m_lastRepaint( 0 ),
|
||||
m_drawing( false ),
|
||||
m_drawingEnabled( false ),
|
||||
m_gal( nullptr ),
|
||||
|
@ -79,8 +78,6 @@ EDA_DRAW_PANEL_GAL::EDA_DRAW_PANEL_GAL( wxWindow* aParentWindow, wxWindowID aWin
|
|||
{
|
||||
m_PaintEventCounter = std::make_unique<PROF_COUNTER>( "Draw panel paint events" );
|
||||
|
||||
m_minRefreshPeriod = 13; // 77 FPS (minus render time) by default
|
||||
|
||||
SetLayoutDirection( wxLayout_LeftToRight );
|
||||
|
||||
m_edaFrame = dynamic_cast<EDA_DRAW_FRAME*>( m_parent );
|
||||
|
@ -191,13 +188,24 @@ void EDA_DRAW_PANEL_GAL::onPaint( wxPaintEvent& WXUNUSED( aEvent ) )
|
|||
}
|
||||
|
||||
|
||||
void EDA_DRAW_PANEL_GAL::DoRePaint()
|
||||
bool EDA_DRAW_PANEL_GAL::DoRePaint()
|
||||
{
|
||||
if( !m_refreshMutex.try_lock() )
|
||||
return;
|
||||
return false;
|
||||
|
||||
std::lock_guard<std::mutex> lock( m_refreshMutex, std::adopt_lock );
|
||||
|
||||
if( !m_drawingEnabled )
|
||||
return false;
|
||||
|
||||
if( !m_gal->IsInitialized() || !m_gal->IsVisible() )
|
||||
return false;
|
||||
|
||||
if( m_drawing )
|
||||
return false;
|
||||
|
||||
m_lastRepaint = wxGetLocalTimeMillis();
|
||||
|
||||
// Repaint the canvas, and fix scrollbar cursors
|
||||
// Usually called by a OnPaint event, but because it does not use a wxPaintDC,
|
||||
// it can be called outside a wxPaintEvent.
|
||||
|
@ -210,17 +218,6 @@ void EDA_DRAW_PANEL_GAL::DoRePaint()
|
|||
if( Pgm().GetCommonSettings()->m_Appearance.show_scrollbars )
|
||||
m_viewControls->UpdateScrollbars();
|
||||
|
||||
if( !m_drawingEnabled )
|
||||
return;
|
||||
|
||||
if( !m_gal->IsInitialized() || !m_gal->IsVisible() )
|
||||
return;
|
||||
|
||||
m_pendingRefresh = false;
|
||||
|
||||
if( m_drawing )
|
||||
return;
|
||||
|
||||
SCOPED_SET_RESET<bool> drawing( m_drawing, true );
|
||||
|
||||
( *m_PaintEventCounter )++;
|
||||
|
@ -337,7 +334,7 @@ void EDA_DRAW_PANEL_GAL::DoRePaint()
|
|||
);
|
||||
}
|
||||
|
||||
m_lastRefresh = wxGetLocalTimeMillis();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
@ -382,28 +379,30 @@ 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_lastRefresh;
|
||||
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 >= m_minRefreshPeriod )
|
||||
if( delta >= minRefreshPeriod )
|
||||
{
|
||||
if( !m_pendingRefresh )
|
||||
ForceRefresh();
|
||||
|
||||
m_refreshTimer.Start( m_minRefreshPeriod, true );
|
||||
if( !DoRePaint() )
|
||||
m_refreshTimer.Start( minRefreshPeriod, true );
|
||||
}
|
||||
else if( !m_refreshTimer.IsRunning() )
|
||||
{
|
||||
m_refreshTimer.Start( ( m_minRefreshPeriod - delta ).ToLong(), true );
|
||||
m_refreshTimer.Start( ( minRefreshPeriod - delta ).ToLong(), true );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void EDA_DRAW_PANEL_GAL::ForceRefresh()
|
||||
{
|
||||
m_pendingRefresh = true;
|
||||
DoRePaint();
|
||||
}
|
||||
|
||||
|
@ -426,7 +425,6 @@ void EDA_DRAW_PANEL_GAL::StopDrawing()
|
|||
m_refreshTimer.Stop();
|
||||
m_drawingEnabled = false;
|
||||
Disconnect( wxEVT_PAINT, wxPaintEventHandler( EDA_DRAW_PANEL_GAL::onPaint ), nullptr, this );
|
||||
m_pendingRefresh = false;
|
||||
}
|
||||
|
||||
|
||||
|
@ -538,12 +536,6 @@ bool EDA_DRAW_PANEL_GAL::SwitchBackend( GAL_TYPE aGalType )
|
|||
|
||||
m_gal->SetGridVisibility( grid_visibility );
|
||||
|
||||
if( m_gal->GetSwapInterval() != 0 )
|
||||
{
|
||||
// In theory this could be 0 but then more CPU cycles will be wasted in SwapBuffers
|
||||
m_minRefreshPeriod = 5;
|
||||
}
|
||||
|
||||
// Make sure the cursor is set on the new canvas
|
||||
SetCurrentCursor( KICURSOR::ARROW );
|
||||
|
||||
|
@ -613,7 +605,6 @@ void EDA_DRAW_PANEL_GAL::onRefreshTimer( wxTimerEvent& aEvent )
|
|||
{
|
||||
if( m_gal && m_gal->IsInitialized() )
|
||||
{
|
||||
m_pendingRefresh = true;
|
||||
Connect( wxEVT_PAINT, wxPaintEventHandler( EDA_DRAW_PANEL_GAL::onPaint ), nullptr,
|
||||
this );
|
||||
m_drawingEnabled = true;
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2013-2018 CERN
|
||||
* Copyright (C) 2013-2022 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2013-2023 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
|
||||
* @author Maciej Suminski <maciej.suminski@cern.ch>
|
||||
|
@ -224,8 +224,10 @@ public:
|
|||
* Usually called by a OnPaint event.
|
||||
*
|
||||
* Because it does not use a wxPaintDC, it can be called outside a wxPaintEvent.
|
||||
*
|
||||
* @return true if the repaint attempt was successful.
|
||||
*/
|
||||
void DoRePaint();
|
||||
bool DoRePaint();
|
||||
|
||||
/**
|
||||
* Create an overlay for rendering debug graphics.
|
||||
|
@ -258,9 +260,7 @@ protected:
|
|||
wxWindow* m_parent; ///< Pointer to the parent window
|
||||
EDA_DRAW_FRAME* m_edaFrame; ///< Parent EDA_DRAW_FRAME (if available)
|
||||
|
||||
int m_minRefreshPeriod; ///< A minimum delay before another draw can start
|
||||
wxLongLong m_lastRefresh; ///< Last timestamp when the panel was refreshed
|
||||
bool m_pendingRefresh; ///< Is there a redraw event requested?
|
||||
wxLongLong m_lastRepaint; ///< Timestamp of the last repaint start
|
||||
wxTimer m_refreshTimer; ///< Timer to prevent too-frequent refreshing
|
||||
|
||||
std::mutex m_refreshMutex; ///< Blocks multiple calls to the draw
|
||||
|
|
Loading…
Reference in New Issue