Added caching of multilayer items (storing multiple group ids for items).

This commit is contained in:
Maciej Suminski 2013-04-24 11:28:11 +02:00
parent 10dd5023e2
commit dd8601cbf8
4 changed files with 141 additions and 19 deletions

View File

@ -207,7 +207,7 @@ void VIEW::SetGAL( GAL* aGal )
// items need to be recached after changing GAL // items need to be recached after changing GAL
if( m_useGroups ) if( m_useGroups )
itemsRecache(); recacheAllItems();
// force the new GAL to display the current viewport. // force the new GAL to display the current viewport.
SetCenter( m_center ); SetCenter( m_center );
@ -371,7 +371,7 @@ struct VIEW::drawItem
if( view->m_useGroups ) if( view->m_useGroups )
{ {
int group = aItem->m_cachedGroup; int group = aItem->getGroup( currentLayer );
if( group >= 0 && aItem->ViewIsVisible() ) if( group >= 0 && aItem->ViewIsVisible() )
{ {
@ -381,7 +381,7 @@ struct VIEW::drawItem
else else
{ {
group = gal->BeginGroup(); group = gal->BeginGroup();
aItem->m_cachedGroup = group; aItem->setGroup( currentLayer, group );
view->m_painter->Draw( static_cast<EDA_ITEM*>( aItem ), currentLayer ); view->m_painter->Draw( static_cast<EDA_ITEM*>( aItem ), currentLayer );
gal->EndGroup(); gal->EndGroup();
gal->DrawGroup( group ); gal->DrawGroup( group );
@ -419,11 +419,9 @@ void VIEW::redrawRect( const BOX2I& aRect )
{ {
drawItem drawFunc( this, l->id ); drawItem drawFunc( this, l->id );
m_gal->BeginLayer();
m_gal->SetLayerDepth( (double) l->renderingOrder ); m_gal->SetLayerDepth( (double) l->renderingOrder );
l->items->Query( aRect, drawFunc ); l->items->Query( aRect, drawFunc );
l->isDirty = false; l->isDirty = false;
m_gal->EndLayer();
totalItems += drawFunc.count; totalItems += drawFunc.count;
totalDrawTime += drawFunc.time; totalDrawTime += drawFunc.time;
@ -454,7 +452,7 @@ struct VIEW::recacheItem
{ {
void operator()( VIEW_ITEM* aItem ) 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 */ l->items->Insert( aItem ); /* reinsert */
if( m_useGroups ) 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 ); std::vector<int> groups = aItem->getAllGroups();
aItem->m_cachedGroup = -1; for(std::vector<int>::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 ) void operator()( VIEW_ITEM* aItem )
{ {
if( aItem->m_cachedGroup >= 0 ) if( aItem->storesGroups() )
{ {
view->GetGAL()->DeleteGroup( aItem->m_cachedGroup ); std::vector<int> groups = aItem->getAllGroups();
aItem->m_cachedGroup = -1; for(std::vector<int>::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; BOX2I r;

View File

@ -66,3 +66,70 @@ void VIEW_ITEM::ViewRelease()
m_view->Remove( this ); 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<int> VIEW_ITEM::getAllGroups() const
{
std::vector<int> 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 );
}

View File

@ -351,7 +351,7 @@ private:
void clearGroupCache(); void clearGroupCache();
///* Rebuilds GAL display lists ///* Rebuilds GAL display lists
void itemsRecache(); void recacheAllItems();
/// Determines rendering order of layers. Used in display order sorting function. /// Determines rendering order of layers. Used in display order sorting function.
static bool compareRenderingOrder( VIEW_LAYER* i, VIEW_LAYER* j ) static bool compareRenderingOrder( VIEW_LAYER* i, VIEW_LAYER* j )

View File

@ -30,6 +30,8 @@
#ifndef __VIEW_ITEM_H #ifndef __VIEW_ITEM_H
#define __VIEW_ITEM_H #define __VIEW_ITEM_H
#include <vector>
#include <math/box2.h> #include <math/box2.h>
namespace KiGfx namespace KiGfx
@ -52,7 +54,6 @@ class VIEW;
class VIEW_ITEM class VIEW_ITEM
{ {
public: public:
/** /**
* Enum ViewUpdateFlags. * Enum ViewUpdateFlags.
* Defines the how severely the shape/appearance of the item has been changed: * Defines the how severely the shape/appearance of the item has been changed:
@ -67,7 +68,7 @@ public:
ALL = 0xff 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. * 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) // release the item from a previously assigned dynamic view (if there is any)
ViewRelease(); ViewRelease();
m_view = aView; m_view = aView;
m_cachedGroup = -1; deleteGroups();
} }
VIEW* m_view; ///* Current dynamic view the item is assigned to. VIEW* m_view; ///* Current dynamic view the item is assigned to.
bool m_viewVisible; ///* Are we visible in the current dynamic VIEW. bool m_viewVisible; ///* Are we visible in the current dynamic VIEW.
private: private:
int m_cachedGroup; ///* Index of cached GAL display list corresponding to the item ///* Helper for storing cached items group ids
typedef std::pair<int, int> 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<int> 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 } // namespace KiGfx