layout: Remove the obsolete layout tracing functionality (#35001)

There were two kinds of layout tracing controlled by the same debugging
option:

 - modern layout: Functionality that dumped a JSON serialization of the
   layout tree before and after layout.
 - legacy layout: A scope based tracing that reported the process of
   layout in a structured way.

I don't think anyone working on layout is using either of these two
features. For modern layout requiring data structure to implement
`serde` serialization is incredibly inconvenient and also generates a
lot of extra code.

We also have a more modern tracing functionality based on perfetto that
we have started to use for layout and IMO it's actually being used and
more robust.

Signed-off-by: Martin Robinson <mrobinson@igalia.com>
This commit is contained in:
Martin Robinson 2025-01-15 14:24:14 +01:00 committed by GitHub
parent 2cd5e1356c
commit e81951a973
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
45 changed files with 64 additions and 675 deletions

View file

@ -41,8 +41,6 @@ range = { path = "../range" }
rayon = { workspace = true }
script_layout_interface = { workspace = true }
selectors = { workspace = true }
serde = { workspace = true }
serde_json = { workspace = true }
servo_arc = { workspace = true }
servo_config = { path = "../config" }
servo_geometry = { path = "../geometry" }
@ -51,7 +49,7 @@ style = { workspace = true }
style_traits = { workspace = true }
taffy = { workspace = true }
tracing = { workspace = true, optional = true }
unicode-bidi = { workspace = true, features = ["with_serde"] }
unicode-bidi = { workspace = true }
unicode-script = { workspace = true }
url = { workspace = true }
webrender_api = { workspace = true }

View file

@ -6,7 +6,6 @@ use std::fmt;
use std::ops::Deref;
use atomic_refcell::AtomicRefCell;
use serde::{Serialize, Serializer};
use servo_arc::Arc;
pub(crate) struct ArcRefCell<T> {
@ -56,15 +55,3 @@ where
self.value.fmt(formatter)
}
}
impl<T> Serialize for ArcRefCell<T>
where
T: Serialize,
{
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
self.borrow().serialize(serializer)
}
}

View file

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

View file

@ -4,7 +4,6 @@
use app_units::Au;
use geom::{FlexAxis, MainStartCrossStart};
use serde::Serialize;
use servo_arc::Arc as ServoArc;
use style::logical_geometry::WritingMode;
use style::properties::longhands::align_items::computed_value::T as AlignItems;
@ -30,7 +29,7 @@ mod layout;
/// A structure to hold the configuration of a flex container for use during layout
/// and preferred width calculation.
#[derive(Clone, Debug, Serialize)]
#[derive(Clone, Debug)]
pub(crate) struct FlexContainerConfig {
container_is_single_line: bool,
writing_mode: WritingMode,
@ -88,11 +87,10 @@ impl FlexContainerConfig {
}
}
#[derive(Debug, Serialize)]
#[derive(Debug)]
pub(crate) struct FlexContainer {
children: Vec<ArcRefCell<FlexLevelBox>>,
#[serde(skip_serializing)]
style: ServoArc<ComputedValues>,
/// The configuration of this [`FlexContainer`].
@ -143,16 +141,14 @@ impl FlexContainer {
}
}
#[derive(Debug, Serialize)]
#[derive(Debug)]
pub(crate) enum FlexLevelBox {
FlexItem(FlexItemBox),
OutOfFlowAbsolutelyPositionedBox(ArcRefCell<AbsolutelyPositionedBox>),
}
#[derive(Serialize)]
pub(crate) struct FlexItemBox {
independent_formatting_context: IndependentFormattingContext,
#[serde(skip)]
block_content_size_cache: ArcRefCell<Option<CachedBlockSizeContribution>>,
}

View file

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

View file

@ -6,7 +6,6 @@ use std::vec::IntoIter;
use app_units::Au;
use fonts::FontMetrics;
use serde::Serialize;
use servo_arc::Arc;
use style::properties::ComputedValues;
@ -19,10 +18,9 @@ use crate::fragment_tree::BaseFragmentInfo;
use crate::style_ext::{ComputedValuesExt, PaddingBorderMargin};
use crate::ContainingBlock;
#[derive(Debug, Serialize)]
#[derive(Debug)]
pub(crate) struct InlineBox {
pub base_fragment_info: BaseFragmentInfo,
#[serde(skip_serializing)]
pub style: Arc<ComputedValues>,
/// The identifier of this inline box in the containing [`super::InlineFormattingContext`].
pub(super) identifier: InlineBoxIdentifier,
@ -56,7 +54,7 @@ impl InlineBox {
}
}
#[derive(Debug, Default, Serialize)]
#[derive(Debug, Default)]
pub(crate) struct InlineBoxes {
/// A collection of all inline boxes in a particular [`super::InlineFormattingContext`].
inline_boxes: Vec<ArcRefCell<InlineBox>>,
@ -158,7 +156,7 @@ impl InlineBoxes {
}
}
#[derive(Clone, Copy, Debug, PartialEq, Serialize)]
#[derive(Clone, Copy, Debug, PartialEq)]
pub(super) enum InlineBoxTreePathToken {
Start(InlineBoxIdentifier),
End(InlineBoxIdentifier),
@ -179,7 +177,7 @@ impl InlineBoxTreePathToken {
/// [`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
/// of the [`InlineBox`] in [`InlineBoxes::inline_boxes`].
#[derive(Clone, Copy, Debug, Default, Eq, Hash, PartialEq, Serialize)]
#[derive(Clone, Copy, Debug, Default, Eq, Hash, PartialEq)]
pub(crate) struct InlineBoxIdentifier {
pub index_of_start_in_tree: u32,
pub index_in_inline_boxes: u32,

View file

@ -88,7 +88,6 @@ use line::{
TextRunLineItem,
};
use line_breaker::LineBreaker;
use serde::Serialize;
use servo_arc::Arc;
use style::computed_values::text_wrap_mode::T as TextWrapMode;
use style::computed_values::vertical_align::T as VerticalAlign;
@ -134,7 +133,7 @@ use crate::{ConstraintSpace, ContainingBlock};
static FONT_SUBSCRIPT_OFFSET_RATIO: f32 = 0.20;
static FONT_SUPERSCRIPT_OFFSET_RATIO: f32 = 0.34;
#[derive(Debug, Serialize)]
#[derive(Debug)]
pub(crate) struct InlineFormattingContext {
/// All [`InlineItem`]s in this [`InlineFormattingContext`] stored in a flat array.
/// [`InlineItem::StartInlineBox`] and [`InlineItem::EndInlineBox`] allow representing
@ -171,14 +170,14 @@ pub(crate) struct InlineFormattingContext {
}
/// A collection of data used to cache [`FontMetrics`] in the [`InlineFormattingContext`]
#[derive(Debug, Serialize)]
#[derive(Debug)]
pub(crate) struct FontKeyAndMetrics {
pub key: FontInstanceKey,
pub pt_size: Au,
pub metrics: FontMetrics,
}
#[derive(Debug, Serialize)]
#[derive(Debug)]
pub(crate) enum InlineItem {
StartInlineBox(ArcRefCell<InlineBox>),
EndInlineBox,

View file

@ -13,7 +13,6 @@ use fonts::{
use fonts_traits::ByteIndex;
use log::warn;
use range::Range as ServoRange;
use serde::Serialize;
use servo_arc::Arc;
use style::computed_values::text_rendering::T as TextRendering;
use style::computed_values::white_space_collapse::T as WhiteSpaceCollapse;
@ -38,10 +37,9 @@ pub(crate) const XI_LINE_BREAKING_CLASS_WJ: u8 = 30;
pub(crate) const XI_LINE_BREAKING_CLASS_ZWJ: u8 = 42;
/// <https://www.w3.org/TR/css-display-3/#css-text-run>
#[derive(Debug, Serialize)]
#[derive(Debug)]
pub(crate) struct TextRun {
pub base_fragment_info: BaseFragmentInfo,
#[serde(skip_serializing)]
pub parent_style: Arc<ComputedValues>,
pub text_range: Range<usize>,
@ -64,14 +62,13 @@ enum SegmentStartSoftWrapPolicy {
FollowLinebreaker,
}
#[derive(Debug, Serialize)]
#[derive(Debug)]
pub(crate) struct TextRunSegment {
/// The index of this font in the parent [`super::InlineFormattingContext`]'s collection of font
/// information.
pub font_index: usize,
/// The [`Script`] of this segment.
#[serde(skip_serializing)]
pub script: Script,
/// The bidi Level of this segment.

View file

@ -8,7 +8,6 @@
use app_units::{Au, MAX_AU};
use inline::InlineFormattingContext;
use rayon::iter::{IntoParallelRefIterator, ParallelIterator};
use serde::Serialize;
use servo_arc::Arc;
use style::computed_values::clear::T as StyleClear;
use style::properties::ComputedValues;
@ -53,13 +52,13 @@ mod root;
pub(crate) use construct::BlockContainerBuilder;
pub use root::{BoxTree, CanvasBackground};
#[derive(Debug, Serialize)]
#[derive(Debug)]
pub(crate) struct BlockFormattingContext {
pub contents: BlockContainer,
pub contains_floats: bool,
}
#[derive(Debug, Serialize)]
#[derive(Debug)]
pub(crate) enum BlockContainer {
BlockLevelBoxes(Vec<ArcRefCell<BlockLevelBox>>),
InlineFormattingContext(InlineFormattingContext),
@ -76,7 +75,7 @@ impl BlockContainer {
}
}
#[derive(Debug, Serialize)]
#[derive(Debug)]
pub(crate) enum BlockLevelBox {
Independent(IndependentFormattingContext),
OutOfFlowAbsolutelyPositionedBox(ArcRefCell<AbsolutelyPositionedBox>),
@ -231,9 +230,8 @@ pub(crate) struct CollapsibleWithParentStartMargin(bool);
/// The contentes of a BlockContainer created to render a list marker
/// for a list that has `list-style-position: outside`.
#[derive(Debug, Serialize)]
#[derive(Debug)]
pub(crate) struct OutsideMarker {
#[serde(skip_serializing)]
pub marker_style: Arc<ComputedValues>,
pub base: LayoutBoxBase,
pub block_container: BlockContainer,

View file

@ -8,7 +8,6 @@ use script_layout_interface::wrapper_traits::{
LayoutNode, ThreadSafeLayoutElement, ThreadSafeLayoutNode,
};
use script_layout_interface::{LayoutElementType, LayoutNodeType};
use serde::Serialize;
use servo_arc::Arc;
use style::dom::OpaqueNode;
use style::properties::ComputedValues;
@ -33,7 +32,6 @@ use crate::style_ext::{ComputedValuesExt, Display, DisplayGeneratingBox, Display
use crate::taffy::{TaffyItemBox, TaffyItemBoxInner};
use crate::DefiniteContainingBlock;
#[derive(Serialize)]
pub struct BoxTree {
/// Contains typically exactly one block-level box, which was generated by the root element.
/// There may be zero if that element has `display: none`.
@ -409,7 +407,7 @@ impl BoxTree {
}
/// <https://drafts.csswg.org/css-backgrounds/#root-background>
#[derive(Clone, Serialize)]
#[derive(Clone)]
pub struct CanvasBackground {
/// DOM node for the root element
pub root_element: OpaqueNode,
@ -420,7 +418,6 @@ pub struct CanvasBackground {
pub from_element: OpaqueNode,
/// The computed styles to take background properties from.
#[serde(skip)]
pub style: Option<Arc<ComputedValues>>,
}

View file

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

View file

@ -4,25 +4,19 @@
use bitflags::bitflags;
use script_layout_interface::{combine_id_with_fragment_type, FragmentType};
use serde::Serialize;
use style::dom::OpaqueNode;
use style::selector_parser::PseudoElement;
use crate::layout_debug::DebugId;
/// This data structure stores fields that are common to all non-base
/// Fragment types and should generally be the first member of all
/// concrete fragments.
#[derive(Clone, Debug, Serialize)]
#[derive(Clone, Debug)]
pub(crate) struct BaseFragment {
/// A tag which identifies the DOM node and pseudo element of this
/// Fragment's content. If this fragment isn't related to any DOM
/// node at all, the tag will be None.
pub tag: Option<Tag>,
/// An id used to uniquely identify this Fragment in debug builds.
pub debug_id: DebugId,
/// Flags which various information about this fragment used during
/// layout.
pub flags: FragmentFlags,
@ -32,7 +26,6 @@ impl BaseFragment {
pub(crate) fn anonymous() -> Self {
BaseFragment {
tag: None,
debug_id: DebugId::new(),
flags: FragmentFlags::empty(),
}
}
@ -45,7 +38,7 @@ impl BaseFragment {
}
/// Information necessary to construct a new BaseFragment.
#[derive(Clone, Copy, Debug, Serialize)]
#[derive(Clone, Copy, Debug)]
pub(crate) struct BaseFragmentInfo {
/// The tag to use for the new BaseFragment, if it is not an anonymous Fragment.
pub tag: Option<Tag>,
@ -74,7 +67,6 @@ impl From<BaseFragmentInfo> for BaseFragment {
fn from(info: BaseFragmentInfo) -> Self {
Self {
tag: info.tag,
debug_id: DebugId::new(),
flags: info.flags,
}
}
@ -82,7 +74,7 @@ impl From<BaseFragmentInfo> for BaseFragment {
bitflags! {
/// Flags used to track various information about a DOM node during layout.
#[derive(Clone, Copy, Debug, Serialize)]
#[derive(Clone, Copy, Debug)]
pub(crate) struct FragmentFlags: u8 {
/// Whether or not the node that created this fragment is a `<body>` element on an HTML document.
const IS_BODY_ELEMENT_OF_HTML_ELEMENT_ROOT = 1 << 0;
@ -113,7 +105,7 @@ bitflags! {
/// A data structure used to hold DOM and pseudo-element information about
/// a particular layout object.
#[derive(Clone, Copy, Debug, Eq, PartialEq, Serialize)]
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub(crate) struct Tag {
pub(crate) node: OpaqueNode,
pub(crate) pseudo: Option<PseudoElement>,

View file

@ -5,7 +5,6 @@
use app_units::Au;
use atomic_refcell::AtomicRefCell;
use base::print_tree::PrintTree;
use serde::Serialize;
use servo_arc::Arc as ServoArc;
use style::computed_values::overflow_x::T as ComputedOverflow;
use style::computed_values::position::T as ComputedPosition;
@ -47,11 +46,9 @@ pub(crate) enum SpecificLayoutInfo {
TableOrTableCell(Box<SpecificTableOrTableCellInfo>),
}
#[derive(Serialize)]
pub(crate) struct BoxFragment {
pub base: BaseFragment,
#[serde(skip_serializing)]
pub style: ServoArc<ComputedValues>,
pub children: Vec<Fragment>,
@ -84,14 +81,11 @@ pub(crate) struct BoxFragment {
/// The resolved box insets if this box is `position: sticky`. These are calculated
/// during stacking context tree construction because they rely on the size of the
/// scroll container.
#[serde(skip_serializing)]
pub(crate) resolved_sticky_insets: AtomicRefCell<Option<PhysicalSides<AuOrAuto>>>,
#[serde(skip_serializing)]
pub background_mode: BackgroundMode,
/// Additional information of from layout that could be used by Javascripts and devtools.
#[serde(skip_serializing)]
pub detailed_layout_info: Option<SpecificLayoutInfo>,
}

View file

@ -5,10 +5,9 @@
use std::sync::Arc;
use app_units::Au;
use base::id::{BrowsingContextId, PipelineId};
use base::id::PipelineId;
use base::print_tree::PrintTree;
use fonts::{FontMetrics, GlyphStore};
use serde::Serialize;
use servo_arc::Arc as ServoArc;
use style::properties::ComputedValues;
use style::values::specified::text::TextDecorationLine;
@ -23,7 +22,7 @@ use crate::cell::ArcRefCell;
use crate::geom::{LogicalSides, PhysicalRect};
use crate::style_ext::ComputedValuesExt;
#[derive(Clone, Serialize)]
#[derive(Clone)]
pub(crate) enum Fragment {
Box(ArcRefCell<BoxFragment>),
/// Floating content. A floated fragment is very similar to a normal
@ -46,27 +45,23 @@ pub(crate) enum Fragment {
IFrame(ArcRefCell<IFrameFragment>),
}
#[derive(Serialize)]
pub(crate) struct CollapsedBlockMargins {
pub collapsed_through: bool,
pub start: CollapsedMargin,
pub end: CollapsedMargin,
}
#[derive(Clone, Copy, Debug, Serialize)]
#[derive(Clone, Copy, Debug)]
pub(crate) struct CollapsedMargin {
max_positive: Au,
min_negative: Au,
}
#[derive(Serialize)]
pub(crate) struct TextFragment {
pub base: BaseFragment,
#[serde(skip_serializing)]
pub parent_style: ServoArc<ComputedValues>,
pub rect: PhysicalRect<Au>,
pub font_metrics: FontMetrics,
#[serde(skip_serializing)]
pub font_key: FontInstanceKey,
pub glyphs: Vec<Arc<GlyphStore>>,
@ -77,24 +72,18 @@ pub(crate) struct TextFragment {
pub justification_adjustment: Au,
}
#[derive(Serialize)]
pub(crate) struct ImageFragment {
pub base: BaseFragment,
#[serde(skip_serializing)]
pub style: ServoArc<ComputedValues>,
pub rect: PhysicalRect<Au>,
pub clip: PhysicalRect<Au>,
#[serde(skip_serializing)]
pub image_key: Option<ImageKey>,
}
#[derive(Serialize)]
pub(crate) struct IFrameFragment {
pub base: BaseFragment,
pub pipeline_id: PipelineId,
pub browsing_context_id: BrowsingContextId,
pub rect: PhysicalRect<Au>,
#[serde(skip_serializing)]
pub style: ServoArc<ComputedValues>,
}

View file

@ -6,7 +6,6 @@ use app_units::Au;
use base::print_tree::PrintTree;
use euclid::default::{Point2D, Rect, Size2D};
use fxhash::FxHashSet;
use serde::Serialize;
use style::animation::AnimationSetKey;
use style::dom::OpaqueNode;
use webrender_api::units;
@ -17,7 +16,6 @@ use crate::display_list::StackingContext;
use crate::flow::CanvasBackground;
use crate::geom::PhysicalRect;
#[derive(Serialize)]
pub struct FragmentTree {
/// Fragments at the top-level of the tree.
///
@ -37,7 +35,6 @@ pub struct FragmentTree {
pub(crate) initial_containing_block: PhysicalRect<Au>,
/// <https://drafts.csswg.org/css-backgrounds/#special-backgrounds>
#[serde(skip)]
pub(crate) canvas_background: CanvasBackground,
/// Whether or not the root element is sensitive to scroll input events.

View file

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

View file

@ -4,7 +4,6 @@
use app_units::Au;
use base::print_tree::PrintTree;
use serde::Serialize;
use servo_arc::Arc as ServoArc;
use style::properties::ComputedValues;
@ -15,7 +14,6 @@ use crate::geom::PhysicalRect;
/// 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
/// generated by boxes.
#[derive(Serialize)]
pub(crate) struct PositioningFragment {
pub base: BaseFragment,
pub rect: PhysicalRect<Au>,
@ -24,7 +22,6 @@ pub(crate) struct PositioningFragment {
pub scrollable_overflow: PhysicalRect<Au>,
/// If this fragment was created with a style, the style of the fragment.
#[serde(skip_serializing)]
pub style: Option<ServoArc<ComputedValues>>,
}

View file

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

View file

@ -3,7 +3,6 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
use atomic_refcell::AtomicRefCell;
use serde::Serialize;
use servo_arc::Arc;
use style::properties::ComputedValues;
@ -19,12 +18,10 @@ use crate::ConstraintSpace;
/// passes.
///
/// In the future, this will hold layout results to support incremental layout.
#[derive(Debug, Serialize)]
#[derive(Debug)]
pub(crate) struct LayoutBoxBase {
pub base_fragment_info: BaseFragmentInfo,
#[serde(skip_serializing)]
pub style: Arc<ComputedValues>,
#[serde(skip_serializing)]
pub cached_inline_content_size:
AtomicRefCell<Option<(SizeConstraint, InlineContentSizesResult)>>,
}

View file

@ -1,184 +0,0 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
//! Supports writing a trace file created during each layout scope
//! that can be viewed by an external tool to make layout debugging easier.
use std::cell::RefCell;
use std::fs;
#[cfg(debug_assertions)]
use std::sync::atomic::{AtomicUsize, Ordering};
use std::sync::Arc;
#[cfg(not(debug_assertions))]
use serde::ser::Serializer;
use serde::Serialize;
use serde_json::{to_string, to_value, Value};
use crate::flow::BoxTree;
use crate::fragment_tree::FragmentTree;
thread_local!(static STATE_KEY: RefCell<Option<State>> = const { RefCell::new(None) });
#[cfg(debug_assertions)]
static DEBUG_ID_COUNTER: AtomicUsize = AtomicUsize::new(0);
pub struct Scope;
#[macro_export]
macro_rules! layout_debug_scope(
($($arg:tt)*) => (
if cfg!(debug_assertions) {
layout_debug::Scope::new(format!($($arg)*))
} else {
layout_debug::Scope
}
)
);
#[derive(Serialize)]
struct TreeValues {
pub box_tree: Value,
pub fragment_tree: Value,
}
#[derive(Serialize)]
struct ScopeData {
name: String,
pre: TreeValues,
post: TreeValues,
children: Vec<ScopeData>,
}
impl ScopeData {
fn new(name: String, box_tree: Value, fragment_tree: Value) -> ScopeData {
ScopeData {
name,
pre: TreeValues {
box_tree,
fragment_tree,
},
post: TreeValues {
box_tree: Value::Null,
fragment_tree: Value::Null,
},
children: vec![],
}
}
}
struct State {
fragment_tree: Arc<FragmentTree>,
box_tree: Arc<BoxTree>,
scope_stack: Vec<ScopeData>,
}
/// A layout debugging scope. The entire state of the box and fragment trees
/// will be output at the beginning and end of this scope.
impl Scope {
pub fn new(name: String) -> Scope {
STATE_KEY.with(|r| {
if let Some(ref mut state) = *r.borrow_mut() {
let box_tree = to_value(&state.box_tree).unwrap();
let fragment_tree = to_value(&state.fragment_tree).unwrap();
let data = Box::new(ScopeData::new(name.clone(), box_tree, fragment_tree));
state.scope_stack.push(*data);
}
});
Scope
}
}
#[cfg(debug_assertions)]
impl Drop for Scope {
fn drop(&mut self) {
STATE_KEY.with(|r| {
if let Some(ref mut state) = *r.borrow_mut() {
let mut current_scope = state.scope_stack.pop().unwrap();
current_scope.post = TreeValues {
box_tree: to_value(&state.box_tree).unwrap(),
fragment_tree: to_value(&state.fragment_tree).unwrap(),
};
let previous_scope = state.scope_stack.last_mut().unwrap();
previous_scope.children.push(current_scope);
}
});
}
}
/// Begin a layout debug trace. If this has not been called,
/// creating debug scopes has no effect.
pub fn begin_trace(box_tree: Arc<BoxTree>, fragment_tree: Arc<FragmentTree>) {
assert!(STATE_KEY.with(|r| r.borrow().is_none()));
STATE_KEY.with(|r| {
let box_tree_value = to_value(&box_tree).unwrap();
let fragment_tree_value = to_value(&fragment_tree).unwrap();
let state = State {
scope_stack: vec![*Box::new(ScopeData::new(
"root".to_owned(),
box_tree_value,
fragment_tree_value,
))],
box_tree,
fragment_tree,
};
*r.borrow_mut() = Some(state);
});
}
/// End the debug layout trace. This will write the layout
/// trace to disk in the current directory. The output
/// file can then be viewed with an external tool.
pub fn end_trace(generation: u32) {
let mut thread_state = STATE_KEY.with(|r| r.borrow_mut().take().unwrap());
assert_eq!(thread_state.scope_stack.len(), 1);
let mut root_scope = thread_state.scope_stack.pop().unwrap();
root_scope.post = TreeValues {
box_tree: to_value(&thread_state.box_tree).unwrap_or(Value::Null),
fragment_tree: to_value(&thread_state.fragment_tree).unwrap_or(Value::Null),
};
let result = to_string(&root_scope).unwrap();
fs::write(
format!("layout_trace-{}.json", generation),
result.as_bytes(),
)
.unwrap();
}
#[cfg(not(debug_assertions))]
#[derive(Clone, Debug)]
pub struct DebugId;
#[cfg(debug_assertions)]
#[derive(Clone, Debug, Serialize)]
#[serde(transparent)]
pub struct DebugId(u16);
#[cfg(not(debug_assertions))]
impl DebugId {
pub fn new() -> DebugId {
DebugId
}
}
#[cfg(debug_assertions)]
impl DebugId {
pub fn new() -> DebugId {
DebugId(DEBUG_ID_COUNTER.fetch_add(1, Ordering::SeqCst) as u16)
}
}
impl Default for DebugId {
fn default() -> Self {
Self::new()
}
}
#[cfg(not(debug_assertions))]
impl Serialize for DebugId {
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
serializer.serialize_str(&format!("{:p}", &self))
}
}

View file

@ -17,7 +17,6 @@ pub mod geom;
mod layout_box_base;
mod taffy;
#[macro_use]
pub mod layout_debug;
mod construct_modern;
mod lists;
mod positioned;
@ -32,7 +31,6 @@ use app_units::Au;
pub use flow::BoxTree;
pub use fragment_tree::FragmentTree;
use geom::AuOrAuto;
use serde::Serialize;
use style::logical_geometry::WritingMode;
use style::properties::ComputedValues;
@ -115,7 +113,7 @@ impl<'a> From<&'_ DefiniteContainingBlock<'a>> for IndefiniteContainingBlock {
}
}
#[derive(Debug, Serialize)]
#[derive(Debug)]
pub(crate) struct ContainingBlockSize {
inline: Au,
block: SizeConstraint,

View file

@ -7,7 +7,6 @@ use std::mem;
use app_units::Au;
use rayon::iter::IntoParallelRefMutIterator;
use rayon::prelude::{IndexedParallelIterator, ParallelIterator};
use serde::Serialize;
use style::computed_values::position::T as Position;
use style::logical_geometry::WritingMode;
use style::properties::ComputedValues;
@ -36,7 +35,7 @@ use crate::{
ConstraintSpace, ContainingBlock, ContainingBlockSize, DefiniteContainingBlock, SizeConstraint,
};
#[derive(Debug, Serialize)]
#[derive(Debug)]
pub(crate) struct AbsolutelyPositionedBox {
pub context: IndependentFormattingContext,
}

View file

@ -15,7 +15,6 @@ use ipc_channel::ipc::{self, IpcSender};
use net_traits::image_cache::{ImageOrMetadataAvailable, UsePlaceholder};
use pixels::Image;
use script_layout_interface::IFrameSize;
use serde::Serialize;
use servo_arc::Arc as ServoArc;
use style::computed_values::object_fit::T as ObjectFit;
use style::logical_geometry::{Direction, WritingMode};
@ -36,7 +35,7 @@ use crate::sizing::{ComputeInlineContentSizes, ContentSizes, InlineContentSizesR
use crate::style_ext::{AspectRatio, Clamp, ComputedValuesExt, ContentBoxSizesAndPBM};
use crate::{ConstraintSpace, ContainingBlock, SizeConstraint};
#[derive(Debug, Serialize)]
#[derive(Debug)]
pub(crate) struct ReplacedContents {
pub kind: ReplacedContentKind,
natural_size: NaturalSizes,
@ -60,7 +59,7 @@ pub(crate) struct ReplacedContents {
///
/// * IFrames do not have natural width and height or natural ratio according
/// to <https://drafts.csswg.org/css-images/#intrinsic-dimensions>.
#[derive(Debug, Serialize)]
#[derive(Debug)]
pub(crate) struct NaturalSizes {
pub width: Option<Au>,
pub height: Option<Au>,
@ -94,7 +93,6 @@ impl NaturalSizes {
}
}
#[derive(Serialize)]
pub(crate) enum CanvasSource {
WebGL(ImageKey),
Image(Arc<Mutex<IpcSender<CanvasMsg>>>),
@ -118,24 +116,24 @@ impl fmt::Debug for CanvasSource {
}
}
#[derive(Debug, Serialize)]
#[derive(Debug)]
pub(crate) struct CanvasInfo {
pub source: CanvasSource,
pub canvas_id: CanvasId,
}
#[derive(Debug, Serialize)]
#[derive(Debug)]
pub(crate) struct IFrameInfo {
pub pipeline_id: PipelineId,
pub browsing_context_id: BrowsingContextId,
}
#[derive(Debug, Serialize)]
#[derive(Debug)]
pub(crate) struct VideoInfo {
pub image_key: webrender_api::ImageKey,
}
#[derive(Debug, Serialize)]
#[derive(Debug)]
pub(crate) enum ReplacedContentKind {
Image(Option<Arc<Image>>),
IFrame(IFrameInfo),
@ -368,7 +366,6 @@ impl ReplacedContents {
base: self.base_fragment_info.into(),
style: style.clone(),
pipeline_id: iframe.pipeline_id,
browsing_context_id: iframe.browsing_context_id,
rect,
}))]
},

View file

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

View file

@ -73,7 +73,6 @@ use std::ops::Range;
pub(crate) use construct::AnonymousTableContent;
pub use construct::TableBuilder;
use euclid::{Point2D, Size2D, UnknownUnit, Vector2D};
use serde::Serialize;
use servo_arc::Arc;
use style::properties::style_structs::Font;
use style::properties::ComputedValues;
@ -90,17 +89,15 @@ use crate::style_ext::BorderStyleColor;
pub type TableSize = Size2D<usize, UnknownUnit>;
#[derive(Debug, Serialize)]
#[derive(Debug)]
pub struct Table {
/// 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
/// wrapper though, such as background and borders, which apply to the grid.
#[serde(skip_serializing)]
style: Arc<ComputedValues>,
/// 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."
#[serde(skip_serializing)]
grid_style: Arc<ComputedValues>,
/// The [`BaseFragmentInfo`] for this table's grid. This is necessary so that when the
@ -190,7 +187,7 @@ impl Table {
type TableSlotCoordinates = Point2D<usize, UnknownUnit>;
pub type TableSlotOffset = Vector2D<usize, UnknownUnit>;
#[derive(Debug, Serialize)]
#[derive(Debug)]
pub struct TableSlotCell {
/// The [`LayoutBoxBase`] of this table cell.
base: LayoutBoxBase,
@ -228,7 +225,6 @@ impl TableSlotCell {
}
}
#[derive(Serialize)]
/// A single table slot. It may be an actual cell, or a reference
/// to a previous cell that is spanned here
///
@ -269,13 +265,12 @@ impl TableSlot {
}
/// A row or column of a table.
#[derive(Clone, Debug, Serialize)]
#[derive(Clone, Debug)]
pub struct TableTrack {
/// The [`BaseFragmentInfo`] of this cell.
base_fragment_info: BaseFragmentInfo,
/// The style of this table column.
#[serde(skip_serializing)]
style: Arc<ComputedValues>,
/// The index of the table row or column group parent in the table's list of row or column
@ -287,7 +282,7 @@ pub struct TableTrack {
is_anonymous: bool,
}
#[derive(Debug, PartialEq, Serialize)]
#[derive(Debug, PartialEq)]
pub enum TableTrackGroupType {
HeaderGroup,
FooterGroup,
@ -295,13 +290,12 @@ pub enum TableTrackGroupType {
ColumnGroup,
}
#[derive(Debug, Serialize)]
#[derive(Debug)]
pub struct TableTrackGroup {
/// The [`BaseFragmentInfo`] of this [`TableTrackGroup`].
base_fragment_info: BaseFragmentInfo,
/// The style of this [`TableTrackGroup`].
#[serde(skip_serializing)]
style: Arc<ComputedValues>,
/// The type of this [`TableTrackGroup`].
@ -317,7 +311,7 @@ impl TableTrackGroup {
}
}
#[derive(Debug, Serialize)]
#[derive(Debug)]
pub struct TableCaption {
/// The contents of this cell, with its own layout.
context: ArcRefCell<IndependentFormattingContext>,

View file

@ -6,7 +6,6 @@ mod stylo_taffy;
use std::fmt;
use app_units::Au;
use serde::Serialize;
use servo_arc::Arc;
use style::properties::ComputedValues;
use style::values::computed::TextDecorationLine;
@ -21,10 +20,9 @@ use crate::formatting_contexts::IndependentFormattingContext;
use crate::fragment_tree::Fragment;
use crate::positioned::{AbsolutelyPositionedBox, PositioningContext};
#[derive(Debug, Serialize)]
#[derive(Debug)]
pub(crate) struct TaffyContainer {
children: Vec<ArcRefCell<TaffyItemBox>>,
#[serde(skip_serializing)]
style: Arc<ComputedValues>,
}
@ -72,18 +70,15 @@ impl TaffyContainer {
}
}
#[derive(Serialize)]
pub(crate) struct TaffyItemBox {
pub(crate) taffy_layout: taffy::Layout,
pub(crate) child_fragments: Vec<Fragment>,
#[serde(skip_serializing)]
pub(crate) positioning_context: PositioningContext,
#[serde(skip_serializing)]
pub(crate) style: Arc<ComputedValues>,
pub(crate) taffy_level_box: TaffyItemBoxInner,
}
#[derive(Debug, Serialize)]
#[derive(Debug)]
pub(crate) enum TaffyItemBoxInner {
InFlowBox(IndependentFormattingContext),
OutOfFlowAbsolutelyPositionedBox(ArcRefCell<AbsolutelyPositionedBox>),