| Index: third_party/WebKit/Source/platform/graphics/ImageDecodingStore.h
|
| diff --git a/third_party/WebKit/Source/platform/graphics/ImageDecodingStore.h b/third_party/WebKit/Source/platform/graphics/ImageDecodingStore.h
|
| index dce492da1f808afd3466117670b96fa81495fec9..87e105c429dc71ec2d15eb82f4dc641ae85149ae 100644
|
| --- a/third_party/WebKit/Source/platform/graphics/ImageDecodingStore.h
|
| +++ b/third_party/WebKit/Source/platform/graphics/ImageDecodingStore.h
|
| @@ -30,6 +30,7 @@
|
| #include "SkSize.h"
|
| #include "SkTypes.h"
|
| #include "platform/PlatformExport.h"
|
| +#include "platform/graphics/ImageFrameGenerator.h"
|
| #include "platform/graphics/skia/SkSizeHash.h"
|
| #include "platform/image-decoders/ImageDecoder.h"
|
| #include "platform/wtf/DoublyLinkedList.h"
|
| @@ -40,7 +41,171 @@
|
|
|
| namespace blink {
|
|
|
| -class ImageFrameGenerator;
|
| +// Decoder cache entry is identified by:
|
| +// 1. Pointer to ImageFrameGenerator.
|
| +// 2. Size of the image.
|
| +// 3. ImageDecoder::AlphaOption
|
| +struct DecoderCacheKey {
|
| + const blink::ImageFrameGenerator* gen_;
|
| + SkISize size_;
|
| + blink::ImageDecoder::AlphaOption alpha_option_;
|
| +
|
| + DecoderCacheKey()
|
| + : gen_(nullptr),
|
| + size_(SkISize::Make(0, 0)),
|
| + alpha_option_(static_cast<blink::ImageDecoder::AlphaOption>(0)) {}
|
| +};
|
| +
|
| +static inline bool operator==(const DecoderCacheKey& a,
|
| + const DecoderCacheKey& b) {
|
| + return a.gen_ == b.gen_ && a.size_ == b.size_ &&
|
| + a.alpha_option_ == b.alpha_option_;
|
| +}
|
| +
|
| +static inline bool operator!=(const DecoderCacheKey& a,
|
| + const DecoderCacheKey& b) {
|
| + return !(a == b);
|
| +}
|
| +
|
| +// Base class for all cache entries.
|
| +class CacheEntry : public DoublyLinkedListNode<CacheEntry> {
|
| + USING_FAST_MALLOC(CacheEntry);
|
| + WTF_MAKE_NONCOPYABLE(CacheEntry);
|
| + friend class WTF::DoublyLinkedListNode<CacheEntry>;
|
| +
|
| + public:
|
| + enum CacheType {
|
| + kTypeDecoder,
|
| + };
|
| +
|
| + CacheEntry(const ImageFrameGenerator* generator, int use_count)
|
| + : generator_(generator), use_count_(use_count), prev_(0), next_(0) {}
|
| +
|
| + virtual ~CacheEntry() { DCHECK(!use_count_); }
|
| +
|
| + const ImageFrameGenerator* Generator() const { return generator_; }
|
| + int UseCount() const { return use_count_; }
|
| + void IncrementUseCount() { ++use_count_; }
|
| + void DecrementUseCount() {
|
| + --use_count_;
|
| + DCHECK_GE(use_count_, 0);
|
| + }
|
| +
|
| + // FIXME: getSafeSize() returns the size in bytes truncated to a 32-bit
|
| + // integer. Find a way to get the size in 64-bits.
|
| + virtual size_t MemoryUsageInBytes() const = 0;
|
| + virtual CacheType GetType() const = 0;
|
| +
|
| + protected:
|
| + const ImageFrameGenerator* generator_;
|
| + int use_count_;
|
| +
|
| + private:
|
| + CacheEntry* prev_;
|
| + CacheEntry* next_;
|
| +};
|
| +
|
| +class DecoderCacheEntry final : public CacheEntry {
|
| + public:
|
| + static std::unique_ptr<DecoderCacheEntry> Create(
|
| + const ImageFrameGenerator* generator,
|
| + std::unique_ptr<ImageDecoder> decoder) {
|
| + return WTF::WrapUnique(
|
| + new DecoderCacheEntry(generator, 0, std::move(decoder)));
|
| + }
|
| +
|
| + size_t MemoryUsageInBytes() const override {
|
| + return size_.width() * size_.height() * 4;
|
| + }
|
| + CacheType GetType() const override { return kTypeDecoder; }
|
| +
|
| + static DecoderCacheKey MakeCacheKey(const ImageFrameGenerator* generator,
|
| + const SkISize& size,
|
| + ImageDecoder::AlphaOption alpha_option) {
|
| + DecoderCacheKey key;
|
| + key.gen_ = generator;
|
| + key.size_ = size;
|
| + key.alpha_option_ = alpha_option;
|
| + return key;
|
| + }
|
| + static DecoderCacheKey MakeCacheKey(const ImageFrameGenerator* generator,
|
| + const ImageDecoder* decoder) {
|
| + return MakeCacheKey(generator,
|
| + SkISize::Make(decoder->DecodedSize().Width(),
|
| + decoder->DecodedSize().Height()),
|
| + decoder->GetAlphaOption());
|
| + }
|
| + DecoderCacheKey CacheKey() const {
|
| + return MakeCacheKey(generator_, size_, alpha_option_);
|
| + }
|
| + ImageDecoder* CachedDecoder() const { return cached_decoder_.get(); }
|
| +
|
| + private:
|
| + DecoderCacheEntry(const ImageFrameGenerator* generator,
|
| + int count,
|
| + std::unique_ptr<ImageDecoder> decoder)
|
| + : CacheEntry(generator, count),
|
| + cached_decoder_(std::move(decoder)),
|
| + size_(SkISize::Make(cached_decoder_->DecodedSize().Width(),
|
| + cached_decoder_->DecodedSize().Height())),
|
| + alpha_option_(cached_decoder_->GetAlphaOption()) {}
|
| +
|
| + std::unique_ptr<ImageDecoder> cached_decoder_;
|
| + SkISize size_;
|
| + ImageDecoder::AlphaOption alpha_option_;
|
| +};
|
| +
|
| +} // namespace blink
|
| +
|
| +namespace WTF {
|
| +
|
| +template <>
|
| +struct DefaultHash<blink::DecoderCacheKey> {
|
| + STATIC_ONLY(DefaultHash);
|
| + struct Hash {
|
| + STATIC_ONLY(Hash);
|
| + static unsigned GetHash(const blink::DecoderCacheKey& p) {
|
| + return HashInts(
|
| + HashInts(DefaultHash<blink::ImageFrameGenerator*>::Hash::GetHash(
|
| + const_cast<blink::ImageFrameGenerator*>(p.gen_)),
|
| + DefaultHash<SkISize>::Hash::GetHash(p.size_)),
|
| + DefaultHash<uint8_t>::Hash::GetHash(
|
| + static_cast<uint8_t>(p.alpha_option_)));
|
| + }
|
| + static bool Equal(const blink::DecoderCacheKey& a,
|
| + const blink::DecoderCacheKey& b) {
|
| + return a.gen_ == b.gen_ && a.size_ == b.size_ &&
|
| + a.alpha_option_ == b.alpha_option_;
|
| + }
|
| + static const bool safe_to_compare_to_empty_or_deleted = true;
|
| + };
|
| +};
|
| +
|
| +template <>
|
| +struct HashTraits<blink::DecoderCacheKey>
|
| + : GenericHashTraits<blink::DecoderCacheKey> {
|
| + STATIC_ONLY(HashTraits);
|
| + static const bool kEmptyValueIsZero = true;
|
| + static blink::DecoderCacheKey EmptyValue() {
|
| + return blink::DecoderCacheEntry::MakeCacheKey(
|
| + nullptr, SkISize::Make(0, 0),
|
| + static_cast<blink::ImageDecoder::AlphaOption>(0));
|
| + }
|
| + static void ConstructDeletedValue(blink::DecoderCacheKey& slot, bool) {
|
| + slot = blink::DecoderCacheEntry::MakeCacheKey(
|
| + nullptr, SkISize::Make(-1, -1),
|
| + static_cast<blink::ImageDecoder::AlphaOption>(-1));
|
| + }
|
| + static bool IsDeletedValue(const blink::DecoderCacheKey& value) {
|
| + return !value.gen_ && value.size_ == SkISize::Make(-1, -1) &&
|
| + value.alpha_option_ ==
|
| + static_cast<blink::ImageDecoder::AlphaOption>(-1);
|
| + }
|
| +};
|
| +
|
| +} // namespace WTF
|
| +
|
| +namespace blink {
|
|
|
| // FUNCTION
|
| //
|
| @@ -53,9 +218,9 @@ class ImageFrameGenerator;
|
| //
|
| // ImageFrameGenerator
|
| // This is a direct user of this cache. Responsible for generating bitmap
|
| -// images using an ImageDecoder. It contains encoded image data and is used to
|
| -// represent one image file. It is used to index image and decoder objects in
|
| -// the cache.
|
| +// images using an ImageDecoder. It contains encoded image data and is used
|
| +// to represent one image file. It is used to index image and decoder
|
| +// objects in the cache.
|
| //
|
| // THREAD SAFETY
|
| //
|
| @@ -74,10 +239,11 @@ class PLATFORM_EXPORT ImageDecodingStore final {
|
| static ImageDecodingStore& Instance();
|
|
|
| // Accesses a cached decoder object. A decoder is indexed by origin
|
| - // (ImageFrameGenerator) and scaled size. Returns true if the cached object is
|
| - // found.
|
| + // (ImageFrameGenerator) and scaled size. Returns true if the cached object
|
| + // is found.
|
| bool LockDecoder(const ImageFrameGenerator*,
|
| const SkISize& scaled_size,
|
| + ImageDecoder::AlphaOption,
|
| ImageDecoder**);
|
| void UnlockDecoder(const ImageFrameGenerator*, const ImageDecoder*);
|
| void InsertDecoder(const ImageFrameGenerator*, std::unique_ptr<ImageDecoder>);
|
| @@ -93,89 +259,6 @@ class PLATFORM_EXPORT ImageDecodingStore final {
|
| int DecoderCacheEntries();
|
|
|
| private:
|
| - // Decoder cache entry is identified by:
|
| - // 1. Pointer to ImageFrameGenerator.
|
| - // 2. Size of the image.
|
| - typedef std::pair<const ImageFrameGenerator*, SkISize> DecoderCacheKey;
|
| -
|
| - // Base class for all cache entries.
|
| - class CacheEntry : public DoublyLinkedListNode<CacheEntry> {
|
| - USING_FAST_MALLOC(CacheEntry);
|
| - WTF_MAKE_NONCOPYABLE(CacheEntry);
|
| - friend class WTF::DoublyLinkedListNode<CacheEntry>;
|
| -
|
| - public:
|
| - enum CacheType {
|
| - kTypeDecoder,
|
| - };
|
| -
|
| - CacheEntry(const ImageFrameGenerator* generator, int use_count)
|
| - : generator_(generator), use_count_(use_count), prev_(0), next_(0) {}
|
| -
|
| - virtual ~CacheEntry() { DCHECK(!use_count_); }
|
| -
|
| - const ImageFrameGenerator* Generator() const { return generator_; }
|
| - int UseCount() const { return use_count_; }
|
| - void IncrementUseCount() { ++use_count_; }
|
| - void DecrementUseCount() {
|
| - --use_count_;
|
| - DCHECK_GE(use_count_, 0);
|
| - }
|
| -
|
| - // FIXME: getSafeSize() returns the size in bytes truncated to a 32-bit
|
| - // integer. Find a way to get the size in 64-bits.
|
| - virtual size_t MemoryUsageInBytes() const = 0;
|
| - virtual CacheType GetType() const = 0;
|
| -
|
| - protected:
|
| - const ImageFrameGenerator* generator_;
|
| - int use_count_;
|
| -
|
| - private:
|
| - CacheEntry* prev_;
|
| - CacheEntry* next_;
|
| - };
|
| -
|
| - class DecoderCacheEntry final : public CacheEntry {
|
| - public:
|
| - static std::unique_ptr<DecoderCacheEntry> Create(
|
| - const ImageFrameGenerator* generator,
|
| - std::unique_ptr<ImageDecoder> decoder) {
|
| - return WTF::WrapUnique(
|
| - new DecoderCacheEntry(generator, 0, std::move(decoder)));
|
| - }
|
| -
|
| - DecoderCacheEntry(const ImageFrameGenerator* generator,
|
| - int count,
|
| - std::unique_ptr<ImageDecoder> decoder)
|
| - : CacheEntry(generator, count),
|
| - cached_decoder_(std::move(decoder)),
|
| - size_(SkISize::Make(cached_decoder_->DecodedSize().Width(),
|
| - cached_decoder_->DecodedSize().Height())) {}
|
| -
|
| - size_t MemoryUsageInBytes() const override {
|
| - return size_.width() * size_.height() * 4;
|
| - }
|
| - CacheType GetType() const override { return kTypeDecoder; }
|
| -
|
| - static DecoderCacheKey MakeCacheKey(const ImageFrameGenerator* generator,
|
| - const SkISize& size) {
|
| - return std::make_pair(generator, size);
|
| - }
|
| - static DecoderCacheKey MakeCacheKey(const ImageFrameGenerator* generator,
|
| - const ImageDecoder* decoder) {
|
| - return std::make_pair(generator,
|
| - SkISize::Make(decoder->DecodedSize().Width(),
|
| - decoder->DecodedSize().Height()));
|
| - }
|
| - DecoderCacheKey CacheKey() const { return MakeCacheKey(generator_, size_); }
|
| - ImageDecoder* CachedDecoder() const { return cached_decoder_.get(); }
|
| -
|
| - private:
|
| - std::unique_ptr<ImageDecoder> cached_decoder_;
|
| - SkISize size_;
|
| - };
|
| -
|
| ImageDecodingStore();
|
|
|
| void Prune();
|
|
|