[mac] Keep around more decoded image data, since it's purgeable
authortimothy_horton@apple.com <timothy_horton@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 7 Dec 2013 00:45:11 +0000 (00:45 +0000)
committertimothy_horton@apple.com <timothy_horton@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 7 Dec 2013 00:45:11 +0000 (00:45 +0000)
https://bugs.webkit.org/show_bug.cgi?id=125273
<rdar://problem/13205438>

Reviewed by Simon Fraser.

No new tests, just an optimization.

Instead of throwing away decoded image data eagerly, allow the operating
system to manage the memory via the standard purgeability mechanism,
where it can.

This improves the performance on some pathological cases (extremely large
animated GIFs) by up to 8x.

* loader/cache/MemoryCache.cpp:
(WebCore::MemoryCache::pruneLiveResourcesToSize):
Don't prune live resources' decoded data if it is purgeable.

* platform/graphics/BitmapImage.cpp:
(WebCore::BitmapImage::destroyDecodedDataIfNecessary):
Don't eagerly throw away decoded image data if it's purgeable.

* loader/cache/CachedImage.h:
* loader/cache/CachedResource.h:
(WebCore::CachedResource::decodedDataIsPurgeable):
* platform/graphics/BitmapImage.h:
* platform/graphics/Image.h:
(WebCore::Image::decodedDataIsPurgeable):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@160260 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/WebCore/ChangeLog
Source/WebCore/loader/cache/CachedImage.h
Source/WebCore/loader/cache/CachedResource.h
Source/WebCore/loader/cache/MemoryCache.cpp
Source/WebCore/platform/graphics/BitmapImage.cpp
Source/WebCore/platform/graphics/BitmapImage.h
Source/WebCore/platform/graphics/Image.h

index a3d217d..2047dc4 100644 (file)
@@ -1,3 +1,35 @@
+2013-12-06  Tim Horton  <timothy_horton@apple.com>
+
+        [mac] Keep around more decoded image data, since it's purgeable
+        https://bugs.webkit.org/show_bug.cgi?id=125273
+        <rdar://problem/13205438>
+
+        Reviewed by Simon Fraser.
+
+        No new tests, just an optimization.
+
+        Instead of throwing away decoded image data eagerly, allow the operating
+        system to manage the memory via the standard purgeability mechanism,
+        where it can.
+
+        This improves the performance on some pathological cases (extremely large
+        animated GIFs) by up to 8x.
+
+        * loader/cache/MemoryCache.cpp:
+        (WebCore::MemoryCache::pruneLiveResourcesToSize):
+        Don't prune live resources' decoded data if it is purgeable.
+
+        * platform/graphics/BitmapImage.cpp:
+        (WebCore::BitmapImage::destroyDecodedDataIfNecessary):
+        Don't eagerly throw away decoded image data if it's purgeable.
+
+        * loader/cache/CachedImage.h:
+        * loader/cache/CachedResource.h:
+        (WebCore::CachedResource::decodedDataIsPurgeable):
+        * platform/graphics/BitmapImage.h:
+        * platform/graphics/Image.h:
+        (WebCore::Image::decodedDataIsPurgeable):
+
 2013-12-06  Antti Koivisto  <antti@apple.com>
 
         Save original text for RenderText to a map
index 47a7cf3..22e606e 100644 (file)
@@ -119,6 +119,8 @@ private:
     virtual bool isImage() const OVERRIDE { return true; }
     virtual bool stillNeedsLoad() const OVERRIDE { return !errorOccurred() && status() == Unknown && !isLoading(); }
 
+    virtual bool decodedDataIsPurgeable() const OVERRIDE { return m_image && m_image->decodedDataIsPurgeable(); }
+
     // ImageObserver
     virtual void decodedSizeChanged(const Image*, int delta) OVERRIDE;
     virtual void didDraw(const Image*) OVERRIDE;
index b5b5a5c..40719ba 100644 (file)
@@ -149,6 +149,8 @@ public:
     unsigned encodedSize() const { return m_encodedSize; }
     unsigned decodedSize() const { return m_decodedSize; }
     unsigned overheadSize() const;
+
+    virtual bool decodedDataIsPurgeable() const { return false; }
     
     bool isLoaded() const { return !m_loading; } // FIXME. Method name is inaccurate. Loading might not have started yet.
 
index 28665cc..5fab510 100644 (file)
@@ -266,6 +266,9 @@ void MemoryCache::pruneLiveResourcesToSize(unsigned targetSize)
             if (elapsedTime < cMinDelayBeforeLiveDecodedPrune)
                 return;
 
+            if (current->decodedDataIsPurgeable())
+                continue;
+
             // Destroy our decoded data. This will remove us from 
             // m_liveDecodedResources, and possibly move us to a different LRU 
             // list in m_allResources.
index c88ab5e..ed058fb 100644 (file)
@@ -102,6 +102,11 @@ void BitmapImage::destroyDecodedDataIfNecessary(bool destroyAll)
     // to one frame at a time.
     static const unsigned cLargeAnimationCutoff = 5242880;
 
+    // If decoded data is purgeable, the operating system will
+    // take care of throwing it away when the system is under pressure.
+    if (decodedDataIsPurgeable())
+        return;
+
     // If we have decoded frames but there is no encoded data, we shouldn't destroy
     // the decoded image since we won't be able to reconstruct it later.
     if (!data() && m_frames.size())
index 4ba9c24..ea753ce 100644 (file)
@@ -260,6 +260,15 @@ protected:
 #endif
 
 private:
+    virtual bool decodedDataIsPurgeable() const OVERRIDE
+    {
+#if PLATFORM(MAC) && !PLATFORM(IOS) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 1090
+    return true;
+#else
+    return false;
+#endif
+    }
+
     ImageSource m_source;
     mutable IntSize m_size; // The size to use for the overall image (will just be the size of the first image).
     mutable IntSize m_sizeRespectingOrientation;
index f8d61c9..f83768b 100644 (file)
@@ -124,6 +124,7 @@ public:
     virtual String filenameExtension() const { return String(); } // null string if unknown
 
     virtual void destroyDecodedData(bool destroyAll = true) = 0;
+    virtual bool decodedDataIsPurgeable() const { return false; }
 
     SharedBuffer* data() { return m_encodedImageData.get(); }