| Index: Source/platform/graphics/ImageDecodingStore.cpp
|
| diff --git a/Source/platform/graphics/ImageDecodingStore.cpp b/Source/platform/graphics/ImageDecodingStore.cpp
|
| index 9c4040eb3ef7c583a4b8d9a39153420883173f92..8954791856c065030505c1d46e90b8d8b4b8dd1d 100644
|
| --- a/Source/platform/graphics/ImageDecodingStore.cpp
|
| +++ b/Source/platform/graphics/ImageDecodingStore.cpp
|
| @@ -33,19 +33,13 @@ namespace blink {
|
|
|
| namespace {
|
|
|
| -// Allow up to 256 MBytes of discardable entries. The previous limit allowed up to
|
| -// 128 entries (independently of their size) which caused OOM errors on websites
|
| -// with a lot of (very) large images.
|
| -static const size_t maxTotalSizeOfDiscardableEntries = 256 * 1024 * 1024;
|
| static const size_t defaultMaxTotalSizeOfHeapEntries = 32 * 1024 * 1024;
|
| -static bool s_imageCachingEnabled = true;
|
|
|
| } // namespace
|
|
|
| ImageDecodingStore::ImageDecodingStore()
|
| : m_heapLimitInBytes(defaultMaxTotalSizeOfHeapEntries)
|
| , m_heapMemoryUsageInBytes(0)
|
| - , m_discardableMemoryUsageInBytes(0)
|
| {
|
| }
|
|
|
| @@ -53,10 +47,8 @@ ImageDecodingStore::~ImageDecodingStore()
|
| {
|
| #if ENABLE(ASSERT)
|
| setCacheLimitInBytes(0);
|
| - ASSERT(!m_imageCacheMap.size());
|
| ASSERT(!m_decoderCacheMap.size());
|
| ASSERT(!m_orderedCacheList.size());
|
| - ASSERT(!m_imageCacheKeyMap.size());
|
| ASSERT(!m_decoderCacheKeyMap.size());
|
| #endif
|
| }
|
| @@ -67,85 +59,6 @@ ImageDecodingStore* ImageDecodingStore::instance()
|
| return store;
|
| }
|
|
|
| -void ImageDecodingStore::setImageCachingEnabled(bool enabled)
|
| -{
|
| - s_imageCachingEnabled = enabled;
|
| -}
|
| -
|
| -bool ImageDecodingStore::lockCache(const ImageFrameGenerator* generator, const SkISize& scaledSize, size_t index, const ScaledImageFragment** cachedImage)
|
| -{
|
| - ASSERT(cachedImage);
|
| -
|
| - Vector<OwnPtr<CacheEntry> > cacheEntriesToDelete;
|
| - {
|
| - MutexLocker lock(m_mutex);
|
| - // Public access is restricted to complete images only.
|
| - ImageCacheMap::iterator iter = m_imageCacheMap.find(ImageCacheEntry::makeCacheKey(generator, scaledSize, index, ScaledImageFragment::CompleteImage));
|
| - if (iter == m_imageCacheMap.end())
|
| - return false;
|
| - return lockCacheEntryInternal(iter->value.get(), cachedImage, &cacheEntriesToDelete);
|
| - }
|
| -}
|
| -
|
| -void ImageDecodingStore::unlockCache(const ImageFrameGenerator* generator, const ScaledImageFragment* cachedImage)
|
| -{
|
| - Vector<OwnPtr<CacheEntry> > cacheEntriesToDelete;
|
| - {
|
| - MutexLocker lock(m_mutex);
|
| - cachedImage->bitmap().unlockPixels();
|
| - ImageCacheMap::iterator iter = m_imageCacheMap.find(ImageCacheEntry::makeCacheKey(generator, cachedImage->scaledSize(), cachedImage->index(), cachedImage->generation()));
|
| - ASSERT_WITH_SECURITY_IMPLICATION(iter != m_imageCacheMap.end());
|
| -
|
| - CacheEntry* cacheEntry = iter->value.get();
|
| - cacheEntry->decrementUseCount();
|
| -
|
| - // Put the entry to the end of list.
|
| - m_orderedCacheList.remove(cacheEntry);
|
| - m_orderedCacheList.append(cacheEntry);
|
| -
|
| - // FIXME: This code is temporary such that in the new Skia
|
| - // discardable memory path we do not cache images.
|
| - // Once the transition is complete the logic to handle
|
| - // image caching should be removed entirely.
|
| - if (!s_imageCachingEnabled && !cacheEntry->useCount()) {
|
| - removeFromCacheInternal(cacheEntry, &cacheEntriesToDelete);
|
| - removeFromCacheListInternal(cacheEntriesToDelete);
|
| - }
|
| - }
|
| -}
|
| -
|
| -const ScaledImageFragment* ImageDecodingStore::insertAndLockCache(const ImageFrameGenerator* generator, PassOwnPtr<ScaledImageFragment> image)
|
| -{
|
| - // Prune old cache entries to give space for the new one.
|
| - prune();
|
| -
|
| - ScaledImageFragment* newImage = image.get();
|
| - OwnPtr<ImageCacheEntry> newCacheEntry = ImageCacheEntry::createAndUse(generator, image);
|
| - Vector<OwnPtr<CacheEntry> > cacheEntriesToDelete;
|
| - {
|
| - MutexLocker lock(m_mutex);
|
| -
|
| - ImageCacheMap::iterator iter = m_imageCacheMap.find(newCacheEntry->cacheKey());
|
| -
|
| - // It is rare but possible that the key of a new cache entry is found.
|
| - // This happens if the generation ID of the image object wraps around.
|
| - // In this case we will try to return the existing cached object and
|
| - // discard the new cache object.
|
| - if (iter != m_imageCacheMap.end()) {
|
| - const ScaledImageFragment* oldImage;
|
| - if (lockCacheEntryInternal(iter->value.get(), &oldImage, &cacheEntriesToDelete)) {
|
| - newCacheEntry->decrementUseCount();
|
| - return oldImage;
|
| - }
|
| - }
|
| -
|
| - // The new image is not locked yet so do it here.
|
| - newImage->bitmap().lockPixels();
|
| - insertCacheInternal(newCacheEntry.release(), &m_imageCacheMap, &m_imageCacheKeyMap);
|
| - }
|
| - return newImage;
|
| -}
|
| -
|
| bool ImageDecodingStore::lockDecoder(const ImageFrameGenerator* generator, const SkISize& scaledSize, ImageDecoder** decoder)
|
| {
|
| ASSERT(decoder);
|
| @@ -178,12 +91,12 @@ void ImageDecodingStore::unlockDecoder(const ImageFrameGenerator* generator, con
|
| m_orderedCacheList.append(cacheEntry);
|
| }
|
|
|
| -void ImageDecodingStore::insertDecoder(const ImageFrameGenerator* generator, PassOwnPtr<ImageDecoder> decoder, bool isDiscardable)
|
| +void ImageDecodingStore::insertDecoder(const ImageFrameGenerator* generator, PassOwnPtr<ImageDecoder> decoder)
|
| {
|
| // Prune old cache entries to give space for the new one.
|
| prune();
|
|
|
| - OwnPtr<DecoderCacheEntry> newCacheEntry = DecoderCacheEntry::create(generator, decoder, isDiscardable);
|
| + OwnPtr<DecoderCacheEntry> newCacheEntry = DecoderCacheEntry::create(generator, decoder);
|
|
|
| MutexLocker lock(m_mutex);
|
| ASSERT(!m_decoderCacheMap.contains(newCacheEntry->cacheKey()));
|
| @@ -212,15 +125,6 @@ void ImageDecodingStore::removeDecoder(const ImageFrameGenerator* generator, con
|
| }
|
| }
|
|
|
| -bool ImageDecodingStore::isCached(const ImageFrameGenerator* generator, const SkISize& scaledSize, size_t index)
|
| -{
|
| - MutexLocker lock(m_mutex);
|
| - ImageCacheMap::iterator iter = m_imageCacheMap.find(ImageCacheEntry::makeCacheKey(generator, scaledSize, index, ScaledImageFragment::CompleteImage));
|
| - if (iter == m_imageCacheMap.end())
|
| - return false;
|
| - return true;
|
| -}
|
| -
|
| void ImageDecodingStore::removeCacheIndexedByGenerator(const ImageFrameGenerator* generator)
|
| {
|
| Vector<OwnPtr<CacheEntry> > cacheEntriesToDelete;
|
| @@ -229,7 +133,6 @@ void ImageDecodingStore::removeCacheIndexedByGenerator(const ImageFrameGenerator
|
|
|
| // Remove image cache objects and decoder cache objects associated
|
| // with a ImageFrameGenerator.
|
| - removeCacheIndexedByGeneratorInternal(&m_imageCacheMap, &m_imageCacheKeyMap, generator, &cacheEntriesToDelete);
|
| removeCacheIndexedByGeneratorInternal(&m_decoderCacheMap, &m_decoderCacheKeyMap, generator, &cacheEntriesToDelete);
|
|
|
| // Remove from LRU list as well.
|
| @@ -256,7 +159,6 @@ void ImageDecodingStore::clear()
|
|
|
| void ImageDecodingStore::setCacheLimitInBytes(size_t cacheLimit)
|
| {
|
| - // Note that the discardable entries limit is constant (i.e. only the heap limit is updated).
|
| {
|
| MutexLocker lock(m_mutex);
|
| m_heapLimitInBytes = cacheLimit;
|
| @@ -273,13 +175,7 @@ size_t ImageDecodingStore::memoryUsageInBytes()
|
| int ImageDecodingStore::cacheEntries()
|
| {
|
| MutexLocker lock(m_mutex);
|
| - return m_imageCacheMap.size() + m_decoderCacheMap.size();
|
| -}
|
| -
|
| -int ImageDecodingStore::imageCacheEntries()
|
| -{
|
| - MutexLocker lock(m_mutex);
|
| - return m_imageCacheMap.size();
|
| + return m_decoderCacheMap.size();
|
| }
|
|
|
| int ImageDecodingStore::decoderCacheEntries()
|
| @@ -302,8 +198,7 @@ void ImageDecodingStore::prune()
|
| // Walk the list of cache entries starting from the least recently used
|
| // and then keep them for deletion later.
|
| while (cacheEntry) {
|
| - const bool isPruneNeeded = m_heapMemoryUsageInBytes > m_heapLimitInBytes || !m_heapLimitInBytes
|
| - || m_discardableMemoryUsageInBytes > maxTotalSizeOfDiscardableEntries;
|
| + const bool isPruneNeeded = m_heapMemoryUsageInBytes > m_heapLimitInBytes || !m_heapLimitInBytes;
|
| if (!isPruneNeeded)
|
| break;
|
|
|
| @@ -318,33 +213,11 @@ void ImageDecodingStore::prune()
|
| }
|
| }
|
|
|
| -bool ImageDecodingStore::lockCacheEntryInternal(ImageCacheEntry* cacheEntry, const ScaledImageFragment** cachedImage, Vector<OwnPtr<CacheEntry> >* deletionList)
|
| -{
|
| - ScaledImageFragment* image = cacheEntry->cachedImage();
|
| -
|
| - image->bitmap().lockPixels();
|
| -
|
| - // Memory for this image entry might be discarded already.
|
| - // In this case remove the entry.
|
| - if (!image->bitmap().getPixels()) {
|
| - image->bitmap().unlockPixels();
|
| - removeFromCacheInternal(cacheEntry, &m_imageCacheMap, &m_imageCacheKeyMap, deletionList);
|
| - removeFromCacheListInternal(*deletionList);
|
| - return false;
|
| - }
|
| - cacheEntry->incrementUseCount();
|
| - *cachedImage = image;
|
| - return true;
|
| -}
|
| -
|
| template<class T, class U, class V>
|
| void ImageDecodingStore::insertCacheInternal(PassOwnPtr<T> cacheEntry, U* cacheMap, V* identifierMap)
|
| {
|
| const size_t cacheEntryBytes = cacheEntry->memoryUsageInBytes();
|
| - if (cacheEntry->isDiscardable())
|
| - m_discardableMemoryUsageInBytes += cacheEntryBytes;
|
| - else
|
| - m_heapMemoryUsageInBytes += cacheEntryBytes;
|
| + m_heapMemoryUsageInBytes += cacheEntryBytes;
|
|
|
| // m_orderedCacheList is used to support LRU operations to reorder cache
|
| // entries quickly.
|
| @@ -355,9 +228,7 @@ void ImageDecodingStore::insertCacheInternal(PassOwnPtr<T> cacheEntry, U* cacheM
|
| result.storedValue->value.add(key);
|
| cacheMap->add(key, cacheEntry);
|
|
|
| - TRACE_COUNTER1("blink", "ImageDecodingStoreDiscardableMemoryUsageBytes", m_discardableMemoryUsageInBytes);
|
| TRACE_COUNTER1("blink", "ImageDecodingStoreHeapMemoryUsageBytes", m_heapMemoryUsageInBytes);
|
| - TRACE_COUNTER1("blink", "ImageDecodingStoreNumOfImages", m_imageCacheMap.size());
|
| TRACE_COUNTER1("blink", "ImageDecodingStoreNumOfDecoders", m_decoderCacheMap.size());
|
| }
|
|
|
| @@ -365,14 +236,8 @@ template<class T, class U, class V>
|
| void ImageDecodingStore::removeFromCacheInternal(const T* cacheEntry, U* cacheMap, V* identifierMap, Vector<OwnPtr<CacheEntry> >* deletionList)
|
| {
|
| const size_t cacheEntryBytes = cacheEntry->memoryUsageInBytes();
|
| - if (cacheEntry->isDiscardable()) {
|
| - ASSERT(m_discardableMemoryUsageInBytes >= cacheEntryBytes);
|
| - m_discardableMemoryUsageInBytes -= cacheEntryBytes;
|
| - } else {
|
| - ASSERT(m_heapMemoryUsageInBytes >= cacheEntryBytes);
|
| - m_heapMemoryUsageInBytes -= cacheEntryBytes;
|
| -
|
| - }
|
| + ASSERT(m_heapMemoryUsageInBytes >= cacheEntryBytes);
|
| + m_heapMemoryUsageInBytes -= cacheEntryBytes;
|
|
|
| // Remove entry from identifier map.
|
| typename V::iterator iter = identifierMap->find(cacheEntry->generator());
|
| @@ -384,17 +249,13 @@ void ImageDecodingStore::removeFromCacheInternal(const T* cacheEntry, U* cacheMa
|
| // Remove entry from cache map.
|
| deletionList->append(cacheMap->take(cacheEntry->cacheKey()));
|
|
|
| - TRACE_COUNTER1("blink", "ImageDecodingStoreDiscardableMemoryUsageBytes", m_discardableMemoryUsageInBytes);
|
| TRACE_COUNTER1("blink", "ImageDecodingStoreHeapMemoryUsageBytes", m_heapMemoryUsageInBytes);
|
| - TRACE_COUNTER1("blink", "ImageDecodingStoreNumOfImages", m_imageCacheMap.size());
|
| TRACE_COUNTER1("blink", "ImageDecodingStoreNumOfDecoders", m_decoderCacheMap.size());
|
| }
|
|
|
| void ImageDecodingStore::removeFromCacheInternal(const CacheEntry* cacheEntry, Vector<OwnPtr<CacheEntry> >* deletionList)
|
| {
|
| - if (cacheEntry->type() == CacheEntry::TypeImage) {
|
| - removeFromCacheInternal(static_cast<const ImageCacheEntry*>(cacheEntry), &m_imageCacheMap, &m_imageCacheKeyMap, deletionList);
|
| - } else if (cacheEntry->type() == CacheEntry::TypeDecoder) {
|
| + if (cacheEntry->type() == CacheEntry::TypeDecoder) {
|
| removeFromCacheInternal(static_cast<const DecoderCacheEntry*>(cacheEntry), &m_decoderCacheMap, &m_decoderCacheKeyMap, deletionList);
|
| } else {
|
| ASSERT(false);
|
|
|