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