layout: Report memory usage for fragment and box trees. (#36553)

Add memory reporter integration for the fragment and box trees that are
persisted in the layout thread.

Testing: Looked at the numbers for https://servo.org and
https://html.spec.whatwg.org/. The former was very small, but the latter
was 700mb.

---------

Signed-off-by: Josh Matthews <josh@joshmatthews.net>
This commit is contained in:
Josh Matthews 2025-04-18 16:05:15 -04:00 committed by GitHub
parent add8c51f47
commit c787688afc
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
33 changed files with 230 additions and 69 deletions

8
Cargo.lock generated
View file

@ -1134,11 +1134,13 @@ dependencies = [
"image", "image",
"ipc-channel", "ipc-channel",
"log", "log",
"malloc_size_of_derive",
"pixels", "pixels",
"profile_traits", "profile_traits",
"raw-window-handle", "raw-window-handle",
"serde", "serde",
"servo_geometry", "servo_geometry",
"servo_malloc_size_of",
"strum_macros", "strum_macros",
"stylo", "stylo",
"stylo_traits", "stylo_traits",
@ -4162,6 +4164,7 @@ dependencies = [
"ipc-channel", "ipc-channel",
"itertools 0.13.0", "itertools 0.13.0",
"log", "log",
"malloc_size_of_derive",
"net_traits", "net_traits",
"num-traits", "num-traits",
"parking_lot", "parking_lot",
@ -4174,6 +4177,7 @@ dependencies = [
"servo_arc", "servo_arc",
"servo_config", "servo_config",
"servo_geometry", "servo_geometry",
"servo_malloc_size_of",
"servo_url", "servo_url",
"stylo", "stylo",
"stylo_traits", "stylo_traits",
@ -6822,6 +6826,7 @@ version = "0.0.1"
dependencies = [ dependencies = [
"accountable-refcell", "accountable-refcell",
"app_units", "app_units",
"atomic_refcell",
"content-security-policy", "content-security-policy",
"crossbeam-channel", "crossbeam-channel",
"euclid", "euclid",
@ -6837,8 +6842,11 @@ dependencies = [
"stylo", "stylo",
"stylo_dom", "stylo_dom",
"stylo_malloc_size_of", "stylo_malloc_size_of",
"taffy",
"thin-vec", "thin-vec",
"tokio", "tokio",
"unicode-bidi",
"unicode-script",
"url", "url",
"uuid", "uuid",
"webrender_api", "webrender_api",

View file

@ -741,9 +741,10 @@ impl fmt::Debug for GlyphStore {
} }
/// A single series of glyphs within a text run. /// A single series of glyphs within a text run.
#[derive(Clone, Debug, Deserialize, Serialize)] #[derive(Clone, Debug, Deserialize, MallocSizeOf, Serialize)]
pub struct GlyphRun { pub struct GlyphRun {
/// The glyphs. /// The glyphs.
#[conditional_malloc_size_of]
pub glyph_store: Arc<GlyphStore>, pub glyph_store: Arc<GlyphStore>,
/// The byte range of characters in the containing run. /// The byte range of characters in the containing run.
pub range: Range<ByteIndex>, pub range: Range<ByteIndex>,

View file

@ -36,6 +36,8 @@ icu_segmenter = { workspace = true }
ipc-channel = { workspace = true } ipc-channel = { workspace = true }
itertools = { workspace = true } itertools = { workspace = true }
log = { workspace = true } log = { workspace = true }
malloc_size_of = { workspace = true }
malloc_size_of_derive = { workspace = true }
net_traits = { workspace = true } net_traits = { workspace = true }
parking_lot = { workspace = true } parking_lot = { workspace = true }
pixels = { path = "../pixels" } pixels = { path = "../pixels" }

View file

@ -6,9 +6,12 @@ use std::fmt;
use std::ops::Deref; use std::ops::Deref;
use atomic_refcell::AtomicRefCell; use atomic_refcell::AtomicRefCell;
use malloc_size_of_derive::MallocSizeOf;
use servo_arc::Arc; use servo_arc::Arc;
#[derive(MallocSizeOf)]
pub struct ArcRefCell<T> { pub struct ArcRefCell<T> {
#[conditional_malloc_size_of]
value: Arc<AtomicRefCell<T>>, value: Arc<AtomicRefCell<T>>,
} }

View file

@ -4,6 +4,7 @@
//! <https://drafts.csswg.org/css-flexbox/#box-model> //! <https://drafts.csswg.org/css-flexbox/#box-model>
use malloc_size_of_derive::MallocSizeOf;
use style::properties::longhands::flex_direction::computed_value::T as FlexDirection; use style::properties::longhands::flex_direction::computed_value::T as FlexDirection;
use crate::geom::{LogicalRect, LogicalSides, LogicalVec2}; use crate::geom::{LogicalRect, LogicalSides, LogicalVec2};
@ -67,7 +68,7 @@ impl<T> FlexRelativeSides<T> {
/// One of the two bits set by the `flex-direction` property /// One of the two bits set by the `flex-direction` property
/// (The other is "forward" v.s. reverse.) /// (The other is "forward" v.s. reverse.)
#[derive(Clone, Copy, Debug, PartialEq)] #[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq)]
pub(super) enum FlexAxis { pub(super) enum FlexAxis {
/// The main axis is the inline axis of the container (not necessarily of flex items!), /// The main axis is the inline axis of the container (not necessarily of flex items!),
/// cross is block. /// cross is block.
@ -78,7 +79,7 @@ pub(super) enum FlexAxis {
/// Which flow-relative sides map to the main-start and cross-start sides, respectively. /// Which flow-relative sides map to the main-start and cross-start sides, respectively.
/// See <https://drafts.csswg.org/css-flexbox/#box-model> /// See <https://drafts.csswg.org/css-flexbox/#box-model>
#[derive(Clone, Copy, Debug)] #[derive(Clone, Copy, Debug, MallocSizeOf)]
pub(super) enum MainStartCrossStart { pub(super) enum MainStartCrossStart {
InlineStartBlockStart, InlineStartBlockStart,
InlineStartBlockEnd, InlineStartBlockEnd,

View file

@ -3,6 +3,7 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
use geom::{FlexAxis, MainStartCrossStart}; use geom::{FlexAxis, MainStartCrossStart};
use malloc_size_of_derive::MallocSizeOf;
use servo_arc::Arc as ServoArc; use servo_arc::Arc as ServoArc;
use style::logical_geometry::WritingMode; use style::logical_geometry::WritingMode;
use style::properties::ComputedValues; use style::properties::ComputedValues;
@ -27,7 +28,7 @@ mod layout;
/// A structure to hold the configuration of a flex container for use during layout /// A structure to hold the configuration of a flex container for use during layout
/// and preferred width calculation. /// and preferred width calculation.
#[derive(Clone, Debug)] #[derive(Clone, Debug, MallocSizeOf)]
pub(crate) struct FlexContainerConfig { pub(crate) struct FlexContainerConfig {
container_is_single_line: bool, container_is_single_line: bool,
writing_mode: WritingMode, writing_mode: WritingMode,
@ -85,10 +86,11 @@ impl FlexContainerConfig {
} }
} }
#[derive(Debug)] #[derive(Debug, MallocSizeOf)]
pub(crate) struct FlexContainer { pub(crate) struct FlexContainer {
children: Vec<ArcRefCell<FlexLevelBox>>, children: Vec<ArcRefCell<FlexLevelBox>>,
#[conditional_malloc_size_of]
style: ServoArc<ComputedValues>, style: ServoArc<ComputedValues>,
/// The configuration of this [`FlexContainer`]. /// The configuration of this [`FlexContainer`].
@ -137,7 +139,7 @@ impl FlexContainer {
} }
} }
#[derive(Debug)] #[derive(Debug, MallocSizeOf)]
pub(crate) enum FlexLevelBox { pub(crate) enum FlexLevelBox {
FlexItem(FlexItemBox), FlexItem(FlexItemBox),
OutOfFlowAbsolutelyPositionedBox(ArcRefCell<AbsolutelyPositionedBox>), OutOfFlowAbsolutelyPositionedBox(ArcRefCell<AbsolutelyPositionedBox>),
@ -171,6 +173,7 @@ impl FlexLevelBox {
} }
} }
#[derive(MallocSizeOf)]
pub(crate) struct FlexItemBox { pub(crate) struct FlexItemBox {
independent_formatting_context: IndependentFormattingContext, independent_formatting_context: IndependentFormattingContext,
} }

View file

@ -13,6 +13,7 @@ use std::ops::Range;
use app_units::{Au, MAX_AU, MIN_AU}; use app_units::{Au, MAX_AU, MIN_AU};
use euclid::num::Zero; use euclid::num::Zero;
use malloc_size_of_derive::MallocSizeOf;
use servo_arc::Arc; use servo_arc::Arc;
use style::computed_values::float::T as FloatProperty; use style::computed_values::float::T as FloatProperty;
use style::computed_values::position::T as Position; use style::computed_values::position::T as Position;
@ -31,7 +32,7 @@ use crate::style_ext::{DisplayInside, PaddingBorderMargin};
use crate::{ContainingBlock, PropagatedBoxTreeData}; use crate::{ContainingBlock, PropagatedBoxTreeData};
/// A floating box. /// A floating box.
#[derive(Debug)] #[derive(Debug, MallocSizeOf)]
pub(crate) struct FloatBox { pub(crate) struct FloatBox {
/// The formatting context that makes up the content of this box. /// The formatting context that makes up the content of this box.
pub contents: IndependentFormattingContext, pub contents: IndependentFormattingContext,

View file

@ -6,6 +6,7 @@ use std::vec::IntoIter;
use app_units::Au; use app_units::Au;
use fonts::FontMetrics; use fonts::FontMetrics;
use malloc_size_of_derive::MallocSizeOf;
use super::{InlineContainerState, InlineContainerStateFlags, inline_container_needs_strut}; use super::{InlineContainerState, InlineContainerStateFlags, inline_container_needs_strut};
use crate::ContainingBlock; use crate::ContainingBlock;
@ -17,7 +18,7 @@ use crate::fragment_tree::BaseFragmentInfo;
use crate::layout_box_base::LayoutBoxBase; use crate::layout_box_base::LayoutBoxBase;
use crate::style_ext::{LayoutStyle, PaddingBorderMargin}; use crate::style_ext::{LayoutStyle, PaddingBorderMargin};
#[derive(Debug)] #[derive(Debug, MallocSizeOf)]
pub(crate) struct InlineBox { pub(crate) struct InlineBox {
pub base: LayoutBoxBase, pub base: LayoutBoxBase,
/// The identifier of this inline box in the containing [`super::InlineFormattingContext`]. /// The identifier of this inline box in the containing [`super::InlineFormattingContext`].
@ -56,7 +57,7 @@ impl InlineBox {
} }
} }
#[derive(Debug, Default)] #[derive(Debug, Default, MallocSizeOf)]
pub(crate) struct InlineBoxes { pub(crate) struct InlineBoxes {
/// A collection of all inline boxes in a particular [`super::InlineFormattingContext`]. /// A collection of all inline boxes in a particular [`super::InlineFormattingContext`].
inline_boxes: Vec<ArcRefCell<InlineBox>>, inline_boxes: Vec<ArcRefCell<InlineBox>>,
@ -162,7 +163,7 @@ impl InlineBoxes {
} }
} }
#[derive(Clone, Copy, Debug, PartialEq)] #[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq)]
pub(super) enum InlineBoxTreePathToken { pub(super) enum InlineBoxTreePathToken {
Start(InlineBoxIdentifier), Start(InlineBoxIdentifier),
End(InlineBoxIdentifier), End(InlineBoxIdentifier),
@ -183,7 +184,7 @@ impl InlineBoxTreePathToken {
/// [`u32`] is used for the index, in order to save space. The value refers to the token /// [`u32`] is used for the index, in order to save space. The value refers to the token
/// in the start tree data structure which can be fetched to find the actual index of /// in the start tree data structure which can be fetched to find the actual index of
/// of the [`InlineBox`] in [`InlineBoxes::inline_boxes`]. /// of the [`InlineBox`] in [`InlineBoxes::inline_boxes`].
#[derive(Clone, Copy, Debug, Default, Eq, Hash, PartialEq)] #[derive(Clone, Copy, Debug, Default, Eq, Hash, MallocSizeOf, PartialEq)]
pub(crate) struct InlineBoxIdentifier { pub(crate) struct InlineBoxIdentifier {
pub index_of_start_in_tree: u32, pub index_of_start_in_tree: u32,
pub index_in_inline_boxes: u32, pub index_in_inline_boxes: u32,

View file

@ -88,6 +88,7 @@ use line::{
TextRunLineItem, TextRunLineItem,
}; };
use line_breaker::LineBreaker; use line_breaker::LineBreaker;
use malloc_size_of_derive::MallocSizeOf;
use range::Range; use range::Range;
use servo_arc::Arc; use servo_arc::Arc;
use style::Zero; use style::Zero;
@ -136,7 +137,7 @@ use crate::{ConstraintSpace, ContainingBlock, PropagatedBoxTreeData};
static FONT_SUBSCRIPT_OFFSET_RATIO: f32 = 0.20; static FONT_SUBSCRIPT_OFFSET_RATIO: f32 = 0.20;
static FONT_SUPERSCRIPT_OFFSET_RATIO: f32 = 0.34; static FONT_SUPERSCRIPT_OFFSET_RATIO: f32 = 0.34;
#[derive(Debug)] #[derive(Debug, MallocSizeOf)]
pub(crate) struct InlineFormattingContext { pub(crate) struct InlineFormattingContext {
/// All [`InlineItem`]s in this [`InlineFormattingContext`] stored in a flat array. /// All [`InlineItem`]s in this [`InlineFormattingContext`] stored in a flat array.
/// [`InlineItem::StartInlineBox`] and [`InlineItem::EndInlineBox`] allow representing /// [`InlineItem::StartInlineBox`] and [`InlineItem::EndInlineBox`] allow representing
@ -173,14 +174,14 @@ pub(crate) struct InlineFormattingContext {
} }
/// A collection of data used to cache [`FontMetrics`] in the [`InlineFormattingContext`] /// A collection of data used to cache [`FontMetrics`] in the [`InlineFormattingContext`]
#[derive(Debug)] #[derive(Debug, MallocSizeOf)]
pub(crate) struct FontKeyAndMetrics { pub(crate) struct FontKeyAndMetrics {
pub key: FontInstanceKey, pub key: FontInstanceKey,
pub pt_size: Au, pub pt_size: Au,
pub metrics: FontMetrics, pub metrics: FontMetrics,
} }
#[derive(Debug)] #[derive(Debug, MallocSizeOf)]
pub(crate) enum InlineItem { pub(crate) enum InlineItem {
StartInlineBox(ArcRefCell<InlineBox>), StartInlineBox(ArcRefCell<InlineBox>),
EndInlineBox, EndInlineBox,
@ -189,9 +190,9 @@ pub(crate) enum InlineItem {
ArcRefCell<AbsolutelyPositionedBox>, ArcRefCell<AbsolutelyPositionedBox>,
usize, /* offset_in_text */ usize, /* offset_in_text */
), ),
OutOfFlowFloatBox(Arc<FloatBox>), OutOfFlowFloatBox(#[conditional_malloc_size_of] Arc<FloatBox>),
Atomic( Atomic(
Arc<IndependentFormattingContext>, #[conditional_malloc_size_of] Arc<IndependentFormattingContext>,
usize, /* offset_in_text */ usize, /* offset_in_text */
Level, /* bidi_level */ Level, /* bidi_level */
), ),

View file

@ -12,6 +12,7 @@ use fonts::{
}; };
use fonts_traits::ByteIndex; use fonts_traits::ByteIndex;
use log::warn; use log::warn;
use malloc_size_of_derive::MallocSizeOf;
use range::Range as ServoRange; use range::Range as ServoRange;
use servo_arc::Arc; use servo_arc::Arc;
use style::computed_values::text_rendering::T as TextRendering; use style::computed_values::text_rendering::T as TextRendering;
@ -37,9 +38,10 @@ pub(crate) const XI_LINE_BREAKING_CLASS_WJ: u8 = 30;
pub(crate) const XI_LINE_BREAKING_CLASS_ZWJ: u8 = 42; pub(crate) const XI_LINE_BREAKING_CLASS_ZWJ: u8 = 42;
/// <https://www.w3.org/TR/css-display-3/#css-text-run> /// <https://www.w3.org/TR/css-display-3/#css-text-run>
#[derive(Debug)] #[derive(Debug, MallocSizeOf)]
pub(crate) struct TextRun { pub(crate) struct TextRun {
pub base_fragment_info: BaseFragmentInfo, pub base_fragment_info: BaseFragmentInfo,
#[conditional_malloc_size_of]
pub parent_style: Arc<ComputedValues>, pub parent_style: Arc<ComputedValues>,
pub text_range: Range<usize>, pub text_range: Range<usize>,
@ -47,6 +49,7 @@ pub(crate) struct TextRun {
/// segments, and shaped. /// segments, and shaped.
pub shaped_text: Vec<TextRunSegment>, pub shaped_text: Vec<TextRunSegment>,
pub selection_range: Option<ServoRange<ByteIndex>>, pub selection_range: Option<ServoRange<ByteIndex>>,
#[conditional_malloc_size_of]
pub selected_style: Arc<ComputedValues>, pub selected_style: Arc<ComputedValues>,
} }
@ -64,7 +67,7 @@ enum SegmentStartSoftWrapPolicy {
FollowLinebreaker, FollowLinebreaker,
} }
#[derive(Debug)] #[derive(Debug, MallocSizeOf)]
pub(crate) struct TextRunSegment { pub(crate) struct TextRunSegment {
/// The index of this font in the parent [`super::InlineFormattingContext`]'s collection of font /// The index of this font in the parent [`super::InlineFormattingContext`]'s collection of font
/// information. /// information.

View file

@ -7,6 +7,7 @@
use app_units::{Au, MAX_AU}; use app_units::{Au, MAX_AU};
use inline::InlineFormattingContext; use inline::InlineFormattingContext;
use malloc_size_of_derive::MallocSizeOf;
use rayon::iter::{IndexedParallelIterator, IntoParallelRefIterator, ParallelIterator}; use rayon::iter::{IndexedParallelIterator, IntoParallelRefIterator, ParallelIterator};
use servo_arc::Arc; use servo_arc::Arc;
use style::Zero; use style::Zero;
@ -53,13 +54,13 @@ mod root;
pub(crate) use construct::BlockContainerBuilder; pub(crate) use construct::BlockContainerBuilder;
pub use root::{BoxTree, CanvasBackground}; pub use root::{BoxTree, CanvasBackground};
#[derive(Debug)] #[derive(Debug, MallocSizeOf)]
pub(crate) struct BlockFormattingContext { pub(crate) struct BlockFormattingContext {
pub contents: BlockContainer, pub contents: BlockContainer,
pub contains_floats: bool, pub contains_floats: bool,
} }
#[derive(Debug)] #[derive(Debug, MallocSizeOf)]
pub(crate) enum BlockContainer { pub(crate) enum BlockContainer {
BlockLevelBoxes(Vec<ArcRefCell<BlockLevelBox>>), BlockLevelBoxes(Vec<ArcRefCell<BlockLevelBox>>),
InlineFormattingContext(InlineFormattingContext), InlineFormattingContext(InlineFormattingContext),
@ -76,7 +77,7 @@ impl BlockContainer {
} }
} }
#[derive(Debug)] #[derive(Debug, MallocSizeOf)]
pub(crate) enum BlockLevelBox { pub(crate) enum BlockLevelBox {
Independent(IndependentFormattingContext), Independent(IndependentFormattingContext),
OutOfFlowAbsolutelyPositionedBox(ArcRefCell<AbsolutelyPositionedBox>), OutOfFlowAbsolutelyPositionedBox(ArcRefCell<AbsolutelyPositionedBox>),
@ -246,8 +247,9 @@ pub(crate) struct CollapsibleWithParentStartMargin(bool);
/// The contentes of a BlockContainer created to render a list marker /// The contentes of a BlockContainer created to render a list marker
/// for a list that has `list-style-position: outside`. /// for a list that has `list-style-position: outside`.
#[derive(Debug)] #[derive(Debug, MallocSizeOf)]
pub(crate) struct OutsideMarker { pub(crate) struct OutsideMarker {
#[conditional_malloc_size_of]
pub list_item_style: Arc<ComputedValues>, pub list_item_style: Arc<ComputedValues>,
pub base: LayoutBoxBase, pub base: LayoutBoxBase,
pub block_container: BlockContainer, pub block_container: BlockContainer,

View file

@ -5,6 +5,7 @@
use app_units::Au; use app_units::Au;
use atomic_refcell::AtomicRef; use atomic_refcell::AtomicRef;
use compositing_traits::display_list::AxesScrollSensitivity; use compositing_traits::display_list::AxesScrollSensitivity;
use malloc_size_of_derive::MallocSizeOf;
use script_layout_interface::wrapper_traits::{ use script_layout_interface::wrapper_traits::{
LayoutNode, ThreadSafeLayoutElement, ThreadSafeLayoutNode, LayoutNode, ThreadSafeLayoutElement, ThreadSafeLayoutNode,
}; };
@ -32,6 +33,7 @@ use crate::style_ext::{ComputedValuesExt, Display, DisplayGeneratingBox, Display
use crate::taffy::{TaffyItemBox, TaffyItemBoxInner}; use crate::taffy::{TaffyItemBox, TaffyItemBoxInner};
use crate::{DefiniteContainingBlock, PropagatedBoxTreeData}; use crate::{DefiniteContainingBlock, PropagatedBoxTreeData};
#[derive(MallocSizeOf)]
pub struct BoxTree { pub struct BoxTree {
/// Contains typically exactly one block-level box, which was generated by the root element. /// Contains typically exactly one block-level box, which was generated by the root element.
/// There may be zero if that element has `display: none`. /// There may be zero if that element has `display: none`.
@ -437,7 +439,7 @@ impl BoxTree {
} }
/// <https://drafts.csswg.org/css-backgrounds/#root-background> /// <https://drafts.csswg.org/css-backgrounds/#root-background>
#[derive(Clone)] #[derive(Clone, MallocSizeOf)]
pub struct CanvasBackground { pub struct CanvasBackground {
/// DOM node for the root element /// DOM node for the root element
pub root_element: OpaqueNode, pub root_element: OpaqueNode,
@ -448,6 +450,7 @@ pub struct CanvasBackground {
pub from_element: OpaqueNode, pub from_element: OpaqueNode,
/// The computed styles to take background properties from. /// The computed styles to take background properties from.
#[conditional_malloc_size_of]
pub style: Option<Arc<ComputedValues>>, pub style: Option<Arc<ComputedValues>>,
} }

View file

@ -3,6 +3,7 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
use app_units::Au; use app_units::Au;
use malloc_size_of_derive::MallocSizeOf;
use servo_arc::Arc; use servo_arc::Arc;
use style::properties::ComputedValues; use style::properties::ComputedValues;
use style::selector_parser::PseudoElement; use style::selector_parser::PseudoElement;
@ -27,13 +28,13 @@ use crate::{
}; };
/// <https://drafts.csswg.org/css-display/#independent-formatting-context> /// <https://drafts.csswg.org/css-display/#independent-formatting-context>
#[derive(Debug)] #[derive(Debug, MallocSizeOf)]
pub(crate) struct IndependentFormattingContext { pub(crate) struct IndependentFormattingContext {
pub base: LayoutBoxBase, pub base: LayoutBoxBase,
pub contents: IndependentFormattingContextContents, pub contents: IndependentFormattingContextContents,
} }
#[derive(Debug)] #[derive(Debug, MallocSizeOf)]
pub(crate) enum IndependentFormattingContextContents { pub(crate) enum IndependentFormattingContextContents {
NonReplaced(IndependentNonReplacedContents), NonReplaced(IndependentNonReplacedContents),
Replaced(ReplacedContents), Replaced(ReplacedContents),
@ -41,7 +42,7 @@ pub(crate) enum IndependentFormattingContextContents {
// Private so that code outside of this module cannot match variants. // Private so that code outside of this module cannot match variants.
// It should got through methods instead. // It should got through methods instead.
#[derive(Debug)] #[derive(Debug, MallocSizeOf)]
pub(crate) enum IndependentNonReplacedContents { pub(crate) enum IndependentNonReplacedContents {
Flow(BlockFormattingContext), Flow(BlockFormattingContext),
Flex(FlexContainer), Flex(FlexContainer),
@ -52,7 +53,7 @@ pub(crate) enum IndependentNonReplacedContents {
/// The baselines of a layout or a [`crate::fragment_tree::BoxFragment`]. Some layout /// The baselines of a layout or a [`crate::fragment_tree::BoxFragment`]. Some layout
/// uses the first and some layout uses the last. /// uses the first and some layout uses the last.
#[derive(Clone, Copy, Debug, Default)] #[derive(Clone, Copy, Debug, Default, MallocSizeOf)]
pub(crate) struct Baselines { pub(crate) struct Baselines {
pub first: Option<Au>, pub first: Option<Au>,
pub last: Option<Au>, pub last: Option<Au>,

View file

@ -3,6 +3,8 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
use bitflags::bitflags; use bitflags::bitflags;
use malloc_size_of::malloc_size_of_is_0;
use malloc_size_of_derive::MallocSizeOf;
use script_layout_interface::combine_id_with_fragment_type; use script_layout_interface::combine_id_with_fragment_type;
use style::dom::OpaqueNode; use style::dom::OpaqueNode;
use style::selector_parser::PseudoElement; use style::selector_parser::PseudoElement;
@ -10,7 +12,7 @@ use style::selector_parser::PseudoElement;
/// This data structure stores fields that are common to all non-base /// This data structure stores fields that are common to all non-base
/// Fragment types and should generally be the first member of all /// Fragment types and should generally be the first member of all
/// concrete fragments. /// concrete fragments.
#[derive(Clone, Debug)] #[derive(Clone, Debug, MallocSizeOf)]
pub(crate) struct BaseFragment { pub(crate) struct BaseFragment {
/// A tag which identifies the DOM node and pseudo element of this /// A tag which identifies the DOM node and pseudo element of this
/// Fragment's content. If this fragment is for an anonymous box, /// Fragment's content. If this fragment is for an anonymous box,
@ -38,7 +40,7 @@ impl BaseFragment {
} }
/// Information necessary to construct a new BaseFragment. /// Information necessary to construct a new BaseFragment.
#[derive(Clone, Copy, Debug)] #[derive(Clone, Copy, Debug, MallocSizeOf)]
pub(crate) struct BaseFragmentInfo { pub(crate) struct BaseFragmentInfo {
/// The tag to use for the new BaseFragment, if it is not an anonymous Fragment. /// The tag to use for the new BaseFragment, if it is not an anonymous Fragment.
pub tag: Option<Tag>, pub tag: Option<Tag>,
@ -107,9 +109,11 @@ bitflags! {
} }
} }
malloc_size_of_is_0!(FragmentFlags);
/// A data structure used to hold DOM and pseudo-element information about /// A data structure used to hold DOM and pseudo-element information about
/// a particular layout object. /// a particular layout object.
#[derive(Clone, Copy, Debug, Eq, PartialEq)] #[derive(Clone, Copy, Debug, Eq, MallocSizeOf, PartialEq)]
pub(crate) struct Tag { pub(crate) struct Tag {
pub(crate) node: OpaqueNode, pub(crate) node: OpaqueNode,
pub(crate) pseudo: Option<PseudoElement>, pub(crate) pseudo: Option<PseudoElement>,

View file

@ -5,6 +5,7 @@
use app_units::Au; use app_units::Au;
use atomic_refcell::AtomicRefCell; use atomic_refcell::AtomicRefCell;
use base::print_tree::PrintTree; use base::print_tree::PrintTree;
use malloc_size_of_derive::MallocSizeOf;
use servo_arc::Arc as ServoArc; use servo_arc::Arc as ServoArc;
use style::Zero; use style::Zero;
use style::computed_values::border_collapse::T as BorderCollapse; use style::computed_values::border_collapse::T as BorderCollapse;
@ -24,6 +25,7 @@ use crate::table::SpecificTableGridInfo;
use crate::taffy::SpecificTaffyGridInfo; use crate::taffy::SpecificTaffyGridInfo;
/// Describes how a [`BoxFragment`] paints its background. /// Describes how a [`BoxFragment`] paints its background.
#[derive(MallocSizeOf)]
pub(crate) enum BackgroundMode { pub(crate) enum BackgroundMode {
/// Draw the normal [`BoxFragment`] background as well as the extra backgrounds /// Draw the normal [`BoxFragment`] background as well as the extra backgrounds
/// based on the style and positioning rectangles in this data structure. /// based on the style and positioning rectangles in this data structure.
@ -36,12 +38,14 @@ pub(crate) enum BackgroundMode {
Normal, Normal,
} }
#[derive(MallocSizeOf)]
pub(crate) struct ExtraBackground { pub(crate) struct ExtraBackground {
#[conditional_malloc_size_of]
pub style: ServoArc<ComputedValues>, pub style: ServoArc<ComputedValues>,
pub rect: PhysicalRect<Au>, pub rect: PhysicalRect<Au>,
} }
#[derive(Clone, Debug)] #[derive(Clone, Debug, MallocSizeOf)]
pub(crate) enum SpecificLayoutInfo { pub(crate) enum SpecificLayoutInfo {
Grid(Box<SpecificTaffyGridInfo>), Grid(Box<SpecificTaffyGridInfo>),
TableCellWithCollapsedBorders, TableCellWithCollapsedBorders,
@ -49,9 +53,11 @@ pub(crate) enum SpecificLayoutInfo {
TableWrapper, TableWrapper,
} }
#[derive(MallocSizeOf)]
pub(crate) struct BoxFragment { pub(crate) struct BoxFragment {
pub base: BaseFragment, pub base: BaseFragment,
#[conditional_malloc_size_of]
pub style: ServoArc<ComputedValues>, pub style: ServoArc<ComputedValues>,
pub children: Vec<Fragment>, pub children: Vec<Fragment>,

View file

@ -8,6 +8,7 @@ use app_units::Au;
use base::id::PipelineId; use base::id::PipelineId;
use base::print_tree::PrintTree; use base::print_tree::PrintTree;
use fonts::{ByteIndex, FontMetrics, GlyphStore}; use fonts::{ByteIndex, FontMetrics, GlyphStore};
use malloc_size_of_derive::MallocSizeOf;
use range::Range as ServoRange; use range::Range as ServoRange;
use servo_arc::Arc as ServoArc; use servo_arc::Arc as ServoArc;
use style::Zero; use style::Zero;
@ -23,7 +24,7 @@ use crate::cell::ArcRefCell;
use crate::geom::{LogicalSides, PhysicalRect}; use crate::geom::{LogicalSides, PhysicalRect};
use crate::style_ext::ComputedValuesExt; use crate::style_ext::ComputedValuesExt;
#[derive(Clone)] #[derive(Clone, MallocSizeOf)]
pub(crate) enum Fragment { pub(crate) enum Fragment {
Box(ArcRefCell<BoxFragment>), Box(ArcRefCell<BoxFragment>),
/// Floating content. A floated fragment is very similar to a normal /// Floating content. A floated fragment is very similar to a normal
@ -46,25 +47,28 @@ pub(crate) enum Fragment {
IFrame(ArcRefCell<IFrameFragment>), IFrame(ArcRefCell<IFrameFragment>),
} }
#[derive(Clone)] #[derive(Clone, MallocSizeOf)]
pub(crate) struct CollapsedBlockMargins { pub(crate) struct CollapsedBlockMargins {
pub collapsed_through: bool, pub collapsed_through: bool,
pub start: CollapsedMargin, pub start: CollapsedMargin,
pub end: CollapsedMargin, pub end: CollapsedMargin,
} }
#[derive(Clone, Copy, Debug)] #[derive(Clone, Copy, Debug, MallocSizeOf)]
pub(crate) struct CollapsedMargin { pub(crate) struct CollapsedMargin {
max_positive: Au, max_positive: Au,
min_negative: Au, min_negative: Au,
} }
#[derive(MallocSizeOf)]
pub(crate) struct TextFragment { pub(crate) struct TextFragment {
pub base: BaseFragment, pub base: BaseFragment,
#[conditional_malloc_size_of]
pub parent_style: ServoArc<ComputedValues>, pub parent_style: ServoArc<ComputedValues>,
pub rect: PhysicalRect<Au>, pub rect: PhysicalRect<Au>,
pub font_metrics: FontMetrics, pub font_metrics: FontMetrics,
pub font_key: FontInstanceKey, pub font_key: FontInstanceKey,
#[conditional_malloc_size_of]
pub glyphs: Vec<Arc<GlyphStore>>, pub glyphs: Vec<Arc<GlyphStore>>,
/// A flag that represents the _used_ value of the text-decoration property. /// A flag that represents the _used_ value of the text-decoration property.
@ -73,21 +77,26 @@ pub(crate) struct TextFragment {
/// Extra space to add for each justification opportunity. /// Extra space to add for each justification opportunity.
pub justification_adjustment: Au, pub justification_adjustment: Au,
pub selection_range: Option<ServoRange<ByteIndex>>, pub selection_range: Option<ServoRange<ByteIndex>>,
#[conditional_malloc_size_of]
pub selected_style: ServoArc<ComputedValues>, pub selected_style: ServoArc<ComputedValues>,
} }
#[derive(MallocSizeOf)]
pub(crate) struct ImageFragment { pub(crate) struct ImageFragment {
pub base: BaseFragment, pub base: BaseFragment,
#[conditional_malloc_size_of]
pub style: ServoArc<ComputedValues>, pub style: ServoArc<ComputedValues>,
pub rect: PhysicalRect<Au>, pub rect: PhysicalRect<Au>,
pub clip: PhysicalRect<Au>, pub clip: PhysicalRect<Au>,
pub image_key: Option<ImageKey>, pub image_key: Option<ImageKey>,
} }
#[derive(MallocSizeOf)]
pub(crate) struct IFrameFragment { pub(crate) struct IFrameFragment {
pub base: BaseFragment, pub base: BaseFragment,
pub pipeline_id: PipelineId, pub pipeline_id: PipelineId,
pub rect: PhysicalRect<Au>, pub rect: PhysicalRect<Au>,
#[conditional_malloc_size_of]
pub style: ServoArc<ComputedValues>, pub style: ServoArc<ComputedValues>,
} }

View file

@ -7,6 +7,7 @@ use base::print_tree::PrintTree;
use compositing_traits::display_list::AxesScrollSensitivity; use compositing_traits::display_list::AxesScrollSensitivity;
use euclid::default::{Point2D, Rect, Size2D}; use euclid::default::{Point2D, Rect, Size2D};
use fxhash::FxHashSet; use fxhash::FxHashSet;
use malloc_size_of_derive::MallocSizeOf;
use style::animation::AnimationSetKey; use style::animation::AnimationSetKey;
use style::dom::OpaqueNode; use style::dom::OpaqueNode;
use webrender_api::units; use webrender_api::units;
@ -16,6 +17,7 @@ use crate::display_list::StackingContext;
use crate::flow::CanvasBackground; use crate::flow::CanvasBackground;
use crate::geom::{PhysicalPoint, PhysicalRect}; use crate::geom::{PhysicalPoint, PhysicalRect};
#[derive(MallocSizeOf)]
pub struct FragmentTree { pub struct FragmentTree {
/// Fragments at the top-level of the tree. /// Fragments at the top-level of the tree.
/// ///

View file

@ -3,6 +3,7 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
use app_units::Au; use app_units::Au;
use malloc_size_of_derive::MallocSizeOf;
use style::logical_geometry::WritingMode; use style::logical_geometry::WritingMode;
use style::values::specified::align::AlignFlags; use style::values::specified::align::AlignFlags;
@ -12,6 +13,7 @@ use crate::geom::{LogicalVec2, PhysicalRect, PhysicalVec};
/// A reference to a Fragment which is shared between `HoistedAbsolutelyPositionedBox` /// A reference to a Fragment which is shared between `HoistedAbsolutelyPositionedBox`
/// and its placeholder `AbsoluteOrFixedPositionedFragment` in the original tree position. /// and its placeholder `AbsoluteOrFixedPositionedFragment` in the original tree position.
/// This will be used later in order to paint this hoisted box in tree order. /// This will be used later in order to paint this hoisted box in tree order.
#[derive(MallocSizeOf)]
pub(crate) struct HoistedSharedFragment { pub(crate) struct HoistedSharedFragment {
pub fragment: Option<Fragment>, pub fragment: Option<Fragment>,
/// The "static-position rect" of this absolutely positioned box. This is defined by the /// The "static-position rect" of this absolutely positioned box. This is defined by the

View file

@ -4,6 +4,7 @@
use app_units::Au; use app_units::Au;
use base::print_tree::PrintTree; use base::print_tree::PrintTree;
use malloc_size_of_derive::MallocSizeOf;
use servo_arc::Arc as ServoArc; use servo_arc::Arc as ServoArc;
use style::properties::ComputedValues; use style::properties::ComputedValues;
@ -14,6 +15,7 @@ use crate::geom::PhysicalRect;
/// Can contain child fragments with relative coordinates, but does not contribute to painting /// Can contain child fragments with relative coordinates, but does not contribute to painting
/// itself. [`PositioningFragment`]s may be completely anonymous, or just non-painting Fragments /// itself. [`PositioningFragment`]s may be completely anonymous, or just non-painting Fragments
/// generated by boxes. /// generated by boxes.
#[derive(MallocSizeOf)]
pub(crate) struct PositioningFragment { pub(crate) struct PositioningFragment {
pub base: BaseFragment, pub base: BaseFragment,
pub rect: PhysicalRect<Au>, pub rect: PhysicalRect<Au>,
@ -22,6 +24,7 @@ pub(crate) struct PositioningFragment {
pub scrollable_overflow: PhysicalRect<Au>, pub scrollable_overflow: PhysicalRect<Au>,
/// If this fragment was created with a style, the style of the fragment. /// If this fragment was created with a style, the style of the fragment.
#[conditional_malloc_size_of]
pub style: Option<ServoArc<ComputedValues>>, pub style: Option<ServoArc<ComputedValues>>,
} }

View file

@ -8,6 +8,7 @@ use std::fmt;
use std::ops::{Add, AddAssign, Neg, Sub, SubAssign}; use std::ops::{Add, AddAssign, Neg, Sub, SubAssign};
use app_units::{Au, MAX_AU}; use app_units::{Au, MAX_AU};
use malloc_size_of_derive::MallocSizeOf;
use style::Zero; use style::Zero;
use style::logical_geometry::{BlockFlowDirection, Direction, InlineBaseDirection, WritingMode}; use style::logical_geometry::{BlockFlowDirection, Direction, InlineBaseDirection, WritingMode};
use style::values::computed::{ use style::values::computed::{
@ -28,7 +29,7 @@ pub type PhysicalSides<U> = euclid::SideOffsets2D<U, CSSPixel>;
pub type AuOrAuto = AutoOr<Au>; pub type AuOrAuto = AutoOr<Au>;
pub type LengthPercentageOrAuto<'a> = AutoOr<&'a LengthPercentage>; pub type LengthPercentageOrAuto<'a> = AutoOr<&'a LengthPercentage>;
#[derive(Clone, Copy, PartialEq)] #[derive(Clone, Copy, MallocSizeOf, PartialEq)]
pub struct LogicalVec2<T> { pub struct LogicalVec2<T> {
pub inline: T, pub inline: T,
pub block: T, pub block: T,
@ -950,7 +951,7 @@ impl Size<Au> {
/// Represents the sizing constraint that the preferred, min and max sizing properties /// Represents the sizing constraint that the preferred, min and max sizing properties
/// impose on one axis. /// impose on one axis.
#[derive(Clone, Copy, Debug, PartialEq)] #[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq)]
pub(crate) enum SizeConstraint { pub(crate) enum SizeConstraint {
/// Represents a definite preferred size, clamped by minimum and maximum sizes (if any). /// Represents a definite preferred size, clamped by minimum and maximum sizes (if any).
Definite(Au), Definite(Au),

View file

@ -6,6 +6,7 @@ use std::fmt::{Debug, Formatter};
use app_units::Au; use app_units::Au;
use atomic_refcell::AtomicRefCell; use atomic_refcell::AtomicRefCell;
use malloc_size_of_derive::MallocSizeOf;
use servo_arc::Arc; use servo_arc::Arc;
use style::properties::ComputedValues; use style::properties::ComputedValues;
@ -23,8 +24,10 @@ use crate::{ConstraintSpace, ContainingBlockSize};
/// passes. /// passes.
/// ///
/// In the future, this will hold layout results to support incremental layout. /// In the future, this will hold layout results to support incremental layout.
#[derive(MallocSizeOf)]
pub(crate) struct LayoutBoxBase { pub(crate) struct LayoutBoxBase {
pub base_fragment_info: BaseFragmentInfo, pub base_fragment_info: BaseFragmentInfo,
#[conditional_malloc_size_of]
pub style: Arc<ComputedValues>, pub style: Arc<ComputedValues>,
pub cached_inline_content_size: pub cached_inline_content_size:
AtomicRefCell<Option<Box<(SizeConstraint, InlineContentSizesResult)>>>, AtomicRefCell<Option<Box<(SizeConstraint, InlineContentSizesResult)>>>,
@ -95,7 +98,7 @@ impl Debug for LayoutBoxBase {
} }
} }
#[derive(Clone)] #[derive(Clone, MallocSizeOf)]
pub(crate) struct CacheableLayoutResult { pub(crate) struct CacheableLayoutResult {
pub fragments: Vec<Fragment>, pub fragments: Vec<Fragment>,
@ -124,6 +127,7 @@ pub(crate) struct CacheableLayoutResult {
} }
/// A collection of layout inputs and a cached layout result for a [`LayoutBoxBase`]. /// A collection of layout inputs and a cached layout result for a [`LayoutBoxBase`].
#[derive(MallocSizeOf)]
pub(crate) struct CacheableLayoutResultAndInputs { pub(crate) struct CacheableLayoutResultAndInputs {
/// The [`CacheableLayoutResult`] for this layout. /// The [`CacheableLayoutResult`] for this layout.
pub result: CacheableLayoutResult, pub result: CacheableLayoutResult,

View file

@ -32,6 +32,7 @@ use app_units::Au;
pub use cell::ArcRefCell; pub use cell::ArcRefCell;
pub use flow::BoxTree; pub use flow::BoxTree;
pub use fragment_tree::FragmentTree; pub use fragment_tree::FragmentTree;
use malloc_size_of_derive::MallocSizeOf;
use style::logical_geometry::WritingMode; use style::logical_geometry::WritingMode;
use style::properties::ComputedValues; use style::properties::ComputedValues;
use style::values::computed::TextDecorationLine; use style::values::computed::TextDecorationLine;
@ -113,7 +114,7 @@ impl<'a> From<&'_ DefiniteContainingBlock<'a>> for IndefiniteContainingBlock {
} }
} }
#[derive(Clone, Debug)] #[derive(Clone, Debug, MallocSizeOf)]
pub(crate) struct ContainingBlockSize { pub(crate) struct ContainingBlockSize {
inline: Au, inline: Au,
block: SizeConstraint, block: SizeConstraint,

View file

@ -5,6 +5,7 @@
use std::mem; use std::mem;
use app_units::Au; use app_units::Au;
use malloc_size_of_derive::MallocSizeOf;
use rayon::iter::IntoParallelRefMutIterator; use rayon::iter::IntoParallelRefMutIterator;
use rayon::prelude::{IndexedParallelIterator, ParallelIterator}; use rayon::prelude::{IndexedParallelIterator, ParallelIterator};
use style::Zero; use style::Zero;
@ -35,12 +36,12 @@ use crate::{
PropagatedBoxTreeData, SizeConstraint, PropagatedBoxTreeData, SizeConstraint,
}; };
#[derive(Debug)] #[derive(Debug, MallocSizeOf)]
pub(crate) struct AbsolutelyPositionedBox { pub(crate) struct AbsolutelyPositionedBox {
pub context: IndependentFormattingContext, pub context: IndependentFormattingContext,
} }
#[derive(Clone)] #[derive(Clone, MallocSizeOf)]
pub(crate) struct PositioningContext { pub(crate) struct PositioningContext {
for_nearest_positioned_ancestor: Option<Vec<HoistedAbsolutelyPositionedBox>>, for_nearest_positioned_ancestor: Option<Vec<HoistedAbsolutelyPositionedBox>>,
@ -50,7 +51,7 @@ pub(crate) struct PositioningContext {
for_nearest_containing_block_for_all_descendants: Vec<HoistedAbsolutelyPositionedBox>, for_nearest_containing_block_for_all_descendants: Vec<HoistedAbsolutelyPositionedBox>,
} }
#[derive(Clone)] #[derive(Clone, MallocSizeOf)]
pub(crate) struct HoistedAbsolutelyPositionedBox { pub(crate) struct HoistedAbsolutelyPositionedBox {
absolutely_positioned_box: ArcRefCell<AbsolutelyPositionedBox>, absolutely_positioned_box: ArcRefCell<AbsolutelyPositionedBox>,

View file

@ -11,6 +11,7 @@ use base::id::{BrowsingContextId, PipelineId};
use data_url::DataUrl; use data_url::DataUrl;
use embedder_traits::ViewportDetails; use embedder_traits::ViewportDetails;
use euclid::{Scale, Size2D}; use euclid::{Scale, Size2D};
use malloc_size_of_derive::MallocSizeOf;
use net_traits::image_cache::{ImageOrMetadataAvailable, UsePlaceholder}; use net_traits::image_cache::{ImageOrMetadataAvailable, UsePlaceholder};
use pixels::Image; use pixels::Image;
use script_layout_interface::IFrameSize; use script_layout_interface::IFrameSize;
@ -37,7 +38,7 @@ use crate::sizing::{ComputeInlineContentSizes, ContentSizes, InlineContentSizesR
use crate::style_ext::{AspectRatio, Clamp, ComputedValuesExt, ContentBoxSizesAndPBM, LayoutStyle}; use crate::style_ext::{AspectRatio, Clamp, ComputedValuesExt, ContentBoxSizesAndPBM, LayoutStyle};
use crate::{ConstraintSpace, ContainingBlock, SizeConstraint}; use crate::{ConstraintSpace, ContainingBlock, SizeConstraint};
#[derive(Debug)] #[derive(Debug, MallocSizeOf)]
pub(crate) struct ReplacedContents { pub(crate) struct ReplacedContents {
pub kind: ReplacedContentKind, pub kind: ReplacedContentKind,
natural_size: NaturalSizes, natural_size: NaturalSizes,
@ -61,7 +62,7 @@ pub(crate) struct ReplacedContents {
/// ///
/// * IFrames do not have natural width and height or natural ratio according /// * IFrames do not have natural width and height or natural ratio according
/// to <https://drafts.csswg.org/css-images/#intrinsic-dimensions>. /// to <https://drafts.csswg.org/css-images/#intrinsic-dimensions>.
#[derive(Debug)] #[derive(Debug, MallocSizeOf)]
pub(crate) struct NaturalSizes { pub(crate) struct NaturalSizes {
pub width: Option<Au>, pub width: Option<Au>,
pub height: Option<Au>, pub height: Option<Au>,
@ -95,6 +96,7 @@ impl NaturalSizes {
} }
} }
#[derive(MallocSizeOf)]
pub(crate) enum CanvasSource { pub(crate) enum CanvasSource {
WebGL(ImageKey), WebGL(ImageKey),
Image(ImageKey), Image(ImageKey),
@ -118,25 +120,25 @@ impl fmt::Debug for CanvasSource {
} }
} }
#[derive(Debug)] #[derive(Debug, MallocSizeOf)]
pub(crate) struct CanvasInfo { pub(crate) struct CanvasInfo {
pub source: CanvasSource, pub source: CanvasSource,
} }
#[derive(Debug)] #[derive(Debug, MallocSizeOf)]
pub(crate) struct IFrameInfo { pub(crate) struct IFrameInfo {
pub pipeline_id: PipelineId, pub pipeline_id: PipelineId,
pub browsing_context_id: BrowsingContextId, pub browsing_context_id: BrowsingContextId,
} }
#[derive(Debug)] #[derive(Debug, MallocSizeOf)]
pub(crate) struct VideoInfo { pub(crate) struct VideoInfo {
pub image_key: webrender_api::ImageKey, pub image_key: webrender_api::ImageKey,
} }
#[derive(Debug)] #[derive(Debug, MallocSizeOf)]
pub(crate) enum ReplacedContentKind { pub(crate) enum ReplacedContentKind {
Image(Option<Arc<Image>>), Image(#[conditional_malloc_size_of] Option<Arc<Image>>),
IFrame(IFrameInfo), IFrame(IFrameInfo),
Canvas(CanvasInfo), Canvas(CanvasInfo),
Video(Option<VideoInfo>), Video(Option<VideoInfo>),

View file

@ -8,6 +8,7 @@ use std::cell::LazyCell;
use std::ops::{Add, AddAssign}; use std::ops::{Add, AddAssign};
use app_units::Au; use app_units::Au;
use malloc_size_of_derive::MallocSizeOf;
use style::Zero; use style::Zero;
use style::values::computed::LengthPercentage; use style::values::computed::LengthPercentage;
@ -32,7 +33,7 @@ pub(crate) enum IntrinsicSizingMode {
Size, Size,
} }
#[derive(Clone, Copy, Debug, Default)] #[derive(Clone, Copy, Debug, Default, MallocSizeOf)]
pub(crate) struct ContentSizes { pub(crate) struct ContentSizes {
pub min_content: Au, pub min_content: Au,
pub max_content: Au, pub max_content: Au,
@ -267,7 +268,7 @@ pub(crate) fn outer_inline(
} }
} }
#[derive(Clone, Copy, Debug)] #[derive(Clone, Copy, Debug, MallocSizeOf)]
pub(crate) struct InlineContentSizesResult { pub(crate) struct InlineContentSizesResult {
pub sizes: ContentSizes, pub sizes: ContentSizes,
pub depends_on_block_constraints: bool, pub depends_on_block_constraints: bool,

View file

@ -3,6 +3,7 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
use app_units::Au; use app_units::Au;
use malloc_size_of_derive::MallocSizeOf;
use style::Zero; use style::Zero;
use style::color::AbsoluteColor; use style::color::AbsoluteColor;
use style::computed_values::direction::T as Direction; use style::computed_values::direction::T as Direction;
@ -238,7 +239,7 @@ pub(crate) struct ContentBoxSizesAndPBM {
pub preferred_size_computes_to_auto: LogicalVec2<bool>, pub preferred_size_computes_to_auto: LogicalVec2<bool>,
} }
#[derive(Clone, Debug, PartialEq)] #[derive(Clone, Debug, MallocSizeOf, PartialEq)]
pub(crate) struct BorderStyleColor { pub(crate) struct BorderStyleColor {
pub style: BorderStyle, pub style: BorderStyle,
pub color: AbsoluteColor, pub color: AbsoluteColor,

View file

@ -75,6 +75,7 @@ use atomic_refcell::AtomicRef;
pub(crate) use construct::AnonymousTableContent; pub(crate) use construct::AnonymousTableContent;
pub use construct::TableBuilder; pub use construct::TableBuilder;
use euclid::{Point2D, Size2D, UnknownUnit, Vector2D}; use euclid::{Point2D, Size2D, UnknownUnit, Vector2D};
use malloc_size_of_derive::MallocSizeOf;
use servo_arc::Arc; use servo_arc::Arc;
use style::properties::ComputedValues; use style::properties::ComputedValues;
use style::properties::style_structs::Font; use style::properties::style_structs::Font;
@ -92,15 +93,17 @@ use crate::table::layout::TableLayout;
pub type TableSize = Size2D<usize, UnknownUnit>; pub type TableSize = Size2D<usize, UnknownUnit>;
#[derive(Debug)] #[derive(Debug, MallocSizeOf)]
pub struct Table { pub struct Table {
/// The style of this table. These are the properties that apply to the "wrapper" ie the element /// The style of this table. These are the properties that apply to the "wrapper" ie the element
/// that contains both the grid and the captions. Not all properties are actually used on the /// that contains both the grid and the captions. Not all properties are actually used on the
/// wrapper though, such as background and borders, which apply to the grid. /// wrapper though, such as background and borders, which apply to the grid.
#[conditional_malloc_size_of]
style: Arc<ComputedValues>, style: Arc<ComputedValues>,
/// The style of this table's grid. This is an anonymous style based on the table's style, but /// The style of this table's grid. This is an anonymous style based on the table's style, but
/// eliminating all the properties handled by the "wrapper." /// eliminating all the properties handled by the "wrapper."
#[conditional_malloc_size_of]
grid_style: Arc<ComputedValues>, grid_style: Arc<ComputedValues>,
/// The [`BaseFragmentInfo`] for this table's grid. This is necessary so that when the /// The [`BaseFragmentInfo`] for this table's grid. This is necessary so that when the
@ -194,7 +197,7 @@ impl Table {
type TableSlotCoordinates = Point2D<usize, UnknownUnit>; type TableSlotCoordinates = Point2D<usize, UnknownUnit>;
pub type TableSlotOffset = Vector2D<usize, UnknownUnit>; pub type TableSlotOffset = Vector2D<usize, UnknownUnit>;
#[derive(Debug)] #[derive(Debug, MallocSizeOf)]
pub struct TableSlotCell { pub struct TableSlotCell {
/// The [`LayoutBoxBase`] of this table cell. /// The [`LayoutBoxBase`] of this table cell.
base: LayoutBoxBase, base: LayoutBoxBase,
@ -236,6 +239,7 @@ impl TableSlotCell {
/// to a previous cell that is spanned here /// to a previous cell that is spanned here
/// ///
/// In case of table model errors, it may be multiple references /// In case of table model errors, it may be multiple references
#[derive(MallocSizeOf)]
pub enum TableSlot { pub enum TableSlot {
/// A table cell, with a colspan and a rowspan. /// A table cell, with a colspan and a rowspan.
Cell(ArcRefCell<TableSlotCell>), Cell(ArcRefCell<TableSlotCell>),
@ -272,7 +276,7 @@ impl TableSlot {
} }
/// A row or column of a table. /// A row or column of a table.
#[derive(Debug)] #[derive(Debug, MallocSizeOf)]
pub struct TableTrack { pub struct TableTrack {
/// The [`LayoutBoxBase`] of this [`TableTrack`]. /// The [`LayoutBoxBase`] of this [`TableTrack`].
base: LayoutBoxBase, base: LayoutBoxBase,
@ -286,7 +290,7 @@ pub struct TableTrack {
is_anonymous: bool, is_anonymous: bool,
} }
#[derive(Debug, PartialEq)] #[derive(Debug, MallocSizeOf, PartialEq)]
pub enum TableTrackGroupType { pub enum TableTrackGroupType {
HeaderGroup, HeaderGroup,
FooterGroup, FooterGroup,
@ -294,7 +298,7 @@ pub enum TableTrackGroupType {
ColumnGroup, ColumnGroup,
} }
#[derive(Debug)] #[derive(Debug, MallocSizeOf)]
pub struct TableTrackGroup { pub struct TableTrackGroup {
/// The [`LayoutBoxBase`] of this [`TableTrackGroup`]. /// The [`LayoutBoxBase`] of this [`TableTrackGroup`].
base: LayoutBoxBase, base: LayoutBoxBase,
@ -312,14 +316,14 @@ impl TableTrackGroup {
} }
} }
#[derive(Debug)] #[derive(Debug, MallocSizeOf)]
pub struct TableCaption { pub struct TableCaption {
/// The contents of this cell, with its own layout. /// The contents of this cell, with its own layout.
context: IndependentFormattingContext, context: IndependentFormattingContext,
} }
/// A calculated collapsed border. /// A calculated collapsed border.
#[derive(Clone, Debug, Default, PartialEq)] #[derive(Clone, Debug, Default, MallocSizeOf, PartialEq)]
pub(crate) struct CollapsedBorder { pub(crate) struct CollapsedBorder {
pub style_color: BorderStyleColor, pub style_color: BorderStyleColor,
pub width: Au, pub width: Au,
@ -328,7 +332,7 @@ pub(crate) struct CollapsedBorder {
/// Represents a piecewise sequence of collapsed borders along a line. /// Represents a piecewise sequence of collapsed borders along a line.
pub(crate) type CollapsedBorderLine = Vec<CollapsedBorder>; pub(crate) type CollapsedBorderLine = Vec<CollapsedBorder>;
#[derive(Clone, Debug)] #[derive(Clone, Debug, MallocSizeOf)]
pub(crate) struct SpecificTableGridInfo { pub(crate) struct SpecificTableGridInfo {
pub collapsed_borders: PhysicalVec<Vec<CollapsedBorderLine>>, pub collapsed_borders: PhysicalVec<Vec<CollapsedBorderLine>>,
pub track_sizes: PhysicalVec<Vec<Au>>, pub track_sizes: PhysicalVec<Vec<Au>>,

View file

@ -6,6 +6,7 @@ mod stylo_taffy;
use std::fmt; use std::fmt;
use app_units::Au; use app_units::Au;
use malloc_size_of_derive::MallocSizeOf;
use servo_arc::Arc; use servo_arc::Arc;
use style::properties::ComputedValues; use style::properties::ComputedValues;
use stylo_taffy::TaffyStyloStyle; use stylo_taffy::TaffyStyloStyle;
@ -20,9 +21,10 @@ use crate::formatting_contexts::IndependentFormattingContext;
use crate::fragment_tree::Fragment; use crate::fragment_tree::Fragment;
use crate::positioned::{AbsolutelyPositionedBox, PositioningContext}; use crate::positioned::{AbsolutelyPositionedBox, PositioningContext};
#[derive(Debug)] #[derive(Debug, MallocSizeOf)]
pub(crate) struct TaffyContainer { pub(crate) struct TaffyContainer {
children: Vec<ArcRefCell<TaffyItemBox>>, children: Vec<ArcRefCell<TaffyItemBox>>,
#[conditional_malloc_size_of]
style: Arc<ComputedValues>, style: Arc<ComputedValues>,
} }
@ -69,15 +71,17 @@ impl TaffyContainer {
} }
} }
#[derive(MallocSizeOf)]
pub(crate) struct TaffyItemBox { pub(crate) struct TaffyItemBox {
pub(crate) taffy_layout: taffy::Layout, pub(crate) taffy_layout: taffy::Layout,
pub(crate) child_fragments: Vec<Fragment>, pub(crate) child_fragments: Vec<Fragment>,
pub(crate) positioning_context: PositioningContext, pub(crate) positioning_context: PositioningContext,
#[conditional_malloc_size_of]
pub(crate) style: Arc<ComputedValues>, pub(crate) style: Arc<ComputedValues>,
pub(crate) taffy_level_box: TaffyItemBoxInner, pub(crate) taffy_level_box: TaffyItemBoxInner,
} }
#[derive(Debug)] #[derive(Debug, MallocSizeOf)]
pub(crate) enum TaffyItemBoxInner { pub(crate) enum TaffyItemBoxInner {
InFlowBox(IndependentFormattingContext), InFlowBox(IndependentFormattingContext),
OutOfFlowAbsolutelyPositionedBox(ArcRefCell<AbsolutelyPositionedBox>), OutOfFlowAbsolutelyPositionedBox(ArcRefCell<AbsolutelyPositionedBox>),
@ -145,7 +149,7 @@ impl TaffyItemBox {
} }
/// Details from Taffy grid layout that will be stored /// Details from Taffy grid layout that will be stored
#[derive(Clone, Debug)] #[derive(Clone, Debug, MallocSizeOf)]
pub(crate) struct SpecificTaffyGridInfo { pub(crate) struct SpecificTaffyGridInfo {
pub rows: SpecificTaffyGridTrackInfo, pub rows: SpecificTaffyGridTrackInfo,
pub columns: SpecificTaffyGridTrackInfo, pub columns: SpecificTaffyGridTrackInfo,
@ -174,7 +178,7 @@ impl SpecificTaffyGridInfo {
} }
} }
#[derive(Clone, Debug)] #[derive(Clone, Debug, MallocSizeOf)]
pub(crate) struct SpecificTaffyGridTrackInfo { pub(crate) struct SpecificTaffyGridTrackInfo {
pub sizes: Box<[Au]>, pub sizes: Box<[Au]>,
} }

View file

@ -8,8 +8,9 @@
//! Layout. Performs layout on the DOM, builds display lists and sends them to be //! Layout. Performs layout on the DOM, builds display lists and sends them to be
//! painted. //! painted.
use std::cell::{Cell, RefCell}; use std::cell::{Cell, LazyCell, RefCell};
use std::collections::HashMap; use std::collections::{HashMap, HashSet};
use std::ffi::c_void;
use std::fmt::Debug; use std::fmt::Debug;
use std::process; use std::process;
use std::sync::{Arc, LazyLock}; use std::sync::{Arc, LazyLock};
@ -38,7 +39,7 @@ use layout::query::{
use layout::traversal::RecalcStyle; use layout::traversal::RecalcStyle;
use layout::{BoxTree, FragmentTree}; use layout::{BoxTree, FragmentTree};
use log::{debug, error}; use log::{debug, error};
use malloc_size_of::{MallocSizeOf, MallocSizeOfOps}; use malloc_size_of::{MallocConditionalSizeOf, MallocSizeOf, MallocSizeOfOps};
use net_traits::image_cache::{ImageCache, UsePlaceholder}; use net_traits::image_cache::{ImageCache, UsePlaceholder};
use parking_lot::{Mutex, RwLock}; use parking_lot::{Mutex, RwLock};
use profile_traits::mem::{Report, ReportKind}; use profile_traits::mem::{Report, ReportKind};
@ -417,7 +418,28 @@ impl Layout for LayoutThread {
reports.push(Report { reports.push(Report {
path: path![formatted_url, "layout-thread", "font-context"], path: path![formatted_url, "layout-thread", "font-context"],
kind: ReportKind::ExplicitJemallocHeapSize, kind: ReportKind::ExplicitJemallocHeapSize,
size: self.font_context.size_of(ops), size: self.font_context.conditional_size_of(ops),
});
reports.push(Report {
path: path![formatted_url, "layout-thread", "box-tree"],
kind: ReportKind::ExplicitJemallocHeapSize,
size: self
.box_tree
.borrow()
.as_ref()
.map_or(0, |tree| tree.conditional_size_of(ops)),
});
reports.push(Report {
path: path![formatted_url, "layout-thread", "fragment-tree"],
kind: ReportKind::ExplicitJemallocHeapSize,
size: self
.fragment_tree
.borrow()
.as_ref()
.map(|tree| tree.conditional_size_of(ops))
.unwrap_or_default(),
}); });
} }
@ -1210,3 +1232,7 @@ impl Debug for LayoutFontMetricsProvider {
f.debug_tuple("LayoutFontMetricsProvider").finish() f.debug_tuple("LayoutFontMetricsProvider").finish()
} }
} }
thread_local!(static SEEN_POINTERS: LazyCell<RefCell<HashSet<*const c_void>>> = const {
LazyCell::new(|| RefCell::new(HashSet::new()))
});

View file

@ -13,6 +13,7 @@ path = "lib.rs"
[dependencies] [dependencies]
accountable-refcell = { workspace = true } accountable-refcell = { workspace = true }
app_units = { workspace = true } app_units = { workspace = true }
atomic_refcell = { workspace = true }
content-security-policy = { workspace = true } content-security-policy = { workspace = true }
crossbeam-channel = { workspace = true } crossbeam-channel = { workspace = true }
euclid = { workspace = true } euclid = { workspace = true }
@ -28,8 +29,11 @@ string_cache = { workspace = true }
stylo = { workspace = true } stylo = { workspace = true }
stylo_dom = { workspace = true } stylo_dom = { workspace = true }
stylo_malloc_size_of = { workspace = true } stylo_malloc_size_of = { workspace = true }
taffy = { workspace = true }
thin-vec = { workspace = true } thin-vec = { workspace = true }
tokio = { workspace = true, features = ["sync"] } tokio = { workspace = true, features = ["sync"] }
unicode-bidi = { workspace = true }
unicode-script = { workspace = true }
url = { workspace = true } url = { workspace = true }
uuid = { workspace = true } uuid = { workspace = true }
webrender_api = { workspace = true } webrender_api = { workspace = true }

View file

@ -52,6 +52,7 @@ use std::hash::{BuildHasher, Hash};
use std::ops::Range; use std::ops::Range;
use std::sync::Arc; use std::sync::Arc;
use style::values::generics::length::GenericLengthPercentageOrAuto;
pub use stylo_malloc_size_of::MallocSizeOfOps; pub use stylo_malloc_size_of::MallocSizeOfOps;
use uuid::Uuid; use uuid::Uuid;
@ -219,6 +220,26 @@ where
} }
} }
impl<T: MallocConditionalSizeOf> MallocConditionalSizeOf for Option<T> {
fn conditional_size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
if let Some(val) = self.as_ref() {
val.conditional_size_of(ops)
} else {
0
}
}
}
impl<T: MallocConditionalSizeOf> MallocConditionalSizeOf for Vec<T> {
fn conditional_size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
let mut n = self.shallow_size_of(ops);
for elem in self.iter() {
n += elem.conditional_size_of(ops);
}
n
}
}
impl<T: MallocSizeOf> MallocSizeOf for Option<T> { impl<T: MallocSizeOf> MallocSizeOf for Option<T> {
fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize { fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
if let Some(val) = self.as_ref() { if let Some(val) = self.as_ref() {
@ -726,7 +747,11 @@ malloc_size_of_is_0!(std::time::Duration);
malloc_size_of_is_0!(std::time::Instant); malloc_size_of_is_0!(std::time::Instant);
malloc_size_of_is_0!(std::time::SystemTime); malloc_size_of_is_0!(std::time::SystemTime);
malloc_size_of_is_0!(style::font_face::SourceList); malloc_size_of_is_0!(style::font_face::SourceList);
malloc_size_of_is_0!(style::properties::ComputedValues);
malloc_size_of_is_0!(style::queries::values::PrefersColorScheme); malloc_size_of_is_0!(style::queries::values::PrefersColorScheme);
malloc_size_of_is_0!(taffy::Layout);
malloc_size_of_is_0!(unicode_bidi::Level);
malloc_size_of_is_0!(unicode_script::Script);
macro_rules! malloc_size_of_is_webrender_malloc_size_of( macro_rules! malloc_size_of_is_webrender_malloc_size_of(
($($ty:ty),+) => ( ($($ty:ty),+) => (
@ -790,6 +815,12 @@ where
} }
} }
impl<T: MallocSizeOf> MallocSizeOf for atomic_refcell::AtomicRefCell<T> {
fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
self.borrow().size_of(ops)
}
}
malloc_size_of_is_stylo_malloc_size_of!(style::animation::DocumentAnimationSet); malloc_size_of_is_stylo_malloc_size_of!(style::animation::DocumentAnimationSet);
malloc_size_of_is_stylo_malloc_size_of!(style::attr::AttrIdentifier); malloc_size_of_is_stylo_malloc_size_of!(style::attr::AttrIdentifier);
malloc_size_of_is_stylo_malloc_size_of!(style::attr::AttrValue); malloc_size_of_is_stylo_malloc_size_of!(style::attr::AttrValue);
@ -797,7 +828,15 @@ malloc_size_of_is_stylo_malloc_size_of!(style::color::AbsoluteColor);
malloc_size_of_is_stylo_malloc_size_of!(style::computed_values::font_variant_caps::T); malloc_size_of_is_stylo_malloc_size_of!(style::computed_values::font_variant_caps::T);
malloc_size_of_is_stylo_malloc_size_of!(style::dom::OpaqueNode); malloc_size_of_is_stylo_malloc_size_of!(style::dom::OpaqueNode);
malloc_size_of_is_stylo_malloc_size_of!(style::invalidation::element::restyle_hints::RestyleHint); malloc_size_of_is_stylo_malloc_size_of!(style::invalidation::element::restyle_hints::RestyleHint);
malloc_size_of_is_stylo_malloc_size_of!(style::logical_geometry::WritingMode);
malloc_size_of_is_stylo_malloc_size_of!(style::media_queries::MediaList); malloc_size_of_is_stylo_malloc_size_of!(style::media_queries::MediaList);
malloc_size_of_is_stylo_malloc_size_of!(
style::properties::longhands::align_items::computed_value::T
);
malloc_size_of_is_stylo_malloc_size_of!(
style::properties::longhands::flex_direction::computed_value::T
);
malloc_size_of_is_stylo_malloc_size_of!(style::properties::longhands::flex_wrap::computed_value::T);
malloc_size_of_is_stylo_malloc_size_of!(style::properties::style_structs::Font); malloc_size_of_is_stylo_malloc_size_of!(style::properties::style_structs::Font);
malloc_size_of_is_stylo_malloc_size_of!(style::selector_parser::PseudoElement); malloc_size_of_is_stylo_malloc_size_of!(style::selector_parser::PseudoElement);
malloc_size_of_is_stylo_malloc_size_of!(style::selector_parser::RestyleDamage); malloc_size_of_is_stylo_malloc_size_of!(style::selector_parser::RestyleDamage);
@ -805,8 +844,22 @@ malloc_size_of_is_stylo_malloc_size_of!(style::selector_parser::Snapshot);
malloc_size_of_is_stylo_malloc_size_of!(style::shared_lock::SharedRwLock); malloc_size_of_is_stylo_malloc_size_of!(style::shared_lock::SharedRwLock);
malloc_size_of_is_stylo_malloc_size_of!(style::stylesheets::DocumentStyleSheet); malloc_size_of_is_stylo_malloc_size_of!(style::stylesheets::DocumentStyleSheet);
malloc_size_of_is_stylo_malloc_size_of!(style::stylist::Stylist); malloc_size_of_is_stylo_malloc_size_of!(style::stylist::Stylist);
malloc_size_of_is_stylo_malloc_size_of!(style::values::computed::AlignContent);
malloc_size_of_is_stylo_malloc_size_of!(style::values::computed::BorderStyle);
malloc_size_of_is_stylo_malloc_size_of!(style::values::computed::FontStretch); malloc_size_of_is_stylo_malloc_size_of!(style::values::computed::FontStretch);
malloc_size_of_is_stylo_malloc_size_of!(style::values::computed::FontStyle); malloc_size_of_is_stylo_malloc_size_of!(style::values::computed::FontStyle);
malloc_size_of_is_stylo_malloc_size_of!(style::values::computed::FontWeight); malloc_size_of_is_stylo_malloc_size_of!(style::values::computed::FontWeight);
malloc_size_of_is_stylo_malloc_size_of!(style::values::computed::font::SingleFontFamily); malloc_size_of_is_stylo_malloc_size_of!(style::values::computed::font::SingleFontFamily);
malloc_size_of_is_stylo_malloc_size_of!(style::values::computed::JustifyContent);
malloc_size_of_is_stylo_malloc_size_of!(style::values::specified::align::AlignFlags);
malloc_size_of_is_stylo_malloc_size_of!(style::values::specified::TextDecorationLine);
malloc_size_of_is_stylo_malloc_size_of!(stylo_dom::ElementState); malloc_size_of_is_stylo_malloc_size_of!(stylo_dom::ElementState);
impl<T> MallocSizeOf for GenericLengthPercentageOrAuto<T>
where
T: stylo_malloc_size_of::MallocSizeOf,
{
fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
<GenericLengthPercentageOrAuto<T> as stylo_malloc_size_of::MallocSizeOf>::size_of(self, ops)
}
}

View file

@ -26,6 +26,8 @@ glow = { workspace = true }
image = { workspace = true } image = { workspace = true }
ipc-channel = { workspace = true } ipc-channel = { workspace = true }
log = { workspace = true } log = { workspace = true }
malloc_size_of = { workspace = true }
malloc_size_of_derive = { workspace = true }
pixels = { path = '../../pixels' } pixels = { path = '../../pixels' }
profile_traits = { path = '../profile' } profile_traits = { path = '../profile' }
raw-window-handle = { version = "0.6" } raw-window-handle = { version = "0.6" }

View file

@ -6,6 +6,7 @@
use base::id::ScrollTreeNodeId; use base::id::ScrollTreeNodeId;
use embedder_traits::Cursor; use embedder_traits::Cursor;
use malloc_size_of_derive::MallocSizeOf;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use style::values::specified::Overflow; use style::values::specified::Overflow;
use webrender_api::units::{LayoutSize, LayoutVector2D}; use webrender_api::units::{LayoutSize, LayoutVector2D};
@ -13,7 +14,7 @@ use webrender_api::{Epoch, ExternalScrollId, PipelineId, ScrollLocation, Spatial
/// The scroll sensitivity of a scroll node in a particular axis ie whether it can be scrolled due to /// The scroll sensitivity of a scroll node in a particular axis ie whether it can be scrolled due to
/// input events and script events or only script events. /// input events and script events or only script events.
#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize)] #[derive(Clone, Copy, Debug, Deserialize, MallocSizeOf, PartialEq, Serialize)]
pub enum ScrollSensitivity { pub enum ScrollSensitivity {
/// This node can be scrolled by input and script events. /// This node can be scrolled by input and script events.
ScriptAndInputEvents, ScriptAndInputEvents,
@ -35,7 +36,7 @@ impl From<Overflow> for ScrollSensitivity {
} }
/// The [ScrollSensitivity] of particular node in the vertical and horizontal axes. /// The [ScrollSensitivity] of particular node in the vertical and horizontal axes.
#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize)] #[derive(Clone, Copy, Debug, Deserialize, MallocSizeOf, PartialEq, Serialize)]
pub struct AxesScrollSensitivity { pub struct AxesScrollSensitivity {
pub x: ScrollSensitivity, pub x: ScrollSensitivity,
pub y: ScrollSensitivity, pub y: ScrollSensitivity,