Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(267)

Side by Side Diff: Source/core/platform/graphics/ImageDecodingStore.h

Issue 99103006: Moving GraphicsContext and dependencies from core to platform. (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Final patch - fixes Android Created 7 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
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 "core/platform/graphics/DiscardablePixelRef.h"
32 #include "core/platform/image-decoders/ImageDecoder.h"
33 #include "platform/graphics/ScaledImageFragment.h"
34 #include "platform/graphics/SkSizeHash.h"
35
36 #include "wtf/DoublyLinkedList.h"
37 #include "wtf/HashSet.h"
38 #include "wtf/OwnPtr.h"
39 #include "wtf/PassOwnPtr.h"
40 #include "wtf/ThreadingPrimitives.h"
41 #include "wtf/Vector.h"
42
43 namespace WebCore {
44
45 class ImageFrameGenerator;
46 class SharedBuffer;
47
48 // FUNCTION
49 //
50 // ImageDecodingStore is a class used to manage image cache objects. There are t wo
51 // types of cache objects stored:
52 //
53 // 1. Image objects
54 // Each image object belongs to one frame decoded and/or resampled from an im age
55 // file. The image object can be complete or partial. Complete means the imag e
56 // is fully decoded and will not mutate in future decoding passes. It can hav e
57 // multiple concurrent users. A partial image object has only one user.
58 //
59 // 2. Decoder objects
60 // A decoder object contains an image decoder. This allows decoding to resume
61 // from previous states. There can be one user per one decoder object at any
62 // time.
63 //
64 // EXTERNAL OBJECTS
65 //
66 // ScaledImageFragment
67 // A cached image object. Contains the bitmap and information about the bitmap
68 // image.
69 //
70 // ImageDecoder
71 // A decoder object. It is used to decode raw data into bitmap images.
72 //
73 // ImageFrameGenerator
74 // This is a direct user of this cache. Responsible for generating bitmap imag es
75 // using an ImageDecoder. It contains encoded image data and is used to repres ent
76 // one image file. It is used to index image and decoder objects in the cache.
77 //
78 // LazyDecodingPixelRef
79 // A read only user of this cache.
80 //
81 // THREAD SAFETY
82 //
83 // All public methods can be used on any thread.
84
85 class ImageDecodingStore {
86 public:
87 static PassOwnPtr<ImageDecodingStore> create() { return adoptPtr(new ImageDe codingStore); }
88 ~ImageDecodingStore();
89
90 static ImageDecodingStore* instance();
91 static void initializeOnce();
92 static void shutdown();
93
94 // Access a complete cached image object. A complete cached image object is
95 // indexed by the origin (ImageFrameGenerator), scaled size and frame index
96 // within the image file.
97 // Return true if the cache object is found.
98 // Return false if the cache object cannot be found or it is incomplete.
99 bool lockCache(const ImageFrameGenerator*, const SkISize& scaledSize, size_t index, const ScaledImageFragment**);
100 void unlockCache(const ImageFrameGenerator*, const ScaledImageFragment*);
101 const ScaledImageFragment* insertAndLockCache(const ImageFrameGenerator*, Pa ssOwnPtr<ScaledImageFragment>);
102
103 // Access a cached decoder object. A decoder is indexed by origin (ImageFram eGenerator)
104 // and scaled size. Return true if the cached object is found.
105 bool lockDecoder(const ImageFrameGenerator*, const SkISize& scaledSize, Imag eDecoder**);
106 void unlockDecoder(const ImageFrameGenerator*, const ImageDecoder*);
107 void insertDecoder(const ImageFrameGenerator*, PassOwnPtr<ImageDecoder>, boo l isDiscardable);
108 void removeDecoder(const ImageFrameGenerator*, const ImageDecoder*);
109
110 // Locks the cache for safety, but does not attempt to lock the object we're checking for.
111 bool isCached(const ImageFrameGenerator*, const SkISize& scaledSize, size_t index);
112
113 // Remove all cache entries indexed by ImageFrameGenerator.
114 void removeCacheIndexedByGenerator(const ImageFrameGenerator*);
115
116 void clear();
117 void setCacheLimitInBytes(size_t);
118 size_t memoryUsageInBytes();
119 int cacheEntries();
120 int imageCacheEntries();
121 int decoderCacheEntries();
122
123 private:
124 // Image cache entry is identified by:
125 // 1. Pointer to ImageFrameGenerator.
126 // 2. Size of the image.
127 // 3. Frame index.
128 // 4. Frame generation. Increments on each progressive decode.
129 //
130 // The use of generation ID is to allow multiple versions of an image frame
131 // be stored in the cache. Each generation comes from a progressive decode.
132 //
133 // Decoder entries are identified by (1) and (2) only.
134 typedef std::pair<const ImageFrameGenerator*, SkISize> DecoderCacheKey;
135 typedef std::pair<size_t, size_t> IndexAndGeneration;
136 typedef std::pair<DecoderCacheKey, IndexAndGeneration> ImageCacheKey;
137
138 // Base class for all cache entries.
139 class CacheEntry : public DoublyLinkedListNode<CacheEntry> {
140 friend class WTF::DoublyLinkedListNode<CacheEntry>;
141 public:
142 enum CacheType {
143 TypeImage,
144 TypeDecoder,
145 };
146
147 CacheEntry(const ImageFrameGenerator* generator, int useCount, bool isDi scardable)
148 : m_generator(generator)
149 , m_useCount(useCount)
150 , m_isDiscardable(isDiscardable)
151 , m_prev(0)
152 , m_next(0)
153 {
154 }
155
156 virtual ~CacheEntry()
157 {
158 ASSERT(!m_useCount);
159 }
160
161 const ImageFrameGenerator* generator() const { return m_generator; }
162 int useCount() const { return m_useCount; }
163 void incrementUseCount() { ++m_useCount; }
164 void decrementUseCount() { --m_useCount; ASSERT(m_useCount >= 0); }
165 bool isDiscardable() const { return m_isDiscardable; }
166
167 // FIXME: getSafeSize() returns size in bytes truncated to a 32-bits int eger.
168 // Find a way to get the size in 64-bits.
169 virtual size_t memoryUsageInBytes() const = 0;
170 virtual CacheType type() const = 0;
171
172 protected:
173 const ImageFrameGenerator* m_generator;
174 int m_useCount;
175 bool m_isDiscardable;
176
177 private:
178 CacheEntry* m_prev;
179 CacheEntry* m_next;
180 };
181
182 class ImageCacheEntry : public CacheEntry {
183 public:
184 static PassOwnPtr<ImageCacheEntry> createAndUse(const ImageFrameGenerato r* generator, PassOwnPtr<ScaledImageFragment> image)
185 {
186 return adoptPtr(new ImageCacheEntry(generator, 1, image));
187 }
188
189 ImageCacheEntry(const ImageFrameGenerator* generator, int count, PassOwn Ptr<ScaledImageFragment> image)
190 : CacheEntry(generator, count, DiscardablePixelRef::isDiscardable(im age->bitmap().pixelRef()))
191 , m_cachedImage(image)
192 {
193 }
194
195 // FIXME: getSafeSize() returns size in bytes truncated to a 32-bits int eger.
196 // Find a way to get the size in 64-bits.
197 virtual size_t memoryUsageInBytes() const { return cachedImage()->bitmap ().getSafeSize(); }
198 virtual CacheType type() const { return TypeImage; }
199
200 static ImageCacheKey makeCacheKey(const ImageFrameGenerator* generator, const SkISize& size, size_t index, size_t generation)
201 {
202 return std::make_pair(std::make_pair(generator, size), std::make_pai r(index, generation));
203 }
204 ImageCacheKey cacheKey() const { return makeCacheKey(m_generator, m_cach edImage->scaledSize(), m_cachedImage->index(), m_cachedImage->generation()); }
205 const ScaledImageFragment* cachedImage() const { return m_cachedImage.ge t(); }
206 ScaledImageFragment* cachedImage() { return m_cachedImage.get(); }
207
208 private:
209 OwnPtr<ScaledImageFragment> m_cachedImage;
210 };
211
212 class DecoderCacheEntry : public CacheEntry {
213 public:
214 static PassOwnPtr<DecoderCacheEntry> create(const ImageFrameGenerator* g enerator, PassOwnPtr<ImageDecoder> decoder, bool isDiscardable)
215 {
216 return adoptPtr(new DecoderCacheEntry(generator, 0, decoder, isDisca rdable));
217 }
218
219 DecoderCacheEntry(const ImageFrameGenerator* generator, int count, PassO wnPtr<ImageDecoder> decoder, bool isDiscardable)
220 : CacheEntry(generator, count, isDiscardable)
221 , m_cachedDecoder(decoder)
222 , m_size(SkISize::Make(m_cachedDecoder->decodedSize().width(), m_cac hedDecoder->decodedSize().height()))
223 {
224 }
225
226 virtual size_t memoryUsageInBytes() const { return m_size.width() * m_si ze.height() * 4; }
227 virtual CacheType type() const { return TypeDecoder; }
228
229 static DecoderCacheKey makeCacheKey(const ImageFrameGenerator* generator , const SkISize& size)
230 {
231 return std::make_pair(generator, size);
232 }
233 static DecoderCacheKey makeCacheKey(const ImageFrameGenerator* generator , const ImageDecoder* decoder)
234 {
235 return std::make_pair(generator, SkISize::Make(decoder->decodedSize( ).width(), decoder->decodedSize().height()));
236 }
237 DecoderCacheKey cacheKey() const { return makeCacheKey(m_generator, m_si ze); }
238 ImageDecoder* cachedDecoder() const { return m_cachedDecoder.get(); }
239
240 private:
241 OwnPtr<ImageDecoder> m_cachedDecoder;
242 SkISize m_size;
243 };
244
245 ImageDecodingStore();
246
247 void prune();
248
249 // These helper methods are called while m_mutex is locked.
250
251 // Find and lock a cache entry, and return true on success.
252 // Memory of the cache entry can be discarded, in which case it is saved in
253 // deletionList.
254 bool lockCacheEntryInternal(ImageCacheEntry*, const ScaledImageFragment**, V ector<OwnPtr<CacheEntry> >* deletionList);
255
256 template<class T, class U, class V> void insertCacheInternal(PassOwnPtr<T> c acheEntry, U* cacheMap, V* identifierMap);
257
258 // Helper method to remove a cache entry. Ownership is transferred to
259 // deletionList. Use of Vector<> is handy when removing multiple entries.
260 template<class T, class U, class V> void removeFromCacheInternal(const T* ca cheEntry, U* cacheMap, V* identifierMap, Vector<OwnPtr<CacheEntry> >* deletionLi st);
261
262 // Helper method to remove a cache entry. Uses the templated version base on
263 // the type of cache entry.
264 void removeFromCacheInternal(const CacheEntry*, Vector<OwnPtr<CacheEntry> >* deletionList);
265
266 // Helper method to remove all cache entries associated with a ImageFraneGen erator.
267 // Ownership of cache entries is transferred to deletionList.
268 template<class U, class V> void removeCacheIndexedByGeneratorInternal(U* cac heMap, V* identifierMap, const ImageFrameGenerator*, Vector<OwnPtr<CacheEntry> > * deletionList);
269
270 // Helper method to remove cache entry pointers from the LRU list.
271 void removeFromCacheListInternal(const Vector<OwnPtr<CacheEntry> >& deletion List);
272
273 void incrementMemoryUsage(size_t size) { m_memoryUsageInBytes += size; }
274 void decrementMemoryUsage(size_t size)
275 {
276 ASSERT(m_memoryUsageInBytes >= size);
277 m_memoryUsageInBytes -= size;
278 }
279
280 // A doubly linked list that maintains usage history of cache entries.
281 // This is used for eviction of old entries.
282 // Head of this list is the least recently used cache entry.
283 // Tail of this list is the most recently used cache entry.
284 DoublyLinkedList<CacheEntry> m_orderedCacheList;
285
286 // A lookup table for all image cache objects. Owns all image cache objects.
287 typedef HashMap<ImageCacheKey, OwnPtr<ImageCacheEntry> > ImageCacheMap;
288 ImageCacheMap m_imageCacheMap;
289
290 // A lookup table for all decoder cache objects. Owns all decoder cache obje cts.
291 typedef HashMap<DecoderCacheKey, OwnPtr<DecoderCacheEntry> > DecoderCacheMap ;
292 DecoderCacheMap m_decoderCacheMap;
293
294 // A lookup table to map ImageFrameGenerator to all associated image
295 // cache keys.
296 typedef HashSet<ImageCacheKey> ImageCacheKeySet;
297 typedef HashMap<const ImageFrameGenerator*, ImageCacheKeySet> ImageCacheKeyM ap;
298 ImageCacheKeyMap m_imageCacheKeyMap;
299
300 // A lookup table to map ImageFrameGenerator to all associated
301 // decoder cache keys.
302 typedef HashSet<DecoderCacheKey> DecoderCacheKeySet;
303 typedef HashMap<const ImageFrameGenerator*, DecoderCacheKeySet> DecoderCache KeyMap;
304 DecoderCacheKeyMap m_decoderCacheKeyMap;
305
306 size_t m_cacheLimitInBytes;
307 size_t m_memoryUsageInBytes;
308
309 // Protect concurrent access to these members:
310 // m_orderedCacheList
311 // m_imageCacheMap, m_decoderCacheMap and all CacheEntrys stored in it
312 // m_imageCacheKeyMap
313 // m_decoderCacheKeyMap
314 // m_cacheLimitInBytes
315 // m_memoryUsageInBytes
316 // This mutex also protects calls to underlying skBitmap's
317 // lockPixels()/unlockPixels() as they are not threadsafe.
318 Mutex m_mutex;
319 };
320
321 } // namespace WebCore
322
323 #endif
OLDNEW
« no previous file with comments | « Source/core/platform/graphics/ImageBuffer.cpp ('k') | Source/core/platform/graphics/ImageDecodingStore.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698