src/hbservers/hbthemeserver/hbicondatacache_p.cpp
changeset 0 16d8024aca5e
child 1 f7ac710697a9
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hbservers/hbthemeserver/hbicondatacache_p.cpp	Mon Apr 19 14:02:13 2010 +0300
@@ -0,0 +1,967 @@
+/****************************************************************************
+**
+** Copyright (C) 2008-2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (developer.feedback@nokia.com)
+**
+** This file is part of the HbServers module of the UI Extensions for Mobile.
+**
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this file.
+** Please review the following information to ensure the GNU Lesser General
+** Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights.  These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at developer.feedback@nokia.com.
+**
+****************************************************************************/
+
+#include "hbicondatacache_p.h"
+#include "hbdoublelinkedlist_p.h"
+#include "hbmemoryutils_p.h"
+#ifdef HB_SGIMAGE_ICON
+#include <sgresource/sgimage.h>
+#include <sgresource/sgresource.h>
+#include "hbsgimageiconprocessor_p.h"
+#endif
+
+/*!
+    @hbserver
+    \class HbIconDataCache
+    \brief HbIconDataCache provides an implementation for the theme server's icon cache.
+    It acts as a central repository for storing the various details of all the icons cached in the server.
+    It provides various methods to insert new items, remove items as well as find existing cached items in the cache.
+    It also has methods to limit the cache size both on Gpu as well as Cpu shared memory.
+
+    Reference count based caching - On performing an Icon look up in the server, if the icon is not already cached,
+    the cache item is created and inserted into cache and its reference count is incremented.
+    If the same icon is requested by another application, the cached instance is returned and only the reference
+    count is incremented. Similarly, the refrence count is decremented whenever an icon is destroyed.
+
+    LRU policy is used for removal of icons from cache.
+    The cache maintains two separate doubly link lists to maintain the order of the least recently used icons created
+    in GPU memory as well as those created in the shared memory. Whenever, the reference count for a cached item becomes 0,
+    it is not deleted from the cache rather; the cached icon instance is appended to the LRU list.
+    Consider now that a scenario arrives when the cache has reached its max limit and there are some unused icons
+    (i.e. icons with reference count = 0) in the LRU list. Suppose at this point there is a new icon caching request.
+    In such a scenario, the unused icons, starting with those at the beginning of the LRU lists are removed from the cache,
+    one after the other, till the new icon can be accommodated.
+
+    Description of data members
+    // A list that maintains an ordered collection of least recently used icons in GPU
+    // which are not being referred to anymore( i.e icons with reference count = 0)
+    HbDLinkList gpuLruList;
+    // A list that maintains an ordered collection of least recently used icons in CPU
+    // which are not being referred to anymore( i.e icons with reference count = 0)
+    HbDLinkList cpuLruList;
+    // Consolidated size of the GPU Cache being occupied by Icons
+    int currentGpuCacheSize;
+    // Consolidated size of the CPU Cache being occupied by Icons
+    int currentCpuCacheSize;
+    // Consolidated size of all the icons with reference count = 0 in GPU Cache
+    int gpuLruListSize;
+    // Consolidated size of all the icons with reference count = 0 in CPU Cache
+    int cpuLruListSize;
+    // Maximum GPU Cache Limit size
+    int maxGpuCacheLimit;
+    // Maximum CPU Cache Limit size
+    int maxCpuCacheLimit;
+
+*/
+
+
+/*!
+    \fn HbIconDataCache::HbIconDataCache()
+    Constructor
+ */
+HbIconDataCache::HbIconDataCache()
+        : gpuLruList(&HbIconCacheItem::gpuLink),
+        cpuLruList(&HbIconCacheItem::cpuLink),
+        currentGpuCacheSize(0),
+        currentCpuCacheSize(0),
+        gpuLruListSize(0),
+        cpuLruListSize(0),
+        maxGpuCacheLimit(0),
+        maxCpuCacheLimit(0),
+        goodMemory(true)
+{
+    cache = new QHash<HbIconKey, HbIconCacheItem*>();
+
+    //Debug Code for Test Purpose
+#ifdef HB_ICON_CACHE_DEBUG
+    addedItemRefCount = 0;
+    addedItemMem = 0;
+    removedItemMem = 0;
+    enableCaching = true;
+    cacheHit = 0;
+    cacheMiss = 0;
+    vectorLruListCount = 0;
+    rasterLruListCount = 0;
+    remRfCount = 0;
+#endif
+}
+
+/*!
+    \fn HbIconDataCache::~HbIconDataCache()
+    Destructor
+ */
+HbIconDataCache::~HbIconDataCache()
+{
+    clear();
+
+    delete cache;
+}
+
+
+/*!
+    \fn HbIconDataCache::clear()
+    Clears the complete cache. Also clears the LRU lists.
+
+ */
+void HbIconDataCache::clear()
+{
+    currentGpuCacheSize = 0;
+    currentCpuCacheSize = 0;
+    gpuLruListSize = 0;
+    cpuLruListSize = 0;
+
+    gpuLruList.removeAll();
+    cpuLruList.removeAll();
+
+    GET_MEMORY_MANAGER(HbMemoryManager::SharedMemory)
+    QHash<HbIconKey, HbIconCacheItem*>::const_iterator itEnd(cache->constEnd());
+    for (QHash < HbIconKey,
+            HbIconCacheItem* >::const_iterator iter = cache->constBegin();
+            iter != itEnd;
+            ++iter) {
+        HbIconCacheItem* temp = iter.value();
+        if (temp->rasterIconData.type != INVALID_FORMAT) {
+            switch (temp->rasterIconData.type) {
+            case PIC :
+                manager->free(temp->rasterIconData.picData.offset);
+                break;
+            case NVG :
+                manager->free(temp->rasterIconData.nvgData.offset);
+                break;
+            case OTHER_SUPPORTED_FORMATS :
+                manager->free(temp->rasterIconData.pixmapData.offset);
+                break;
+            case SGIMAGE:
+#ifdef HB_SGIMAGE_ICON
+                HbSgImageRenderer::removeSgImageFromHash(temp->rasterIconData.sgImageData.id);
+#endif
+                break;
+            default:
+                break;
+            }
+        }
+        if (temp->vectorIconData.type != INVALID_FORMAT) {
+            switch (temp->vectorIconData.type) {
+            case PIC :
+                manager->free(temp->vectorIconData.picData.offset);
+                break;
+            case NVG :
+                manager->free(temp->vectorIconData.nvgData.offset);
+                break;
+            case OTHER_SUPPORTED_FORMATS :
+                manager->free(temp->vectorIconData.pixmapData.offset);
+                break;
+            default:
+                break;
+            }
+        }
+        if (temp->blobIconData.type == BLOB) {
+            manager->free(temp->blobIconData.blobData.offset);
+        }
+        delete   iter.value();
+    }
+    cache->clear();
+
+    //Debug Code for Test Purpose
+#ifdef HB_ICON_CACHE_DEBUG
+    addedItemRefCount = 0;
+    addedItemMem = 0;
+    removedItemMem = 0;
+    remRfCount = 0;
+    enableCaching = true;
+    cacheHit = 0;
+    cacheMiss = 0;
+    vectorLruListCount = 0;
+    rasterLruListCount = 0;
+#endif
+
+}
+
+/*!
+    \fn HbIconDataCache::getCacheItem()
+    Provides a mechanism for finidng whether a cache item is present in the cache.
+    If found, returns the cache item and increments the reference count else returns NULL.
+    \a key denotes the unique identifier for the cache item that is to be searched in the cache.
+
+ */
+HbIconCacheItem* HbIconDataCache::getCacheItem(const HbIconKey &key ,
+        bool isMultiIconPiece)
+{
+    HbIconCacheItem* item = 0;
+
+    if (!cache->contains(key)) {
+        return 0;
+    }
+    // Get the cache item associated with the key
+    item = (*cache)[(key)];
+
+//Debug Code for Test Purpose
+#ifdef HB_ICON_CACHE_DEBUG
+    addedItemMem = item->rasterIconDataCost;
+    cacheHit++;
+#endif
+
+    // If the Icon is present in GPU LRU list, then remove it from the list
+    if (((item->gpuLink.next() != 0) || (item->gpuLink.prev() != 0)) ||
+            ((item == gpuLruList.front()) && (item == gpuLruList.back()))) {
+        gpuLruList.removeNode(item);
+        updateGpuLruSize(-item->rasterIconDataCost);
+        if (gpuLruListSize < 0) {
+            gpuLruListSize = 0;
+        }
+
+        //Debug Code for Test Purpose
+#ifdef HB_ICON_CACHE_DEBUG
+        addedItemMem = item->rasterIconDataCost;
+        rasterLruListCount--;
+        if (rasterLruListCount < 0) {
+            rasterLruListCount = 0;
+        }
+#endif
+    }
+
+    // If the Icon does not have GPU shared data and there is enough space to cache
+    // the icon in GPU cache now, we go ahead and create GPU shared data
+    if ((item->rasterIconData.type == INVALID_FORMAT) &&
+            (goodMemory && !isMultiIconPiece)) {
+        if (item->vectorIconData.type == NVG) {
+
+            HbIconCacheItemCreator::createCacheItem(*item, key);
+            if (item->rasterIconData.type != INVALID_FORMAT) {
+                currentGpuCacheSize += item->rasterIconDataCost;
+            }
+        }
+
+//Debug Code for Test Purpose
+#ifdef HB_ICON_CACHE_DEBUG
+        addedItemMem = item->rasterIconDataCost;
+#endif
+    }
+
+    // If the Icon is present in CPU LRU list, then remove it from the list
+    if (((item->cpuLink.next() != 0) || (item->cpuLink.prev() != 0)) ||
+            ((item == cpuLruList.front()) && (item == cpuLruList.back()))) {
+        cpuLruList.removeNode(item);
+        if (item->rasterIconData.type == OTHER_SUPPORTED_FORMATS) {
+            updateCpuLruSize(-item->rasterIconDataCost);
+        } else {
+            updateCpuLruSize(-item->vectorIconDataCost);
+        }
+                 
+        if (cpuLruListSize < 0){
+            cpuLruListSize = 0;
+        }
+
+        //Debug Code for Test Purpose
+#ifdef HB_ICON_CACHE_DEBUG
+        addedItemMem = item->vectorIconDataCost;
+        vectorLruListCount--;
+        if (vectorLruListCount < 0) {
+            vectorLruListCount = 0;
+        }
+#endif
+    }
+
+    // If the Icon does not have CPU data and there is enough space to create
+    // the icon in CPU cache now, we go ahead and create CPU shared data
+    if ((item->vectorIconData.type == INVALID_FORMAT) &&
+            (item->rasterIconData.type == SGIMAGE)) {
+
+        if ((item->vectorIconDataCost < (maxCpuCacheLimit - currentCpuCacheSize))) {
+            HbIconCacheItemCreator::createCacheItem(*item, key);
+            if (item->vectorIconData.type != INVALID_FORMAT) {
+                currentCpuCacheSize += item->vectorIconDataCost;
+            }
+        }
+    }
+    item->refCount ++;
+
+    //Debug Code for Test Purpose
+#ifdef HB_ICON_CACHE_DEBUG
+    addedItemRefCount = item->refCount;
+    qDebug() << "HbIconDataCache::getCacheItem: " << "Cache hit in Server-Cache for" << key.filename;
+    qDebug() << "HbIconDataCache::getCacheItem: Server RefCount now = " << item->refCount;
+#endif
+
+    return item;
+}
+
+/*!
+    \fn HbIconDataCache::insert()
+    Provides a mechanism for inserting items into the cache.
+    Checks are first done to see whether item can be accomodated in the GPU memory.
+    If so the Gpu limits are updated. Next it tries to cache the item in the Cpu.
+    If possible, the Cpu limits are updated. If niether is possible, a failure to insert is returned.
+    In case of success, the item is inserted into the cache and the reference count for the item is incremented by 1.
+    \a key denotes the unique identifier for the cache item that is to be inserted into the cache.
+    \a item the cache item that is to be inserted into the cache.
+
+ */
+bool HbIconDataCache::insert(const HbIconKey &key, HbIconCacheItem* item)
+{
+    if (!item)
+        return false;
+
+    // Check if Item can be accomdated in GPU cache
+    bool gpuCaching = isItemCachableInGpu(item);
+    // Check if Item can be accomdated in CPU cache
+    bool cpuCaching = isItemCachableInCpu(item);
+
+    // Item cannot be inserted either into GPU cache memory or CPU cache memory
+    if ((!gpuCaching) && (!cpuCaching)) {
+        return false;
+    }
+
+    // Item can be accomdated in GPU cache
+    if (gpuCaching) {
+        // Increment the GPU cache size
+        if( item->rasterIconDataCost <=  maxGpuCacheLimit ) {
+            currentGpuCacheSize += item->rasterIconDataCost;
+        } 
+    }
+
+    // Item can be accomdated in CPU cache
+    if (cpuCaching) {
+        if (item->rasterIconData.type == OTHER_SUPPORTED_FORMATS) {
+            if (item->rasterIconDataCost <= (maxCpuCacheLimit - currentCpuCacheSize)) {
+                currentCpuCacheSize += item->rasterIconDataCost;
+            } else {
+                createCpuCacheSpace(item->rasterIconDataCost);
+                currentCpuCacheSize += item->rasterIconDataCost;
+            }
+        }
+        if (item->vectorIconData.type != INVALID_FORMAT) {
+            // Increment the CPU cache size
+            if (item->vectorIconDataCost <= (maxCpuCacheLimit - currentCpuCacheSize)) {
+                currentCpuCacheSize += item->vectorIconDataCost;
+            } else {
+                // New item's icon data cost is more than available free CPU cahe size
+                // Check if some items, whose ref count is 0, can be removed to make way for new item
+                createCpuCacheSpace(item->vectorIconDataCost);
+                currentCpuCacheSize += item->vectorIconDataCost;
+            }
+        }
+
+        if (currentCpuCacheSize > maxCpuCacheLimit) {
+            currentCpuCacheSize = maxCpuCacheLimit;
+        }
+    }
+    QHash<HbIconKey, HbIconCacheItem*>::iterator iter = cache->insert(key, const_cast<HbIconCacheItem*>(item));
+    if (iter == cache->end()) {
+        return false;
+    }
+
+    item->refCount ++;
+
+    //Debug Code for Test Purpose
+#ifdef HB_ICON_CACHE_DEBUG
+    cacheMiss++;
+    addedItemRefCount = item->refCount;
+    if (gpuCaching) {
+        addedItemMem = item->rasterIconDataCost;
+    } else if (cpuCaching) {
+        addedItemMem = item->vectorIconDataCost;
+    }
+    qDebug() << "HbIconDataCache::insert: " << "Item " << key.filename<<" inserted in Server-Cache";
+    qDebug() << "HbIconDataCache::insert: Server RefCount now = " << item->refCount;
+#endif
+
+    return true;
+}
+
+/*!
+    \fn HbIconDataCache::remove()
+    Remove provides a mechanism for decrementing the reference count of a cached item.
+    In case the reference count becomes 0, the cache item instance is appended to the corresponding LRU list.
+    Actual removal of the cache item from the cache only occurs when the cache has reached a max limit and a new request for
+    insert comes.
+    \a key denotes the unique identifier for the cache item whose ref count is to be decremented in the cache.
+
+ */
+bool HbIconDataCache::remove(const HbIconKey& key)
+{
+    if (key.filename.isEmpty() || !cache->contains(key)) {
+        return false;
+    }
+    HbIconCacheItem* item = (*cache)[(key)];
+    item->refCount--;
+
+    //Debug Code for Test Purpose
+#ifdef HB_ICON_CACHE_DEBUG
+    remRfCount = item->refCount;
+#endif
+
+    if (item->refCount == 0) {
+        if (item->rasterIconData.type == SGIMAGE) {
+            gpuLruList.insertBack(item);
+            updateGpuLruSize(item->rasterIconDataCost);
+        }
+
+        if (item->rasterIconData.type == OTHER_SUPPORTED_FORMATS) {
+            cpuLruList.insertBack(item);
+            updateCpuLruSize(item->rasterIconDataCost);
+        }
+
+
+        //Debug Code for Test Purpose
+#ifdef HB_ICON_CACHE_DEBUG
+        if (! enableCaching) {
+            currentGpuCacheSize -= item->rasterIconDataCost;
+            removedItemMem = item->rasterIconDataCost;
+            removeFromCache(key, item);
+            rasterLruListCount--;
+            if (rasterLruListCount < 0) {
+                rasterLruListCount = 0;
+            }
+
+            if (currentGpuCacheSize < 0) {
+                currentGpuCacheSize = 0;
+            }
+        } else {
+#endif
+
+
+            //Debug Code for Test Purpose
+#ifdef HB_ICON_CACHE_DEBUG
+            rasterLruListCount++;
+        }
+#endif
+
+
+        if ((item->vectorIconData.type != INVALID_FORMAT) &&  item->refCount == 0) {
+
+            //Debug Code for Test Purpose
+#ifdef HB_ICON_CACHE_DEBUG
+            if (! enableCaching) {
+                currentCpuCacheSize -= item->vectorIconDataCost;
+                removedItemMem = item->vectorIconDataCost;
+                removeFromCache(key, item);
+                vectorLruListCount--;
+                if (vectorLruListCount < 0) {
+                    vectorLruListCount = 0;
+                }
+                if (currentCpuCacheSize < 0) {
+                    currentCpuCacheSize = 0;
+                }
+            } else {
+#endif
+
+                cpuLruList.insertBack(item);
+                updateCpuLruSize(item->vectorIconDataCost);
+
+                //Debug Code for Test Purpose
+#ifdef HB_ICON_CACHE_DEBUG
+                vectorLruListCount++;
+            }
+#endif
+        }
+    }
+    return true;
+}
+
+/*!
+    \fn HbIconDataCache::setMaxGpuCacheSize()
+    Provides an internal mechanism for setting the Gpu cache limit
+    \a size denotes the cache limit in bytes e.g. size = 0x500000
+
+ */
+void HbIconDataCache::setMaxGpuCacheSize(int size)
+{
+    //Debug Code for Test Purpose
+#ifdef HB_ICON_CACHE_DEBUG
+    if (maxGpuCacheLimit != size) {
+        if (maxGpuCacheLimit > size) {
+            // remove the item with refcount = 0 in the cache
+            // i.e all the item in both LRU lists.
+            cleanRasterLRUList();
+            if (size <= currentGpuCacheSize) {
+                maxGpuCacheLimit = currentGpuCacheSize;
+            } else {
+                maxGpuCacheLimit = size;
+            }
+        } else {
+            maxGpuCacheLimit = size;
+        }
+    }
+#else
+    maxGpuCacheLimit = size;
+#endif
+
+}
+
+/*!
+    \fn HbIconDataCache::setMaxCpuCacheSize()
+    Provides an internal mechanism for setting the Cpu cache limit
+    \a size denotes the cache limit in bytes e.g. size = 0x500000
+ */
+void HbIconDataCache::setMaxCpuCacheSize(int size)
+{
+    //Debug Code for Test Purpose
+#ifdef HB_ICON_CACHE_DEBUG
+    if (maxCpuCacheLimit != size) {
+        if (maxCpuCacheLimit > size) {
+            // remove the item with refcount = 0 in the cache
+            // i.e all the item in both LRU lists.
+            cleanVectorLRUList();
+            if (size <= currentCpuCacheSize) {
+                maxGpuCacheLimit = currentCpuCacheSize;
+            } else {
+                maxCpuCacheLimit = size;
+            }
+        } else {
+            maxCpuCacheLimit = size;
+        }
+    }
+#else
+    maxCpuCacheLimit = size;
+#endif
+}
+
+/*!
+    \fn HbIconDataCache::contains()
+    Provides a mecahnism for finding whether an item exists in cache.
+    Is different from the find function in that, this function simply checks whether an item is presentin cache, whereas find
+    also performs additional operations such as incrementing the reference count.
+    \a key denotes the unique identifier for the cache item that is to be found into the cache.
+
+ */
+bool HbIconDataCache::contains(const HbIconKey &key)const
+{
+    return (cache->contains(key));
+}
+
+/*!
+    \fn HbIconDataCache::value()
+    Value provides a mechanism for returning the value of the cache item associated with the key
+    \a key denotes the unique identifier for the cache item whose value is to be returned
+
+ */
+HbIconCacheItem* HbIconDataCache::value(const HbIconKey &key)const
+{
+    if (cache->contains(key)) {
+        return cache->value(key);
+    } else {
+        return 0;
+    }
+}
+
+
+/*!
+    \fn HbIconDataCache::isItemCachableInGpu()
+    Checks if the new item can be accomdated in the Gpu memory.
+    \a item is the new item to be cached
+  BLOB is always cached in cpu so this function always returns false for such items.
+ */
+bool HbIconDataCache::isItemCachableInGpu(const HbIconCacheItem* item)const
+{
+    if (maxGpuCacheLimit <= 0 || item->rasterIconDataCost <= 0 || item->blobIconData.type != INVALID_FORMAT ||
+            item->rasterIconData.type != SGIMAGE) {
+        return false;
+    }
+    // Item's GPU Icon's cost is greater than the max GPU Limit
+    if (item->rasterIconDataCost  > maxGpuCacheLimit)
+        return false;
+
+    return true;
+}
+
+/*!
+    \fn HbIconDataCache::isItemCachableInCpu()
+    Checks if the new item can be accomdated in the cpu shared memory.
+    \a item is the new item to be cached
+  BLOB is always cached in cpu, never in gpu.
+ */
+bool HbIconDataCache::isItemCachableInCpu(const HbIconCacheItem* item)const
+{
+    if (maxCpuCacheLimit <= 0) {
+        return false;
+    }
+    if (item->rasterIconData.type == OTHER_SUPPORTED_FORMATS) {
+        if (item->rasterIconDataCost <= 0 || item->rasterIconDataCost > maxCpuCacheLimit) {
+            return false;
+        }
+        if (item->rasterIconDataCost <= (maxCpuCacheLimit - currentCpuCacheSize)) {
+            return true;
+        } else {
+            return (item->rasterIconDataCost <= (maxCpuCacheLimit - currentCpuCacheSize) + cpuLruListSize);
+        }
+    }
+
+    if (item->vectorIconData.type != INVALID_FORMAT) {
+        if (item->vectorIconDataCost <= 0 || item->vectorIconDataCost > maxCpuCacheLimit) {
+            return false;
+        }
+        if (item->vectorIconDataCost <= (maxCpuCacheLimit - currentCpuCacheSize)) {
+            return true;
+        } else {
+            return (item->vectorIconDataCost <= (maxCpuCacheLimit - currentCpuCacheSize) + cpuLruListSize);
+        }
+    }
+    return false;
+}
+
+/*!
+    \fn HbIconDataCache::createGpuCacheSpace()
+    This method provides a way to remove the unused icons( icons with ref count =0.
+    It starts removing the icons from the cache, starting with those that are at the front of the Gpu LRU list.
+    It continues removal of items till there is enough space created to cache the new item in Gpu
+    \a itemCost - cost of the new item to be cached in the Gpu memory
+
+ */
+void HbIconDataCache::createGpuCacheSpace(int itemCost)
+{
+    if (!gpuLruList.isEmpty()) {
+        // Keep removing  items from the cache till there is
+        // enough space to accomdate the new item
+        int freedMemory = 0;
+        while (itemCost > (freedMemory)) {
+            HbIconCacheItem* itemToRemove = gpuLruList.removeFront();
+            // Decrement the Size by the cost of the removed icon's data cost
+            //GET_MEMORY_MANAGER(HbMemoryManager::SharedMemory)
+            //qDebug() << "HbIconDataCache : Calling SgImage Close. Cost = %d  "<< itemToRemove->rasterIconDataCost;
+#ifdef HB_SGIMAGE_ICON
+#ifdef HB_ICON_CACHE_DEBUG
+            qDebug() << "HbIconDataCache : Calling SgImage Close. Cost = %d  "<< itemToRemove->rasterIconDataCost;
+#endif
+            HbSgImageRenderer::removeSgImageFromHash(itemToRemove->rasterIconData.sgImageData.id);  
+#endif
+            itemToRemove->rasterIconData.type = INVALID_FORMAT;
+            itemToRemove->gpuLink.setNext(0);
+            itemToRemove->gpuLink.setPrev(0);
+            currentGpuCacheSize -= itemToRemove->rasterIconDataCost;
+            updateGpuLruSize(-itemToRemove->rasterIconDataCost);
+            freedMemory += itemToRemove->rasterIconDataCost;
+
+            if (currentGpuCacheSize < 0) {
+                currentGpuCacheSize = 0;
+            }
+
+            if (gpuLruListSize < 0) {
+                gpuLruListSize = 0;
+            }
+            //Debug Code for Test Purpose
+#ifdef HB_ICON_CACHE_DEBUG
+            removedItemMem = itemToRemove->rasterIconDataCost;
+            rasterLruListCount--;
+            if (rasterLruListCount < 0) {
+                rasterLruListCount = 0;
+            }
+#endif
+
+            // This is the case where Icon has no CPU data and
+            // the GPU cached data has also  been deleted to make way for new Icon
+            // In such a case the Item can be removed from the Hash
+
+            if ((itemToRemove->rasterIconData.type == INVALID_FORMAT) &&
+                    (itemToRemove->vectorIconData.type == INVALID_FORMAT)) {
+                cache->remove(cache->key(itemToRemove));
+                delete itemToRemove;
+            }
+        }
+    }
+}
+
+/*!
+    \fn HbIconDataCache::createCpuCacheSpace()
+    This method provides a way to remove the unused icons( icons with ref count =0).
+    It starts removing the icons from the cache, starting with those that are at the front of the CPU LRU list.
+    It continues removal of items till there is enough space created to cache the new item in Cpu
+    \a itemCost - cost of the new item to be cached in the Cpu memory
+
+ */
+void HbIconDataCache::createCpuCacheSpace(int itemCost)
+{
+    if (!cpuLruList.isEmpty()) {
+        // Keep removing  items from the cache till there is
+        // enough space to accomdate the new item
+        GET_MEMORY_MANAGER(HbMemoryManager::SharedMemory)
+        while (itemCost > (maxCpuCacheLimit - currentCpuCacheSize)) {
+            HbIconCacheItem* itemToRemove = cpuLruList.removeFront();
+            if (itemToRemove->rasterIconData.type == OTHER_SUPPORTED_FORMATS) {
+                manager->free(itemToRemove->rasterIconData.pixmapData.offset);
+                itemToRemove->rasterIconData.type = INVALID_FORMAT;
+                currentCpuCacheSize -= itemToRemove->rasterIconDataCost;
+                updateCpuLruSize(-itemToRemove->rasterIconDataCost);
+            } else {
+                // Decrement the Size by the cost of the removed icon's data  cost
+                if((itemToRemove->vectorIconData.type == PIC)){
+                    manager->free(itemToRemove->vectorIconData.picData.offset);
+                } else if (itemToRemove->vectorIconData.type == NVG) {
+                    manager->free(itemToRemove->vectorIconData.nvgData.offset);
+                } else if (itemToRemove->blobIconData.type == BLOB) {
+                    manager->free(itemToRemove->blobIconData.blobData.offset);
+                }
+
+                itemToRemove->vectorIconData.type = INVALID_FORMAT;
+                currentCpuCacheSize -= itemToRemove->vectorIconDataCost;
+                updateCpuLruSize(-itemToRemove->vectorIconDataCost);
+            }
+
+
+            itemToRemove->cpuLink.setNext(0);
+            itemToRemove->cpuLink.setPrev(0);
+
+            if (currentCpuCacheSize < 0) {
+                currentCpuCacheSize = 0;
+            }
+
+            if (cpuLruListSize < 0) {
+                cpuLruListSize = 0;
+            }
+
+            //Debug Code for Test Purpose
+#ifdef HB_ICON_CACHE_DEBUG
+            removedItemMem = itemToRemove->vectorIconDataCost;
+            vectorLruListCount--;
+            if (vectorLruListCount < 0) {
+                vectorLruListCount = 0;
+            }
+#endif
+
+            // This is the case where Icon has no CPU data and
+            // the GPU cached data has also  been deleted to make way for new Icon
+            // In such a case the Item can be removed from the Hash
+
+            if ((itemToRemove->vectorIconData.type == INVALID_FORMAT) &&
+                    (itemToRemove->rasterIconData.type == INVALID_FORMAT)) {
+                cache->remove(cache->key(itemToRemove));
+                delete itemToRemove;
+            }
+        }
+    }
+}
+
+void HbIconDataCache::updateGpuLruSize(int iconDataCost)
+{
+    gpuLruListSize += iconDataCost;
+}
+
+void HbIconDataCache::updateCpuLruSize(int iconDataCost)
+{
+    cpuLruListSize += iconDataCost;
+}
+
+void HbIconDataCache::memoryGood()
+{
+    goodMemory = true;
+}
+
+void HbIconDataCache::freeGpuRam(int bytes)
+{
+    goodMemory = false;
+    if (bytes  <= gpuLruListSize) {
+        createGpuCacheSpace(bytes);
+    } else {
+        createGpuCacheSpace(gpuLruListSize);
+    }
+}
+
+//Debug Code for Test Purpose
+#ifdef HB_ICON_CACHE_DEBUG
+void HbIconDataCache::cleanVectorLRUList()
+{
+
+    // remove all the items in cpu LRU list.
+    while (cpuLruList.front()) {
+        HbIconCacheItem* itemToRemove = cpuLruList.removeFront();
+
+        // update the member
+        currentCpuCacheSize -= itemToRemove->vectorIconDataCost;
+        cpuLruListSize -= itemToRemove->vectorIconDataCost;
+        if (currentCpuCacheSize < 0) {
+            currentCpuCacheSize = 0;
+        }
+
+        if (cpuLruListSize < 0) {
+            cpuLruListSize = 0;
+        }
+
+#ifdef HB_ICON_CACHE_DEBUG
+        removedItemMem = itemToRemove->vectorIconDataCost;
+        vectorLruListCount--;
+        if (vectorLruListCount < 0) {
+            vectorLruListCount = 0;
+        }
+#endif
+
+        // remove the shared memory allocatedfor this item.
+        releaseVectorItem(itemToRemove);
+
+        // release item from cache
+        removeFromCache(cache->key(itemToRemove), itemToRemove);
+    }
+}
+
+void HbIconDataCache::releaseVectorItem(HbIconCacheItem* releaseItem)
+{
+    if (!releaseItem) {
+        return;
+    }
+    GET_MEMORY_MANAGER(HbMemoryManager::SharedMemory)
+    // release the specific items  data
+    if (releaseItem->vectorIconData.type == OTHER_SUPPORTED_FORMATS) {
+        manager->free(releaseItem->vectorIconData.pixmapData.offset);
+    } else if ((releaseItem->vectorIconData.type == PIC) ||
+               (releaseItem->vectorIconData.type == SVG)) {
+        manager->free(releaseItem->vectorIconData.picData.offset);
+    } else if (releaseItem->vectorIconData.type == NVG) {
+        manager->free(releaseItem->vectorIconData.nvgData.offset);
+    } else if (releaseItem->blobIconData.type == BLOB) {
+        manager->free(releaseItem->blobIconData.blobData.offset);
+    }
+    releaseItem->vectorIconData.type = INVALID_FORMAT;
+    releaseItem->cpuLink.setNext(0);
+    releaseItem->cpuLink.setPrev(0);
+}
+
+void HbIconDataCache::cleanRasterLRUList()
+{
+
+    // remove all the items from the gpu LRU list
+    while (gpuLruList.front()) {
+        HbIconCacheItem* itemToRemove = gpuLruList.removeFront();
+
+        // update the member
+        currentGpuCacheSize -= itemToRemove->rasterIconDataCost;
+        gpuLruListSize -= itemToRemove->rasterIconDataCost;
+
+        if (currentGpuCacheSize < 0) {
+            currentGpuCacheSize = 0;
+        }
+
+        if (gpuLruListSize < 0) {
+            gpuLruListSize = 0;
+        }
+#ifdef HB_ICON_CACHE_DEBUG
+        removedItemMem = itemToRemove->rasterIconDataCost;
+        rasterLruListCount--;
+        if (rasterLruListCount < 0) {
+            rasterLruListCount = 0;
+        }
+#endif
+
+        // release the shared memory (later raster memory)of this item.
+        releaseRasterItem(itemToRemove);
+
+        // relese from the cache.
+        removeFromCache(cache->key(itemToRemove), itemToRemove);
+    }
+}
+
+void HbIconDataCache::releaseRasterItem(HbIconCacheItem* releaseItem)
+{
+    if (!releaseItem) {
+        return;
+    }
+    GET_MEMORY_MANAGER(HbMemoryManager::SharedMemory)
+    // release the removed item data
+    manager->free(releaseItem->rasterIconData.pixmapData.offset);
+    releaseItem->rasterIconData.type = INVALID_FORMAT;
+}
+
+void HbIconDataCache::removeFromCache(const HbIconKey &key, const HbIconCacheItem* releaseItem)
+{
+    if (!releaseItem) {
+        return;
+    }
+
+    if ((releaseItem->vectorIconData.type == INVALID_FORMAT) &&
+            (releaseItem->rasterIconData.type == INVALID_FORMAT)) {
+        cache->remove(key);
+        delete releaseItem;
+    }
+}
+
+int HbIconDataCache::count() const
+{
+    return cache->count();
+}
+
+int HbIconDataCache::gpuLRUSize() const
+{
+    return gpuLruListSize;
+}
+
+int HbIconDataCache::freeVectorMemory()
+{
+    return (maxCpuCacheLimit - currentCpuCacheSize);
+}
+
+int HbIconDataCache::freeRasterMemory()
+{
+    return (maxGpuCacheLimit - currentGpuCacheSize);
+}
+int HbIconDataCache::lastAddedRefCount()
+{
+    return addedItemRefCount;
+}
+int HbIconDataCache::lastAddedItemMem()
+{
+    return addedItemMem;
+}
+int HbIconDataCache::lastRemovedItemMem()
+{
+    return removedItemMem;
+}
+
+int HbIconDataCache::lastRemovedItemRfCount()
+{
+    return remRfCount;
+}
+
+bool HbIconDataCache::enableCache(bool cacheIt)
+{
+    bool success = false;
+    if (enableCaching != cacheIt) {
+        enableCaching = cacheIt;
+        if (!enableCaching) {
+            cleanVectorLRUList();
+            cleanRasterLRUList();
+        }
+        success = true;
+    }
+    return success;
+}
+
+int HbIconDataCache::cacheHitCount()
+{
+    return cacheHit;
+}
+
+int HbIconDataCache::cacheMissCount()
+{
+    return cacheMiss;
+}
+
+int HbIconDataCache::rasterLruCount()
+{
+    return gpuLruListSize;
+}
+
+int HbIconDataCache::vectorLruCount()
+{
+    return cpuLruListSize;
+}
+#endif