Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / platform / graphics / ImageDecodingStore.h
1 /*
2  * Copyright (C) 2012 Google Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
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.
12  *
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.
24  */
25
26 #ifndef ImageDecodingStore_h
27 #define ImageDecodingStore_h
28
29 #include "SkSize.h"
30 #include "SkTypes.h"
31 #include "platform/PlatformExport.h"
32 #include "platform/graphics/DiscardablePixelRef.h"
33 #include "platform/graphics/ScaledImageFragment.h"
34 #include "platform/graphics/skia/SkSizeHash.h"
35 #include "platform/image-decoders/ImageDecoder.h"
36
37 #include "wtf/DoublyLinkedList.h"
38 #include "wtf/HashSet.h"
39 #include "wtf/OwnPtr.h"
40 #include "wtf/PassOwnPtr.h"
41 #include "wtf/ThreadingPrimitives.h"
42 #include "wtf/Vector.h"
43
44 namespace blink {
45
46 class ImageFrameGenerator;
47 class SharedBuffer;
48
49 // FUNCTION
50 //
51 // ImageDecodingStore is a class used to manage image cache objects. There are two
52 // types of cache objects stored:
53 //
54 // 1. Image objects
55 //    Each image object belongs to one frame decoded and/or resampled from an image
56 //    file. The image object can be complete or partial. Complete means the image
57 //    is fully decoded and will not mutate in future decoding passes. It can have
58 //    multiple concurrent users. A partial image object has only one user.
59 //
60 // 2. Decoder objects
61 //    A decoder object contains an image decoder. This allows decoding to resume
62 //    from previous states. There can be one user per one decoder object at any
63 //    time.
64 //
65 // EXTERNAL OBJECTS
66 //
67 // ScaledImageFragment
68 //   A cached image object. Contains the bitmap and information about the bitmap
69 //   image.
70 //
71 // ImageDecoder
72 //   A decoder object. It is used to decode raw data into bitmap images.
73 //
74 // ImageFrameGenerator
75 //   This is a direct user of this cache. Responsible for generating bitmap images
76 //   using an ImageDecoder. It contains encoded image data and is used to represent
77 //   one image file. It is used to index image and decoder objects in the cache.
78 //
79 // LazyDecodingPixelRef
80 //   A read only user of this cache.
81 //
82 // THREAD SAFETY
83 //
84 // All public methods can be used on any thread.
85
86 class PLATFORM_EXPORT ImageDecodingStore {
87 public:
88     static PassOwnPtr<ImageDecodingStore> create() { return adoptPtr(new ImageDecodingStore); }
89     ~ImageDecodingStore();
90
91     static ImageDecodingStore* instance();
92
93     // Why do we need this?
94     // ImageDecodingStore is used in two code paths:
95     // 1. Android uses this to cache both images and decoders.
96     // 2. Skia discardable memory path has its own cache. We still want cache
97     //    decoders but not images because Skia will take care of it.
98     // Because of the two use cases we want to just disable image caching.
99     //
100     // FIXME: It is weird to have this behavior. We want to remove image
101     // caching from this class once the transition to Skia discardable memory
102     // is complete.
103     static void setImageCachingEnabled(bool);
104
105     // Access a complete cached image object. A complete cached image object is
106     // indexed by the origin (ImageFrameGenerator), scaled size and frame index
107     // within the image file.
108     // Return true if the cache object is found.
109     // Return false if the cache object cannot be found or it is incomplete.
110     bool lockCache(const ImageFrameGenerator*, const SkISize& scaledSize, size_t index, const ScaledImageFragment**);
111     void unlockCache(const ImageFrameGenerator*, const ScaledImageFragment*);
112     const ScaledImageFragment* insertAndLockCache(const ImageFrameGenerator*, PassOwnPtr<ScaledImageFragment>);
113
114     // Access a cached decoder object. A decoder is indexed by origin (ImageFrameGenerator)
115     // and scaled size. Return true if the cached object is found.
116     bool lockDecoder(const ImageFrameGenerator*, const SkISize& scaledSize, ImageDecoder**);
117     void unlockDecoder(const ImageFrameGenerator*, const ImageDecoder*);
118     void insertDecoder(const ImageFrameGenerator*, PassOwnPtr<ImageDecoder>, bool isDiscardable);
119     void removeDecoder(const ImageFrameGenerator*, const ImageDecoder*);
120
121     // Locks the cache for safety, but does not attempt to lock the object we're checking for.
122     bool isCached(const ImageFrameGenerator*, const SkISize& scaledSize, size_t index);
123
124     // Remove all cache entries indexed by ImageFrameGenerator.
125     void removeCacheIndexedByGenerator(const ImageFrameGenerator*);
126
127     void clear();
128     void setCacheLimitInBytes(size_t);
129     size_t memoryUsageInBytes();
130     int cacheEntries();
131     int imageCacheEntries();
132     int decoderCacheEntries();
133
134 private:
135     // Image cache entry is identified by:
136     // 1. Pointer to ImageFrameGenerator.
137     // 2. Size of the image.
138     // 3. LocalFrame index.
139     // 4. LocalFrame generation. Increments on each progressive decode.
140     //
141     // The use of generation ID is to allow multiple versions of an image frame
142     // be stored in the cache. Each generation comes from a progressive decode.
143     //
144     // Decoder entries are identified by (1) and (2) only.
145     typedef std::pair<const ImageFrameGenerator*, SkISize> DecoderCacheKey;
146     typedef std::pair<size_t, size_t> IndexAndGeneration;
147     typedef std::pair<DecoderCacheKey, IndexAndGeneration> ImageCacheKey;
148
149     // Base class for all cache entries.
150     class CacheEntry : public DoublyLinkedListNode<CacheEntry> {
151         friend class WTF::DoublyLinkedListNode<CacheEntry>;
152     public:
153         enum CacheType {
154             TypeImage,
155             TypeDecoder,
156         };
157
158         CacheEntry(const ImageFrameGenerator* generator, int useCount, bool isDiscardable)
159             : m_generator(generator)
160             , m_useCount(useCount)
161             , m_isDiscardable(isDiscardable)
162             , m_prev(0)
163             , m_next(0)
164         {
165         }
166
167         virtual ~CacheEntry()
168         {
169             ASSERT(!m_useCount);
170         }
171
172         const ImageFrameGenerator* generator() const { return m_generator; }
173         int useCount() const { return m_useCount; }
174         void incrementUseCount() { ++m_useCount; }
175         void decrementUseCount() { --m_useCount; ASSERT(m_useCount >= 0); }
176         bool isDiscardable() const { return m_isDiscardable; }
177
178         // FIXME: getSafeSize() returns size in bytes truncated to a 32-bits integer.
179         //        Find a way to get the size in 64-bits.
180         virtual size_t memoryUsageInBytes() const = 0;
181         virtual CacheType type() const = 0;
182
183     protected:
184         const ImageFrameGenerator* m_generator;
185         int m_useCount;
186         bool m_isDiscardable;
187
188     private:
189         CacheEntry* m_prev;
190         CacheEntry* m_next;
191     };
192
193     class ImageCacheEntry FINAL : public CacheEntry {
194     public:
195         static PassOwnPtr<ImageCacheEntry> createAndUse(const ImageFrameGenerator* generator, PassOwnPtr<ScaledImageFragment> image)
196         {
197             return adoptPtr(new ImageCacheEntry(generator, 1, image));
198         }
199
200         ImageCacheEntry(const ImageFrameGenerator* generator, int count, PassOwnPtr<ScaledImageFragment> image)
201             : CacheEntry(generator, count, DiscardablePixelRef::isDiscardable(image->bitmap().pixelRef()))
202             , m_cachedImage(image)
203         {
204         }
205
206         // FIXME: getSafeSize() returns size in bytes truncated to a 32-bits integer.
207         //        Find a way to get the size in 64-bits.
208         virtual size_t memoryUsageInBytes() const OVERRIDE { return cachedImage()->bitmap().getSafeSize(); }
209         virtual CacheType type() const OVERRIDE { return TypeImage; }
210
211         static ImageCacheKey makeCacheKey(const ImageFrameGenerator* generator, const SkISize& size, size_t index, size_t generation)
212         {
213             return std::make_pair(std::make_pair(generator, size), std::make_pair(index, generation));
214         }
215         ImageCacheKey cacheKey() const { return makeCacheKey(m_generator, m_cachedImage->scaledSize(), m_cachedImage->index(), m_cachedImage->generation()); }
216         const ScaledImageFragment* cachedImage() const { return m_cachedImage.get(); }
217         ScaledImageFragment* cachedImage() { return m_cachedImage.get(); }
218
219     private:
220         OwnPtr<ScaledImageFragment> m_cachedImage;
221     };
222
223     class DecoderCacheEntry FINAL : public CacheEntry {
224     public:
225         static PassOwnPtr<DecoderCacheEntry> create(const ImageFrameGenerator* generator, PassOwnPtr<ImageDecoder> decoder, bool isDiscardable)
226         {
227             return adoptPtr(new DecoderCacheEntry(generator, 0, decoder, isDiscardable));
228         }
229
230         DecoderCacheEntry(const ImageFrameGenerator* generator, int count, PassOwnPtr<ImageDecoder> decoder, bool isDiscardable)
231             : CacheEntry(generator, count, isDiscardable)
232             , m_cachedDecoder(decoder)
233             , m_size(SkISize::Make(m_cachedDecoder->decodedSize().width(), m_cachedDecoder->decodedSize().height()))
234         {
235         }
236
237         virtual size_t memoryUsageInBytes() const OVERRIDE { return m_size.width() * m_size.height() * 4; }
238         virtual CacheType type() const OVERRIDE { return TypeDecoder; }
239
240         static DecoderCacheKey makeCacheKey(const ImageFrameGenerator* generator, const SkISize& size)
241         {
242             return std::make_pair(generator, size);
243         }
244         static DecoderCacheKey makeCacheKey(const ImageFrameGenerator* generator, const ImageDecoder* decoder)
245         {
246             return std::make_pair(generator, SkISize::Make(decoder->decodedSize().width(), decoder->decodedSize().height()));
247         }
248         DecoderCacheKey cacheKey() const { return makeCacheKey(m_generator, m_size); }
249         ImageDecoder* cachedDecoder() const { return m_cachedDecoder.get(); }
250
251     private:
252         OwnPtr<ImageDecoder> m_cachedDecoder;
253         SkISize m_size;
254     };
255
256     ImageDecodingStore();
257
258     void prune();
259
260     // These helper methods are called while m_mutex is locked.
261
262     // Find and lock a cache entry, and return true on success.
263     // Memory of the cache entry can be discarded, in which case it is saved in
264     // deletionList.
265     bool lockCacheEntryInternal(ImageCacheEntry*, const ScaledImageFragment**, Vector<OwnPtr<CacheEntry> >* deletionList);
266
267     template<class T, class U, class V> void insertCacheInternal(PassOwnPtr<T> cacheEntry, U* cacheMap, V* identifierMap);
268
269     // Helper method to remove a cache entry. Ownership is transferred to
270     // deletionList. Use of Vector<> is handy when removing multiple entries.
271     template<class T, class U, class V> void removeFromCacheInternal(const T* cacheEntry, U* cacheMap, V* identifierMap, Vector<OwnPtr<CacheEntry> >* deletionList);
272
273     // Helper method to remove a cache entry. Uses the templated version base on
274     // the type of cache entry.
275     void removeFromCacheInternal(const CacheEntry*, Vector<OwnPtr<CacheEntry> >* deletionList);
276
277     // Helper method to remove all cache entries associated with a ImageFraneGenerator.
278     // Ownership of cache entries is transferred to deletionList.
279     template<class U, class V> void removeCacheIndexedByGeneratorInternal(U* cacheMap, V* identifierMap, const ImageFrameGenerator*, Vector<OwnPtr<CacheEntry> >* deletionList);
280
281     // Helper method to remove cache entry pointers from the LRU list.
282     void removeFromCacheListInternal(const Vector<OwnPtr<CacheEntry> >& deletionList);
283
284     // A doubly linked list that maintains usage history of cache entries.
285     // This is used for eviction of old entries.
286     // Head of this list is the least recently used cache entry.
287     // Tail of this list is the most recently used cache entry.
288     DoublyLinkedList<CacheEntry> m_orderedCacheList;
289
290     // A lookup table for all image cache objects. Owns all image cache objects.
291     typedef HashMap<ImageCacheKey, OwnPtr<ImageCacheEntry> > ImageCacheMap;
292     ImageCacheMap m_imageCacheMap;
293
294     // A lookup table for all decoder cache objects. Owns all decoder cache objects.
295     typedef HashMap<DecoderCacheKey, OwnPtr<DecoderCacheEntry> > DecoderCacheMap;
296     DecoderCacheMap m_decoderCacheMap;
297
298     // A lookup table to map ImageFrameGenerator to all associated image
299     // cache keys.
300     typedef HashSet<ImageCacheKey> ImageCacheKeySet;
301     typedef HashMap<const ImageFrameGenerator*, ImageCacheKeySet> ImageCacheKeyMap;
302     ImageCacheKeyMap m_imageCacheKeyMap;
303
304     // A lookup table to map ImageFrameGenerator to all associated
305     // decoder cache keys.
306     typedef HashSet<DecoderCacheKey> DecoderCacheKeySet;
307     typedef HashMap<const ImageFrameGenerator*, DecoderCacheKeySet> DecoderCacheKeyMap;
308     DecoderCacheKeyMap m_decoderCacheKeyMap;
309
310     size_t m_heapLimitInBytes;
311     size_t m_heapMemoryUsageInBytes;
312     size_t m_discardableMemoryUsageInBytes;
313
314     // Protect concurrent access to these members:
315     //   m_orderedCacheList
316     //   m_imageCacheMap, m_decoderCacheMap and all CacheEntrys stored in it
317     //   m_imageCacheKeyMap
318     //   m_decoderCacheKeyMap
319     //   m_heapLimitInBytes
320     //   m_heapMemoryUsageInBytes
321     //   m_discardableMemoryUsageInBytes
322     // This mutex also protects calls to underlying skBitmap's
323     // lockPixels()/unlockPixels() as they are not threadsafe.
324     Mutex m_mutex;
325 };
326
327 } // namespace blink
328
329 #endif