Performance enhancements for PCBNew scrolling and zooming.

Fixes https://gitlab.com/kicad/code/kicad/issues/5136
This commit is contained in:
Jeff Young 2020-08-10 22:52:22 +01:00
parent e1c449902d
commit 9716c62e32
4 changed files with 52 additions and 78 deletions

View File

@ -412,9 +412,11 @@ LSEQ LSET::Seq() const
{
LSEQ ret;
for( unsigned i=0; i<size(); ++i )
ret.reserve( size() );
for( unsigned i = 0; i < size(); ++i )
{
if( test(i) )
if( test( i ) )
ret.push_back( PCB_LAYER_ID( i ) );
}

View File

@ -312,12 +312,22 @@ VIEW::VIEW( bool aIsDynamic ) :
// Redraw everything at the beginning
MarkDirty();
m_layers.reserve( VIEW_MAX_LAYERS );
// View uses layers to display EDA_ITEMs (item may be displayed on several layers, for example
// pad may be shown on pad, pad hole and solder paste layers). There are usual copper layers
// (eg. F.Cu, B.Cu, internal and so on) and layers for displaying objects such as texts,
// silkscreen, pads, vias, etc.
for( int i = 0; i < VIEW_MAX_LAYERS; i++ )
AddLayer( i );
for( int ii = 0; ii < VIEW_MAX_LAYERS; ++ii )
{
m_layers.emplace_back();
m_layers[ii].items = std::make_shared<VIEW_RTREE>();
m_layers[ii].id = ii;
m_layers[ii].renderingOrder = ii;
m_layers[ii].visible = true;
m_layers[ii].displayOnly = false;
m_layers[ii].target = TARGET_CACHED;
}
sortLayers();
@ -332,21 +342,6 @@ VIEW::~VIEW()
}
void VIEW::AddLayer( int aLayer, bool aDisplayOnly )
{
if( m_layers.find( aLayer ) == m_layers.end() )
{
m_layers[aLayer] = VIEW_LAYER();
m_layers[aLayer].items.reset( new VIEW_RTREE() );
m_layers[aLayer].id = aLayer;
m_layers[aLayer].renderingOrder = aLayer;
m_layers[aLayer].visible = true;
m_layers[aLayer].displayOnly = aDisplayOnly;
m_layers[aLayer].target = TARGET_CACHED;
}
}
void VIEW::Add( VIEW_ITEM* aItem, int aDrawPriority )
{
int layers[VIEW_MAX_LAYERS], layers_count;
@ -709,25 +704,22 @@ void VIEW::SortLayers( int aLayers[], int& aCount ) const
void VIEW::ReorderLayerData( std::unordered_map<int, int> aReorderMap )
{
LAYER_MAP new_map;
std::vector<VIEW_LAYER> new_map;
new_map.reserve( m_layers.size() );
for( const auto& it : m_layers )
for( int ii = 0; ii < VIEW_MAX_LAYERS; ++ii )
new_map.emplace_back();
for( const VIEW_LAYER& layer : m_layers )
{
int orig_idx = it.first;
VIEW_LAYER layer = it.second;
int new_idx;
int orig_idx = layer.id;
int new_idx = orig_idx;
try
{
if( aReorderMap.count( orig_idx ) )
new_idx = aReorderMap.at( orig_idx );
}
catch( const std::out_of_range& )
{
new_idx = orig_idx;
}
layer.id = new_idx;
new_map[new_idx] = layer;
new_map[new_idx].id = new_idx;
}
m_layers = new_map;
@ -1118,8 +1110,8 @@ void VIEW::Clear()
r.SetMaximum();
m_allItems->clear();
for( LAYER_MAP_ITER i = m_layers.begin(); i != m_layers.end(); ++i )
i->second.items->RemoveAll();
for( VIEW_LAYER& layer : m_layers )
layer.items->RemoveAll();
m_nextDrawPriority = 0;
@ -1209,11 +1201,8 @@ void VIEW::clearGroupCache()
r.SetMaximum();
clearLayerCache visitor( this );
for( LAYER_MAP_ITER i = m_layers.begin(); i != m_layers.end(); ++i )
{
VIEW_LAYER* l = &( ( *i ).second );
l->items->Query( r, visitor );
}
for( VIEW_LAYER& layer : m_layers )
layer.items->Query( r, visitor );
}
@ -1268,8 +1257,8 @@ void VIEW::sortLayers()
m_orderedLayers.resize( m_layers.size() );
for( LAYER_MAP_ITER i = m_layers.begin(); i != m_layers.end(); ++i )
m_orderedLayers[n++] = &i->second;
for( VIEW_LAYER& layer : m_layers )
m_orderedLayers[n++] = &layer;
sort( m_orderedLayers.begin(), m_orderedLayers.end(), compareRenderingOrder );
@ -1409,14 +1398,12 @@ void VIEW::RecacheAllItems()
r.SetMaximum();
for( LAYER_MAP_ITER i = m_layers.begin(); i != m_layers.end(); ++i )
for( const VIEW_LAYER& l : m_layers )
{
VIEW_LAYER* l = &( ( *i ).second );
if( IsCached( l->id ) )
if( IsCached( l.id ) )
{
recacheItem visitor( this, m_gal, l->id );
l->items->Query( r, visitor );
recacheItem visitor( this, m_gal, l.id );
l.items->Query( r, visitor );
}
}
}

View File

@ -368,22 +368,6 @@ public:
*/
const VECTOR2I& GetScreenPixelSize() const;
/**
* Function AddLayer()
* Adds a new layer to the view.
* @param aLayer: unique ID of the layer to be added.
* @param aDisplayOnly: layer is display-only (example: selection boxes, floating hints/menus).
* Objects belonging to this layer are not taken into account by Query() method.
*/
void AddLayer( int aLayer, bool aDisplayOnly = false );
/**
* Function ClearLayer()
* Removes all items from a given layer.
* @param aLayer: ID of the layer to be cleared
*/
void ClearLayer( int aLayer );
/**
* Function Clear()
* Removes all items from the view.
@ -717,12 +701,6 @@ protected:
std::set<int> requiredLayers; ///< layers that have to be enabled to show the layer
};
// Convenience typedefs
typedef std::unordered_map<int, VIEW_LAYER> LAYER_MAP;
typedef LAYER_MAP::iterator LAYER_MAP_ITER;
typedef std::vector<VIEW_LAYER*> LAYER_ORDER;
typedef std::vector<VIEW_LAYER*>::iterator LAYER_ORDER_ITER;
// Function objects that need to access VIEW/VIEW_ITEM private/protected members
struct clearLayerCache;
struct recacheItem;
@ -816,14 +794,14 @@ protected:
bool m_enableOrderModifier;
/// Contains set of possible displayed layers and its properties
LAYER_MAP m_layers;
std::vector<VIEW_LAYER> m_layers;
/// Sorted list of pointers to members of m_layers
std::vector<VIEW_LAYER*> m_orderedLayers;
/// Flat list of all items
std::shared_ptr<std::vector<VIEW_ITEM*>> m_allItems;
/// Sorted list of pointers to members of m_layers
LAYER_ORDER m_orderedLayers;
/// Stores set of layers that are displayed on the top
std::set<unsigned int> m_topLayers;

View File

@ -604,16 +604,23 @@ unsigned int VIA::ViewGetLOD( int aLayer, KIGFX::VIEW* aView ) const
if( IsNetnameLayer( aLayer ) )
return m_Width == 0 ? HIDE : ( Millimeter2iu( 10 ) / m_Width );
LSET visibleLayers;
bool onVisibleLayer = false;
for( int i = 0; i < PCB_LAYER_ID_COUNT; ++i )
PCB_LAYER_ID top;
PCB_LAYER_ID bottom;
LayerPair( &top, &bottom );
for( int layer = top; layer <= bottom; ++layer )
{
if( aView->IsLayerVisible( i ) )
visibleLayers.set( i );
if( aView->IsLayerVisible( layer ) )
{
onVisibleLayer = true;
break;
}
}
// Only draw the via if at least one of the layers it crosses is being displayed
if( ( visibleLayers & GetLayerSet() ).any() && aView->IsLayerVisible( LAYER_VIAS ) )
if( onVisibleLayer && aView->IsLayerVisible( LAYER_VIAS ) )
{
switch( m_ViaType )
{