Update contrib.
1 // Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
2 // All rights reserved.
3 // This component and the accompanying materials are made available
4 // under the terms of "Eclipse Public License v1.0"
5 // which accompanies this distribution, and is available
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
16 #include "vgimagecache.h"
17 #include "directgdiadapter.h"
20 Given a TDisplayMode, returns the closest TDisplayMode that is pixel-for-pixel-compatible
21 with an OpenVG format, such that the given TDisplayMode may be converted into the result
22 without loss of colour information.
24 @param aDisplayMode Pixel format to find a match for.
26 @return Closest TDisplayMode for which there is a OpenVG-compatible match.
28 static TDisplayMode ClosestVgCompatibleDisplayMode (TDisplayMode aDisplayMode)
52 Image Cache Item constructor.
54 CVgImageCache::CVgImageCacheItem::CVgImageCacheItem()
60 Image Cache Item destructor.
61 Destroys the VGImage owned by the cache item.
63 CVgImageCache::CVgImageCacheItem::~CVgImageCacheItem()
65 vgDestroyImage(iImage);
71 Forms a 32-bit hash value from a 64-bit integer.
73 @param aKey The 64-bit key to be hashed.
74 @return 32-bit hash value.
76 TUint32 CVgImageCache::Hash(const TInt64& aKey)
78 TPckgC<TInt64> bytes(aKey);
79 return DefaultHash::Des8(bytes);
83 Image Cache constructor.
84 Initialises the hashmap and double-linked queue
86 CVgImageCache::CVgImageCache(TInt aMaxCacheSize)
87 :iCacheItemMap(THashFunction32<TInt64>(CVgImageCache::Hash), TIdentityRelation<TInt64>()),
88 iVgImageCache(_FOFF(CVgImageCacheItem, iLink)),
89 iMaxCacheSizeInBytes(aMaxCacheSize)
94 Image Cache destructor.
95 Iterates through all the items in the cache and deletes them.
97 CVgImageCache::~CVgImageCache()
99 // cycle through all the items and destroy the VGImages.
100 TDblQueIter<CVgImageCacheItem> iter(iVgImageCache);
101 CVgImageCacheItem* item;
102 while((item=iter++)!=NULL)
106 iCacheItemMap.Close();
110 Deletes a cache item.
111 This removes the supplied item from the queue and the hashmap,
112 destroys the VGImage in that item, and deletes the item itself.
113 @param aItem The image cache item to be deleted.
115 void CVgImageCache::DeleteItem(CVgImageCacheItem* aItem)
117 aItem->iLink.Deque();
118 iCacheSizeInBytes -= aItem->iImageSizeInBytes;
119 iCacheItemMap.Remove(aItem->iSerialNumber);
124 Adds a VGImage to the cache using the associated CFbsBitmap as a reference.
126 A new image cache item is created which stores the VGImage, the size of the image in pixels,
127 the serial number of the CFbsBitmap (which acts as a unique identifier) and the touch count
128 of the CFbsBitmap. The touch count determines the number of times the underlying data of
129 the CFbsBitmap has changed.
131 The least-recently used items will be removed from the cache to create space for the new item, if needed.
133 @param aBitmap The bitmap from which the VGImage was created.
134 @param aImage The VGImage to store in the cache.
135 @param aOrigin The origin used to create a tiled VGImage.
137 @return ETrue if the VGImage was successfully added to the cache, EFalse if not.
139 TBool CVgImageCache::AddImage(const CFbsBitmap& aBitmap, VGImage& aImage, const TPoint& aOrigin)
141 // Calculate approximate size in bytes of image
142 TDisplayMode vgCompatibleDisplayMode = ClosestVgCompatibleDisplayMode(aBitmap.DisplayMode());
143 TSize imageSize = aBitmap.SizeInPixels();
144 TInt dataStride = CFbsBitmap::ScanLineLength(imageSize.iWidth, vgCompatibleDisplayMode);
145 TInt imageSizeInBytes = imageSize.iHeight * dataStride;
146 // if size of image is too large to fit in cache
147 if(imageSizeInBytes > iMaxCacheSizeInBytes)
152 CVgImageCacheItem* newItem = new CVgImageCacheItem;
158 // check there is enough room in the cache
159 // i.e. less than user-specified max memory allowed for cache
160 // if not enough space, remove items from end of cache until enough space is available.
161 while(iMaxCacheSizeInBytes < iCacheSizeInBytes + imageSizeInBytes)
163 DeleteItem(iVgImageCache.Last());
165 newItem->iSerialNumber = aBitmap.SerialNumber();
166 newItem->iImage = aImage;
167 newItem->iTouchCount = aBitmap.TouchCount();
168 newItem->iOrigin = aOrigin;
169 newItem->iImageSizeInBytes = imageSizeInBytes;
170 TInt err = iCacheItemMap.Insert(newItem->iSerialNumber, newItem);
176 iVgImageCache.AddFirst(*newItem);
177 iCacheSizeInBytes += newItem->iImageSizeInBytes;
182 Retrieves the VGImage from the cache that was created from the supplied CFbsBitmap.
183 The cache is first searched to find the item containing the VGImage that was created from the CFbsBitmap.
184 If no matching item is found, no VGImage is returned.
185 If the matching item is found, the touch count is checked to determine whether the
186 CFbsBitmap has been updated since the stored VGImage was created from it. If it has, the matching item
187 and VGImage is deleted from the cache and no VGImage is returned.
188 If the matching item is found and the CFbsitmap has not been updated sionce the VGImage was created,
189 the associated VGImage is returned.
191 @param aBitmap The bitmap used to reference the item containing the VGImage.
192 @param aOrigin The origin of the VGImage, relative to the top left corner of the source image.
194 @return VG_INVALID_HANDLE if no VGImage exists for the supplied CFbsBitmap or if the stored VGImage is out of date.
195 Otherwise the VGImage associated with the CFbsBitmap is returned.
197 VGImage CVgImageCache::GetVgImageFromBitmap(const CFbsBitmap& aBitmap, const TPoint& aOrigin)
199 // search through cache to find the item with a matching bitmap ID
200 CVgImageCacheItem** itemPtr = iCacheItemMap.Find(aBitmap.SerialNumber());
204 // searched all the way through cache and there is no matching image
206 return VG_INVALID_HANDLE;
208 CVgImageCacheItem* item = *itemPtr;
209 // Check whether the VGImage held by the item is up-to-date
210 // - check touch counts are equal.
211 // - check origins used for creating VGImage are equal.
212 if (aBitmap.TouchCount() != item->iTouchCount || aOrigin != item->iOrigin)
214 // VGImage in item needs updating, so remove and delete the entry
215 // and return NULL to indicate that a new entry needs to be created.
217 return VG_INVALID_HANDLE;
219 // VGImage is up-to date.
220 // If item is not already at front of list, move it there
221 if(!iVgImageCache.IsFirst(item))
224 iVgImageCache.AddFirst(*item);
232 Determines whether an item exists for a specified bitmap's serial number.
234 @param aSerialNumber The unique identifier of a CFbsBitmap.
236 @return ETrue if a matching item is found using the serial number. EFalse if not.
238 TBool CVgImageCache::IsInCache(TInt64 aSerialNumber)
240 return (iCacheItemMap.Find(aSerialNumber) != NULL);
244 The touch count stored in the item associated with the supplied serial number.
246 @param aSerialNumber The unique identifier of a CFbsBitmap.
248 @return The touch count stored in the item associated with the supplied serial number.
249 KErrNotFound if no matching item is found using the serial number.
251 TInt CVgImageCache::TouchCount(TInt64 aSerialNumber)
253 CVgImageCacheItem** itemPtr = iCacheItemMap.Find(aSerialNumber);
256 // searched all the way through cache and there is no matching image
259 return (*itemPtr)->iTouchCount;
263 The number of entries in the cache.
264 @return The number of entries in the cache.
266 TInt CVgImageCache::NumEntries() const
268 return iCacheItemMap.Count();
272 Returns a list of the serial numbers of all the cache items, with the most-recently used item at ordinal 0
273 and the least-recently used item and the end of the list.
275 @param aSerialNumberList A reference to a list in which to return the serial number list.
276 @param aListSize The number of entries allocated for the list.
278 void CVgImageCache::GetOrderedCacheEntries(TInt64& aSerialNumberList, TInt aListSize)
280 GRAPHICS_ASSERT_ALWAYS(aSerialNumberList, EDirectGdiPanicInvalidPointArray)
281 TDblQueIter<CVgImageCacheItem> iter(iVgImageCache);
283 TInt n = iCacheItemMap.Count();
284 // If n is greater than number of entries in list, restrict to number of entries.
285 if (n > aListSize) n = aListSize;
286 for (TInt ii = 0; ii < n; ++ii)
288 CVgImageCacheItem* item = iter++;
289 (&aSerialNumberList)[ii] = item->iSerialNumber;
292 // If n is less than number of entries in list, pad out entries with 0
293 // (i.e. invlaid serial numbers)
294 while (n < aListSize)
296 (&aSerialNumberList)[n++] = 0;
301 The total size of the cache in bytes.
302 @return The total size of the cache in bytes.
304 TInt CVgImageCache::CacheSizeInBytes() const
306 return iCacheSizeInBytes;
310 The maximum size of the cache in bytes.
311 @return The maximum size of the cache in bytes.
313 TInt CVgImageCache::MaxCacheSize() const
315 return iMaxCacheSizeInBytes;
319 Resets the cache. Iterates through all the items in the cache and deletes them.
321 void CVgImageCache::ResetCache()
323 // cycle through all the items and destroy the VGImages.
324 TDblQueIter<CVgImageCacheItem> iter(iVgImageCache);
325 CVgImageCacheItem* item;
326 while((item=iter++)!=NULL)
333 Sets the maximum size in bytes of the cache. Checks the current size of the
334 cache and sets the maximum cache size if the current cache size is smaller
335 or equal to aCacheSize.
336 @param aMaxCacheSize The maximum size in bytes to allow for the cache.
337 @return KErrNone if the maximum cache size has been changed successfully,
338 KErrArgument if aMaxCacheSize is smaller than the current cache size.
340 TInt CVgImageCache::SetMaxCacheSize(TInt aMaxCacheSize)
342 if (iCacheSizeInBytes <= aMaxCacheSize)
344 iMaxCacheSizeInBytes = aMaxCacheSize;