src/hbservers/hbthemeserver/hbicondatacache_p.cpp
changeset 0 16d8024aca5e
child 1 f7ac710697a9
equal deleted inserted replaced
-1:000000000000 0:16d8024aca5e
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2008-2010 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (developer.feedback@nokia.com)
       
     6 **
       
     7 ** This file is part of the HbServers module of the UI Extensions for Mobile.
       
     8 **
       
     9 ** GNU Lesser General Public License Usage
       
    10 ** This file may be used under the terms of the GNU Lesser General Public
       
    11 ** License version 2.1 as published by the Free Software Foundation and
       
    12 ** appearing in the file LICENSE.LGPL included in the packaging of this file.
       
    13 ** Please review the following information to ensure the GNU Lesser General
       
    14 ** Public License version 2.1 requirements will be met:
       
    15 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
       
    16 **
       
    17 ** In addition, as a special exception, Nokia gives you certain additional
       
    18 ** rights.  These rights are described in the Nokia Qt LGPL Exception
       
    19 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
       
    20 **
       
    21 ** If you have questions regarding the use of this file, please contact
       
    22 ** Nokia at developer.feedback@nokia.com.
       
    23 **
       
    24 ****************************************************************************/
       
    25 
       
    26 #include "hbicondatacache_p.h"
       
    27 #include "hbdoublelinkedlist_p.h"
       
    28 #include "hbmemoryutils_p.h"
       
    29 #ifdef HB_SGIMAGE_ICON
       
    30 #include <sgresource/sgimage.h>
       
    31 #include <sgresource/sgresource.h>
       
    32 #include "hbsgimageiconprocessor_p.h"
       
    33 #endif
       
    34 
       
    35 /*!
       
    36     @hbserver
       
    37     \class HbIconDataCache
       
    38     \brief HbIconDataCache provides an implementation for the theme server's icon cache.
       
    39     It acts as a central repository for storing the various details of all the icons cached in the server.
       
    40     It provides various methods to insert new items, remove items as well as find existing cached items in the cache.
       
    41     It also has methods to limit the cache size both on Gpu as well as Cpu shared memory.
       
    42 
       
    43     Reference count based caching - On performing an Icon look up in the server, if the icon is not already cached,
       
    44     the cache item is created and inserted into cache and its reference count is incremented.
       
    45     If the same icon is requested by another application, the cached instance is returned and only the reference
       
    46     count is incremented. Similarly, the refrence count is decremented whenever an icon is destroyed.
       
    47 
       
    48     LRU policy is used for removal of icons from cache.
       
    49     The cache maintains two separate doubly link lists to maintain the order of the least recently used icons created
       
    50     in GPU memory as well as those created in the shared memory. Whenever, the reference count for a cached item becomes 0,
       
    51     it is not deleted from the cache rather; the cached icon instance is appended to the LRU list.
       
    52     Consider now that a scenario arrives when the cache has reached its max limit and there are some unused icons
       
    53     (i.e. icons with reference count = 0) in the LRU list. Suppose at this point there is a new icon caching request.
       
    54     In such a scenario, the unused icons, starting with those at the beginning of the LRU lists are removed from the cache,
       
    55     one after the other, till the new icon can be accommodated.
       
    56 
       
    57     Description of data members
       
    58     // A list that maintains an ordered collection of least recently used icons in GPU
       
    59     // which are not being referred to anymore( i.e icons with reference count = 0)
       
    60     HbDLinkList gpuLruList;
       
    61     // A list that maintains an ordered collection of least recently used icons in CPU
       
    62     // which are not being referred to anymore( i.e icons with reference count = 0)
       
    63     HbDLinkList cpuLruList;
       
    64     // Consolidated size of the GPU Cache being occupied by Icons
       
    65     int currentGpuCacheSize;
       
    66     // Consolidated size of the CPU Cache being occupied by Icons
       
    67     int currentCpuCacheSize;
       
    68     // Consolidated size of all the icons with reference count = 0 in GPU Cache
       
    69     int gpuLruListSize;
       
    70     // Consolidated size of all the icons with reference count = 0 in CPU Cache
       
    71     int cpuLruListSize;
       
    72     // Maximum GPU Cache Limit size
       
    73     int maxGpuCacheLimit;
       
    74     // Maximum CPU Cache Limit size
       
    75     int maxCpuCacheLimit;
       
    76 
       
    77 */
       
    78 
       
    79 
       
    80 /*!
       
    81     \fn HbIconDataCache::HbIconDataCache()
       
    82     Constructor
       
    83  */
       
    84 HbIconDataCache::HbIconDataCache()
       
    85         : gpuLruList(&HbIconCacheItem::gpuLink),
       
    86         cpuLruList(&HbIconCacheItem::cpuLink),
       
    87         currentGpuCacheSize(0),
       
    88         currentCpuCacheSize(0),
       
    89         gpuLruListSize(0),
       
    90         cpuLruListSize(0),
       
    91         maxGpuCacheLimit(0),
       
    92         maxCpuCacheLimit(0),
       
    93         goodMemory(true)
       
    94 {
       
    95     cache = new QHash<HbIconKey, HbIconCacheItem*>();
       
    96 
       
    97     //Debug Code for Test Purpose
       
    98 #ifdef HB_ICON_CACHE_DEBUG
       
    99     addedItemRefCount = 0;
       
   100     addedItemMem = 0;
       
   101     removedItemMem = 0;
       
   102     enableCaching = true;
       
   103     cacheHit = 0;
       
   104     cacheMiss = 0;
       
   105     vectorLruListCount = 0;
       
   106     rasterLruListCount = 0;
       
   107     remRfCount = 0;
       
   108 #endif
       
   109 }
       
   110 
       
   111 /*!
       
   112     \fn HbIconDataCache::~HbIconDataCache()
       
   113     Destructor
       
   114  */
       
   115 HbIconDataCache::~HbIconDataCache()
       
   116 {
       
   117     clear();
       
   118 
       
   119     delete cache;
       
   120 }
       
   121 
       
   122 
       
   123 /*!
       
   124     \fn HbIconDataCache::clear()
       
   125     Clears the complete cache. Also clears the LRU lists.
       
   126 
       
   127  */
       
   128 void HbIconDataCache::clear()
       
   129 {
       
   130     currentGpuCacheSize = 0;
       
   131     currentCpuCacheSize = 0;
       
   132     gpuLruListSize = 0;
       
   133     cpuLruListSize = 0;
       
   134 
       
   135     gpuLruList.removeAll();
       
   136     cpuLruList.removeAll();
       
   137 
       
   138     GET_MEMORY_MANAGER(HbMemoryManager::SharedMemory)
       
   139     QHash<HbIconKey, HbIconCacheItem*>::const_iterator itEnd(cache->constEnd());
       
   140     for (QHash < HbIconKey,
       
   141             HbIconCacheItem* >::const_iterator iter = cache->constBegin();
       
   142             iter != itEnd;
       
   143             ++iter) {
       
   144         HbIconCacheItem* temp = iter.value();
       
   145         if (temp->rasterIconData.type != INVALID_FORMAT) {
       
   146             switch (temp->rasterIconData.type) {
       
   147             case PIC :
       
   148                 manager->free(temp->rasterIconData.picData.offset);
       
   149                 break;
       
   150             case NVG :
       
   151                 manager->free(temp->rasterIconData.nvgData.offset);
       
   152                 break;
       
   153             case OTHER_SUPPORTED_FORMATS :
       
   154                 manager->free(temp->rasterIconData.pixmapData.offset);
       
   155                 break;
       
   156             case SGIMAGE:
       
   157 #ifdef HB_SGIMAGE_ICON
       
   158                 HbSgImageRenderer::removeSgImageFromHash(temp->rasterIconData.sgImageData.id);
       
   159 #endif
       
   160                 break;
       
   161             default:
       
   162                 break;
       
   163             }
       
   164         }
       
   165         if (temp->vectorIconData.type != INVALID_FORMAT) {
       
   166             switch (temp->vectorIconData.type) {
       
   167             case PIC :
       
   168                 manager->free(temp->vectorIconData.picData.offset);
       
   169                 break;
       
   170             case NVG :
       
   171                 manager->free(temp->vectorIconData.nvgData.offset);
       
   172                 break;
       
   173             case OTHER_SUPPORTED_FORMATS :
       
   174                 manager->free(temp->vectorIconData.pixmapData.offset);
       
   175                 break;
       
   176             default:
       
   177                 break;
       
   178             }
       
   179         }
       
   180         if (temp->blobIconData.type == BLOB) {
       
   181             manager->free(temp->blobIconData.blobData.offset);
       
   182         }
       
   183         delete   iter.value();
       
   184     }
       
   185     cache->clear();
       
   186 
       
   187     //Debug Code for Test Purpose
       
   188 #ifdef HB_ICON_CACHE_DEBUG
       
   189     addedItemRefCount = 0;
       
   190     addedItemMem = 0;
       
   191     removedItemMem = 0;
       
   192     remRfCount = 0;
       
   193     enableCaching = true;
       
   194     cacheHit = 0;
       
   195     cacheMiss = 0;
       
   196     vectorLruListCount = 0;
       
   197     rasterLruListCount = 0;
       
   198 #endif
       
   199 
       
   200 }
       
   201 
       
   202 /*!
       
   203     \fn HbIconDataCache::getCacheItem()
       
   204     Provides a mechanism for finidng whether a cache item is present in the cache.
       
   205     If found, returns the cache item and increments the reference count else returns NULL.
       
   206     \a key denotes the unique identifier for the cache item that is to be searched in the cache.
       
   207 
       
   208  */
       
   209 HbIconCacheItem* HbIconDataCache::getCacheItem(const HbIconKey &key ,
       
   210         bool isMultiIconPiece)
       
   211 {
       
   212     HbIconCacheItem* item = 0;
       
   213 
       
   214     if (!cache->contains(key)) {
       
   215         return 0;
       
   216     }
       
   217     // Get the cache item associated with the key
       
   218     item = (*cache)[(key)];
       
   219 
       
   220 //Debug Code for Test Purpose
       
   221 #ifdef HB_ICON_CACHE_DEBUG
       
   222     addedItemMem = item->rasterIconDataCost;
       
   223     cacheHit++;
       
   224 #endif
       
   225 
       
   226     // If the Icon is present in GPU LRU list, then remove it from the list
       
   227     if (((item->gpuLink.next() != 0) || (item->gpuLink.prev() != 0)) ||
       
   228             ((item == gpuLruList.front()) && (item == gpuLruList.back()))) {
       
   229         gpuLruList.removeNode(item);
       
   230         updateGpuLruSize(-item->rasterIconDataCost);
       
   231         if (gpuLruListSize < 0) {
       
   232             gpuLruListSize = 0;
       
   233         }
       
   234 
       
   235         //Debug Code for Test Purpose
       
   236 #ifdef HB_ICON_CACHE_DEBUG
       
   237         addedItemMem = item->rasterIconDataCost;
       
   238         rasterLruListCount--;
       
   239         if (rasterLruListCount < 0) {
       
   240             rasterLruListCount = 0;
       
   241         }
       
   242 #endif
       
   243     }
       
   244 
       
   245     // If the Icon does not have GPU shared data and there is enough space to cache
       
   246     // the icon in GPU cache now, we go ahead and create GPU shared data
       
   247     if ((item->rasterIconData.type == INVALID_FORMAT) &&
       
   248             (goodMemory && !isMultiIconPiece)) {
       
   249         if (item->vectorIconData.type == NVG) {
       
   250 
       
   251             HbIconCacheItemCreator::createCacheItem(*item, key);
       
   252             if (item->rasterIconData.type != INVALID_FORMAT) {
       
   253                 currentGpuCacheSize += item->rasterIconDataCost;
       
   254             }
       
   255         }
       
   256 
       
   257 //Debug Code for Test Purpose
       
   258 #ifdef HB_ICON_CACHE_DEBUG
       
   259         addedItemMem = item->rasterIconDataCost;
       
   260 #endif
       
   261     }
       
   262 
       
   263     // If the Icon is present in CPU LRU list, then remove it from the list
       
   264     if (((item->cpuLink.next() != 0) || (item->cpuLink.prev() != 0)) ||
       
   265             ((item == cpuLruList.front()) && (item == cpuLruList.back()))) {
       
   266         cpuLruList.removeNode(item);
       
   267         if (item->rasterIconData.type == OTHER_SUPPORTED_FORMATS) {
       
   268             updateCpuLruSize(-item->rasterIconDataCost);
       
   269         } else {
       
   270             updateCpuLruSize(-item->vectorIconDataCost);
       
   271         }
       
   272                  
       
   273         if (cpuLruListSize < 0){
       
   274             cpuLruListSize = 0;
       
   275         }
       
   276 
       
   277         //Debug Code for Test Purpose
       
   278 #ifdef HB_ICON_CACHE_DEBUG
       
   279         addedItemMem = item->vectorIconDataCost;
       
   280         vectorLruListCount--;
       
   281         if (vectorLruListCount < 0) {
       
   282             vectorLruListCount = 0;
       
   283         }
       
   284 #endif
       
   285     }
       
   286 
       
   287     // If the Icon does not have CPU data and there is enough space to create
       
   288     // the icon in CPU cache now, we go ahead and create CPU shared data
       
   289     if ((item->vectorIconData.type == INVALID_FORMAT) &&
       
   290             (item->rasterIconData.type == SGIMAGE)) {
       
   291 
       
   292         if ((item->vectorIconDataCost < (maxCpuCacheLimit - currentCpuCacheSize))) {
       
   293             HbIconCacheItemCreator::createCacheItem(*item, key);
       
   294             if (item->vectorIconData.type != INVALID_FORMAT) {
       
   295                 currentCpuCacheSize += item->vectorIconDataCost;
       
   296             }
       
   297         }
       
   298     }
       
   299     item->refCount ++;
       
   300 
       
   301     //Debug Code for Test Purpose
       
   302 #ifdef HB_ICON_CACHE_DEBUG
       
   303     addedItemRefCount = item->refCount;
       
   304     qDebug() << "HbIconDataCache::getCacheItem: " << "Cache hit in Server-Cache for" << key.filename;
       
   305     qDebug() << "HbIconDataCache::getCacheItem: Server RefCount now = " << item->refCount;
       
   306 #endif
       
   307 
       
   308     return item;
       
   309 }
       
   310 
       
   311 /*!
       
   312     \fn HbIconDataCache::insert()
       
   313     Provides a mechanism for inserting items into the cache.
       
   314     Checks are first done to see whether item can be accomodated in the GPU memory.
       
   315     If so the Gpu limits are updated. Next it tries to cache the item in the Cpu.
       
   316     If possible, the Cpu limits are updated. If niether is possible, a failure to insert is returned.
       
   317     In case of success, the item is inserted into the cache and the reference count for the item is incremented by 1.
       
   318     \a key denotes the unique identifier for the cache item that is to be inserted into the cache.
       
   319     \a item the cache item that is to be inserted into the cache.
       
   320 
       
   321  */
       
   322 bool HbIconDataCache::insert(const HbIconKey &key, HbIconCacheItem* item)
       
   323 {
       
   324     if (!item)
       
   325         return false;
       
   326 
       
   327     // Check if Item can be accomdated in GPU cache
       
   328     bool gpuCaching = isItemCachableInGpu(item);
       
   329     // Check if Item can be accomdated in CPU cache
       
   330     bool cpuCaching = isItemCachableInCpu(item);
       
   331 
       
   332     // Item cannot be inserted either into GPU cache memory or CPU cache memory
       
   333     if ((!gpuCaching) && (!cpuCaching)) {
       
   334         return false;
       
   335     }
       
   336 
       
   337     // Item can be accomdated in GPU cache
       
   338     if (gpuCaching) {
       
   339         // Increment the GPU cache size
       
   340         if( item->rasterIconDataCost <=  maxGpuCacheLimit ) {
       
   341             currentGpuCacheSize += item->rasterIconDataCost;
       
   342         } 
       
   343     }
       
   344 
       
   345     // Item can be accomdated in CPU cache
       
   346     if (cpuCaching) {
       
   347         if (item->rasterIconData.type == OTHER_SUPPORTED_FORMATS) {
       
   348             if (item->rasterIconDataCost <= (maxCpuCacheLimit - currentCpuCacheSize)) {
       
   349                 currentCpuCacheSize += item->rasterIconDataCost;
       
   350             } else {
       
   351                 createCpuCacheSpace(item->rasterIconDataCost);
       
   352                 currentCpuCacheSize += item->rasterIconDataCost;
       
   353             }
       
   354         }
       
   355         if (item->vectorIconData.type != INVALID_FORMAT) {
       
   356             // Increment the CPU cache size
       
   357             if (item->vectorIconDataCost <= (maxCpuCacheLimit - currentCpuCacheSize)) {
       
   358                 currentCpuCacheSize += item->vectorIconDataCost;
       
   359             } else {
       
   360                 // New item's icon data cost is more than available free CPU cahe size
       
   361                 // Check if some items, whose ref count is 0, can be removed to make way for new item
       
   362                 createCpuCacheSpace(item->vectorIconDataCost);
       
   363                 currentCpuCacheSize += item->vectorIconDataCost;
       
   364             }
       
   365         }
       
   366 
       
   367         if (currentCpuCacheSize > maxCpuCacheLimit) {
       
   368             currentCpuCacheSize = maxCpuCacheLimit;
       
   369         }
       
   370     }
       
   371     QHash<HbIconKey, HbIconCacheItem*>::iterator iter = cache->insert(key, const_cast<HbIconCacheItem*>(item));
       
   372     if (iter == cache->end()) {
       
   373         return false;
       
   374     }
       
   375 
       
   376     item->refCount ++;
       
   377 
       
   378     //Debug Code for Test Purpose
       
   379 #ifdef HB_ICON_CACHE_DEBUG
       
   380     cacheMiss++;
       
   381     addedItemRefCount = item->refCount;
       
   382     if (gpuCaching) {
       
   383         addedItemMem = item->rasterIconDataCost;
       
   384     } else if (cpuCaching) {
       
   385         addedItemMem = item->vectorIconDataCost;
       
   386     }
       
   387     qDebug() << "HbIconDataCache::insert: " << "Item " << key.filename<<" inserted in Server-Cache";
       
   388     qDebug() << "HbIconDataCache::insert: Server RefCount now = " << item->refCount;
       
   389 #endif
       
   390 
       
   391     return true;
       
   392 }
       
   393 
       
   394 /*!
       
   395     \fn HbIconDataCache::remove()
       
   396     Remove provides a mechanism for decrementing the reference count of a cached item.
       
   397     In case the reference count becomes 0, the cache item instance is appended to the corresponding LRU list.
       
   398     Actual removal of the cache item from the cache only occurs when the cache has reached a max limit and a new request for
       
   399     insert comes.
       
   400     \a key denotes the unique identifier for the cache item whose ref count is to be decremented in the cache.
       
   401 
       
   402  */
       
   403 bool HbIconDataCache::remove(const HbIconKey& key)
       
   404 {
       
   405     if (key.filename.isEmpty() || !cache->contains(key)) {
       
   406         return false;
       
   407     }
       
   408     HbIconCacheItem* item = (*cache)[(key)];
       
   409     item->refCount--;
       
   410 
       
   411     //Debug Code for Test Purpose
       
   412 #ifdef HB_ICON_CACHE_DEBUG
       
   413     remRfCount = item->refCount;
       
   414 #endif
       
   415 
       
   416     if (item->refCount == 0) {
       
   417         if (item->rasterIconData.type == SGIMAGE) {
       
   418             gpuLruList.insertBack(item);
       
   419             updateGpuLruSize(item->rasterIconDataCost);
       
   420         }
       
   421 
       
   422         if (item->rasterIconData.type == OTHER_SUPPORTED_FORMATS) {
       
   423             cpuLruList.insertBack(item);
       
   424             updateCpuLruSize(item->rasterIconDataCost);
       
   425         }
       
   426 
       
   427 
       
   428         //Debug Code for Test Purpose
       
   429 #ifdef HB_ICON_CACHE_DEBUG
       
   430         if (! enableCaching) {
       
   431             currentGpuCacheSize -= item->rasterIconDataCost;
       
   432             removedItemMem = item->rasterIconDataCost;
       
   433             removeFromCache(key, item);
       
   434             rasterLruListCount--;
       
   435             if (rasterLruListCount < 0) {
       
   436                 rasterLruListCount = 0;
       
   437             }
       
   438 
       
   439             if (currentGpuCacheSize < 0) {
       
   440                 currentGpuCacheSize = 0;
       
   441             }
       
   442         } else {
       
   443 #endif
       
   444 
       
   445 
       
   446             //Debug Code for Test Purpose
       
   447 #ifdef HB_ICON_CACHE_DEBUG
       
   448             rasterLruListCount++;
       
   449         }
       
   450 #endif
       
   451 
       
   452 
       
   453         if ((item->vectorIconData.type != INVALID_FORMAT) &&  item->refCount == 0) {
       
   454 
       
   455             //Debug Code for Test Purpose
       
   456 #ifdef HB_ICON_CACHE_DEBUG
       
   457             if (! enableCaching) {
       
   458                 currentCpuCacheSize -= item->vectorIconDataCost;
       
   459                 removedItemMem = item->vectorIconDataCost;
       
   460                 removeFromCache(key, item);
       
   461                 vectorLruListCount--;
       
   462                 if (vectorLruListCount < 0) {
       
   463                     vectorLruListCount = 0;
       
   464                 }
       
   465                 if (currentCpuCacheSize < 0) {
       
   466                     currentCpuCacheSize = 0;
       
   467                 }
       
   468             } else {
       
   469 #endif
       
   470 
       
   471                 cpuLruList.insertBack(item);
       
   472                 updateCpuLruSize(item->vectorIconDataCost);
       
   473 
       
   474                 //Debug Code for Test Purpose
       
   475 #ifdef HB_ICON_CACHE_DEBUG
       
   476                 vectorLruListCount++;
       
   477             }
       
   478 #endif
       
   479         }
       
   480     }
       
   481     return true;
       
   482 }
       
   483 
       
   484 /*!
       
   485     \fn HbIconDataCache::setMaxGpuCacheSize()
       
   486     Provides an internal mechanism for setting the Gpu cache limit
       
   487     \a size denotes the cache limit in bytes e.g. size = 0x500000
       
   488 
       
   489  */
       
   490 void HbIconDataCache::setMaxGpuCacheSize(int size)
       
   491 {
       
   492     //Debug Code for Test Purpose
       
   493 #ifdef HB_ICON_CACHE_DEBUG
       
   494     if (maxGpuCacheLimit != size) {
       
   495         if (maxGpuCacheLimit > size) {
       
   496             // remove the item with refcount = 0 in the cache
       
   497             // i.e all the item in both LRU lists.
       
   498             cleanRasterLRUList();
       
   499             if (size <= currentGpuCacheSize) {
       
   500                 maxGpuCacheLimit = currentGpuCacheSize;
       
   501             } else {
       
   502                 maxGpuCacheLimit = size;
       
   503             }
       
   504         } else {
       
   505             maxGpuCacheLimit = size;
       
   506         }
       
   507     }
       
   508 #else
       
   509     maxGpuCacheLimit = size;
       
   510 #endif
       
   511 
       
   512 }
       
   513 
       
   514 /*!
       
   515     \fn HbIconDataCache::setMaxCpuCacheSize()
       
   516     Provides an internal mechanism for setting the Cpu cache limit
       
   517     \a size denotes the cache limit in bytes e.g. size = 0x500000
       
   518  */
       
   519 void HbIconDataCache::setMaxCpuCacheSize(int size)
       
   520 {
       
   521     //Debug Code for Test Purpose
       
   522 #ifdef HB_ICON_CACHE_DEBUG
       
   523     if (maxCpuCacheLimit != size) {
       
   524         if (maxCpuCacheLimit > size) {
       
   525             // remove the item with refcount = 0 in the cache
       
   526             // i.e all the item in both LRU lists.
       
   527             cleanVectorLRUList();
       
   528             if (size <= currentCpuCacheSize) {
       
   529                 maxGpuCacheLimit = currentCpuCacheSize;
       
   530             } else {
       
   531                 maxCpuCacheLimit = size;
       
   532             }
       
   533         } else {
       
   534             maxCpuCacheLimit = size;
       
   535         }
       
   536     }
       
   537 #else
       
   538     maxCpuCacheLimit = size;
       
   539 #endif
       
   540 }
       
   541 
       
   542 /*!
       
   543     \fn HbIconDataCache::contains()
       
   544     Provides a mecahnism for finding whether an item exists in cache.
       
   545     Is different from the find function in that, this function simply checks whether an item is presentin cache, whereas find
       
   546     also performs additional operations such as incrementing the reference count.
       
   547     \a key denotes the unique identifier for the cache item that is to be found into the cache.
       
   548 
       
   549  */
       
   550 bool HbIconDataCache::contains(const HbIconKey &key)const
       
   551 {
       
   552     return (cache->contains(key));
       
   553 }
       
   554 
       
   555 /*!
       
   556     \fn HbIconDataCache::value()
       
   557     Value provides a mechanism for returning the value of the cache item associated with the key
       
   558     \a key denotes the unique identifier for the cache item whose value is to be returned
       
   559 
       
   560  */
       
   561 HbIconCacheItem* HbIconDataCache::value(const HbIconKey &key)const
       
   562 {
       
   563     if (cache->contains(key)) {
       
   564         return cache->value(key);
       
   565     } else {
       
   566         return 0;
       
   567     }
       
   568 }
       
   569 
       
   570 
       
   571 /*!
       
   572     \fn HbIconDataCache::isItemCachableInGpu()
       
   573     Checks if the new item can be accomdated in the Gpu memory.
       
   574     \a item is the new item to be cached
       
   575   BLOB is always cached in cpu so this function always returns false for such items.
       
   576  */
       
   577 bool HbIconDataCache::isItemCachableInGpu(const HbIconCacheItem* item)const
       
   578 {
       
   579     if (maxGpuCacheLimit <= 0 || item->rasterIconDataCost <= 0 || item->blobIconData.type != INVALID_FORMAT ||
       
   580             item->rasterIconData.type != SGIMAGE) {
       
   581         return false;
       
   582     }
       
   583     // Item's GPU Icon's cost is greater than the max GPU Limit
       
   584     if (item->rasterIconDataCost  > maxGpuCacheLimit)
       
   585         return false;
       
   586 
       
   587     return true;
       
   588 }
       
   589 
       
   590 /*!
       
   591     \fn HbIconDataCache::isItemCachableInCpu()
       
   592     Checks if the new item can be accomdated in the cpu shared memory.
       
   593     \a item is the new item to be cached
       
   594   BLOB is always cached in cpu, never in gpu.
       
   595  */
       
   596 bool HbIconDataCache::isItemCachableInCpu(const HbIconCacheItem* item)const
       
   597 {
       
   598     if (maxCpuCacheLimit <= 0) {
       
   599         return false;
       
   600     }
       
   601     if (item->rasterIconData.type == OTHER_SUPPORTED_FORMATS) {
       
   602         if (item->rasterIconDataCost <= 0 || item->rasterIconDataCost > maxCpuCacheLimit) {
       
   603             return false;
       
   604         }
       
   605         if (item->rasterIconDataCost <= (maxCpuCacheLimit - currentCpuCacheSize)) {
       
   606             return true;
       
   607         } else {
       
   608             return (item->rasterIconDataCost <= (maxCpuCacheLimit - currentCpuCacheSize) + cpuLruListSize);
       
   609         }
       
   610     }
       
   611 
       
   612     if (item->vectorIconData.type != INVALID_FORMAT) {
       
   613         if (item->vectorIconDataCost <= 0 || item->vectorIconDataCost > maxCpuCacheLimit) {
       
   614             return false;
       
   615         }
       
   616         if (item->vectorIconDataCost <= (maxCpuCacheLimit - currentCpuCacheSize)) {
       
   617             return true;
       
   618         } else {
       
   619             return (item->vectorIconDataCost <= (maxCpuCacheLimit - currentCpuCacheSize) + cpuLruListSize);
       
   620         }
       
   621     }
       
   622     return false;
       
   623 }
       
   624 
       
   625 /*!
       
   626     \fn HbIconDataCache::createGpuCacheSpace()
       
   627     This method provides a way to remove the unused icons( icons with ref count =0.
       
   628     It starts removing the icons from the cache, starting with those that are at the front of the Gpu LRU list.
       
   629     It continues removal of items till there is enough space created to cache the new item in Gpu
       
   630     \a itemCost - cost of the new item to be cached in the Gpu memory
       
   631 
       
   632  */
       
   633 void HbIconDataCache::createGpuCacheSpace(int itemCost)
       
   634 {
       
   635     if (!gpuLruList.isEmpty()) {
       
   636         // Keep removing  items from the cache till there is
       
   637         // enough space to accomdate the new item
       
   638         int freedMemory = 0;
       
   639         while (itemCost > (freedMemory)) {
       
   640             HbIconCacheItem* itemToRemove = gpuLruList.removeFront();
       
   641             // Decrement the Size by the cost of the removed icon's data cost
       
   642             //GET_MEMORY_MANAGER(HbMemoryManager::SharedMemory)
       
   643             //qDebug() << "HbIconDataCache : Calling SgImage Close. Cost = %d  "<< itemToRemove->rasterIconDataCost;
       
   644 #ifdef HB_SGIMAGE_ICON
       
   645 #ifdef HB_ICON_CACHE_DEBUG
       
   646             qDebug() << "HbIconDataCache : Calling SgImage Close. Cost = %d  "<< itemToRemove->rasterIconDataCost;
       
   647 #endif
       
   648             HbSgImageRenderer::removeSgImageFromHash(itemToRemove->rasterIconData.sgImageData.id);  
       
   649 #endif
       
   650             itemToRemove->rasterIconData.type = INVALID_FORMAT;
       
   651             itemToRemove->gpuLink.setNext(0);
       
   652             itemToRemove->gpuLink.setPrev(0);
       
   653             currentGpuCacheSize -= itemToRemove->rasterIconDataCost;
       
   654             updateGpuLruSize(-itemToRemove->rasterIconDataCost);
       
   655             freedMemory += itemToRemove->rasterIconDataCost;
       
   656 
       
   657             if (currentGpuCacheSize < 0) {
       
   658                 currentGpuCacheSize = 0;
       
   659             }
       
   660 
       
   661             if (gpuLruListSize < 0) {
       
   662                 gpuLruListSize = 0;
       
   663             }
       
   664             //Debug Code for Test Purpose
       
   665 #ifdef HB_ICON_CACHE_DEBUG
       
   666             removedItemMem = itemToRemove->rasterIconDataCost;
       
   667             rasterLruListCount--;
       
   668             if (rasterLruListCount < 0) {
       
   669                 rasterLruListCount = 0;
       
   670             }
       
   671 #endif
       
   672 
       
   673             // This is the case where Icon has no CPU data and
       
   674             // the GPU cached data has also  been deleted to make way for new Icon
       
   675             // In such a case the Item can be removed from the Hash
       
   676 
       
   677             if ((itemToRemove->rasterIconData.type == INVALID_FORMAT) &&
       
   678                     (itemToRemove->vectorIconData.type == INVALID_FORMAT)) {
       
   679                 cache->remove(cache->key(itemToRemove));
       
   680                 delete itemToRemove;
       
   681             }
       
   682         }
       
   683     }
       
   684 }
       
   685 
       
   686 /*!
       
   687     \fn HbIconDataCache::createCpuCacheSpace()
       
   688     This method provides a way to remove the unused icons( icons with ref count =0).
       
   689     It starts removing the icons from the cache, starting with those that are at the front of the CPU LRU list.
       
   690     It continues removal of items till there is enough space created to cache the new item in Cpu
       
   691     \a itemCost - cost of the new item to be cached in the Cpu memory
       
   692 
       
   693  */
       
   694 void HbIconDataCache::createCpuCacheSpace(int itemCost)
       
   695 {
       
   696     if (!cpuLruList.isEmpty()) {
       
   697         // Keep removing  items from the cache till there is
       
   698         // enough space to accomdate the new item
       
   699         GET_MEMORY_MANAGER(HbMemoryManager::SharedMemory)
       
   700         while (itemCost > (maxCpuCacheLimit - currentCpuCacheSize)) {
       
   701             HbIconCacheItem* itemToRemove = cpuLruList.removeFront();
       
   702             if (itemToRemove->rasterIconData.type == OTHER_SUPPORTED_FORMATS) {
       
   703                 manager->free(itemToRemove->rasterIconData.pixmapData.offset);
       
   704                 itemToRemove->rasterIconData.type = INVALID_FORMAT;
       
   705                 currentCpuCacheSize -= itemToRemove->rasterIconDataCost;
       
   706                 updateCpuLruSize(-itemToRemove->rasterIconDataCost);
       
   707             } else {
       
   708                 // Decrement the Size by the cost of the removed icon's data  cost
       
   709                 if((itemToRemove->vectorIconData.type == PIC)){
       
   710                     manager->free(itemToRemove->vectorIconData.picData.offset);
       
   711                 } else if (itemToRemove->vectorIconData.type == NVG) {
       
   712                     manager->free(itemToRemove->vectorIconData.nvgData.offset);
       
   713                 } else if (itemToRemove->blobIconData.type == BLOB) {
       
   714                     manager->free(itemToRemove->blobIconData.blobData.offset);
       
   715                 }
       
   716 
       
   717                 itemToRemove->vectorIconData.type = INVALID_FORMAT;
       
   718                 currentCpuCacheSize -= itemToRemove->vectorIconDataCost;
       
   719                 updateCpuLruSize(-itemToRemove->vectorIconDataCost);
       
   720             }
       
   721 
       
   722 
       
   723             itemToRemove->cpuLink.setNext(0);
       
   724             itemToRemove->cpuLink.setPrev(0);
       
   725 
       
   726             if (currentCpuCacheSize < 0) {
       
   727                 currentCpuCacheSize = 0;
       
   728             }
       
   729 
       
   730             if (cpuLruListSize < 0) {
       
   731                 cpuLruListSize = 0;
       
   732             }
       
   733 
       
   734             //Debug Code for Test Purpose
       
   735 #ifdef HB_ICON_CACHE_DEBUG
       
   736             removedItemMem = itemToRemove->vectorIconDataCost;
       
   737             vectorLruListCount--;
       
   738             if (vectorLruListCount < 0) {
       
   739                 vectorLruListCount = 0;
       
   740             }
       
   741 #endif
       
   742 
       
   743             // This is the case where Icon has no CPU data and
       
   744             // the GPU cached data has also  been deleted to make way for new Icon
       
   745             // In such a case the Item can be removed from the Hash
       
   746 
       
   747             if ((itemToRemove->vectorIconData.type == INVALID_FORMAT) &&
       
   748                     (itemToRemove->rasterIconData.type == INVALID_FORMAT)) {
       
   749                 cache->remove(cache->key(itemToRemove));
       
   750                 delete itemToRemove;
       
   751             }
       
   752         }
       
   753     }
       
   754 }
       
   755 
       
   756 void HbIconDataCache::updateGpuLruSize(int iconDataCost)
       
   757 {
       
   758     gpuLruListSize += iconDataCost;
       
   759 }
       
   760 
       
   761 void HbIconDataCache::updateCpuLruSize(int iconDataCost)
       
   762 {
       
   763     cpuLruListSize += iconDataCost;
       
   764 }
       
   765 
       
   766 void HbIconDataCache::memoryGood()
       
   767 {
       
   768     goodMemory = true;
       
   769 }
       
   770 
       
   771 void HbIconDataCache::freeGpuRam(int bytes)
       
   772 {
       
   773     goodMemory = false;
       
   774     if (bytes  <= gpuLruListSize) {
       
   775         createGpuCacheSpace(bytes);
       
   776     } else {
       
   777         createGpuCacheSpace(gpuLruListSize);
       
   778     }
       
   779 }
       
   780 
       
   781 //Debug Code for Test Purpose
       
   782 #ifdef HB_ICON_CACHE_DEBUG
       
   783 void HbIconDataCache::cleanVectorLRUList()
       
   784 {
       
   785 
       
   786     // remove all the items in cpu LRU list.
       
   787     while (cpuLruList.front()) {
       
   788         HbIconCacheItem* itemToRemove = cpuLruList.removeFront();
       
   789 
       
   790         // update the member
       
   791         currentCpuCacheSize -= itemToRemove->vectorIconDataCost;
       
   792         cpuLruListSize -= itemToRemove->vectorIconDataCost;
       
   793         if (currentCpuCacheSize < 0) {
       
   794             currentCpuCacheSize = 0;
       
   795         }
       
   796 
       
   797         if (cpuLruListSize < 0) {
       
   798             cpuLruListSize = 0;
       
   799         }
       
   800 
       
   801 #ifdef HB_ICON_CACHE_DEBUG
       
   802         removedItemMem = itemToRemove->vectorIconDataCost;
       
   803         vectorLruListCount--;
       
   804         if (vectorLruListCount < 0) {
       
   805             vectorLruListCount = 0;
       
   806         }
       
   807 #endif
       
   808 
       
   809         // remove the shared memory allocatedfor this item.
       
   810         releaseVectorItem(itemToRemove);
       
   811 
       
   812         // release item from cache
       
   813         removeFromCache(cache->key(itemToRemove), itemToRemove);
       
   814     }
       
   815 }
       
   816 
       
   817 void HbIconDataCache::releaseVectorItem(HbIconCacheItem* releaseItem)
       
   818 {
       
   819     if (!releaseItem) {
       
   820         return;
       
   821     }
       
   822     GET_MEMORY_MANAGER(HbMemoryManager::SharedMemory)
       
   823     // release the specific items  data
       
   824     if (releaseItem->vectorIconData.type == OTHER_SUPPORTED_FORMATS) {
       
   825         manager->free(releaseItem->vectorIconData.pixmapData.offset);
       
   826     } else if ((releaseItem->vectorIconData.type == PIC) ||
       
   827                (releaseItem->vectorIconData.type == SVG)) {
       
   828         manager->free(releaseItem->vectorIconData.picData.offset);
       
   829     } else if (releaseItem->vectorIconData.type == NVG) {
       
   830         manager->free(releaseItem->vectorIconData.nvgData.offset);
       
   831     } else if (releaseItem->blobIconData.type == BLOB) {
       
   832         manager->free(releaseItem->blobIconData.blobData.offset);
       
   833     }
       
   834     releaseItem->vectorIconData.type = INVALID_FORMAT;
       
   835     releaseItem->cpuLink.setNext(0);
       
   836     releaseItem->cpuLink.setPrev(0);
       
   837 }
       
   838 
       
   839 void HbIconDataCache::cleanRasterLRUList()
       
   840 {
       
   841 
       
   842     // remove all the items from the gpu LRU list
       
   843     while (gpuLruList.front()) {
       
   844         HbIconCacheItem* itemToRemove = gpuLruList.removeFront();
       
   845 
       
   846         // update the member
       
   847         currentGpuCacheSize -= itemToRemove->rasterIconDataCost;
       
   848         gpuLruListSize -= itemToRemove->rasterIconDataCost;
       
   849 
       
   850         if (currentGpuCacheSize < 0) {
       
   851             currentGpuCacheSize = 0;
       
   852         }
       
   853 
       
   854         if (gpuLruListSize < 0) {
       
   855             gpuLruListSize = 0;
       
   856         }
       
   857 #ifdef HB_ICON_CACHE_DEBUG
       
   858         removedItemMem = itemToRemove->rasterIconDataCost;
       
   859         rasterLruListCount--;
       
   860         if (rasterLruListCount < 0) {
       
   861             rasterLruListCount = 0;
       
   862         }
       
   863 #endif
       
   864 
       
   865         // release the shared memory (later raster memory)of this item.
       
   866         releaseRasterItem(itemToRemove);
       
   867 
       
   868         // relese from the cache.
       
   869         removeFromCache(cache->key(itemToRemove), itemToRemove);
       
   870     }
       
   871 }
       
   872 
       
   873 void HbIconDataCache::releaseRasterItem(HbIconCacheItem* releaseItem)
       
   874 {
       
   875     if (!releaseItem) {
       
   876         return;
       
   877     }
       
   878     GET_MEMORY_MANAGER(HbMemoryManager::SharedMemory)
       
   879     // release the removed item data
       
   880     manager->free(releaseItem->rasterIconData.pixmapData.offset);
       
   881     releaseItem->rasterIconData.type = INVALID_FORMAT;
       
   882 }
       
   883 
       
   884 void HbIconDataCache::removeFromCache(const HbIconKey &key, const HbIconCacheItem* releaseItem)
       
   885 {
       
   886     if (!releaseItem) {
       
   887         return;
       
   888     }
       
   889 
       
   890     if ((releaseItem->vectorIconData.type == INVALID_FORMAT) &&
       
   891             (releaseItem->rasterIconData.type == INVALID_FORMAT)) {
       
   892         cache->remove(key);
       
   893         delete releaseItem;
       
   894     }
       
   895 }
       
   896 
       
   897 int HbIconDataCache::count() const
       
   898 {
       
   899     return cache->count();
       
   900 }
       
   901 
       
   902 int HbIconDataCache::gpuLRUSize() const
       
   903 {
       
   904     return gpuLruListSize;
       
   905 }
       
   906 
       
   907 int HbIconDataCache::freeVectorMemory()
       
   908 {
       
   909     return (maxCpuCacheLimit - currentCpuCacheSize);
       
   910 }
       
   911 
       
   912 int HbIconDataCache::freeRasterMemory()
       
   913 {
       
   914     return (maxGpuCacheLimit - currentGpuCacheSize);
       
   915 }
       
   916 int HbIconDataCache::lastAddedRefCount()
       
   917 {
       
   918     return addedItemRefCount;
       
   919 }
       
   920 int HbIconDataCache::lastAddedItemMem()
       
   921 {
       
   922     return addedItemMem;
       
   923 }
       
   924 int HbIconDataCache::lastRemovedItemMem()
       
   925 {
       
   926     return removedItemMem;
       
   927 }
       
   928 
       
   929 int HbIconDataCache::lastRemovedItemRfCount()
       
   930 {
       
   931     return remRfCount;
       
   932 }
       
   933 
       
   934 bool HbIconDataCache::enableCache(bool cacheIt)
       
   935 {
       
   936     bool success = false;
       
   937     if (enableCaching != cacheIt) {
       
   938         enableCaching = cacheIt;
       
   939         if (!enableCaching) {
       
   940             cleanVectorLRUList();
       
   941             cleanRasterLRUList();
       
   942         }
       
   943         success = true;
       
   944     }
       
   945     return success;
       
   946 }
       
   947 
       
   948 int HbIconDataCache::cacheHitCount()
       
   949 {
       
   950     return cacheHit;
       
   951 }
       
   952 
       
   953 int HbIconDataCache::cacheMissCount()
       
   954 {
       
   955     return cacheMiss;
       
   956 }
       
   957 
       
   958 int HbIconDataCache::rasterLruCount()
       
   959 {
       
   960     return gpuLruListSize;
       
   961 }
       
   962 
       
   963 int HbIconDataCache::vectorLruCount()
       
   964 {
       
   965     return cpuLruListSize;
       
   966 }
       
   967 #endif