Display lists owned the accumulated visual context tree through a ref-counted pointer. That tied visual-context state to display-list lifetime and made compositor updates treat the two as one unit, even though AVC trees need to become independently updateable compositor state. Make accumulated visual context trees plain versioned values, have each display list store the compatible tree version, and pass the matching tree alongside display-list updates and replay calls. Replay verifies that the provided tree matches the display list before executing it. This prepares the compositor for receiving AVC tree updates separately from display-list updates: it now accepts the tree as a separate update parameter, stores it next to the display list, and uses that stored tree for replay and async-scroll hit testing. Nested display-list resources carry their own tree snapshots for the same version check.
82 lines
3.2 KiB
C++
82 lines
3.2 KiB
C++
/*
|
|
* Copyright (c) 2022, Andreas Kling <andreas@ladybird.org>
|
|
*
|
|
* SPDX-License-Identifier: BSD-2-Clause
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include <LibWeb/Layout/SVGGraphicsBox.h>
|
|
#include <LibWeb/Painting/SVGMaskable.h>
|
|
#include <LibWeb/Painting/SVGPaintable.h>
|
|
|
|
namespace Web::Painting {
|
|
|
|
class SVGGraphicsPaintable : public SVGPaintable
|
|
, public SVGMaskable {
|
|
public:
|
|
class ComputedTransforms {
|
|
public:
|
|
ComputedTransforms(Gfx::AffineTransform svg_to_viewbox_transform, Gfx::AffineTransform svg_transform)
|
|
: m_svg_to_viewbox_transform(svg_to_viewbox_transform)
|
|
, m_svg_transform(svg_transform)
|
|
{
|
|
}
|
|
|
|
ComputedTransforms() = default;
|
|
|
|
Gfx::AffineTransform const& svg_to_viewbox_transform() const { return m_svg_to_viewbox_transform; }
|
|
Gfx::AffineTransform const& svg_transform() const { return m_svg_transform; }
|
|
|
|
Gfx::AffineTransform svg_to_css_pixels_transform(
|
|
Optional<Gfx::AffineTransform const&> additional_svg_transform = {}) const
|
|
{
|
|
return Gfx::AffineTransform {}.multiply(svg_to_viewbox_transform()).multiply(additional_svg_transform.value_or(Gfx::AffineTransform {})).multiply(svg_transform());
|
|
}
|
|
|
|
Gfx::AffineTransform svg_to_device_pixels_transform(DisplayListRecordingContext const& context) const
|
|
{
|
|
auto css_scale = context.device_pixels_per_css_pixel();
|
|
return Gfx::AffineTransform {}.scale({ css_scale, css_scale }).multiply(svg_to_css_pixels_transform(context.svg_transform()));
|
|
}
|
|
|
|
private:
|
|
Gfx::AffineTransform m_svg_to_viewbox_transform {};
|
|
Gfx::AffineTransform m_svg_transform {};
|
|
};
|
|
|
|
static NonnullRefPtr<SVGGraphicsPaintable> create(Layout::SVGGraphicsBox const&);
|
|
virtual StringView class_name() const override { return "SVGGraphicsPaintable"sv; }
|
|
|
|
virtual GC::Ptr<DOM::Node const> dom_node_of_svg() const override { return dom_node(); }
|
|
virtual Optional<CSSPixelRect> get_mask_area() const override { return get_svg_mask_area(); }
|
|
virtual Optional<Gfx::MaskKind> get_mask_type() const override { return get_svg_mask_type(); }
|
|
virtual Optional<DisplayListResource> calculate_mask(DisplayListRecordingContext& context, CSSPixelRect const& mask_area) const override { return calculate_svg_mask_display_list(context, mask_area); }
|
|
virtual Optional<CSSPixelRect> get_clip_area() const override { return get_svg_clip_area(); }
|
|
virtual Optional<DisplayListResource> calculate_clip(DisplayListRecordingContext& context, CSSPixelRect const& clip_area) const override { return calculate_svg_clip_display_list(context, clip_area); }
|
|
|
|
void set_computed_transforms(ComputedTransforms computed_transforms)
|
|
{
|
|
m_computed_transforms = computed_transforms;
|
|
}
|
|
|
|
ComputedTransforms const& computed_transforms() const
|
|
{
|
|
return m_computed_transforms;
|
|
}
|
|
|
|
virtual void reset_for_relayout() override;
|
|
|
|
protected:
|
|
SVGGraphicsPaintable(Layout::SVGGraphicsBox const&);
|
|
|
|
ComputedTransforms m_computed_transforms;
|
|
|
|
private:
|
|
virtual bool is_svg_graphics_paintable() const final { return true; }
|
|
};
|
|
|
|
template<>
|
|
inline bool Paintable::fast_is<SVGGraphicsPaintable>() const { return is_svg_graphics_paintable(); }
|
|
|
|
}
|