From bf3690d8417f9c0c331ec03e363f66e93f83bafc Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 4 Sep 2013 16:23:26 +0200 Subject: [PATCH] More effective way of updating bounding boxes. IsCached() method made public. Removed some of unused fields from the layer description structure. --- common/view/view.cpp | 44 ++++++++++++++++++++++++++++++-------------- include/view/view.h | 19 ++++++++++--------- 2 files changed, 40 insertions(+), 23 deletions(-) diff --git a/common/view/view.cpp b/common/view/view.cpp index 4fcd86b9ba..72d8cf79c7 100644 --- a/common/view/view.cpp +++ b/common/view/view.cpp @@ -98,9 +98,9 @@ void VIEW::Add( VIEW_ITEM* aItem ) for( int i = 0; i < layers_count; i++ ) { - VIEW_LAYER* l = &m_layers[layers[i]]; - l->items->Insert( aItem ); - l->dirtyExtents.Merge( aItem->ViewBBox() ); + VIEW_LAYER& l = m_layers[layers[i]]; + l.items->Insert( aItem ); + l.isDirty = true; } if( m_dynamic ) @@ -386,7 +386,7 @@ struct VIEW::updateItemsColor void VIEW::UpdateLayerColor( int aLayer ) { // There is no point in updating non-cached layers - if( !isCached( aLayer ) ) + if( !IsCached( aLayer ) ) return; BOX2I r; @@ -409,7 +409,7 @@ void VIEW::UpdateAllLayersColor() VIEW_LAYER* l = &( ( *i ).second ); // There is no point in updating non-cached layers - if( !isCached( l->id ) ) + if( !IsCached( l->id ) ) continue; updateItemsColor visitor( l->id, m_painter, m_gal ); @@ -441,7 +441,7 @@ struct VIEW::changeItemsDepth void VIEW::ChangeLayerDepth( int aLayer, int aDepth ) { // There is no point in updating non-cached layers - if( !isCached( aLayer ) ) + if( !IsCached( aLayer ) ) return; BOX2I r; @@ -564,6 +564,7 @@ void VIEW::redrawRect( const BOX2I& aRect ) m_gal->SetLayerDepth( l->renderingOrder ); l->items->Query( aRect, drawFunc ); } + l->isDirty = false; } } @@ -571,7 +572,7 @@ void VIEW::redrawRect( const BOX2I& aRect ) void VIEW::draw( VIEW_ITEM* aItem, int aLayer, bool aImmediate ) const { - if( isCached( aLayer ) && !aImmediate ) + if( IsCached( aLayer ) && !aImmediate ) { // Draw using cached information or create one int group = aItem->getGroup( aLayer ); @@ -697,6 +698,7 @@ void VIEW::Clear() { VIEW_LAYER* l = &( ( *i ).second ); unlinkItem v; + if( m_dynamic ) l->items->Query( r, v ); @@ -789,6 +791,9 @@ void VIEW::invalidateItem( VIEW_ITEM* aItem, int aUpdateFlags ) int layers[VIEW_MAX_LAYERS], layers_count; aItem->getLayers( layers, layers_count ); + if( aUpdateFlags & VIEW_ITEM::GEOMETRY ) + updateBbox( aItem ); + // Iterate through layers used by the item and recache it immediately for( int i = 0; i < layers_count; i++ ) { @@ -796,12 +801,8 @@ void VIEW::invalidateItem( VIEW_ITEM* aItem, int aUpdateFlags ) if( aUpdateFlags & VIEW_ITEM::GEOMETRY ) { - // Reinsert item in order to update bounding box - Remove( aItem ); - Add( aItem ); - - if( isCached( layerId ) ) - updateItemGeometry( aItem, layerId ); /// TODO is it still necessary? + if( IsCached( layerId ) ) + updateItemGeometry( aItem, layerId ); } else if( aUpdateFlags & VIEW_ITEM::COLOR ) { @@ -860,6 +861,21 @@ void VIEW::updateItemGeometry( VIEW_ITEM* aItem, int aLayer ) } +void VIEW::updateBbox( VIEW_ITEM* aItem ) +{ + int layers[VIEW_MAX_LAYERS], layers_count; + aItem->ViewGetLayers( layers, layers_count ); + + for( int i = 0; i < layers_count; i++ ) + { + VIEW_LAYER& l = m_layers[layers[i]]; + l.items->Remove( aItem ); + l.items->Insert( aItem ); + l.isDirty = true; + } +} + + bool VIEW::areRequiredLayersEnabled( int aLayerId ) const { wxASSERT( (unsigned) aLayerId < m_layers.size() ); @@ -893,7 +909,7 @@ void VIEW::RecacheAllItems( bool aImmediately ) { VIEW_LAYER* l = &( ( *i ).second ); - if( isCached( l->id ) ) + if( IsCached( l->id ) ) { m_gal->SetTarget( l->target ); m_gal->SetLayerDepth( l->renderingOrder ); diff --git a/include/view/view.h b/include/view/view.h index 4ad11828f5..d5a1b9348c 100644 --- a/include/view/view.h +++ b/include/view/view.h @@ -423,6 +423,13 @@ public: m_dirtyTargets[aTarget] = true; } + /// Returns true if the layer is cached + inline bool IsCached( int aLayer ) const + { + return ( m_layers.at( aLayer ).target == TARGET_CACHED ); + } + + static const int VIEW_MAX_LAYERS = 128; ///* maximum number of layers that may be shown private: @@ -432,11 +439,8 @@ private: bool isDirty; ///* does it contain any dirty items (updated since last redraw) bool displayOnly; ///* is the layer display only? VIEW_RTREE* items; ///* R-tree indexing all items on this layer. - std::vector dirtyItems; ///* set of dirty items collected since last redraw int renderingOrder; ///* rendering order of this layer int id; ///* layer ID - BOX2I extents; ///* sum of bboxes of all items on the layer - BOX2I dirtyExtents; ///* sum of bboxes of all dirty items on the layer RenderTarget target; ///* where the layer should be rendered std::set requiredLayers; ///* layers that are required to be enabled to show the layer }; @@ -515,6 +519,9 @@ private: /// Updates all informations needed to draw an item void updateItemGeometry( VIEW_ITEM* aItem, int aLayer ); + /// Updates bounding box of an item + void updateBbox( VIEW_ITEM* aItem ); + /// Determines rendering order of layers. Used in display order sorting function. static bool compareRenderingOrder( VIEW_LAYER* i, VIEW_LAYER* j ) { @@ -524,12 +531,6 @@ private: /// Checks if every layer required by the aLayerId layer is enabled. bool areRequiredLayersEnabled( int aLayerId ) const; - /// Returns true if the layer is cached - inline bool isCached( int aLayer ) const - { - return ( m_layers.at( aLayer ).target == TARGET_CACHED ); - } - ///* Whether to use rendering order modifier or not bool m_enableOrderModifier;