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

Side by Side Diff: third_party/WebKit/Source/platform/graphics/ImageDecodingStore.h

Issue 2787053004: Respect colorSpace in DecodingImageGenerator::onGetPixels() (Closed)
Patch Set: Rebase Created 3 years, 8 months 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
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2012 Google Inc. All rights reserved. 2 * Copyright (C) 2012 Google Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions 5 * modification, are permitted provided that the following conditions
6 * are met: 6 * are met:
7 * 1. Redistributions of source code must retain the above copyright 7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer. 8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright 9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the 10 * notice, this list of conditions and the following disclaimer in the
(...skipping 12 matching lines...) Expand all
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */ 24 */
25 25
26 #ifndef ImageDecodingStore_h 26 #ifndef ImageDecodingStore_h
27 #define ImageDecodingStore_h 27 #define ImageDecodingStore_h
28 28
29 #include <memory> 29 #include <memory>
30 #include "SkSize.h" 30 #include "SkSize.h"
31 #include "SkTypes.h" 31 #include "SkTypes.h"
32 #include "platform/PlatformExport.h" 32 #include "platform/PlatformExport.h"
33 #include "platform/graphics/ImageFrameGenerator.h"
33 #include "platform/graphics/skia/SkSizeHash.h" 34 #include "platform/graphics/skia/SkSizeHash.h"
34 #include "platform/image-decoders/ImageDecoder.h" 35 #include "platform/image-decoders/ImageDecoder.h"
35 #include "platform/wtf/DoublyLinkedList.h" 36 #include "platform/wtf/DoublyLinkedList.h"
36 #include "platform/wtf/HashSet.h" 37 #include "platform/wtf/HashSet.h"
37 #include "platform/wtf/PtrUtil.h" 38 #include "platform/wtf/PtrUtil.h"
38 #include "platform/wtf/ThreadingPrimitives.h" 39 #include "platform/wtf/ThreadingPrimitives.h"
39 #include "platform/wtf/Vector.h" 40 #include "platform/wtf/Vector.h"
40 41
41 namespace blink { 42 namespace blink {
42 43
43 class ImageFrameGenerator; 44 // Decoder cache entry is identified by:
45 // 1. Pointer to ImageFrameGenerator.
46 // 2. Size of the image.
47 // 3. ImageDecoder::AlphaOption
48 struct DecoderCacheKey {
49 const blink::ImageFrameGenerator* gen_;
50 SkISize size_;
51 blink::ImageDecoder::AlphaOption alpha_option_;
52
53 DecoderCacheKey()
54 : gen_(nullptr),
55 size_(SkISize::Make(0, 0)),
56 alpha_option_(static_cast<blink::ImageDecoder::AlphaOption>(0)) {}
57 };
58
59 static inline bool operator==(const DecoderCacheKey& a,
60 const DecoderCacheKey& b) {
61 return a.gen_ == b.gen_ && a.size_ == b.size_ &&
62 a.alpha_option_ == b.alpha_option_;
63 }
64
65 static inline bool operator!=(const DecoderCacheKey& a,
66 const DecoderCacheKey& b) {
67 return !(a == b);
68 }
69
70 // Base class for all cache entries.
71 class CacheEntry : public DoublyLinkedListNode<CacheEntry> {
72 USING_FAST_MALLOC(CacheEntry);
73 WTF_MAKE_NONCOPYABLE(CacheEntry);
74 friend class WTF::DoublyLinkedListNode<CacheEntry>;
75
76 public:
77 enum CacheType {
78 kTypeDecoder,
79 };
80
81 CacheEntry(const ImageFrameGenerator* generator, int use_count)
82 : generator_(generator), use_count_(use_count), prev_(0), next_(0) {}
83
84 virtual ~CacheEntry() { DCHECK(!use_count_); }
85
86 const ImageFrameGenerator* Generator() const { return generator_; }
87 int UseCount() const { return use_count_; }
88 void IncrementUseCount() { ++use_count_; }
89 void DecrementUseCount() {
90 --use_count_;
91 DCHECK_GE(use_count_, 0);
92 }
93
94 // FIXME: getSafeSize() returns the size in bytes truncated to a 32-bit
95 // integer. Find a way to get the size in 64-bits.
96 virtual size_t MemoryUsageInBytes() const = 0;
97 virtual CacheType GetType() const = 0;
98
99 protected:
100 const ImageFrameGenerator* generator_;
101 int use_count_;
102
103 private:
104 CacheEntry* prev_;
105 CacheEntry* next_;
106 };
107
108 class DecoderCacheEntry final : public CacheEntry {
109 public:
110 static std::unique_ptr<DecoderCacheEntry> Create(
111 const ImageFrameGenerator* generator,
112 std::unique_ptr<ImageDecoder> decoder) {
113 return WTF::WrapUnique(
114 new DecoderCacheEntry(generator, 0, std::move(decoder)));
115 }
116
117 size_t MemoryUsageInBytes() const override {
118 return size_.width() * size_.height() * 4;
119 }
120 CacheType GetType() const override { return kTypeDecoder; }
121
122 static DecoderCacheKey MakeCacheKey(const ImageFrameGenerator* generator,
123 const SkISize& size,
124 ImageDecoder::AlphaOption alpha_option) {
125 DecoderCacheKey key;
126 key.gen_ = generator;
127 key.size_ = size;
128 key.alpha_option_ = alpha_option;
129 return key;
130 }
131 static DecoderCacheKey MakeCacheKey(const ImageFrameGenerator* generator,
132 const ImageDecoder* decoder) {
133 return MakeCacheKey(generator,
134 SkISize::Make(decoder->DecodedSize().Width(),
135 decoder->DecodedSize().Height()),
136 decoder->GetAlphaOption());
137 }
138 DecoderCacheKey CacheKey() const {
139 return MakeCacheKey(generator_, size_, alpha_option_);
140 }
141 ImageDecoder* CachedDecoder() const { return cached_decoder_.get(); }
142
143 private:
144 DecoderCacheEntry(const ImageFrameGenerator* generator,
145 int count,
146 std::unique_ptr<ImageDecoder> decoder)
147 : CacheEntry(generator, count),
148 cached_decoder_(std::move(decoder)),
149 size_(SkISize::Make(cached_decoder_->DecodedSize().Width(),
150 cached_decoder_->DecodedSize().Height())),
151 alpha_option_(cached_decoder_->GetAlphaOption()) {}
152
153 std::unique_ptr<ImageDecoder> cached_decoder_;
154 SkISize size_;
155 ImageDecoder::AlphaOption alpha_option_;
156 };
157
158 } // namespace blink
159
160 namespace WTF {
161
162 template <>
163 struct DefaultHash<blink::DecoderCacheKey> {
164 STATIC_ONLY(DefaultHash);
165 struct Hash {
166 STATIC_ONLY(Hash);
167 static unsigned GetHash(const blink::DecoderCacheKey& p) {
168 return HashInts(
169 HashInts(DefaultHash<blink::ImageFrameGenerator*>::Hash::GetHash(
170 const_cast<blink::ImageFrameGenerator*>(p.gen_)),
171 DefaultHash<SkISize>::Hash::GetHash(p.size_)),
172 DefaultHash<uint8_t>::Hash::GetHash(
173 static_cast<uint8_t>(p.alpha_option_)));
174 }
175 static bool Equal(const blink::DecoderCacheKey& a,
176 const blink::DecoderCacheKey& b) {
177 return a.gen_ == b.gen_ && a.size_ == b.size_ &&
178 a.alpha_option_ == b.alpha_option_;
179 }
180 static const bool safe_to_compare_to_empty_or_deleted = true;
181 };
182 };
183
184 template <>
185 struct HashTraits<blink::DecoderCacheKey>
186 : GenericHashTraits<blink::DecoderCacheKey> {
187 STATIC_ONLY(HashTraits);
188 static const bool kEmptyValueIsZero = true;
189 static blink::DecoderCacheKey EmptyValue() {
190 return blink::DecoderCacheEntry::MakeCacheKey(
191 nullptr, SkISize::Make(0, 0),
192 static_cast<blink::ImageDecoder::AlphaOption>(0));
193 }
194 static void ConstructDeletedValue(blink::DecoderCacheKey& slot, bool) {
195 slot = blink::DecoderCacheEntry::MakeCacheKey(
196 nullptr, SkISize::Make(-1, -1),
197 static_cast<blink::ImageDecoder::AlphaOption>(-1));
198 }
199 static bool IsDeletedValue(const blink::DecoderCacheKey& value) {
200 return !value.gen_ && value.size_ == SkISize::Make(-1, -1) &&
201 value.alpha_option_ ==
202 static_cast<blink::ImageDecoder::AlphaOption>(-1);
203 }
204 };
205
206 } // namespace WTF
207
208 namespace blink {
44 209
45 // FUNCTION 210 // FUNCTION
46 // 211 //
47 // ImageDecodingStore is a class used to manage cached decoder objects. 212 // ImageDecodingStore is a class used to manage cached decoder objects.
48 // 213 //
49 // EXTERNAL OBJECTS 214 // EXTERNAL OBJECTS
50 // 215 //
51 // ImageDecoder 216 // ImageDecoder
52 // A decoder object. It is used to decode raw data into bitmap images. 217 // A decoder object. It is used to decode raw data into bitmap images.
53 // 218 //
54 // ImageFrameGenerator 219 // ImageFrameGenerator
55 // This is a direct user of this cache. Responsible for generating bitmap 220 // This is a direct user of this cache. Responsible for generating bitmap
56 // images using an ImageDecoder. It contains encoded image data and is used to 221 // images using an ImageDecoder. It contains encoded image data and is used
57 // represent one image file. It is used to index image and decoder objects in 222 // to represent one image file. It is used to index image and decoder
58 // the cache. 223 // objects in the cache.
59 // 224 //
60 // THREAD SAFETY 225 // THREAD SAFETY
61 // 226 //
62 // All public methods can be used on any thread. 227 // All public methods can be used on any thread.
63 228
64 class PLATFORM_EXPORT ImageDecodingStore final { 229 class PLATFORM_EXPORT ImageDecodingStore final {
65 USING_FAST_MALLOC(ImageDecodingStore); 230 USING_FAST_MALLOC(ImageDecodingStore);
66 WTF_MAKE_NONCOPYABLE(ImageDecodingStore); 231 WTF_MAKE_NONCOPYABLE(ImageDecodingStore);
67 232
68 public: 233 public:
69 static std::unique_ptr<ImageDecodingStore> Create() { 234 static std::unique_ptr<ImageDecodingStore> Create() {
70 return WTF::WrapUnique(new ImageDecodingStore); 235 return WTF::WrapUnique(new ImageDecodingStore);
71 } 236 }
72 ~ImageDecodingStore(); 237 ~ImageDecodingStore();
73 238
74 static ImageDecodingStore& Instance(); 239 static ImageDecodingStore& Instance();
75 240
76 // Accesses a cached decoder object. A decoder is indexed by origin 241 // Accesses a cached decoder object. A decoder is indexed by origin
77 // (ImageFrameGenerator) and scaled size. Returns true if the cached object is 242 // (ImageFrameGenerator) and scaled size. Returns true if the cached object
78 // found. 243 // is found.
79 bool LockDecoder(const ImageFrameGenerator*, 244 bool LockDecoder(const ImageFrameGenerator*,
80 const SkISize& scaled_size, 245 const SkISize& scaled_size,
246 ImageDecoder::AlphaOption,
81 ImageDecoder**); 247 ImageDecoder**);
82 void UnlockDecoder(const ImageFrameGenerator*, const ImageDecoder*); 248 void UnlockDecoder(const ImageFrameGenerator*, const ImageDecoder*);
83 void InsertDecoder(const ImageFrameGenerator*, std::unique_ptr<ImageDecoder>); 249 void InsertDecoder(const ImageFrameGenerator*, std::unique_ptr<ImageDecoder>);
84 void RemoveDecoder(const ImageFrameGenerator*, const ImageDecoder*); 250 void RemoveDecoder(const ImageFrameGenerator*, const ImageDecoder*);
85 251
86 // Remove all cache entries indexed by ImageFrameGenerator. 252 // Remove all cache entries indexed by ImageFrameGenerator.
87 void RemoveCacheIndexedByGenerator(const ImageFrameGenerator*); 253 void RemoveCacheIndexedByGenerator(const ImageFrameGenerator*);
88 254
89 void Clear(); 255 void Clear();
90 void SetCacheLimitInBytes(size_t); 256 void SetCacheLimitInBytes(size_t);
91 size_t MemoryUsageInBytes(); 257 size_t MemoryUsageInBytes();
92 int CacheEntries(); 258 int CacheEntries();
93 int DecoderCacheEntries(); 259 int DecoderCacheEntries();
94 260
95 private: 261 private:
96 // Decoder cache entry is identified by:
97 // 1. Pointer to ImageFrameGenerator.
98 // 2. Size of the image.
99 typedef std::pair<const ImageFrameGenerator*, SkISize> DecoderCacheKey;
100
101 // Base class for all cache entries.
102 class CacheEntry : public DoublyLinkedListNode<CacheEntry> {
103 USING_FAST_MALLOC(CacheEntry);
104 WTF_MAKE_NONCOPYABLE(CacheEntry);
105 friend class WTF::DoublyLinkedListNode<CacheEntry>;
106
107 public:
108 enum CacheType {
109 kTypeDecoder,
110 };
111
112 CacheEntry(const ImageFrameGenerator* generator, int use_count)
113 : generator_(generator), use_count_(use_count), prev_(0), next_(0) {}
114
115 virtual ~CacheEntry() { DCHECK(!use_count_); }
116
117 const ImageFrameGenerator* Generator() const { return generator_; }
118 int UseCount() const { return use_count_; }
119 void IncrementUseCount() { ++use_count_; }
120 void DecrementUseCount() {
121 --use_count_;
122 DCHECK_GE(use_count_, 0);
123 }
124
125 // FIXME: getSafeSize() returns the size in bytes truncated to a 32-bit
126 // integer. Find a way to get the size in 64-bits.
127 virtual size_t MemoryUsageInBytes() const = 0;
128 virtual CacheType GetType() const = 0;
129
130 protected:
131 const ImageFrameGenerator* generator_;
132 int use_count_;
133
134 private:
135 CacheEntry* prev_;
136 CacheEntry* next_;
137 };
138
139 class DecoderCacheEntry final : public CacheEntry {
140 public:
141 static std::unique_ptr<DecoderCacheEntry> Create(
142 const ImageFrameGenerator* generator,
143 std::unique_ptr<ImageDecoder> decoder) {
144 return WTF::WrapUnique(
145 new DecoderCacheEntry(generator, 0, std::move(decoder)));
146 }
147
148 DecoderCacheEntry(const ImageFrameGenerator* generator,
149 int count,
150 std::unique_ptr<ImageDecoder> decoder)
151 : CacheEntry(generator, count),
152 cached_decoder_(std::move(decoder)),
153 size_(SkISize::Make(cached_decoder_->DecodedSize().Width(),
154 cached_decoder_->DecodedSize().Height())) {}
155
156 size_t MemoryUsageInBytes() const override {
157 return size_.width() * size_.height() * 4;
158 }
159 CacheType GetType() const override { return kTypeDecoder; }
160
161 static DecoderCacheKey MakeCacheKey(const ImageFrameGenerator* generator,
162 const SkISize& size) {
163 return std::make_pair(generator, size);
164 }
165 static DecoderCacheKey MakeCacheKey(const ImageFrameGenerator* generator,
166 const ImageDecoder* decoder) {
167 return std::make_pair(generator,
168 SkISize::Make(decoder->DecodedSize().Width(),
169 decoder->DecodedSize().Height()));
170 }
171 DecoderCacheKey CacheKey() const { return MakeCacheKey(generator_, size_); }
172 ImageDecoder* CachedDecoder() const { return cached_decoder_.get(); }
173
174 private:
175 std::unique_ptr<ImageDecoder> cached_decoder_;
176 SkISize size_;
177 };
178
179 ImageDecodingStore(); 262 ImageDecodingStore();
180 263
181 void Prune(); 264 void Prune();
182 265
183 // These helper methods are called while m_mutex is locked. 266 // These helper methods are called while m_mutex is locked.
184 template <class T, class U, class V> 267 template <class T, class U, class V>
185 void InsertCacheInternal(std::unique_ptr<T> cache_entry, 268 void InsertCacheInternal(std::unique_ptr<T> cache_entry,
186 U* cache_map, 269 U* cache_map,
187 V* identifier_map); 270 V* identifier_map);
188 271
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
244 // m_heapLimitInBytes 327 // m_heapLimitInBytes
245 // m_heapMemoryUsageInBytes 328 // m_heapMemoryUsageInBytes
246 // This mutex also protects calls to underlying skBitmap's 329 // This mutex also protects calls to underlying skBitmap's
247 // lockPixels()/unlockPixels() as they are not threadsafe. 330 // lockPixels()/unlockPixels() as they are not threadsafe.
248 Mutex mutex_; 331 Mutex mutex_;
249 }; 332 };
250 333
251 } // namespace blink 334 } // namespace blink
252 335
253 #endif 336 #endif
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698