kicad-developers team mailing list archive
-
kicad-developers team
-
Mailing list archive
-
Message #34328
[PATCH] GerbView performance optimizations
These patches improves redraw performance when toggling sketch/filled draw
modes.
On Linux at least, the difference is quite noticeable on complicated Gerber
files.
-Jon
From 04cb51708ff6f46773b3f1acad2b8b8e9adf2db6 Mon Sep 17 00:00:00 2001
From: Jon Evans <jon@xxxxxxxxxxxxx>
Date: Sun, 25 Feb 2018 15:14:28 -0500
Subject: [PATCH 2/2] Add a method to conditionally update VIEW_ITEMs (GerbView
performance)
---
common/view/view.cpp | 18 +++++++++++
gerbview/events_called_functions.cpp | 62 ++++++++++++++++++++++++++++++++----
include/view/view.h | 8 +++++
3 files changed, 81 insertions(+), 7 deletions(-)
diff --git a/common/view/view.cpp b/common/view/view.cpp
index b3c37afdd..9b7a48cfc 100644
--- a/common/view/view.cpp
+++ b/common/view/view.cpp
@@ -1302,6 +1302,24 @@ void VIEW::UpdateAllItems( int aUpdateFlags )
}
+void VIEW::UpdateAllItemsConditionally( int aUpdateFlags,
+ std::function<bool( VIEW_ITEM* )> aCondition )
+{
+ for( VIEW_ITEM* item : m_allItems )
+ {
+ if( aCondition( item ) )
+ {
+ auto viewData = item->viewPrivData();
+
+ if( !viewData )
+ continue;
+
+ viewData->m_requiredUpdate |= aUpdateFlags;
+ }
+ }
+}
+
+
struct VIEW::extentsVisitor
{
BOX2I extents;
diff --git a/gerbview/events_called_functions.cpp b/gerbview/events_called_functions.cpp
index 8d5043e97..1cfb59463 100644
--- a/gerbview/events_called_functions.cpp
+++ b/gerbview/events_called_functions.cpp
@@ -451,7 +451,6 @@ void GERBVIEW_FRAME::OnSelectOptionToolbar( wxCommandEvent& event )
int id = event.GetId();
bool state;
bool needs_refresh = false;
- bool needs_repaint = false;
switch( id )
{
@@ -473,17 +472,17 @@ void GERBVIEW_FRAME::OnSelectOptionToolbar( wxCommandEvent& event )
case ID_TB_OPTIONS_SHOW_FLASHED_ITEMS_SKETCH:
m_DisplayOptions.m_DisplayFlashedItemsFill = not state;
- needs_refresh = needs_repaint = true;
+ needs_refresh = true;
break;
case ID_TB_OPTIONS_SHOW_LINES_SKETCH:
m_DisplayOptions.m_DisplayLinesFill = not state;
- needs_refresh = needs_repaint = true;
+ needs_refresh = true;
break;
case ID_TB_OPTIONS_SHOW_POLYGONS_SKETCH:
m_DisplayOptions.m_DisplayPolygonsFill = not state;
- needs_refresh = needs_repaint = true;
+ needs_refresh = true;
break;
case ID_TB_OPTIONS_SHOW_DCODES:
@@ -532,10 +531,59 @@ void GERBVIEW_FRAME::OnSelectOptionToolbar( wxCommandEvent& event )
applyDisplaySettingsToGAL();
auto view = GetGalCanvas()->GetView();
- if( needs_repaint )
- view->UpdateAllItems( KIGFX::REPAINT );
- else
+ switch( id )
+ {
+ case ID_TB_OPTIONS_SHOW_FLASHED_ITEMS_SKETCH:
+ view->UpdateAllItemsConditionally( KIGFX::REPAINT,
+ []( KIGFX::VIEW_ITEM* aItem ) {
+ auto item = static_cast<GERBER_DRAW_ITEM*>( aItem );
+
+ switch( item->m_Shape )
+ {
+ case GBR_SPOT_CIRCLE:
+ case GBR_SPOT_RECT:
+ case GBR_SPOT_OVAL:
+ case GBR_SPOT_POLY:
+ case GBR_SPOT_MACRO:
+ return true;
+
+ default:
+ return false;
+ }
+ } );
+ break;
+
+ case ID_TB_OPTIONS_SHOW_LINES_SKETCH:
+ view->UpdateAllItemsConditionally( KIGFX::REPAINT,
+ []( KIGFX::VIEW_ITEM* aItem ) {
+ auto item = static_cast<GERBER_DRAW_ITEM*>( aItem );
+
+ switch( item->m_Shape )
+ {
+ case GBR_CIRCLE:
+ case GBR_ARC:
+ case GBR_SEGMENT:
+ return true;
+
+ default:
+ return false;
+ }
+ } );
+ break;
+
+ case ID_TB_OPTIONS_SHOW_POLYGONS_SKETCH:
+ view->UpdateAllItemsConditionally( KIGFX::REPAINT,
+ []( KIGFX::VIEW_ITEM* aItem ) {
+ auto item = static_cast<GERBER_DRAW_ITEM*>( aItem );
+
+ return ( item->m_Shape == GBR_POLYGON );
+ } );
+ break;
+
+ default:
view->UpdateAllItems( KIGFX::COLOR );
+ break;
+ }
m_canvas->Refresh( true );
}
diff --git a/include/view/view.h b/include/view/view.h
index 15f851e13..9029b7be2 100644
--- a/include/view/view.h
+++ b/include/view/view.h
@@ -616,6 +616,14 @@ public:
*/
void UpdateAllItems( int aUpdateFlags );
+ /**
+ * Updates items in the view according to the given flags and condition
+ * @param aUpdateFlags is is according to KIGFX::VIEW_UPDATE_FLAGS
+ * @param aCondition is a function returning true if the item should be updated
+ */
+ void UpdateAllItemsConditionally( int aUpdateFlags,
+ std::function<bool( VIEW_ITEM* )> aCondition );
+
const BOX2I CalculateExtents() ;
/**
--
2.14.1
From 03ed9575d9134058ea860fc1317ab362431bbd3d Mon Sep 17 00:00:00 2001
From: Jon Evans <jon@xxxxxxxxxxxxx>
Date: Sun, 25 Feb 2018 15:01:17 -0500
Subject: [PATCH 1/2] Add a REPAINT flag for faster redraw when bounding box
hasn't changed
---
common/view/view.cpp | 2 +-
gerbview/events_called_functions.cpp | 2 +-
include/view/view_item.h | 1 +
3 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/common/view/view.cpp b/common/view/view.cpp
index b2d5a87e1..b3c37afdd 100644
--- a/common/view/view.cpp
+++ b/common/view/view.cpp
@@ -1092,7 +1092,7 @@ void VIEW::invalidateItem( VIEW_ITEM* aItem, int aUpdateFlags )
if( IsCached( layerId ) )
{
- if( aUpdateFlags & ( GEOMETRY | LAYERS ) )
+ if( aUpdateFlags & ( GEOMETRY | LAYERS | REPAINT ) )
updateItemGeometry( aItem, layerId );
else if( aUpdateFlags & COLOR )
updateItemColor( aItem, layerId );
diff --git a/gerbview/events_called_functions.cpp b/gerbview/events_called_functions.cpp
index bca5f36c6..8d5043e97 100644
--- a/gerbview/events_called_functions.cpp
+++ b/gerbview/events_called_functions.cpp
@@ -533,7 +533,7 @@ void GERBVIEW_FRAME::OnSelectOptionToolbar( wxCommandEvent& event )
auto view = GetGalCanvas()->GetView();
if( needs_repaint )
- view->UpdateAllItems( KIGFX::GEOMETRY );
+ view->UpdateAllItems( KIGFX::REPAINT );
else
view->UpdateAllItems( KIGFX::COLOR );
diff --git a/include/view/view_item.h b/include/view/view_item.h
index 8c1825caa..67d6dad74 100644
--- a/include/view/view_item.h
+++ b/include/view/view_item.h
@@ -57,6 +57,7 @@ enum VIEW_UPDATE_FLAGS {
GEOMETRY = 0x04, /// Position or shape has changed
LAYERS = 0x08, /// Layers have changed
INITIAL_ADD = 0x10, /// Item is being added to the view
+ REPAINT = 0x20, /// Item needs to be redrawn
ALL = 0xef /// All except INITIAL_ADD
};
--
2.14.1
Follow ups