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.
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_drawing = 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();
}
@ -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() );
m_viewControls->UpdateScrollbars();
m_gal->BeginUpdate();
m_view->UpdateItems();
m_gal->EndUpdate();
m_gal->BeginDrawing();
m_gal->ClearScreen( settings->GetBackgroundColor() );
@ -442,7 +447,7 @@ void EDA_DRAW_PANEL_GAL::onRefreshTimer( wxTimerEvent& aEvent )
{
if( !m_drawingEnabled )
{
if( m_gal->IsInitialized() )
if( m_gal && m_gal->IsInitialized() )
{
m_drawing = false;
m_pendingRefresh = true;
@ -452,7 +457,7 @@ void EDA_DRAW_PANEL_GAL::onRefreshTimer( wxTimerEvent& aEvent )
else
{
// Try again soon
m_refreshTimer.Start( 100, true );
m_refreshTimer.StartOnce( 100 );
return;
}
}
@ -461,4 +466,15 @@ void EDA_DRAW_PANEL_GAL::onRefreshTimer( wxTimerEvent& aEvent )
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" );

View File

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

View File

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

View File

@ -1,8 +1,9 @@
/*
* 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 Maciej Suminski <maciej.suminski@cern.ch>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -695,8 +696,8 @@ struct VIEW::unlinkItem
struct VIEW::recacheItem
{
recacheItem( VIEW* aView, GAL* aGal, int aLayer, bool aImmediately ) :
view( aView ), gal( aGal ), layer( aLayer ), immediately( aImmediately )
recacheItem( VIEW* aView, GAL* aGal, int aLayer ) :
view( aView ), gal( aGal ), layer( aLayer )
{
}
@ -708,21 +709,8 @@ struct VIEW::recacheItem
if( group >= 0 )
gal->DeleteGroup( group );
if( immediately )
{
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 );
}
aItem->ViewUpdate( VIEW_ITEM::ALL );
return true;
}
@ -730,7 +718,6 @@ struct VIEW::recacheItem
VIEW* view;
GAL* gal;
int layer;
bool immediately;
};
@ -1005,46 +992,29 @@ bool VIEW::areRequiredLayersEnabled( int aLayerId ) const
}
void VIEW::RecacheAllItems( bool aImmediately )
void VIEW::RecacheAllItems()
{
BOX2I r;
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 )
{
VIEW_LAYER* l = &( ( *i ).second );
if( IsCached( l->id ) )
{
m_gal->SetTarget( l->target );
m_gal->SetLayerDepth( l->renderingOrder );
recacheItem visitor( this, m_gal, l->id, aImmediately );
recacheItem visitor( this, m_gal, l->id );
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()
{
// Update items that need this
m_gal->BeginUpdate();
BOOST_FOREACH( VIEW_ITEM* item, m_needsUpdate )
{
assert( item->viewRequiredUpdate() != VIEW_ITEM::NONE );
@ -1052,6 +1022,7 @@ void VIEW::UpdateItems()
invalidateItem( item, item->viewRequiredUpdate() );
}
m_gal->EndUpdate();
m_needsUpdate.clear();
}

View File

@ -188,6 +188,12 @@ public:
*/
virtual bool LoadGalSettings();
/**
* Function OnShow()
* Called when the window is shown for the first time.
*/
virtual void OnShow() {}
protected:
void onPaint( wxPaintEvent& WXUNUSED( aEvent ) );
void onSize( wxSizeEvent& aEvent );
@ -195,6 +201,7 @@ protected:
void onEnter( wxEvent& aEvent );
void onLostFocus( wxFocusEvent& aEvent );
void onRefreshTimer( wxTimerEvent& aEvent );
void onShowTimer( wxTimerEvent& aEvent );
static const int MinRefreshPeriod = 17; ///< 60 FPS.
@ -219,6 +226,9 @@ protected:
/// Timer responsible for preventing too frequent refresh
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
KIGFX::GAL* m_gal;

View File

@ -463,10 +463,8 @@ public:
/**
* Function RecacheAllItems()
* 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()

View File

@ -56,9 +56,6 @@
#include <math/vector2d.h>
#include <trigo.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_dispatcher.h>
@ -976,7 +973,7 @@ void PCB_BASE_FRAME::UseGalCanvas( bool aEnable )
if( m_toolManager )
m_toolManager->ResetTools( TOOL_BASE::GAL_SWITCH );
galCanvas->GetView()->RecacheAllItems( true );
galCanvas->GetView()->RecacheAllItems();
galCanvas->SetEventDispatcher( m_toolDispatcher );
galCanvas->StartDrawing();
}

View File

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

View File

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

View File

@ -165,18 +165,6 @@ void PCB_DRAW_PANEL_GAL::DisplayBoard( const BOARD* aBoard )
// Display settings
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()
{
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()
void GetMsgPanelInfo( std::vector<MSG_PANEL_ITEM>& aList );
///> @copydoc EDA_DRAW_PANEL_GAL::OnShow()
void OnShow() override;
protected:
///> Reassigns layer order to the initial settings.
void setDefaultLayerOrder();