瀏覽代碼

LibWeb: Allow SVGDecodedImageData to cache bitmaps at different sizes

This avoids constantly re-rendering the same SVG image over and over
during painting when it's being used at a couple of different sizes
(for example when used as a CSS background).
Andreas Kling 1 年之前
父節點
當前提交
9759f44faf

+ 10 - 4
Userland/Libraries/LibWeb/SVG/SVGDecodedImageData.cpp

@@ -147,11 +147,17 @@ RefPtr<Gfx::ImmutableBitmap> SVGDecodedImageData::bitmap(size_t, Gfx::IntSize si
     if (size.is_empty())
         return nullptr;
 
-    if (m_immutable_bitmap && m_immutable_bitmap->size() == size)
-        return m_immutable_bitmap;
+    if (auto it = m_cached_rendered_bitmaps.find(size); it != m_cached_rendered_bitmaps.end())
+        return it->value;
 
-    m_immutable_bitmap = Gfx::ImmutableBitmap::create(*render(size));
-    return m_immutable_bitmap;
+    // Prevent the cache from growing too big.
+    // FIXME: Evict least used entries.
+    if (m_cached_rendered_bitmaps.size() > 10)
+        m_cached_rendered_bitmaps.remove(m_cached_rendered_bitmaps.begin());
+
+    auto immutable_bitmap = Gfx::ImmutableBitmap::create(*render(size));
+    m_cached_rendered_bitmaps.set(size, immutable_bitmap);
+    return immutable_bitmap;
 }
 
 Optional<CSSPixels> SVGDecodedImageData::intrinsic_width() const

+ 2 - 1
Userland/Libraries/LibWeb/SVG/SVGDecodedImageData.h

@@ -40,7 +40,8 @@ private:
     SVGDecodedImageData(JS::NonnullGCPtr<Page>, JS::NonnullGCPtr<SVGPageClient>, JS::NonnullGCPtr<DOM::Document>, JS::NonnullGCPtr<SVG::SVGSVGElement>);
 
     RefPtr<Gfx::Bitmap> render(Gfx::IntSize) const;
-    mutable RefPtr<Gfx::ImmutableBitmap> m_immutable_bitmap;
+
+    mutable HashMap<Gfx::IntSize, NonnullRefPtr<Gfx::ImmutableBitmap>> m_cached_rendered_bitmaps;
 
     JS::NonnullGCPtr<Page> m_page;
     JS::NonnullGCPtr<SVGPageClient> m_page_client;