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).
This commit is contained in:
Andreas Kling 2024-02-24 08:34:49 +01:00
parent 2484324f9a
commit 9759f44faf
Notes: sideshowbarker 2024-07-17 08:37:36 +09:00
2 changed files with 12 additions and 5 deletions

View file

@ -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

View file

@ -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;