From 18fa662eb2183a16e5abfd110540ba0d47f5e53a Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Tue, 15 Oct 2019 21:53:08 +0200 Subject: [PATCH] LibHTML: Use ImageLoader for elements to defer bitmap decoding We now wait until the pixels are actually needed before fully decoding images in elements. This needs some more work and is currently a bit memory-wasteful since we'll hang on to the raw image data forever. --- Libraries/LibHTML/DOM/HTMLImageElement.cpp | 15 +++++++++------ Libraries/LibHTML/DOM/HTMLImageElement.h | 4 ++++ Libraries/LibHTML/Layout/LayoutImage.cpp | 6 +++++- 3 files changed, 18 insertions(+), 7 deletions(-) diff --git a/Libraries/LibHTML/DOM/HTMLImageElement.cpp b/Libraries/LibHTML/DOM/HTMLImageElement.cpp index 2b34659a46..3ae099290b 100644 --- a/Libraries/LibHTML/DOM/HTMLImageElement.cpp +++ b/Libraries/LibHTML/DOM/HTMLImageElement.cpp @@ -29,7 +29,8 @@ void HTMLImageElement::load_image(const String& src) return; } - m_bitmap = load_png_from_memory(data.data(), data.size()); + m_image_data = data; + m_image_loader = ImageLoader::create(m_image_data.data(), m_image_data.size()); document().update_layout(); }); } @@ -41,8 +42,8 @@ int HTMLImageElement::preferred_width() const if (ok) return width; - if (m_bitmap) - return m_bitmap->width(); + if (m_image_loader) + return m_image_loader->width(); return 0; } @@ -54,8 +55,8 @@ int HTMLImageElement::preferred_height() const if (ok) return height; - if (m_bitmap) - return m_bitmap->height(); + if (m_image_loader) + return m_image_loader->height(); return 0; } @@ -71,5 +72,7 @@ RefPtr HTMLImageElement::create_layout_node(const StyleProperties* p const GraphicsBitmap* HTMLImageElement::bitmap() const { - return m_bitmap; + if (!m_image_loader) + return nullptr; + return m_image_loader->bitmap(); } diff --git a/Libraries/LibHTML/DOM/HTMLImageElement.h b/Libraries/LibHTML/DOM/HTMLImageElement.h index d9091fb052..04d265ed11 100644 --- a/Libraries/LibHTML/DOM/HTMLImageElement.h +++ b/Libraries/LibHTML/DOM/HTMLImageElement.h @@ -1,6 +1,7 @@ #pragma once #include +#include #include class HTMLImageElement : public HTMLElement { @@ -16,11 +17,14 @@ public: int preferred_height() const; const GraphicsBitmap* bitmap() const; + const ImageLoader* image_loader() const { return m_image_loader; } private: void load_image(const String& src); virtual RefPtr create_layout_node(const StyleProperties* parent_style) const override; + RefPtr m_image_loader; mutable RefPtr m_bitmap; + ByteBuffer m_image_data; }; diff --git a/Libraries/LibHTML/Layout/LayoutImage.cpp b/Libraries/LibHTML/Layout/LayoutImage.cpp index 72a03f03cb..f25da78db5 100644 --- a/Libraries/LibHTML/Layout/LayoutImage.cpp +++ b/Libraries/LibHTML/Layout/LayoutImage.cpp @@ -37,6 +37,10 @@ void LayoutImage::render(RenderingContext& context) if (!is_visible()) return; + // FIXME: This should be done at a different level. Also rect() does not include padding etc! + if (!context.viewport_rect().intersects(rect())) + return; + if (renders_as_alt_text()) { context.painter().set_font(Font::default_font()); StylePainter::paint_frame(context.painter(), rect(), FrameShape::Container, FrameShadow::Sunken, 2); @@ -52,5 +56,5 @@ void LayoutImage::render(RenderingContext& context) bool LayoutImage::renders_as_alt_text() const { - return !node().bitmap(); + return !node().image_loader(); }