ladybird/Libraries/LibWeb/Layout/ImageProvider.h
Andreas Kling 17902b02ab LibWeb: Stop idle animated CSS image timers
Keep animated ImageStyleValue frame advancement owned by the
style value. The current frame and loop state live there, so a
separate document scheduler would duplicate ownership of that state.

Start the ImageStyleValue timer only while it has layout clients.
Stop it when the last client unregisters, or when a finite animation
completes. Expose a document-scoped active timer count through
internals for focused regression tests.

Clear image observers when layout nodes detach. Use current-node
cleanup for per-DOM-node clearing, and explicit subtree cleanup for
tree replacement, full tree teardown, and synthetic pseudo-elements.
This keeps large document clearing linear.

Unregister generated-content image providers during layout detach
instead of waiting for GC to finalize the provider.

Cover hidden animated background images, generated content images,
layout node replacement, full layout tree teardown, and document
scoping for the internals counter.
2026-05-23 11:36:53 +02:00

52 lines
1.5 KiB
C++

/*
* Copyright (c) 2023, Andreas Kling <andreas@ladybird.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#pragma once
#include <AK/Optional.h>
#include <LibGC/Cell.h>
#include <LibGfx/DecodedImageFrame.h>
#include <LibGfx/Size.h>
#include <LibWeb/Forward.h>
#include <LibWeb/PixelUnits.h>
namespace Web::Layout {
class ImageProvider {
public:
virtual ~ImageProvider() { }
virtual bool is_image_available() const = 0;
virtual size_t current_frame_index() const = 0;
virtual GC::Ptr<HTML::DecodedImageData> decoded_image_data() const = 0;
virtual Optional<CSSPixels> intrinsic_width() const = 0;
virtual Optional<CSSPixels> intrinsic_height() const = 0;
Optional<CSSPixelSize> intrinsic_size() const;
virtual Optional<CSSPixelFraction> intrinsic_aspect_ratio() const = 0;
virtual Optional<Gfx::DecodedImageFrame> current_image_frame() const;
virtual Optional<Gfx::DecodedImageFrame> current_image_frame_sized(Gfx::IntSize) const = 0;
virtual Optional<Gfx::DecodedImageFrame> default_image_frame() const;
virtual Optional<Gfx::DecodedImageFrame> default_image_frame_sized(Gfx::IntSize) const;
virtual void set_visible_in_viewport(bool) = 0;
virtual void layout_node_was_detached() const { }
virtual void image_provider_visit_edges(GC::Cell::Visitor& visitor) const
{
visitor.visit(to_html_element());
}
protected:
virtual GC::Ptr<DOM::Element const> to_html_element() const = 0;
static void did_update_alt_text(ImageBox&);
};
}