diff --git a/components/layout_2020/flow/inline.rs b/components/layout_2020/flow/inline.rs index 58dfb6581db..ae75b8f055b 100644 --- a/components/layout_2020/flow/inline.rs +++ b/components/layout_2020/flow/inline.rs @@ -7,7 +7,7 @@ use crate::flow::float::FloatBox; use crate::flow::FlowLayout; use crate::formatting_contexts::IndependentFormattingContext; use crate::fragments::CollapsedBlockMargins; -use crate::fragments::{AnonymousFragment, BoxFragment, Fragment, TextFragment}; +use crate::fragments::{AnonymousFragment, BoxFragment, DebugId, Fragment, TextFragment}; use crate::geom::flow_relative::{Rect, Sides, Vec2}; use crate::positioned::{relative_adjustement, AbsolutelyPositionedBox, PositioningContext}; use crate::sizing::ContentSizes; @@ -713,6 +713,7 @@ impl TextRun { .fragments_so_far .push(Fragment::Text(TextFragment { tag: self.tag, + debug_id: DebugId::new(), parent_style: self.parent_style.clone(), rect, ascent: font_ascent.into(), diff --git a/components/layout_2020/flow/mod.rs b/components/layout_2020/flow/mod.rs index b047fee78df..f407b4ffd0e 100644 --- a/components/layout_2020/flow/mod.rs +++ b/components/layout_2020/flow/mod.rs @@ -8,8 +8,9 @@ use crate::context::LayoutContext; use crate::flow::float::{FloatBox, FloatContext}; use crate::flow::inline::InlineFormattingContext; use crate::formatting_contexts::{IndependentFormattingContext, IndependentLayout, NonReplacedIFC}; -use crate::fragments::{AnonymousFragment, BoxFragment, Fragment}; +use crate::fragments::{AnonymousFragment, BoxFragment}; use crate::fragments::{CollapsedBlockMargins, CollapsedMargin}; +use crate::fragments::{DebugId, Fragment}; use crate::geom::flow_relative::{Rect, Sides, Vec2}; use crate::positioned::{AbsolutelyPositionedBox, PositioningContext}; use crate::replaced::ReplacedContent; diff --git a/components/layout_2020/fragments.rs b/components/layout_2020/fragments.rs index 87b362c14f0..5dddb18ca49 100644 --- a/components/layout_2020/fragments.rs +++ b/components/layout_2020/fragments.rs @@ -4,6 +4,7 @@ use crate::geom::flow_relative::{Rect, Sides, Vec2}; use crate::geom::{PhysicalPoint, PhysicalRect}; +use crate::layout_debug; use gfx::text::glyph::GlyphStore; use gfx_traits::print_tree::PrintTree; use serde::ser::{Serialize, SerializeStruct, Serializer}; @@ -27,6 +28,7 @@ pub(crate) enum Fragment { pub(crate) struct BoxFragment { pub tag: OpaqueNode, + pub debug_id: DebugId, pub style: ServoArc, pub children: Vec, @@ -61,6 +63,7 @@ pub(crate) struct CollapsedMargin { /// Can contain child fragments with relative coordinates, but does not contribute to painting itself. #[derive(Serialize)] pub(crate) struct AnonymousFragment { + pub debug_id: DebugId, pub rect: Rect, pub children: Vec, pub mode: WritingMode, @@ -70,6 +73,7 @@ pub(crate) struct AnonymousFragment { } pub(crate) struct TextFragment { + pub debug_id: DebugId, pub tag: OpaqueNode, pub parent_style: ServoArc, pub rect: Rect, @@ -79,6 +83,7 @@ pub(crate) struct TextFragment { } pub(crate) struct ImageFragment { + pub debug_id: DebugId, pub style: ServoArc, pub rect: Rect, pub image_key: ImageKey, @@ -123,6 +128,7 @@ impl Fragment { impl AnonymousFragment { pub fn no_op(mode: WritingMode) -> Self { Self { + debug_id: DebugId::new(), children: vec![], rect: Rect::zero(), mode, @@ -140,6 +146,7 @@ impl AnonymousFragment { ) }); AnonymousFragment { + debug_id: DebugId::new(), rect, children, mode, @@ -179,6 +186,7 @@ impl BoxFragment { }); BoxFragment { tag, + debug_id: DebugId::new(), style, children, content_rect, @@ -349,7 +357,8 @@ impl CollapsedMargin { impl Serialize for BoxFragment { fn serialize(&self, serializer: S) -> Result { - let mut serializer = serializer.serialize_struct("BoxFragment", 6)?; + let mut serializer = serializer.serialize_struct("BoxFragment", 7)?; + serializer.serialize_field("debug_id", &self.debug_id)?; serializer.serialize_field("content_rect", &self.content_rect)?; serializer.serialize_field("padding", &self.padding)?; serializer.serialize_field("border", &self.border)?; @@ -365,7 +374,8 @@ impl Serialize for BoxFragment { impl Serialize for TextFragment { fn serialize(&self, serializer: S) -> Result { - let mut serializer = serializer.serialize_struct("TextFragment", 3)?; + let mut serializer = serializer.serialize_struct("TextFragment", 4)?; + serializer.serialize_field("debug_id", &self.debug_id)?; serializer.serialize_field("rect", &self.rect)?; serializer.serialize_field("ascent", &self.ascent)?; serializer.serialize_field("glyphs", &self.glyphs)?; @@ -375,8 +385,45 @@ impl Serialize for TextFragment { impl Serialize for ImageFragment { fn serialize(&self, serializer: S) -> Result { - let mut serializer = serializer.serialize_struct("ImageFragment", 1)?; + let mut serializer = serializer.serialize_struct("ImageFragment", 2)?; + serializer.serialize_field("debug_id", &self.debug_id)?; serializer.serialize_field("rect", &self.rect)?; serializer.end() } } + +#[cfg(not(debug_assertions))] +#[derive(Clone)] +pub struct DebugId; + +#[cfg(debug_assertions)] +#[derive(Clone)] +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(layout_debug::generate_unique_debug_id()) + } +} + +#[cfg(not(debug_assertions))] +impl Serialize for DebugId { + fn serialize(&self, serializer: S) -> Result { + serializer.serialize_str(&format!("{:p}", &self)) + } +} + +#[cfg(debug_assertions)] +impl Serialize for DebugId { + fn serialize(&self, serializer: S) -> Result { + serializer.serialize_u16(self.0) + } +} diff --git a/components/layout_2020/layout_debug.rs b/components/layout_2020/layout_debug.rs index 32ab13fc484..4e28ce8ffeb 100644 --- a/components/layout_2020/layout_debug.rs +++ b/components/layout_2020/layout_debug.rs @@ -10,10 +10,15 @@ use serde_json::{to_string, to_value, Value}; use std::cell::RefCell; use std::fs::File; use std::io::Write; +#[cfg(debug_assertions)] +use std::sync::atomic::{AtomicUsize, Ordering}; use std::sync::Arc; thread_local!(static STATE_KEY: RefCell> = RefCell::new(None)); +#[cfg(debug_assertions)] +static DEBUG_ID_COUNTER: AtomicUsize = AtomicUsize::new(0); + pub struct Scope; #[macro_export] @@ -80,6 +85,12 @@ impl Drop for Scope { } } +/// Generate a unique ID for Fragments. +#[cfg(debug_assertions)] +pub fn generate_unique_debug_id() -> u16 { + DEBUG_ID_COUNTER.fetch_add(1, Ordering::SeqCst) as u16 +} + /// Begin a layout debug trace. If this has not been called, /// creating debug scopes has no effect. pub fn begin_trace(root: Arc) { diff --git a/components/layout_2020/positioned.rs b/components/layout_2020/positioned.rs index 7b7d67bd122..3c4ec876fc7 100644 --- a/components/layout_2020/positioned.rs +++ b/components/layout_2020/positioned.rs @@ -5,7 +5,7 @@ use crate::context::LayoutContext; use crate::dom_traversal::{Contents, NodeExt}; use crate::formatting_contexts::IndependentFormattingContext; -use crate::fragments::{AnonymousFragment, BoxFragment, CollapsedBlockMargins, Fragment}; +use crate::fragments::{AnonymousFragment, BoxFragment, CollapsedBlockMargins, DebugId, Fragment}; use crate::geom::flow_relative::{Rect, Sides, Vec2}; use crate::sizing::ContentSizesRequest; use crate::style_ext::{ComputedValuesExt, DisplayInside}; diff --git a/components/layout_2020/replaced.rs b/components/layout_2020/replaced.rs index 2157d07f0b4..d979c9df481 100644 --- a/components/layout_2020/replaced.rs +++ b/components/layout_2020/replaced.rs @@ -3,7 +3,7 @@ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ use crate::dom_traversal::NodeExt; -use crate::fragments::{Fragment, ImageFragment}; +use crate::fragments::{DebugId, Fragment, ImageFragment}; use crate::geom::flow_relative::{Rect, Vec2}; use crate::geom::PhysicalSize; use crate::sizing::ContentSizes; @@ -113,6 +113,7 @@ impl ReplacedContent { .and_then(|image| image.id) .map(|image_key| { Fragment::Image(ImageFragment { + debug_id: DebugId::new(), style: style.clone(), rect: Rect { start_corner: Vec2::zero(), diff --git a/etc/layout_viewer/viewer.html b/etc/layout_viewer/viewer.html index a3e0e2b1db0..2dd339b0bda 100644 --- a/etc/layout_viewer/viewer.html +++ b/etc/layout_viewer/viewer.html @@ -57,8 +57,8 @@
-
Flow Tree
-
+
Fragment Tree
+
@@ -90,28 +90,19 @@