Commit dd8601cb authored by Maciej Suminski's avatar Maciej Suminski
Browse files

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

parent 10dd5023
Loading
Loading
Loading
Loading
+22 −14
Original line number Diff line number Diff line
@@ -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<EDA_ITEM*>( 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<int> groups = aItem->getAllGroups();
        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 )
    {
        if( aItem->m_cachedGroup >= 0 )
        if( aItem->storesGroups() )
        {
            view->GetGAL()->DeleteGroup( aItem->m_cachedGroup );
            aItem->m_cachedGroup = -1;
            std::vector<int> groups = aItem->getAllGroups();
            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;

+67 −0
Original line number Diff line number Diff line
@@ -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<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 );
}
+1 −1
Original line number Diff line number Diff line
@@ -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 )
+51 −4
Original line number Diff line number Diff line
@@ -30,6 +30,8 @@
#ifndef __VIEW_ITEM_H
#define __VIEW_ITEM_H

#include <vector>

#include <math/box2.h>

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<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