From 9759f44faf1f61b4984135ad8798b0ac9fdb3d0c Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Sat, 24 Feb 2024 08:34:49 +0100 Subject: [PATCH] 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). --- .../Libraries/LibWeb/SVG/SVGDecodedImageData.cpp | 14 ++++++++++---- .../Libraries/LibWeb/SVG/SVGDecodedImageData.h | 3 ++- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/Userland/Libraries/LibWeb/SVG/SVGDecodedImageData.cpp b/Userland/Libraries/LibWeb/SVG/SVGDecodedImageData.cpp index ada4cb1183..2267297547 100644 --- a/Userland/Libraries/LibWeb/SVG/SVGDecodedImageData.cpp +++ b/Userland/Libraries/LibWeb/SVG/SVGDecodedImageData.cpp @@ -147,11 +147,17 @@ RefPtr 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 SVGDecodedImageData::intrinsic_width() const diff --git a/Userland/Libraries/LibWeb/SVG/SVGDecodedImageData.h b/Userland/Libraries/LibWeb/SVG/SVGDecodedImageData.h index 0e71598e65..673656e6c7 100644 --- a/Userland/Libraries/LibWeb/SVG/SVGDecodedImageData.h +++ b/Userland/Libraries/LibWeb/SVG/SVGDecodedImageData.h @@ -40,7 +40,8 @@ private: SVGDecodedImageData(JS::NonnullGCPtr, JS::NonnullGCPtr, JS::NonnullGCPtr, JS::NonnullGCPtr); RefPtr render(Gfx::IntSize) const; - mutable RefPtr m_immutable_bitmap; + + mutable HashMap> m_cached_rendered_bitmaps; JS::NonnullGCPtr m_page; JS::NonnullGCPtr m_page_client;