2 * Copyright (C) 2012 Google Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
13 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 #ifndef ImageDecodingStore_h
27 #define ImageDecodingStore_h
31 #include "platform/PlatformExport.h"
32 #include "platform/graphics/skia/SkSizeHash.h"
33 #include "platform/image-decoders/ImageDecoder.h"
35 #include "wtf/DoublyLinkedList.h"
36 #include "wtf/HashSet.h"
37 #include "wtf/OwnPtr.h"
38 #include "wtf/PassOwnPtr.h"
39 #include "wtf/ThreadingPrimitives.h"
40 #include "wtf/Vector.h"
44 class ImageFrameGenerator
;
48 // ImageDecodingStore is a class used to manage cached decoder objects.
53 // A decoder object. It is used to decode raw data into bitmap images.
55 // ImageFrameGenerator
56 // This is a direct user of this cache. Responsible for generating bitmap images
57 // using an ImageDecoder. It contains encoded image data and is used to represent
58 // one image file. It is used to index image and decoder objects in the cache.
62 // All public methods can be used on any thread.
64 class PLATFORM_EXPORT ImageDecodingStore
{
66 static PassOwnPtr
<ImageDecodingStore
> create() { return adoptPtr(new ImageDecodingStore
); }
67 ~ImageDecodingStore();
69 static ImageDecodingStore
& instance();
71 // Access a cached decoder object. A decoder is indexed by origin (ImageFrameGenerator)
72 // and scaled size. Return true if the cached object is found.
73 bool lockDecoder(const ImageFrameGenerator
*, const SkISize
& scaledSize
, ImageDecoder
**);
74 void unlockDecoder(const ImageFrameGenerator
*, const ImageDecoder
*);
75 void insertDecoder(const ImageFrameGenerator
*, PassOwnPtr
<ImageDecoder
>);
76 void removeDecoder(const ImageFrameGenerator
*, const ImageDecoder
*);
78 // Remove all cache entries indexed by ImageFrameGenerator.
79 void removeCacheIndexedByGenerator(const ImageFrameGenerator
*);
82 void setCacheLimitInBytes(size_t);
83 size_t memoryUsageInBytes();
85 int decoderCacheEntries();
88 // Decoder cache entry is identified by:
89 // 1. Pointer to ImageFrameGenerator.
90 // 2. Size of the image.
91 typedef std::pair
<const ImageFrameGenerator
*, SkISize
> DecoderCacheKey
;
93 // Base class for all cache entries.
94 class CacheEntry
: public DoublyLinkedListNode
<CacheEntry
> {
95 friend class WTF::DoublyLinkedListNode
<CacheEntry
>;
101 CacheEntry(const ImageFrameGenerator
* generator
, int useCount
)
102 : m_generator(generator
)
103 , m_useCount(useCount
)
109 virtual ~CacheEntry()
114 const ImageFrameGenerator
* generator() const { return m_generator
; }
115 int useCount() const { return m_useCount
; }
116 void incrementUseCount() { ++m_useCount
; }
117 void decrementUseCount() { --m_useCount
; ASSERT(m_useCount
>= 0); }
119 // FIXME: getSafeSize() returns size in bytes truncated to a 32-bits integer.
120 // Find a way to get the size in 64-bits.
121 virtual size_t memoryUsageInBytes() const = 0;
122 virtual CacheType
type() const = 0;
125 const ImageFrameGenerator
* m_generator
;
133 class DecoderCacheEntry final
: public CacheEntry
{
135 static PassOwnPtr
<DecoderCacheEntry
> create(const ImageFrameGenerator
* generator
, PassOwnPtr
<ImageDecoder
> decoder
)
137 return adoptPtr(new DecoderCacheEntry(generator
, 0, decoder
));
140 DecoderCacheEntry(const ImageFrameGenerator
* generator
, int count
, PassOwnPtr
<ImageDecoder
> decoder
)
141 : CacheEntry(generator
, count
)
142 , m_cachedDecoder(decoder
)
143 , m_size(SkISize::Make(m_cachedDecoder
->decodedSize().width(), m_cachedDecoder
->decodedSize().height()))
147 size_t memoryUsageInBytes() const override
{ return m_size
.width() * m_size
.height() * 4; }
148 CacheType
type() const override
{ return TypeDecoder
; }
150 static DecoderCacheKey
makeCacheKey(const ImageFrameGenerator
* generator
, const SkISize
& size
)
152 return std::make_pair(generator
, size
);
154 static DecoderCacheKey
makeCacheKey(const ImageFrameGenerator
* generator
, const ImageDecoder
* decoder
)
156 return std::make_pair(generator
, SkISize::Make(decoder
->decodedSize().width(), decoder
->decodedSize().height()));
158 DecoderCacheKey
cacheKey() const { return makeCacheKey(m_generator
, m_size
); }
159 ImageDecoder
* cachedDecoder() const { return m_cachedDecoder
.get(); }
162 OwnPtr
<ImageDecoder
> m_cachedDecoder
;
166 ImageDecodingStore();
170 // These helper methods are called while m_mutex is locked.
171 template<class T
, class U
, class V
> void insertCacheInternal(PassOwnPtr
<T
> cacheEntry
, U
* cacheMap
, V
* identifierMap
);
173 // Helper method to remove a cache entry. Ownership is transferred to
174 // deletionList. Use of Vector<> is handy when removing multiple entries.
175 template<class T
, class U
, class V
> void removeFromCacheInternal(const T
* cacheEntry
, U
* cacheMap
, V
* identifierMap
, Vector
<OwnPtr
<CacheEntry
>>* deletionList
);
177 // Helper method to remove a cache entry. Uses the templated version base on
178 // the type of cache entry.
179 void removeFromCacheInternal(const CacheEntry
*, Vector
<OwnPtr
<CacheEntry
>>* deletionList
);
181 // Helper method to remove all cache entries associated with a ImageFraneGenerator.
182 // Ownership of cache entries is transferred to deletionList.
183 template<class U
, class V
> void removeCacheIndexedByGeneratorInternal(U
* cacheMap
, V
* identifierMap
, const ImageFrameGenerator
*, Vector
<OwnPtr
<CacheEntry
>>* deletionList
);
185 // Helper method to remove cache entry pointers from the LRU list.
186 void removeFromCacheListInternal(const Vector
<OwnPtr
<CacheEntry
>>& deletionList
);
188 // A doubly linked list that maintains usage history of cache entries.
189 // This is used for eviction of old entries.
190 // Head of this list is the least recently used cache entry.
191 // Tail of this list is the most recently used cache entry.
192 DoublyLinkedList
<CacheEntry
> m_orderedCacheList
;
194 // A lookup table for all decoder cache objects. Owns all decoder cache objects.
195 typedef HashMap
<DecoderCacheKey
, OwnPtr
<DecoderCacheEntry
>> DecoderCacheMap
;
196 DecoderCacheMap m_decoderCacheMap
;
198 // A lookup table to map ImageFrameGenerator to all associated
199 // decoder cache keys.
200 typedef HashSet
<DecoderCacheKey
> DecoderCacheKeySet
;
201 typedef HashMap
<const ImageFrameGenerator
*, DecoderCacheKeySet
> DecoderCacheKeyMap
;
202 DecoderCacheKeyMap m_decoderCacheKeyMap
;
204 size_t m_heapLimitInBytes
;
205 size_t m_heapMemoryUsageInBytes
;
207 // Protect concurrent access to these members:
208 // m_orderedCacheList
209 // m_decoderCacheMap and all CacheEntrys stored in it
210 // m_decoderCacheKeyMap
211 // m_heapLimitInBytes
212 // m_heapMemoryUsageInBytes
213 // This mutex also protects calls to underlying skBitmap's
214 // lockPixels()/unlockPixels() as they are not threadsafe.