213 HbIconCacheItem *HbIconDataCache::getCacheItem(const HbIconKey &key, |
221 HbIconCacheItem *HbIconDataCache::getCacheItem(const HbIconKey &key, |
214 HbRenderingMode currentRenderingMode, |
222 HbRenderingMode currentRenderingMode, |
215 bool isMultiIconPiece) |
223 bool isMultiIconPiece) |
216 { |
224 { |
217 HbIconCacheItem *item = 0; |
225 HbIconCacheItem *item = 0; |
218 |
|
219 if (!cache->contains(key)) { |
226 if (!cache->contains(key)) { |
220 return 0; |
227 return 0; |
221 } |
228 } |
222 // Get the cache item associated with the key |
229 // Get the cache item associated with the key |
223 item = (*cache)[(key)]; |
230 item = (*cache)[key]; |
224 |
231 |
225 //Debug Code for Test Purpose |
232 //Debug Code for Test Purpose |
226 #ifdef HB_ICON_CACHE_DEBUG |
233 #ifdef HB_ICON_CACHE_DEBUG |
227 addedItemMem = item->rasterIconDataCost; |
234 addedItemMem = item->rasterIconDataCost; |
228 cacheHit++; |
235 cacheHit++; |
250 // If the Icon does not have GPU shared data and there is enough space to cache |
257 // If the Icon does not have GPU shared data and there is enough space to cache |
251 // the icon in GPU cache now, we go ahead and create GPU shared data |
258 // the icon in GPU cache now, we go ahead and create GPU shared data |
252 if ((item->rasterIconData.type == INVALID_FORMAT) && |
259 if ((item->rasterIconData.type == INVALID_FORMAT) && |
253 (goodMemory && !isMultiIconPiece)) { |
260 (goodMemory && !isMultiIconPiece)) { |
254 if (item->vectorIconData.type == NVG) { |
261 if (item->vectorIconData.type == NVG) { |
|
262 int gpuItemCost = HbThemeServerUtils::computeGpuCost(key, NVG, false); |
|
263 if (!isItemCachableInGpu(gpuItemCost, NVG)) { |
|
264 return 0; |
|
265 } |
255 HbIconCacheItemCreator::createCacheItem(*item, key, currentRenderingMode); |
266 HbIconCacheItemCreator::createCacheItem(*item, key, currentRenderingMode); |
256 if (item->rasterIconData.type != INVALID_FORMAT) { |
267 if (item->rasterIconData.type == SGIMAGE) { |
257 currentGpuCacheSize += item->rasterIconDataCost; |
268 currentGpuCacheSize += item->rasterIconDataCost; |
258 } |
269 } |
|
270 |
259 } |
271 } |
260 //Debug Code for Test Purpose |
272 //Debug Code for Test Purpose |
261 #ifdef HB_ICON_CACHE_DEBUG |
273 #ifdef HB_ICON_CACHE_DEBUG |
262 addedItemMem = item->rasterIconDataCost; |
274 addedItemMem = item->rasterIconDataCost; |
263 #endif |
275 #endif |
288 // If the Icon does not have CPU data and there is enough space to create |
300 // If the Icon does not have CPU data and there is enough space to create |
289 // the icon in CPU cache now, we go ahead and create CPU shared data |
301 // the icon in CPU cache now, we go ahead and create CPU shared data |
290 if ((item->vectorIconData.type == INVALID_FORMAT) && |
302 if ((item->vectorIconData.type == INVALID_FORMAT) && |
291 (item->rasterIconData.type == SGIMAGE)) { |
303 (item->rasterIconData.type == SGIMAGE)) { |
292 |
304 |
293 if ((item->vectorIconDataCost < (maxCpuCacheLimit - currentCpuCacheSize))) { |
305 if ((item->vectorIconDataCost > 0 ) && |
|
306 (item->vectorIconDataCost < (maxCpuCacheLimit - currentCpuCacheSize))) { |
294 HbIconCacheItemCreator::createCacheItem(*item, key, currentRenderingMode); |
307 HbIconCacheItemCreator::createCacheItem(*item, key, currentRenderingMode); |
295 if (item->vectorIconData.type != INVALID_FORMAT) { |
308 if (item->vectorIconData.type == NVG) { |
296 currentCpuCacheSize += item->vectorIconDataCost; |
309 currentCpuCacheSize += item->vectorIconDataCost; |
297 } |
310 } |
298 } |
311 } |
299 } |
312 } |
300 item->refCount ++; |
313 item->refCount ++; |
304 addedItemRefCount = item->refCount; |
317 addedItemRefCount = item->refCount; |
305 qDebug() << "HbIconDataCache::getCacheItem: " |
318 qDebug() << "HbIconDataCache::getCacheItem: " |
306 << "Cache hit in Server-Cache for" << key.filename; |
319 << "Cache hit in Server-Cache for" << key.filename; |
307 qDebug() << "HbIconDataCache::getCacheItem: Server RefCount now = " << item->refCount; |
320 qDebug() << "HbIconDataCache::getCacheItem: Server RefCount now = " << item->refCount; |
308 #endif |
321 #endif |
309 |
322 if( EHWRendering == key.renderMode && |
|
323 ESWRendering == currentRenderingMode && |
|
324 INVALID_FORMAT == item->rasterIconData.type && |
|
325 NVG == item->vectorIconData.type ) { |
|
326 HbIconCacheItemCreator::createCacheItem(*item, key, currentRenderingMode); |
|
327 //deleting the vectordata type here. |
|
328 releaseVectorItem(item); |
|
329 } |
310 return item; |
330 return item; |
311 } |
331 } |
312 |
332 |
313 /*! |
333 /*! |
314 \fn HbIconDataCache::insert() |
334 \fn HbIconDataCache::insert() |
327 { |
347 { |
328 if (!item) { |
348 if (!item) { |
329 return false; |
349 return false; |
330 } |
350 } |
331 |
351 |
332 // Check if Item can be accomdated in GPU cache |
352 //Check if item can be inserted |
333 bool gpuCaching = isItemCachableInGpu(item); |
353 bool caching = isItemCacheable(item); |
334 // Check if Item can be accomdated in CPU cache |
354 if (!caching) { |
335 bool cpuCaching = isItemCachableInCpu(item); |
|
336 |
|
337 // Item cannot be inserted either into GPU cache memory or CPU cache memory |
|
338 if ((!gpuCaching) && (!cpuCaching)) { |
|
339 return false; |
355 return false; |
340 } |
356 } |
|
357 |
341 // Item can be accomdated in GPU cache |
358 // Item can be accomdated in GPU cache |
342 if (gpuCaching) { |
359 if (item->rasterIconData.type == SGIMAGE) { |
343 // Increment the GPU cache size |
360 // Increment the GPU cache size |
344 if( item->rasterIconDataCost <= maxGpuCacheLimit ) { |
361 if ( item->rasterIconDataCost <= (maxGpuCacheLimit - currentGpuCacheSize) ) { |
345 currentGpuCacheSize += item->rasterIconDataCost; |
362 currentGpuCacheSize += item->rasterIconDataCost; |
346 } |
363 } else { |
|
364 createGpuCacheSpace(item->rasterIconDataCost); |
|
365 currentGpuCacheSize += item->rasterIconDataCost; |
|
366 } |
347 } |
367 } |
348 |
368 |
349 // Item can be accomdated in CPU cache |
369 // Item can be accomdated in CPU cache |
350 if (cpuCaching) { |
370 if (item->rasterIconData.type == OTHER_SUPPORTED_FORMATS) { |
351 if (item->rasterIconData.type == OTHER_SUPPORTED_FORMATS) { |
371 if (item->rasterIconDataCost <= (maxCpuCacheLimit - currentCpuCacheSize)) { |
352 if (item->rasterIconDataCost <= (maxCpuCacheLimit - currentCpuCacheSize)) { |
372 currentCpuCacheSize += item->rasterIconDataCost; |
353 currentCpuCacheSize += item->rasterIconDataCost; |
373 } else { |
354 } else { |
374 createCpuCacheSpace(item->rasterIconDataCost); |
355 createCpuCacheSpace(item->rasterIconDataCost); |
375 currentCpuCacheSize += item->rasterIconDataCost; |
356 currentCpuCacheSize += item->rasterIconDataCost; |
376 } |
357 } |
377 } |
358 } |
378 if (item->vectorIconData.type != INVALID_FORMAT || |
359 if (item->vectorIconData.type != INVALID_FORMAT) { |
379 item->blobIconData.type != INVALID_FORMAT) { |
360 // Increment the CPU cache size |
380 // Increment the CPU cache size |
361 if (item->vectorIconDataCost <= (maxCpuCacheLimit - currentCpuCacheSize)) { |
381 if (item->vectorIconDataCost <= (maxCpuCacheLimit - currentCpuCacheSize)) { |
362 currentCpuCacheSize += item->vectorIconDataCost; |
382 currentCpuCacheSize += item->vectorIconDataCost; |
363 } else { |
383 } else { |
364 // New item's icon data cost is more than available free CPU cahe size |
384 // New item's icon data cost is more than available free CPU cahe size |
365 // Check if some items, whose ref count is 0, |
385 // Check if some items, whose ref count is 0, |
366 // can be removed to make way for new item |
386 // can be removed to make way for new item |
367 createCpuCacheSpace(item->vectorIconDataCost); |
387 createCpuCacheSpace(item->vectorIconDataCost); |
368 currentCpuCacheSize += item->vectorIconDataCost; |
388 currentCpuCacheSize += item->vectorIconDataCost; |
369 } |
389 } |
370 } |
390 } |
371 if (currentCpuCacheSize > maxCpuCacheLimit) { |
391 if (currentCpuCacheSize > maxCpuCacheLimit) { |
372 currentCpuCacheSize = maxCpuCacheLimit; |
392 currentCpuCacheSize = maxCpuCacheLimit; |
373 } |
393 } |
374 } |
394 |
375 QHash<HbIconKey, HbIconCacheItem*>::iterator iter = |
395 QHash<HbIconKey, HbIconCacheItem*>::iterator iter = |
376 cache->insert(key, const_cast<HbIconCacheItem*>(item)); |
396 cache->insert(key, const_cast<HbIconCacheItem*>(item)); |
377 if (iter == cache->end()) { |
397 if (iter == cache->end()) { |
378 return false; |
398 return false; |
379 } |
399 } |
382 |
402 |
383 //Debug Code for Test Purpose |
403 //Debug Code for Test Purpose |
384 #ifdef HB_ICON_CACHE_DEBUG |
404 #ifdef HB_ICON_CACHE_DEBUG |
385 cacheMiss++; |
405 cacheMiss++; |
386 addedItemRefCount = item->refCount; |
406 addedItemRefCount = item->refCount; |
387 if (gpuCaching) { |
407 |
388 addedItemMem = item->rasterIconDataCost; |
|
389 } else if (cpuCaching) { |
|
390 addedItemMem = item->vectorIconDataCost; |
|
391 } |
|
392 qDebug() << "HbIconDataCache::insert: " << "Item " << key.filename |
408 qDebug() << "HbIconDataCache::insert: " << "Item " << key.filename |
393 << " inserted in Server-Cache"; |
409 << " inserted in Server-Cache"; |
394 qDebug() << "HbIconDataCache::insert: Server RefCount now = " << item->refCount; |
410 qDebug() << "HbIconDataCache::insert: Server RefCount now = " << item->refCount; |
395 #endif |
411 #endif |
396 |
412 |
421 remRfCount = item->refCount; |
437 remRfCount = item->refCount; |
422 #endif |
438 #endif |
423 |
439 |
424 if (item->refCount == 0) { |
440 if (item->refCount == 0) { |
425 if (item->rasterIconData.type == SGIMAGE) { |
441 if (item->rasterIconData.type == SGIMAGE) { |
426 if (keepInCache) { |
442 if (keepInCache && goodMemory) { |
427 gpuLruList.insertBack(item); |
443 gpuLruList.insertBack(item); |
428 updateGpuLruSize(item->rasterIconDataCost); |
444 updateGpuLruSize(item->rasterIconDataCost); |
429 } else { |
445 } else { |
430 releaseRasterItem(item); |
446 #ifdef HB_SGIMAGE_ICON |
431 removeFromCache(key, item); |
447 HbSgImageRenderer::removeSgImageFromHash( |
|
448 item->rasterIconData.sgImageData.id); |
|
449 item->rasterIconData.type = INVALID_FORMAT; |
|
450 #endif |
|
451 removeFromCache(key, item); |
|
452 // close the sgimage driver after all the |
|
453 // sgimage items and its memory were deleted. |
|
454 #ifdef HB_SGIMAGE_ICON |
|
455 if (!goodMemory && (currentGpuCacheSize <= 0) ) { |
|
456 HbSgImageRenderer::global()->terminate(); |
|
457 } |
|
458 #endif |
432 return true; |
459 return true; |
433 } |
460 } |
434 } |
461 } |
435 if (item->rasterIconData.type == OTHER_SUPPORTED_FORMATS) { |
462 if (item->rasterIconData.type == OTHER_SUPPORTED_FORMATS) { |
436 if (keepInCache) { |
463 if (keepInCache) { |
589 \fn HbIconDataCache::isItemCachableInGpu() |
617 \fn HbIconDataCache::isItemCachableInGpu() |
590 Checks if the new item can be accomdated in the Gpu memory. |
618 Checks if the new item can be accomdated in the Gpu memory. |
591 \a item is the new item to be cached |
619 \a item is the new item to be cached |
592 BLOB is always cached in cpu so this function always returns false for such items. |
620 BLOB is always cached in cpu so this function always returns false for such items. |
593 */ |
621 */ |
594 bool HbIconDataCache::isItemCachableInGpu(const HbIconCacheItem *item) const |
622 bool HbIconDataCache::isItemCachableInGpu(int itemCost, HbIconFormatType type) const |
595 { |
623 { |
596 if (maxGpuCacheLimit <= 0 || item->rasterIconDataCost <= 0 |
624 if (maxGpuCacheLimit <= 0) { |
597 || item->blobIconData.type != INVALID_FORMAT || item->rasterIconData.type != SGIMAGE) { |
|
598 return false; |
625 return false; |
599 } |
626 } |
600 // Item's GPU Icon's cost is greater than the max GPU Limit |
627 |
601 if (item->rasterIconDataCost > maxGpuCacheLimit) { |
628 // SgImage is only created from NVG data |
|
629 if (type != NVG) { |
602 return false; |
630 return false; |
603 } |
631 } |
604 return true; |
632 if (itemCost <= 0 || itemCost > maxGpuCacheLimit) { |
|
633 return false; |
|
634 } |
|
635 if (itemCost <= (maxGpuCacheLimit - currentGpuCacheSize)) { |
|
636 return true; |
|
637 } else { |
|
638 return (itemCost <= (maxGpuCacheLimit - currentGpuCacheSize) |
|
639 + gpuLruListSize); |
|
640 } |
|
641 |
605 } |
642 } |
606 |
643 |
607 /*! |
644 /*! |
608 \fn HbIconDataCache::isItemCachableInCpu() |
645 \fn HbIconDataCache::isItemCachableInCpu() |
609 Checks if the new item can be accomdated in the cpu shared memory. |
646 Checks if the new item can be accomdated in the cpu shared memory. |
610 \a item is the new item to be cached |
647 \a item is the new item to be cached |
611 BLOB is always cached in cpu, never in gpu. |
648 BLOB is always cached in cpu, never in gpu. |
612 */ |
649 */ |
613 bool HbIconDataCache::isItemCachableInCpu(const HbIconCacheItem *item) const |
650 bool HbIconDataCache::isItemCachableInCpu(int itemCost, HbIconFormatType type) const |
614 { |
651 { |
615 if (maxCpuCacheLimit <= 0) { |
652 if (maxCpuCacheLimit <= 0) { |
616 return false; |
653 return false; |
617 } |
654 } |
|
655 if (!(type == SVG || type == NVG || type == BLOB)) { |
|
656 return false; |
|
657 } |
|
658 |
|
659 if (itemCost <= 0 || itemCost > maxCpuCacheLimit) { |
|
660 return false; |
|
661 } |
|
662 if (itemCost <= (maxCpuCacheLimit - currentCpuCacheSize)) { |
|
663 return true; |
|
664 } else { |
|
665 return (itemCost <= (maxCpuCacheLimit - currentCpuCacheSize) |
|
666 + cpuLruListSize); |
|
667 } |
|
668 |
|
669 } |
|
670 |
|
671 bool HbIconDataCache::isItemCacheable(const HbIconCacheItem * item ) |
|
672 { |
|
673 // For a Hardware icon, check if SGIMAGE can be accomdated in GPU |
|
674 if (item->rasterIconData.type == SGIMAGE) { |
|
675 if (item->rasterIconDataCost <= (maxGpuCacheLimit - currentGpuCacheSize)) { |
|
676 return true; |
|
677 } else { |
|
678 return (item->rasterIconDataCost <= ((maxGpuCacheLimit - currentGpuCacheSize) |
|
679 + gpuLruListSize)); |
|
680 } |
|
681 } |
|
682 |
|
683 // For a Software Icon, check if pixmap can be accomdated in CPU |
618 if (item->rasterIconData.type == OTHER_SUPPORTED_FORMATS) { |
684 if (item->rasterIconData.type == OTHER_SUPPORTED_FORMATS) { |
619 if (item->rasterIconDataCost <= 0 || item->rasterIconDataCost > maxCpuCacheLimit) { |
|
620 return false; |
|
621 } |
|
622 if (item->rasterIconDataCost <= (maxCpuCacheLimit - currentCpuCacheSize)) { |
685 if (item->rasterIconDataCost <= (maxCpuCacheLimit - currentCpuCacheSize)) { |
623 return true; |
686 return true; |
624 } else { |
687 } else { |
625 return (item->rasterIconDataCost <= (maxCpuCacheLimit - currentCpuCacheSize) |
688 return (item->rasterIconDataCost <= ((maxCpuCacheLimit - currentCpuCacheSize) |
626 + cpuLruListSize); |
689 + cpuLruListSize)); |
627 } |
690 } |
628 } |
691 } |
629 if (item->vectorIconData.type != INVALID_FORMAT) { |
692 |
630 if (item->vectorIconDataCost <= 0 || item->vectorIconDataCost > maxCpuCacheLimit) { |
693 // For a BLOB, check if BLOB data can be accomdated in CPU |
631 return false; |
694 // For a individual piece of Multi piece icon, check if it can be accomdated in CPU |
632 } |
695 if (item->blobIconData.type == BLOB || item->vectorIconData.type == NVG) { |
633 if (item->vectorIconDataCost <= (maxCpuCacheLimit - currentCpuCacheSize)) { |
696 if (item->vectorIconDataCost <= (maxCpuCacheLimit - currentCpuCacheSize)) { |
634 return true; |
697 return true; |
635 } else { |
698 } else { |
636 return (item->vectorIconDataCost <= (maxCpuCacheLimit - currentCpuCacheSize) |
699 return (item->vectorIconDataCost <= ((maxCpuCacheLimit - currentCpuCacheSize) |
637 + cpuLruListSize); |
700 + cpuLruListSize)); |
638 } |
701 } |
639 } |
702 } |
|
703 |
640 return false; |
704 return false; |
641 } |
705 } |
|
706 |
642 |
707 |
643 /*! |
708 /*! |
644 \fn HbIconDataCache::createGpuCacheSpace() |
709 \fn HbIconDataCache::createGpuCacheSpace() |
645 This method provides a way to remove the unused icons( icons with ref count =0. |
710 This method provides a way to remove the unused icons( icons with ref count =0. |
646 It starts removing the icons from the cache, |
711 It starts removing the icons from the cache, |
785 } |
857 } |
786 |
858 |
787 void HbIconDataCache::freeGpuRam(int bytes, bool useSwRendering) |
859 void HbIconDataCache::freeGpuRam(int bytes, bool useSwRendering) |
788 { |
860 { |
789 goodMemory = false; |
861 goodMemory = false; |
790 if (bytes <= gpuLruListSize) { |
862 if ((bytes <= gpuLruListSize) && !useSwRendering) { |
791 createGpuCacheSpace(bytes); |
863 createGpuCacheSpace(bytes); |
792 } else { |
864 } else { |
793 createGpuCacheSpace(gpuLruListSize); |
865 createGpuCacheSpace(gpuLruListSize); |
794 } |
866 } |
795 |
867 } |
796 if (useSwRendering) { |
868 |
797 // Iterate through the cache and remove any active SgImages, before the context |
869 int HbIconDataCache::cachedSgImagesCount() const |
798 // is destroyed. |
870 { |
|
871 int sgImagesCount = 0; |
799 QHash<HbIconKey, HbIconCacheItem*>::const_iterator itEnd(cache->constEnd()); |
872 QHash<HbIconKey, HbIconCacheItem*>::const_iterator itEnd(cache->constEnd()); |
800 for (QHash<HbIconKey, |
873 for (QHash<HbIconKey, |
801 HbIconCacheItem *>::const_iterator iter = cache->constBegin(); |
874 HbIconCacheItem *>::const_iterator iter = cache->constBegin(); |
802 iter != itEnd; |
875 iter != itEnd; |
803 ++iter) { |
876 ++iter) { |
804 HbIconCacheItem *temp = iter.value(); |
877 HbIconCacheItem *temp = iter.value(); |
805 if( temp->rasterIconData.type == SGIMAGE ){ |
878 if( temp->rasterIconData.type == SGIMAGE ){ |
806 #ifdef HB_SGIMAGE_ICON |
879 sgImagesCount++; |
807 HbSgImageRenderer::removeSgImageFromHash(temp->rasterIconData.sgImageData.id); |
880 } |
808 #endif |
881 } |
809 temp->rasterIconData.type = INVALID_FORMAT; |
882 return sgImagesCount; |
810 currentGpuCacheSize -= temp->rasterIconDataCost; |
883 } |
811 } |
884 |
812 } |
885 int HbIconDataCache::totalSgImagesCost() const |
813 gpuLruList.removeAll(); |
886 { |
814 gpuLruListSize = 0; |
887 int sgImagesCost = 0; |
815 } |
888 QHash<HbIconKey, HbIconCacheItem*>::const_iterator itEnd(cache->constEnd()); |
816 } |
889 for (QHash<HbIconKey, |
817 |
890 HbIconCacheItem *>::const_iterator iter = cache->constBegin(); |
|
891 iter != itEnd; |
|
892 ++iter) { |
|
893 HbIconCacheItem *temp = iter.value(); |
|
894 if( temp->rasterIconData.type == SGIMAGE ){ |
|
895 sgImagesCost += temp->rasterIconDataCost; |
|
896 } |
|
897 } |
|
898 return sgImagesCost; |
|
899 } |
|
900 |
|
901 int HbIconDataCache::cachedPixmapCount() const |
|
902 { |
|
903 int pixmapCount = 0; |
|
904 QHash<HbIconKey, HbIconCacheItem*>::const_iterator itEnd(cache->constEnd()); |
|
905 for (QHash<HbIconKey, |
|
906 HbIconCacheItem *>::const_iterator iter = cache->constBegin(); |
|
907 iter != itEnd; |
|
908 ++iter) { |
|
909 HbIconCacheItem *temp = iter.value(); |
|
910 if( temp->rasterIconData.type == OTHER_SUPPORTED_FORMATS ){ |
|
911 pixmapCount++; |
|
912 } |
|
913 } |
|
914 return pixmapCount; |
|
915 } |
|
916 |
|
917 void HbIconDataCache::freeGpuRam() |
|
918 { |
|
919 createGpuCacheSpace(gpuLruListSize); |
|
920 } |
818 /*! |
921 /*! |
819 \fn HbIconDataCache::freeUnusedGpuResources() |
922 \fn HbIconDataCache::freeUnusedGpuResources() |
820 This function internally calls createGpuCacheSpace() which will free up |
923 This function internally calls createGpuCacheSpace() which will free up |
821 all the unused sgImage icons. |
924 all the unused sgImage icons. |
822 */ |
925 */ |
890 manager->free(releaseItem->vectorIconData.picData.offset); |
993 manager->free(releaseItem->vectorIconData.picData.offset); |
891 } else if (releaseItem->vectorIconData.type == NVG) { |
994 } else if (releaseItem->vectorIconData.type == NVG) { |
892 manager->free(releaseItem->vectorIconData.nvgData.offset); |
995 manager->free(releaseItem->vectorIconData.nvgData.offset); |
893 } else if (releaseItem->blobIconData.type == BLOB) { |
996 } else if (releaseItem->blobIconData.type == BLOB) { |
894 manager->free(releaseItem->blobIconData.blobData.offset); |
997 manager->free(releaseItem->blobIconData.blobData.offset); |
|
998 releaseItem->blobIconData.type = INVALID_FORMAT; |
895 } |
999 } |
896 releaseItem->vectorIconData.type = INVALID_FORMAT; |
1000 releaseItem->vectorIconData.type = INVALID_FORMAT; |
897 releaseItem->cpuLink.setNext(0); |
1001 releaseItem->cpuLink.setNext(0); |
898 releaseItem->cpuLink.setPrev(0); |
1002 releaseItem->cpuLink.setPrev(0); |
899 } |
1003 } |