Fixed a crash when starting pcbnew with OpenGL GAL.

This commit is contained in:
Maciej Suminski 2016-05-09 17:23:01 +02:00
parent ad66af66af
commit d9f4877c94
11 changed files with 80 additions and 80 deletions

View File

@ -99,12 +99,20 @@ EDA_DRAW_PANEL_GAL::EDA_DRAW_PANEL_GAL( wxWindow* aParentWindow, wxWindowID aWin
// on updated viewport data. // on updated viewport data.
m_viewControls = new KIGFX::WX_VIEW_CONTROLS( m_view, this ); m_viewControls = new KIGFX::WX_VIEW_CONTROLS( m_view, this );
// Set up timer that prevents too frequent redraw commands
m_refreshTimer.SetOwner( this );
m_pendingRefresh = false; m_pendingRefresh = false;
m_drawing = false; m_drawing = false;
m_drawingEnabled = false; m_drawingEnabled = false;
Connect( wxEVT_TIMER, wxTimerEventHandler( EDA_DRAW_PANEL_GAL::onRefreshTimer ), NULL, this );
// Set up timer that prevents too frequent redraw commands
m_refreshTimer.SetOwner( this );
Connect( m_refreshTimer.GetId(), wxEVT_TIMER,
wxTimerEventHandler( EDA_DRAW_PANEL_GAL::onRefreshTimer ), NULL, this );
// Set up timer to execute OnShow() method when the window appears on the screen
m_onShowTimer.SetOwner( this );
Connect( m_onShowTimer.GetId(), wxEVT_TIMER,
wxTimerEventHandler( EDA_DRAW_PANEL_GAL::onShowTimer ), NULL, this );
m_onShowTimer.Start( 10 );
LoadGalSettings(); LoadGalSettings();
} }
@ -153,10 +161,7 @@ void EDA_DRAW_PANEL_GAL::onPaint( wxPaintEvent& WXUNUSED( aEvent ) )
KIGFX::PCB_RENDER_SETTINGS* settings = static_cast<KIGFX::PCB_RENDER_SETTINGS*>( m_painter->GetSettings() ); KIGFX::PCB_RENDER_SETTINGS* settings = static_cast<KIGFX::PCB_RENDER_SETTINGS*>( m_painter->GetSettings() );
m_viewControls->UpdateScrollbars(); m_viewControls->UpdateScrollbars();
m_gal->BeginUpdate();
m_view->UpdateItems(); m_view->UpdateItems();
m_gal->EndUpdate();
m_gal->BeginDrawing(); m_gal->BeginDrawing();
m_gal->ClearScreen( settings->GetBackgroundColor() ); m_gal->ClearScreen( settings->GetBackgroundColor() );
@ -442,7 +447,7 @@ void EDA_DRAW_PANEL_GAL::onRefreshTimer( wxTimerEvent& aEvent )
{ {
if( !m_drawingEnabled ) if( !m_drawingEnabled )
{ {
if( m_gal->IsInitialized() ) if( m_gal && m_gal->IsInitialized() )
{ {
m_drawing = false; m_drawing = false;
m_pendingRefresh = true; m_pendingRefresh = true;
@ -452,7 +457,7 @@ void EDA_DRAW_PANEL_GAL::onRefreshTimer( wxTimerEvent& aEvent )
else else
{ {
// Try again soon // Try again soon
m_refreshTimer.Start( 100, true ); m_refreshTimer.StartOnce( 100 );
return; return;
} }
} }
@ -461,4 +466,15 @@ void EDA_DRAW_PANEL_GAL::onRefreshTimer( wxTimerEvent& aEvent )
wxPostEvent( this, redrawEvent ); wxPostEvent( this, redrawEvent );
} }
void EDA_DRAW_PANEL_GAL::onShowTimer( wxTimerEvent& aEvent )
{
if( IsShownOnScreen() )
{
m_onShowTimer.Stop();
OnShow();
}
}
const wxChar EDA_DRAW_PANEL_GAL::GRID_STYLE_CFG[] = wxT( "GridStyle" ); const wxChar EDA_DRAW_PANEL_GAL::GRID_STYLE_CFG[] = wxT( "GridStyle" );

View File

@ -85,8 +85,6 @@ CAIRO_GAL::CAIRO_GAL( wxWindow* aParent, wxEvtHandler* aMouseListener,
// Allocate memory for pixel storage // Allocate memory for pixel storage
allocateBitmaps(); allocateBitmaps();
initSurface();
} }

View File

@ -127,20 +127,25 @@ OPENGL_GAL::OPENGL_GAL( wxWindow* aParent, wxEvtHandler* aMouseListener,
OPENGL_GAL::~OPENGL_GAL() OPENGL_GAL::~OPENGL_GAL()
{ {
SetCurrent( *OPENGL_GAL::glContext ); gluDeleteTess( tesselator );
ClearCache();
if( IsShown() )
SetCurrent( *OPENGL_GAL::glContext );
glFlush(); glFlush();
if( --instanceCounter == 0 ) if( --instanceCounter == 0 )
{ {
glDeleteTextures( 1, &fontTexture ); if( isBitmapFontLoaded )
isBitmapFontLoaded = false; {
glDeleteTextures( 1, &fontTexture );
isBitmapFontLoaded = false;
}
delete OPENGL_GAL::glContext; delete OPENGL_GAL::glContext;
glContext = NULL; glContext = NULL;
} }
gluDeleteTess( tesselator );
ClearCache();
} }
@ -302,9 +307,7 @@ void OPENGL_GAL::EndDrawing()
void OPENGL_GAL::BeginUpdate() void OPENGL_GAL::BeginUpdate()
{ {
if( IsShownOnScreen() ) SetCurrent( *OPENGL_GAL::glContext );
SetCurrent( *OPENGL_GAL::glContext );
cachedManager.Map(); cachedManager.Map();
} }

View File

@ -1,8 +1,9 @@
/* /*
* This program source code file is part of KiCad, a free EDA CAD application. * This program source code file is part of KiCad, a free EDA CAD application.
* *
* Copyright (C) 2013 CERN * Copyright (C) 2013-2016 CERN
* @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch> * @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
* @author Maciej Suminski <maciej.suminski@cern.ch>
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@ -695,8 +696,8 @@ struct VIEW::unlinkItem
struct VIEW::recacheItem struct VIEW::recacheItem
{ {
recacheItem( VIEW* aView, GAL* aGal, int aLayer, bool aImmediately ) : recacheItem( VIEW* aView, GAL* aGal, int aLayer ) :
view( aView ), gal( aGal ), layer( aLayer ), immediately( aImmediately ) view( aView ), gal( aGal ), layer( aLayer )
{ {
} }
@ -708,21 +709,8 @@ struct VIEW::recacheItem
if( group >= 0 ) if( group >= 0 )
gal->DeleteGroup( group ); gal->DeleteGroup( group );
if( immediately ) aItem->setGroup( layer, -1 );
{ aItem->ViewUpdate( VIEW_ITEM::ALL );
group = gal->BeginGroup();
aItem->setGroup( layer, group );
if( !view->m_painter->Draw( aItem, layer ) )
aItem->ViewDraw( layer, gal ); // Alternative drawing method
gal->EndGroup();
}
else
{
aItem->ViewUpdate( VIEW_ITEM::ALL );
aItem->setGroup( layer, -1 );
}
return true; return true;
} }
@ -730,7 +718,6 @@ struct VIEW::recacheItem
VIEW* view; VIEW* view;
GAL* gal; GAL* gal;
int layer; int layer;
bool immediately;
}; };
@ -1005,46 +992,29 @@ bool VIEW::areRequiredLayersEnabled( int aLayerId ) const
} }
void VIEW::RecacheAllItems( bool aImmediately ) void VIEW::RecacheAllItems()
{ {
BOX2I r; BOX2I r;
r.SetMaximum(); r.SetMaximum();
#ifdef __WXDEBUG__
prof_counter totalRealTime;
prof_start( &totalRealTime );
#endif /* __WXDEBUG__ */
m_gal->BeginUpdate();
for( LAYER_MAP_ITER i = m_layers.begin(); i != m_layers.end(); ++i ) for( LAYER_MAP_ITER i = m_layers.begin(); i != m_layers.end(); ++i )
{ {
VIEW_LAYER* l = &( ( *i ).second ); VIEW_LAYER* l = &( ( *i ).second );
if( IsCached( l->id ) ) if( IsCached( l->id ) )
{ {
m_gal->SetTarget( l->target ); recacheItem visitor( this, m_gal, l->id );
m_gal->SetLayerDepth( l->renderingOrder );
recacheItem visitor( this, m_gal, l->id, aImmediately );
l->items->Query( r, visitor ); l->items->Query( r, visitor );
MarkTargetDirty( l->target );
} }
} }
m_gal->EndUpdate();
#ifdef __WXDEBUG__
prof_end( &totalRealTime );
wxLogTrace( "GAL_PROFILE", wxT( "RecacheAllItems::immediately: %u %.1f ms" ),
aImmediately, totalRealTime.msecs() );
#endif /* __WXDEBUG__ */
} }
void VIEW::UpdateItems() void VIEW::UpdateItems()
{ {
// Update items that need this m_gal->BeginUpdate();
BOOST_FOREACH( VIEW_ITEM* item, m_needsUpdate ) BOOST_FOREACH( VIEW_ITEM* item, m_needsUpdate )
{ {
assert( item->viewRequiredUpdate() != VIEW_ITEM::NONE ); assert( item->viewRequiredUpdate() != VIEW_ITEM::NONE );
@ -1052,6 +1022,7 @@ void VIEW::UpdateItems()
invalidateItem( item, item->viewRequiredUpdate() ); invalidateItem( item, item->viewRequiredUpdate() );
} }
m_gal->EndUpdate();
m_needsUpdate.clear(); m_needsUpdate.clear();
} }

View File

@ -188,6 +188,12 @@ public:
*/ */
virtual bool LoadGalSettings(); virtual bool LoadGalSettings();
/**
* Function OnShow()
* Called when the window is shown for the first time.
*/
virtual void OnShow() {}
protected: protected:
void onPaint( wxPaintEvent& WXUNUSED( aEvent ) ); void onPaint( wxPaintEvent& WXUNUSED( aEvent ) );
void onSize( wxSizeEvent& aEvent ); void onSize( wxSizeEvent& aEvent );
@ -195,6 +201,7 @@ protected:
void onEnter( wxEvent& aEvent ); void onEnter( wxEvent& aEvent );
void onLostFocus( wxFocusEvent& aEvent ); void onLostFocus( wxFocusEvent& aEvent );
void onRefreshTimer( wxTimerEvent& aEvent ); void onRefreshTimer( wxTimerEvent& aEvent );
void onShowTimer( wxTimerEvent& aEvent );
static const int MinRefreshPeriod = 17; ///< 60 FPS. static const int MinRefreshPeriod = 17; ///< 60 FPS.
@ -219,6 +226,9 @@ protected:
/// Timer responsible for preventing too frequent refresh /// Timer responsible for preventing too frequent refresh
wxTimer m_refreshTimer; wxTimer m_refreshTimer;
/// Timer used to execute OnShow() when the window finally appears on the screen.
wxTimer m_onShowTimer;
/// Interface for drawing objects on a 2D-surface /// Interface for drawing objects on a 2D-surface
KIGFX::GAL* m_gal; KIGFX::GAL* m_gal;

View File

@ -463,10 +463,8 @@ public:
/** /**
* Function RecacheAllItems() * Function RecacheAllItems()
* Rebuilds GAL display lists. * Rebuilds GAL display lists.
* @param aForceNow decides if every item should be instantly recached. Otherwise items are
* going to be recached when they become visible.
*/ */
void RecacheAllItems( bool aForceNow = false ); void RecacheAllItems();
/** /**
* Function IsDynamic() * Function IsDynamic()

View File

@ -56,9 +56,6 @@
#include <math/vector2d.h> #include <math/vector2d.h>
#include <trigo.h> #include <trigo.h>
#include <pcb_painter.h> #include <pcb_painter.h>
#include <worksheet_viewitem.h>
#include <ratsnest_data.h>
#include <ratsnest_viewitem.h>
#include <tool/tool_manager.h> #include <tool/tool_manager.h>
#include <tool/tool_dispatcher.h> #include <tool/tool_dispatcher.h>
@ -976,7 +973,7 @@ void PCB_BASE_FRAME::UseGalCanvas( bool aEnable )
if( m_toolManager ) if( m_toolManager )
m_toolManager->ResetTools( TOOL_BASE::GAL_SWITCH ); m_toolManager->ResetTools( TOOL_BASE::GAL_SWITCH );
galCanvas->GetView()->RecacheAllItems( true ); galCanvas->GetView()->RecacheAllItems();
galCanvas->SetEventDispatcher( m_toolDispatcher ); galCanvas->SetEventDispatcher( m_toolDispatcher );
galCanvas->StartDrawing(); galCanvas->StartDrawing();
} }

View File

@ -470,7 +470,7 @@ void PCB_LAYER_WIDGET::OnLayerVisible( int aLayer, bool isVisible, bool isFinal
{ {
KIGFX::VIEW* view = galCanvas->GetView(); KIGFX::VIEW* view = galCanvas->GetView();
view->SetLayerVisible( aLayer, isVisible ); view->SetLayerVisible( aLayer, isVisible );
view->RecacheAllItems( true ); view->RecacheAllItems();
} }
if( isFinal ) if( isFinal )

View File

@ -175,7 +175,7 @@ void DIALOG_DISPLAY_OPTIONS::OnOkClick(wxCommandEvent& event)
KIGFX::PCB_RENDER_SETTINGS* settings = KIGFX::PCB_RENDER_SETTINGS* settings =
static_cast<KIGFX::PCB_RENDER_SETTINGS*>( painter->GetSettings() ); static_cast<KIGFX::PCB_RENDER_SETTINGS*>( painter->GetSettings() );
settings->LoadDisplayOptions( displ_opts ); settings->LoadDisplayOptions( displ_opts );
view->RecacheAllItems( true ); view->RecacheAllItems();
m_Parent->GetCanvas()->Refresh(); m_Parent->GetCanvas()->Refresh();

View File

@ -165,18 +165,6 @@ void PCB_DRAW_PANEL_GAL::DisplayBoard( const BOARD* aBoard )
// Display settings // Display settings
UseColorScheme( aBoard->GetColorsSettings() ); UseColorScheme( aBoard->GetColorsSettings() );
PCB_BASE_FRAME* frame = dynamic_cast<PCB_BASE_FRAME*>( GetParent() );
if( frame )
{
SetTopLayer( frame->GetActiveLayer() );
DISPLAY_OPTIONS* displ_opts = (DISPLAY_OPTIONS*) frame->GetDisplayOptions();
static_cast<KIGFX::PCB_RENDER_SETTINGS*>(
m_view->GetPainter()->GetSettings() )->LoadDisplayOptions( displ_opts );
}
m_view->RecacheAllItems( true );
} }
@ -363,6 +351,22 @@ void PCB_DRAW_PANEL_GAL::GetMsgPanelInfo( std::vector<MSG_PANEL_ITEM>& aList )
} }
void PCB_DRAW_PANEL_GAL::OnShow()
{
PCB_BASE_FRAME* frame = dynamic_cast<PCB_BASE_FRAME*>( GetParent() );
if( frame )
{
SetTopLayer( frame->GetActiveLayer() );
DISPLAY_OPTIONS* displ_opts = (DISPLAY_OPTIONS*) frame->GetDisplayOptions();
static_cast<KIGFX::PCB_RENDER_SETTINGS*>(
m_view->GetPainter()->GetSettings() )->LoadDisplayOptions( displ_opts );
}
m_view->RecacheAllItems();
}
void PCB_DRAW_PANEL_GAL::setDefaultLayerOrder() void PCB_DRAW_PANEL_GAL::setDefaultLayerOrder()
{ {
for( LAYER_NUM i = 0; (unsigned) i < sizeof( GAL_LAYER_ORDER ) / sizeof( LAYER_NUM ); ++i ) for( LAYER_NUM i = 0; (unsigned) i < sizeof( GAL_LAYER_ORDER ) / sizeof( LAYER_NUM ); ++i )

View File

@ -80,6 +80,9 @@ public:
///> @copydoc EDA_DRAW_PANEL_GAL::GetMsgPanelInfo() ///> @copydoc EDA_DRAW_PANEL_GAL::GetMsgPanelInfo()
void GetMsgPanelInfo( std::vector<MSG_PANEL_ITEM>& aList ); void GetMsgPanelInfo( std::vector<MSG_PANEL_ITEM>& aList );
///> @copydoc EDA_DRAW_PANEL_GAL::OnShow()
void OnShow() override;
protected: protected:
///> Reassigns layer order to the initial settings. ///> Reassigns layer order to the initial settings.
void setDefaultLayerOrder(); void setDefaultLayerOrder();