From 8663a6c7a0bef354b3192f6e354136b051cce5b3 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 24 Apr 2013 11:28:11 +0200 Subject: [PATCH] Added caching of multilayer items (storing multiple group ids for items). --- common/view/view.cpp | 36 +++++++++++++-------- common/view/view_item.cpp | 67 +++++++++++++++++++++++++++++++++++++++ include/view/view.h | 2 +- include/view/view_item.h | 55 +++++++++++++++++++++++++++++--- 4 files changed, 141 insertions(+), 19 deletions(-) diff --git a/common/view/view.cpp b/common/view/view.cpp index 4fc6d92968..c185430d3e 100644 --- a/common/view/view.cpp +++ b/common/view/view.cpp @@ -207,7 +207,7 @@ void VIEW::SetGAL( GAL* aGal ) // items need to be recached after changing GAL if( m_useGroups ) - itemsRecache(); + recacheAllItems(); // force the new GAL to display the current viewport. SetCenter( m_center ); @@ -371,7 +371,7 @@ struct VIEW::drawItem if( view->m_useGroups ) { - int group = aItem->m_cachedGroup; + int group = aItem->getGroup( currentLayer ); if( group >= 0 && aItem->ViewIsVisible() ) { @@ -381,7 +381,7 @@ struct VIEW::drawItem else { group = gal->BeginGroup(); - aItem->m_cachedGroup = group; + aItem->setGroup( currentLayer, group ); view->m_painter->Draw( static_cast( aItem ), currentLayer ); gal->EndGroup(); gal->DrawGroup( group ); @@ -419,11 +419,9 @@ void VIEW::redrawRect( const BOX2I& aRect ) { drawItem drawFunc( this, l->id ); - m_gal->BeginLayer(); m_gal->SetLayerDepth( (double) l->renderingOrder ); l->items->Query( aRect, drawFunc ); l->isDirty = false; - m_gal->EndLayer(); totalItems += drawFunc.count; totalDrawTime += drawFunc.time; @@ -454,7 +452,7 @@ struct VIEW::recacheItem { void operator()( VIEW_ITEM* aItem ) { - aItem->m_cachedGroup = -1; + aItem->deleteGroups(); } }; @@ -513,14 +511,19 @@ void VIEW::invalidateItem( VIEW_ITEM* aItem, int aUpdateFlags ) l->items->Insert( aItem ); /* reinsert */ if( m_useGroups ) - aItem->m_cachedGroup = -1; + aItem->deleteGroups(); } } - if( m_useGroups && aItem->m_cachedGroup >= 0 ) + if( m_useGroups && aItem->storesGroups() ) { - m_gal->DeleteGroup( aItem->m_cachedGroup ); - aItem->m_cachedGroup = -1; + std::vector groups = aItem->getAllGroups(); + for(std::vector::iterator i = groups.begin(); i != groups.end(); i++ ) + { + m_gal->DeleteGroup( *i ); + } + + aItem->deleteGroups(); } } @@ -534,10 +537,15 @@ struct VIEW::clearItemCache void operator()( VIEW_ITEM* aItem ) { - if( aItem->m_cachedGroup >= 0 ) + if( aItem->storesGroups() ) { - view->GetGAL()->DeleteGroup( aItem->m_cachedGroup ); - aItem->m_cachedGroup = -1; + std::vector groups = aItem->getAllGroups(); + for(std::vector::iterator i = groups.begin(); i != groups.end(); i++ ) + { + view->GetGAL()->DeleteGroup( *i ); + } + + aItem->deleteGroups(); } } @@ -560,7 +568,7 @@ void VIEW::clearGroupCache() } -void VIEW::itemsRecache() +void VIEW::recacheAllItems() { BOX2I r; diff --git a/common/view/view_item.cpp b/common/view/view_item.cpp index dce0120882..b7f680252d 100644 --- a/common/view/view_item.cpp +++ b/common/view/view_item.cpp @@ -66,3 +66,70 @@ void VIEW_ITEM::ViewRelease() m_view->Remove( this ); } } + + +int VIEW_ITEM::getGroup( int aLayer ) const +{ + for( int i = 0; i < m_groupsSize; ++i ) + { + if( m_groups[i].first == aLayer ) + return m_groups[i].second; + } + + return -1; +} + + +std::vector VIEW_ITEM::getAllGroups() const +{ + std::vector groups( m_groupsSize ); + + for( int i = 0; i < m_groupsSize; ++i ) + { + groups[i] = m_groups[i].second; + } + + return groups; +} + + +void VIEW_ITEM::setGroup( int aLayer, int aId ) +{ + // Look if there is already an entry for the layer + for( int i = 0; i < m_groupsSize; ++i ) + { + if( m_groups[i].first == aLayer ) + { + m_groups[i].second = aId; + return; + } + } + + // If there was no entry for the given layer - create one + GroupPair* newGroups = new GroupPair[m_groupsSize + 1]; + + if( m_groupsSize > 0 ) + { + std::copy( m_groups, m_groups + m_groupsSize, newGroups ); + delete m_groups; + } + + m_groups = newGroups; + newGroups[m_groupsSize++] = GroupPair( aLayer, aId ); +} + + +void VIEW_ITEM::deleteGroups() +{ + if( m_groupsSize > 0 ) + { + delete m_groups; + m_groupsSize = 0; + } +} + + +bool VIEW_ITEM::storesGroups() const +{ + return ( m_groupsSize > 0 ); +} diff --git a/include/view/view.h b/include/view/view.h index d7c879ee47..4cf09cc5c2 100644 --- a/include/view/view.h +++ b/include/view/view.h @@ -351,7 +351,7 @@ private: void clearGroupCache(); ///* Rebuilds GAL display lists - void itemsRecache(); + void recacheAllItems(); /// Determines rendering order of layers. Used in display order sorting function. static bool compareRenderingOrder( VIEW_LAYER* i, VIEW_LAYER* j ) diff --git a/include/view/view_item.h b/include/view/view_item.h index 36643c0a92..019b00fb72 100644 --- a/include/view/view_item.h +++ b/include/view/view_item.h @@ -30,6 +30,8 @@ #ifndef __VIEW_ITEM_H #define __VIEW_ITEM_H +#include + #include namespace KiGfx @@ -52,7 +54,6 @@ class VIEW; class VIEW_ITEM { public: - /** * Enum ViewUpdateFlags. * Defines the how severely the shape/appearance of the item has been changed: @@ -67,7 +68,7 @@ public: ALL = 0xff }; - VIEW_ITEM() : m_view( NULL ), m_viewVisible( true ), m_cachedGroup( -1 ) {} + VIEW_ITEM() : m_view( NULL ), m_viewVisible( true ), m_groupsSize( 0 ) {} /** * Destructor. For dynamic views, removes the item from the view. @@ -167,13 +168,59 @@ protected: // release the item from a previously assigned dynamic view (if there is any) ViewRelease(); m_view = aView; - m_cachedGroup = -1; + deleteGroups(); } VIEW* m_view; ///* Current dynamic view the item is assigned to. bool m_viewVisible; ///* Are we visible in the current dynamic VIEW. private: - int m_cachedGroup; ///* Index of cached GAL display list corresponding to the item + ///* Helper for storing cached items group ids + typedef std::pair GroupPair; + + ///* Indexes of cached GAL display lists corresponding to the item (for every layer it occupies). + ///* (in the std::pair "first" stores layer number, "second" stores group id). + GroupPair* m_groups; + int m_groupsSize; + + /** + * Function getGroup() + * Returns number of the group id for the given layer, or -1 in case it was not cached before. + * + * @param aLayer is the layer number for which group id is queried. + * @return group id or -1 in case there is no group id (ie. item is not cached). + */ + int getGroup( int aLayer ) const; + + /** + * Function getAllGroups() + * Returns all group ids for the item (collected from all layers the item occupies). + * + * @return vector of group ids. + */ + std::vector getAllGroups() const; + + /** + * Function setGroup() + * Sets a group id for the item and the layer combination. + * + * @param aLayer is the layer numbe. + * @param aGroup is the group id. + */ + void setGroup( int aLayer, int aGroup ); + + /** + * Function deleteGroups() + * Removes all of the stored group ids. Forces recaching of the item. + */ + void deleteGroups(); + + /** + * Function storesGroups() + * Returns information if the item uses at least one group id (ie. if it is cached at all). + * + * @returns true in case it is cached at least for one layer. + */ + bool storesGroups() const; }; } // namespace KiGfx