aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--components/gfx_traits/lib.rs5
-rw-r--r--components/layout/display_list/items.rs16
-rw-r--r--components/layout/display_list/mod.rs1
-rw-r--r--components/layout/display_list/webrender_helpers.rs53
-rw-r--r--components/layout_2020/display_list/items.rs24
-rw-r--r--components/layout_2020/display_list/mod.rs8
-rw-r--r--components/layout_2020/display_list/webrender_helpers.rs26
-rw-r--r--components/layout_2020/fragment.rs2
-rw-r--r--components/layout_2020/lib.rs4
-rw-r--r--components/layout_2020/opaque_node.rs2
-rw-r--r--components/layout_2020/query.rs9
-rw-r--r--components/layout_thread/lib.rs6
-rw-r--r--components/layout_thread_2020/lib.rs23
-rw-r--r--components/metrics/lib.rs6
-rw-r--r--tests/unit/metrics/paint_time.rs32
15 files changed, 62 insertions, 155 deletions
diff --git a/components/gfx_traits/lib.rs b/components/gfx_traits/lib.rs
index a3a85499a9e..165059c7996 100644
--- a/components/gfx_traits/lib.rs
+++ b/components/gfx_traits/lib.rs
@@ -103,8 +103,3 @@ pub fn node_id_from_scroll_id(id: usize) -> Option<usize> {
}
None
}
-
-pub trait DisplayList {
- /// Returns true if this display list contains meaningful content.
- fn is_contentful(&self) -> bool;
-}
diff --git a/components/layout/display_list/items.rs b/components/layout/display_list/items.rs
index de7e49d306e..f838a95bf08 100644
--- a/components/layout/display_list/items.rs
+++ b/components/layout/display_list/items.rs
@@ -137,22 +137,6 @@ impl DisplayList {
}
}
-impl gfx_traits::DisplayList for DisplayList {
- /// Analyze the display list to figure out if this may be the first
- /// contentful paint (i.e. the display list contains items of type text,
- /// image, non-white canvas or SVG). Used by metrics.
- fn is_contentful(&self) -> bool {
- for item in &self.list {
- match item {
- &DisplayItem::Text(_) | &DisplayItem::Image(_) => return true,
- _ => (),
- }
- }
-
- false
- }
-}
-
/// Display list sections that make up a stacking context. Each section here refers
/// to the steps in CSS 2.1 Appendix E.
///
diff --git a/components/layout/display_list/mod.rs b/components/layout/display_list/mod.rs
index 302728fbf22..257d9eb6ddc 100644
--- a/components/layout/display_list/mod.rs
+++ b/components/layout/display_list/mod.rs
@@ -8,7 +8,6 @@ pub use self::builder::IndexableText;
pub use self::builder::StackingContextCollectionFlags;
pub use self::builder::StackingContextCollectionState;
pub use self::conversions::ToLayout;
-pub use self::webrender_helpers::WebRenderDisplayListConverter;
mod background;
mod border;
diff --git a/components/layout/display_list/webrender_helpers.rs b/components/layout/display_list/webrender_helpers.rs
index a27979a3189..993e2b38cef 100644
--- a/components/layout/display_list/webrender_helpers.rs
+++ b/components/layout/display_list/webrender_helpers.rs
@@ -17,10 +17,6 @@ use webrender_api::{
RasterSpace, ReferenceFrameKind, SpaceAndClipInfo, SpatialId, StackingContext,
};
-pub trait WebRenderDisplayListConverter {
- fn convert_to_webrender(&mut self, pipeline_id: PipelineId) -> DisplayListBuilder;
-}
-
struct ClipScrollState {
clip_ids: Vec<Option<ClipId>>,
spatial_ids: Vec<Option<SpatialId>>,
@@ -28,17 +24,17 @@ struct ClipScrollState {
active_spatial_id: SpatialId,
}
-trait WebRenderDisplayItemConverter {
- fn convert_to_webrender(
- &mut self,
- clip_scroll_nodes: &[ClipScrollNode],
- state: &mut ClipScrollState,
- builder: &mut DisplayListBuilder,
- );
-}
+/// Contentful paint, for the purpose of
+/// https://w3c.github.io/paint-timing/#first-contentful-paint
+/// (i.e. the display list contains items of type text,
+/// image, non-white canvas or SVG). Used by metrics.
+pub struct IsContentful(pub bool);
-impl WebRenderDisplayListConverter for DisplayList {
- fn convert_to_webrender(&mut self, pipeline_id: PipelineId) -> DisplayListBuilder {
+impl DisplayList {
+ pub fn convert_to_webrender(
+ &mut self,
+ pipeline_id: PipelineId,
+ ) -> (DisplayListBuilder, IsContentful) {
let mut clip_ids = vec![None; self.clip_scroll_nodes.len()];
let mut spatial_ids = vec![None; self.clip_scroll_nodes.len()];
@@ -67,21 +63,24 @@ impl WebRenderDisplayListConverter for DisplayList {
1024 * 1024, // 1 MB of space
);
+ let mut is_contentful = IsContentful(false);
for item in &mut self.list {
- item.convert_to_webrender(&self.clip_scroll_nodes, &mut state, &mut builder);
+ is_contentful.0 |= item
+ .convert_to_webrender(&self.clip_scroll_nodes, &mut state, &mut builder)
+ .0;
}
- builder
+ (builder, is_contentful)
}
}
-impl WebRenderDisplayItemConverter for DisplayItem {
+impl DisplayItem {
fn convert_to_webrender(
&mut self,
clip_scroll_nodes: &[ClipScrollNode],
state: &mut ClipScrollState,
builder: &mut DisplayListBuilder,
- ) {
+ ) -> IsContentful {
// Note: for each time of a display item, if we register one of `clip_ids` or `spatial_ids`,
// we also register the other one as inherited from the current state or the stack.
// This is not an ideal behavior, but it is compatible with the old WebRender model
@@ -109,15 +108,18 @@ impl WebRenderDisplayItemConverter for DisplayItem {
DisplayItem::Rectangle(ref mut item) => {
item.item.common = build_common_item_properties(&item.base, state);
builder.push_item(&WrDisplayItem::Rectangle(item.item));
+ IsContentful(false)
},
DisplayItem::Text(ref mut item) => {
item.item.common = build_common_item_properties(&item.base, state);
builder.push_item(&WrDisplayItem::Text(item.item));
builder.push_iter(item.data.iter());
+ IsContentful(true)
},
DisplayItem::Image(ref mut item) => {
item.item.common = build_common_item_properties(&item.base, state);
builder.push_item(&WrDisplayItem::Image(item.item));
+ IsContentful(true)
},
DisplayItem::Border(ref mut item) => {
item.item.common = build_common_item_properties(&item.base, state);
@@ -125,24 +127,29 @@ impl WebRenderDisplayItemConverter for DisplayItem {
builder.push_stops(item.data.as_ref());
}
builder.push_item(&WrDisplayItem::Border(item.item));
+ IsContentful(false)
},
DisplayItem::Gradient(ref mut item) => {
item.item.common = build_common_item_properties(&item.base, state);
builder.push_stops(item.data.as_ref());
builder.push_item(&WrDisplayItem::Gradient(item.item));
+ IsContentful(false)
},
DisplayItem::RadialGradient(ref mut item) => {
item.item.common = build_common_item_properties(&item.base, state);
builder.push_stops(item.data.as_ref());
builder.push_item(&WrDisplayItem::RadialGradient(item.item));
+ IsContentful(false)
},
DisplayItem::Line(ref mut item) => {
item.item.common = build_common_item_properties(&item.base, state);
builder.push_item(&WrDisplayItem::Line(item.item));
+ IsContentful(false)
},
DisplayItem::BoxShadow(ref mut item) => {
item.item.common = build_common_item_properties(&item.base, state);
builder.push_item(&WrDisplayItem::BoxShadow(item.item));
+ IsContentful(false)
},
DisplayItem::PushTextShadow(ref mut item) => {
let common = build_common_item_properties(&item.base, state);
@@ -154,9 +161,11 @@ impl WebRenderDisplayItemConverter for DisplayItem {
item.shadow,
true,
);
+ IsContentful(false)
},
DisplayItem::PopAllTextShadows(_) => {
builder.push_item(&WrDisplayItem::PopAllShadows);
+ IsContentful(false)
},
DisplayItem::Iframe(ref mut item) => {
let common = build_common_item_properties(&item.base, state);
@@ -170,6 +179,7 @@ impl WebRenderDisplayItemConverter for DisplayItem {
item.iframe.to_webrender(),
true,
);
+ IsContentful(false)
},
DisplayItem::PushStackingContext(ref mut item) => {
let stacking_context = &item.stacking_context;
@@ -235,8 +245,12 @@ impl WebRenderDisplayItemConverter for DisplayItem {
};
builder.push_item(&WrDisplayItem::PushStackingContext(wr_item));
+ IsContentful(false)
+ },
+ DisplayItem::PopStackingContext(_) => {
+ builder.pop_stacking_context();
+ IsContentful(false)
},
- DisplayItem::PopStackingContext(_) => builder.pop_stacking_context(),
DisplayItem::DefineClipScrollNode(ref mut item) => {
let node = &clip_scroll_nodes[item.node_index.to_index()];
let item_rect = node.clip.main;
@@ -298,6 +312,7 @@ impl WebRenderDisplayItemConverter for DisplayItem {
unreachable!("Found DefineClipScrollNode for Placeholder type node.");
},
};
+ IsContentful(false)
},
}
}
diff --git a/components/layout_2020/display_list/items.rs b/components/layout_2020/display_list/items.rs
deleted file mode 100644
index 68ec3fcc188..00000000000
--- a/components/layout_2020/display_list/items.rs
+++ /dev/null
@@ -1,24 +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/. */
-
-use euclid::Vector2D;
-use gfx_traits;
-use std::collections::HashMap;
-use std::f32;
-use webrender_api::units::LayoutPixel;
-use webrender_api::ExternalScrollId;
-
-pub use style::dom::OpaqueNode;
-
-#[derive(Serialize)]
-pub struct DisplayList {}
-
-impl gfx_traits::DisplayList for DisplayList {
- fn is_contentful(&self) -> bool {
- false
- }
-}
-
-/// The type of the scroll offset list. This is only populated if WebRender is in use.
-pub type ScrollOffsetMap = HashMap<ExternalScrollId, Vector2D<f32, LayoutPixel>>;
diff --git a/components/layout_2020/display_list/mod.rs b/components/layout_2020/display_list/mod.rs
deleted file mode 100644
index dcdab26adb8..00000000000
--- a/components/layout_2020/display_list/mod.rs
+++ /dev/null
@@ -1,8 +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/. */
-
-pub use self::webrender_helpers::WebRenderDisplayListConverter;
-
-pub mod items;
-mod webrender_helpers;
diff --git a/components/layout_2020/display_list/webrender_helpers.rs b/components/layout_2020/display_list/webrender_helpers.rs
deleted file mode 100644
index 23ca4138e3e..00000000000
--- a/components/layout_2020/display_list/webrender_helpers.rs
+++ /dev/null
@@ -1,26 +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/. */
-
-use crate::display_list::items::DisplayList;
-use msg::constellation_msg::PipelineId;
-use webrender_api::units::LayoutSize;
-use webrender_api::{self, DisplayListBuilder};
-
-pub trait WebRenderDisplayListConverter {
- fn convert_to_webrender(&mut self, pipeline_id: PipelineId) -> DisplayListBuilder;
-}
-
-impl WebRenderDisplayListConverter for DisplayList {
- fn convert_to_webrender(&mut self, pipeline_id: PipelineId) -> DisplayListBuilder {
- let webrender_pipeline = pipeline_id.to_webrender();
-
- let builder = DisplayListBuilder::with_capacity(
- webrender_pipeline,
- LayoutSize::zero(),
- 1024 * 1024, // 1 MB of space
- );
-
- builder
- }
-}
diff --git a/components/layout_2020/fragment.rs b/components/layout_2020/fragment.rs
index f1fa89d141d..71e23b7ffaa 100644
--- a/components/layout_2020/fragment.rs
+++ b/components/layout_2020/fragment.rs
@@ -5,11 +5,11 @@
//! The `Fragment` type, which represents the leaves of the layout tree.
use crate::context::LayoutContext;
-use crate::display_list::items::OpaqueNode;
use crate::ServoArc;
use app_units::Au;
use script_layout_interface::wrapper_traits::{PseudoElementType, ThreadSafeLayoutNode};
use serde::ser::{Serialize, SerializeStruct, Serializer};
+use style::dom::OpaqueNode;
use style::logical_geometry::{LogicalMargin, LogicalRect};
use style::properties::ComputedValues;
use style::selector_parser::RestyleDamage;
diff --git a/components/layout_2020/lib.rs b/components/layout_2020/lib.rs
index e08d962df22..4af20789529 100644
--- a/components/layout_2020/lib.rs
+++ b/components/layout_2020/lib.rs
@@ -4,12 +4,8 @@
#![deny(unsafe_code)]
-#[macro_use]
-extern crate serde;
-
pub mod context;
pub mod data;
-pub mod display_list;
mod fragment;
pub mod opaque_node;
pub mod query;
diff --git a/components/layout_2020/opaque_node.rs b/components/layout_2020/opaque_node.rs
index 3d56ef21dae..36df7c640f4 100644
--- a/components/layout_2020/opaque_node.rs
+++ b/components/layout_2020/opaque_node.rs
@@ -2,9 +2,9 @@
* 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/. */
-use crate::display_list::items::OpaqueNode;
use libc::c_void;
use script_traits::UntrustedNodeAddress;
+use style::dom::OpaqueNode;
pub trait OpaqueNodeMethods {
fn to_untrusted_node_address(&self) -> UntrustedNodeAddress;
diff --git a/components/layout_2020/query.rs b/components/layout_2020/query.rs
index fc308005806..23816521c70 100644
--- a/components/layout_2020/query.rs
+++ b/components/layout_2020/query.rs
@@ -5,9 +5,9 @@
//! Utilities for querying the layout, as needed by the layout thread.
use crate::context::LayoutContext;
-use crate::display_list::items::{DisplayList, OpaqueNode, ScrollOffsetMap};
use app_units::Au;
use euclid::default::{Point2D, Rect};
+use euclid::Vector2D;
use ipc_channel::ipc::IpcSender;
use msg::constellation_msg::PipelineId;
use script_layout_interface::rpc::TextIndexResponse;
@@ -17,9 +17,12 @@ use script_layout_interface::rpc::{OffsetParentResponse, ResolvedStyleResponse,
use script_layout_interface::wrapper_traits::{LayoutNode, ThreadSafeLayoutNode};
use script_traits::LayoutMsg as ConstellationMsg;
use script_traits::UntrustedNodeAddress;
+use std::collections::HashMap;
use std::sync::{Arc, Mutex};
+use style::dom::OpaqueNode;
use style::properties::PropertyId;
use style::selector_parser::PseudoElement;
+use webrender_api::units::LayoutPixel;
use webrender_api::ExternalScrollId;
/// Mutable data belonging to the LayoutThread.
@@ -30,7 +33,7 @@ pub struct LayoutThreadData {
pub constellation_chan: IpcSender<ConstellationMsg>,
/// The root stacking context.
- pub display_list: Option<DisplayList>,
+ pub display_list: Option<webrender_api::DisplayListBuilder>,
/// A queued response for the union of the content boxes of a node.
pub content_box_response: Option<Rect<Au>>,
@@ -57,7 +60,7 @@ pub struct LayoutThreadData {
pub style_response: StyleResponse,
/// Scroll offsets of scrolling regions.
- pub scroll_offsets: ScrollOffsetMap,
+ pub scroll_offsets: HashMap<ExternalScrollId, Vector2D<f32, LayoutPixel>>,
/// Index in a text fragment. We need this do determine the insertion point.
pub text_index_response: TextIndexResponse,
diff --git a/components/layout_thread/lib.rs b/components/layout_thread/lib.rs
index 887c31f4657..e24360db2dc 100644
--- a/components/layout_thread/lib.rs
+++ b/components/layout_thread/lib.rs
@@ -45,7 +45,7 @@ use layout::context::LayoutContext;
use layout::context::RegisteredPainter;
use layout::context::RegisteredPainters;
use layout::display_list::items::{OpaqueNode, WebRenderImageInfo};
-use layout::display_list::{IndexableText, ToLayout, WebRenderDisplayListConverter};
+use layout::display_list::{IndexableText, ToLayout};
use layout::flow::{Flow, GetBaseFlow, ImmutableFlowUtils, MutableOwnedFlowUtils};
use layout::flow_ref::FlowRef;
use layout::incremental::{RelayoutMode, SpecialRestyleDamage};
@@ -1233,7 +1233,7 @@ impl LayoutThread {
debug!("Layout done!");
// TODO: Avoid the temporary conversion and build webrender sc/dl directly!
- let builder = display_list.convert_to_webrender(self.id);
+ let (builder, is_contentful) = display_list.convert_to_webrender(self.id);
let viewport_size = Size2D::new(
self.viewport_size.width.to_f32_px(),
@@ -1250,7 +1250,7 @@ impl LayoutThread {
// sending the display list to WebRender in order to set time related
// Progressive Web Metrics.
self.paint_time_metrics
- .maybe_observe_paint_time(self, epoch, &*display_list);
+ .maybe_observe_paint_time(self, epoch, is_contentful.0);
let mut txn = webrender_api::Transaction::new();
txn.set_display_list(
diff --git a/components/layout_thread_2020/lib.rs b/components/layout_thread_2020/lib.rs
index 82919fa75c1..ec31d858b9f 100644
--- a/components/layout_thread_2020/lib.rs
+++ b/components/layout_thread_2020/lib.rs
@@ -37,8 +37,6 @@ use histogram::Histogram;
use ipc_channel::ipc::{self, IpcReceiver, IpcSender};
use ipc_channel::router::ROUTER;
use layout::context::LayoutContext;
-use layout::display_list::items::DisplayList;
-use layout::display_list::WebRenderDisplayListConverter;
use layout::query::{
process_content_box_request, process_content_boxes_request, LayoutRPCImpl, LayoutThreadData,
};
@@ -1338,36 +1336,35 @@ impl LayoutThread {
document.will_paint();
}
- let mut display_list = DisplayList {};
-
- debug!("Layout done!");
-
- // TODO: Avoid the temporary conversion and build webrender sc/dl directly!
- let builder = display_list.convert_to_webrender(self.id);
-
let viewport_size = Size2D::new(
self.viewport_size.width.to_f32_px(),
self.viewport_size.height.to_f32_px(),
);
+ let viewport_size = webrender_api::units::LayoutSize::from_untyped(viewport_size);
+
+ let display_list =
+ webrender_api::DisplayListBuilder::new(self.id.to_webrender(), viewport_size);
+ let is_contentful = false;
+
+ debug!("Layout done!");
+
let mut epoch = self.epoch.get();
epoch.next();
self.epoch.set(epoch);
- let viewport_size = webrender_api::units::LayoutSize::from_untyped(viewport_size);
-
// Observe notifications about rendered frames if needed right before
// sending the display list to WebRender in order to set time related
// Progressive Web Metrics.
self.paint_time_metrics
- .maybe_observe_paint_time(self, epoch, &display_list);
+ .maybe_observe_paint_time(self, epoch, is_contentful);
let mut txn = webrender_api::Transaction::new();
txn.set_display_list(
webrender_api::Epoch(epoch.0),
None,
viewport_size,
- builder.finalize(),
+ display_list.finalize(),
true,
);
txn.generate_frame();
diff --git a/components/metrics/lib.rs b/components/metrics/lib.rs
index bfe4ad831c0..1165c8f45ca 100644
--- a/components/metrics/lib.rs
+++ b/components/metrics/lib.rs
@@ -7,7 +7,7 @@ extern crate log;
#[macro_use]
extern crate malloc_size_of_derive;
-use gfx_traits::{DisplayList, Epoch};
+use gfx_traits::Epoch;
use ipc_channel::ipc::IpcSender;
use msg::constellation_msg::PipelineId;
use profile_traits::time::TimerMetadata;
@@ -306,7 +306,7 @@ impl PaintTimeMetrics {
&self,
profiler_metadata_factory: &T,
epoch: Epoch,
- display_list: &dyn DisplayList,
+ display_list_is_contentful: bool,
) where
T: ProfilerMetadataFactory,
{
@@ -319,7 +319,7 @@ impl PaintTimeMetrics {
epoch,
(
profiler_metadata_factory.new_metadata(),
- display_list.is_contentful(),
+ display_list_is_contentful,
),
);
diff --git a/tests/unit/metrics/paint_time.rs b/tests/unit/metrics/paint_time.rs
index c404e4d6e7b..ac8ade3842c 100644
--- a/tests/unit/metrics/paint_time.rs
+++ b/tests/unit/metrics/paint_time.rs
@@ -4,13 +4,10 @@
use gfx_traits::Epoch;
use ipc_channel::ipc;
-use layout::display_list::items::{BaseDisplayItem, CommonDisplayItem, DisplayItem, DisplayList};
use metrics::{PaintTimeMetrics, ProfilerMetadataFactory, ProgressiveWebMetric};
use msg::constellation_msg::TEST_PIPELINE_ID;
use profile_traits::time::{ProfilerChan, TimerMetadata};
use servo_url::ServoUrl;
-use webrender_api::units::{LayoutRect, LayoutSize};
-use webrender_api::{AlphaType, ColorF, ImageDisplayItem, ImageKey, ImageRendering};
struct DummyProfilerMetadataFactory {}
impl ProfilerMetadataFactory for DummyProfilerMetadataFactory {
@@ -49,7 +46,7 @@ fn test_paint_metrics_construction() {
);
}
-fn test_common(display_list: &DisplayList, epoch: Epoch) -> PaintTimeMetrics {
+fn test_common(display_list_is_contentful: bool, epoch: Epoch) -> PaintTimeMetrics {
let (sender, _) = ipc::channel().unwrap();
let profiler_chan = ProfilerChan(sender);
let (layout_sender, _) = ipc::channel().unwrap();
@@ -66,7 +63,7 @@ fn test_common(display_list: &DisplayList, epoch: Epoch) -> PaintTimeMetrics {
paint_time_metrics.maybe_observe_paint_time(
&dummy_profiler_metadata_factory,
epoch,
- &*display_list,
+ display_list_is_contentful,
);
// Should not set any metric until navigation start is set.
@@ -95,12 +92,8 @@ fn test_common(display_list: &DisplayList, epoch: Epoch) -> PaintTimeMetrics {
#[test]
fn test_first_paint_setter() {
- let empty_display_list = DisplayList {
- list: Vec::new(),
- clip_scroll_nodes: Vec::new(),
- };
let epoch = Epoch(0);
- let paint_time_metrics = test_common(&empty_display_list, epoch);
+ let paint_time_metrics = test_common(false, epoch);
let now = time::precise_time_ns();
paint_time_metrics.maybe_set_metric(epoch, now);
assert!(
@@ -116,25 +109,8 @@ fn test_first_paint_setter() {
#[test]
fn test_first_contentful_paint_setter() {
- let image = DisplayItem::Image(CommonDisplayItem::new(
- BaseDisplayItem::empty(),
- ImageDisplayItem {
- bounds: LayoutRect::zero(),
- common: layout::display_list::items::empty_common_item_properties(),
- image_key: ImageKey::DUMMY,
- stretch_size: LayoutSize::zero(),
- tile_spacing: LayoutSize::zero(),
- image_rendering: ImageRendering::Auto,
- alpha_type: AlphaType::PremultipliedAlpha,
- color: ColorF::WHITE,
- },
- ));
- let display_list = DisplayList {
- list: vec![image],
- clip_scroll_nodes: Vec::new(),
- };
let epoch = Epoch(0);
- let paint_time_metrics = test_common(&display_list, epoch);
+ let paint_time_metrics = test_common(true, epoch);
let now = time::precise_time_ns();
paint_time_metrics.maybe_set_metric(epoch, now);
assert!(