mirror of
https://github.com/servo/servo.git
synced 2025-06-06 16:45:39 +00:00
Clean up and document the send_display_list
interface
This moves more members to the CompositorDisplayListInfo struct, which now holds all miscellaneous, non-WebRender data when sending display lists. It also documents what each things sent with a display list does.
This commit is contained in:
parent
0377a1853a
commit
4d3625ec80
8 changed files with 85 additions and 79 deletions
|
@ -662,31 +662,32 @@ impl<Window: WindowMethods + ?Sized> IOCompositor<Window> {
|
|||
.send_transaction(self.webrender_document, txn);
|
||||
},
|
||||
|
||||
WebrenderMsg::Layout(script_traits::WebrenderMsg::SendDisplayList(
|
||||
epoch,
|
||||
size,
|
||||
pipeline,
|
||||
size2,
|
||||
receiver,
|
||||
descriptor,
|
||||
compositor_display_list_info,
|
||||
)) => match receiver.recv() {
|
||||
WebrenderMsg::Layout(script_traits::WebrenderMsg::SendDisplayList {
|
||||
display_list_info,
|
||||
content_size,
|
||||
display_list_descriptor,
|
||||
display_list_receiver,
|
||||
}) => match display_list_receiver.recv() {
|
||||
Ok(data) => {
|
||||
self.waiting_on_pending_frame = true;
|
||||
|
||||
let details = self.pipeline_details(PipelineId::from_webrender(pipeline));
|
||||
details.hit_test_items = compositor_display_list_info.hit_test_info;
|
||||
details.install_new_scroll_tree(compositor_display_list_info.scroll_tree);
|
||||
let pipeline_id = display_list_info.pipeline_id;
|
||||
let details = self.pipeline_details(PipelineId::from_webrender(pipeline_id));
|
||||
details.hit_test_items = display_list_info.hit_test_info;
|
||||
details.install_new_scroll_tree(display_list_info.scroll_tree);
|
||||
|
||||
let mut txn = webrender_api::Transaction::new();
|
||||
txn.set_display_list(
|
||||
epoch,
|
||||
display_list_info.epoch,
|
||||
None,
|
||||
size,
|
||||
display_list_info.viewport_size,
|
||||
(
|
||||
pipeline,
|
||||
size2,
|
||||
webrender_api::BuiltDisplayList::from_data(data, descriptor),
|
||||
pipeline_id,
|
||||
content_size,
|
||||
webrender_api::BuiltDisplayList::from_data(
|
||||
data,
|
||||
display_list_descriptor,
|
||||
),
|
||||
),
|
||||
true,
|
||||
);
|
||||
|
@ -694,7 +695,7 @@ impl<Window: WindowMethods + ?Sized> IOCompositor<Window> {
|
|||
self.webrender_api
|
||||
.send_transaction(self.webrender_document, txn);
|
||||
},
|
||||
Err(e) => warn!("error receiving display data: {:?}", e),
|
||||
Err(e) => warn!("error receiving display list data: {e:?}"),
|
||||
},
|
||||
|
||||
WebrenderMsg::Layout(script_traits::WebrenderMsg::HitTest(
|
||||
|
|
|
@ -28,6 +28,12 @@ impl Epoch {
|
|||
}
|
||||
}
|
||||
|
||||
impl Into<webrender_api::Epoch> for Epoch {
|
||||
fn into(self) -> webrender_api::Epoch {
|
||||
webrender_api::Epoch(self.0)
|
||||
}
|
||||
}
|
||||
|
||||
/// A unique ID for every stacking context.
|
||||
#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, MallocSizeOf, PartialEq, Serialize)]
|
||||
pub struct StackingContextId(
|
||||
|
|
|
@ -13,7 +13,7 @@ use msg::constellation_msg::PipelineId;
|
|||
use script_traits::compositor::{CompositorDisplayListInfo, ScrollTreeNodeId, ScrollableNodeInfo};
|
||||
use webrender_api::units::{LayoutPoint, LayoutSize, LayoutVector2D};
|
||||
use webrender_api::{
|
||||
self, ClipId, CommonItemProperties, DisplayItem as WrDisplayItem, DisplayListBuilder,
|
||||
self, ClipId, CommonItemProperties, DisplayItem as WrDisplayItem, DisplayListBuilder, Epoch,
|
||||
PrimitiveFlags, PropertyBinding, PushStackingContextDisplayItem, RasterSpace,
|
||||
ReferenceFrameKind, SpaceAndClipInfo, SpatialId, StackingContext,
|
||||
};
|
||||
|
@ -25,20 +25,11 @@ struct ClipScrollState {
|
|||
}
|
||||
|
||||
impl ClipScrollState {
|
||||
fn new(
|
||||
size: usize,
|
||||
content_size: LayoutSize,
|
||||
viewport_size: LayoutSize,
|
||||
pipeline_id: webrender_api::PipelineId,
|
||||
) -> Self {
|
||||
fn new(size: usize, compositor_info: CompositorDisplayListInfo) -> Self {
|
||||
let mut state = ClipScrollState {
|
||||
clip_ids: vec![None; size],
|
||||
scroll_node_ids: vec![None; size],
|
||||
compositor_info: CompositorDisplayListInfo::new(
|
||||
viewport_size,
|
||||
content_size,
|
||||
pipeline_id,
|
||||
),
|
||||
compositor_info,
|
||||
};
|
||||
|
||||
// We need to register the WebRender root reference frame and root scroll node ids
|
||||
|
@ -49,7 +40,7 @@ impl ClipScrollState {
|
|||
state.scroll_node_ids[0] = Some(state.compositor_info.root_reference_frame_id);
|
||||
state.scroll_node_ids[1] = Some(state.compositor_info.root_scroll_node_id);
|
||||
|
||||
let root_clip_id = ClipId::root(pipeline_id);
|
||||
let root_clip_id = ClipId::root(state.compositor_info.pipeline_id);
|
||||
state.add_clip_node_mapping(0, root_clip_id);
|
||||
state.add_clip_node_mapping(1, root_clip_id);
|
||||
|
||||
|
@ -106,13 +97,17 @@ impl DisplayList {
|
|||
&mut self,
|
||||
pipeline_id: PipelineId,
|
||||
viewport_size: LayoutSize,
|
||||
epoch: Epoch,
|
||||
) -> (DisplayListBuilder, CompositorDisplayListInfo, IsContentful) {
|
||||
let webrender_pipeline = pipeline_id.to_webrender();
|
||||
let mut state = ClipScrollState::new(
|
||||
self.clip_scroll_nodes.len(),
|
||||
self.bounds().size,
|
||||
viewport_size,
|
||||
webrender_pipeline,
|
||||
CompositorDisplayListInfo::new(
|
||||
viewport_size,
|
||||
self.bounds().size,
|
||||
webrender_pipeline,
|
||||
epoch,
|
||||
),
|
||||
);
|
||||
|
||||
let mut builder = DisplayListBuilder::with_capacity(
|
||||
|
|
|
@ -70,6 +70,7 @@ impl DisplayList {
|
|||
viewport_size: units::LayoutSize,
|
||||
content_size: units::LayoutSize,
|
||||
pipeline_id: wr::PipelineId,
|
||||
epoch: wr::Epoch,
|
||||
) -> Self {
|
||||
Self {
|
||||
wr: wr::DisplayListBuilder::new(pipeline_id, content_size),
|
||||
|
@ -77,6 +78,7 @@ impl DisplayList {
|
|||
viewport_size,
|
||||
content_size,
|
||||
pipeline_id,
|
||||
epoch,
|
||||
),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1069,26 +1069,22 @@ impl LayoutThread {
|
|||
self.viewport_size.height.to_f32_px(),
|
||||
);
|
||||
|
||||
// TODO: Avoid the temporary conversion and build webrender sc/dl directly!
|
||||
let (builder, compositor_info, is_contentful) =
|
||||
display_list.convert_to_webrender(self.id, viewport_size);
|
||||
|
||||
let mut epoch = self.epoch.get();
|
||||
epoch.next();
|
||||
self.epoch.set(epoch);
|
||||
|
||||
// TODO: Avoid the temporary conversion and build webrender sc/dl directly!
|
||||
let (builder, compositor_info, is_contentful) =
|
||||
display_list.convert_to_webrender(self.id, viewport_size, epoch.into());
|
||||
|
||||
// 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, is_contentful.0);
|
||||
|
||||
self.webrender_api.send_display_list(
|
||||
epoch,
|
||||
viewport_size,
|
||||
compositor_info,
|
||||
builder.finalize(),
|
||||
);
|
||||
self.webrender_api
|
||||
.send_display_list(compositor_info, builder.finalize());
|
||||
},
|
||||
);
|
||||
}
|
||||
|
|
|
@ -1264,6 +1264,10 @@ impl LayoutThread {
|
|||
document.will_paint();
|
||||
}
|
||||
|
||||
let mut epoch = self.epoch.get();
|
||||
epoch.next();
|
||||
self.epoch.set(epoch);
|
||||
|
||||
let viewport_size = webrender_api::units::LayoutSize::from_untyped(Size2D::new(
|
||||
self.viewport_size.width.to_f32_px(),
|
||||
self.viewport_size.height.to_f32_px(),
|
||||
|
@ -1272,6 +1276,7 @@ impl LayoutThread {
|
|||
viewport_size,
|
||||
fragment_tree.scrollable_overflow(),
|
||||
self.id.to_webrender(),
|
||||
epoch.into(),
|
||||
);
|
||||
|
||||
// `dump_serialized_display_list` doesn't actually print anything. It sets up
|
||||
|
@ -1296,22 +1301,14 @@ impl LayoutThread {
|
|||
}
|
||||
debug!("Layout done!");
|
||||
|
||||
let mut epoch = self.epoch.get();
|
||||
epoch.next();
|
||||
self.epoch.set(epoch);
|
||||
|
||||
// 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, is_contentful);
|
||||
|
||||
self.webrender_api.send_display_list(
|
||||
epoch,
|
||||
viewport_size,
|
||||
display_list.compositor_info,
|
||||
display_list.wr.finalize(),
|
||||
);
|
||||
self.webrender_api
|
||||
.send_display_list(display_list.compositor_info, display_list.wr.finalize());
|
||||
|
||||
self.update_iframe_sizes(iframe_sizes);
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
use embedder_traits::Cursor;
|
||||
use webrender_api::{
|
||||
units::{LayoutSize, LayoutVector2D},
|
||||
ExternalScrollId, ScrollLocation, ScrollSensitivity, SpatialId,
|
||||
Epoch, ExternalScrollId, PipelineId, ScrollLocation, ScrollSensitivity, SpatialId,
|
||||
};
|
||||
|
||||
/// Information that Servo keeps alongside WebRender display items
|
||||
|
@ -213,6 +213,15 @@ impl ScrollTree {
|
|||
/// display lists sent to the compositor.
|
||||
#[derive(Debug, Deserialize, Serialize)]
|
||||
pub struct CompositorDisplayListInfo {
|
||||
/// The WebRender [PipelineId] of this display list.
|
||||
pub pipeline_id: PipelineId,
|
||||
|
||||
/// The size of the viewport that this display list renders into.
|
||||
pub viewport_size: LayoutSize,
|
||||
|
||||
/// The epoch of the display list.
|
||||
pub epoch: Epoch,
|
||||
|
||||
/// An array of `HitTestInfo` which is used to store information
|
||||
/// to assist the compositor to take various actions (set the cursor,
|
||||
/// scroll without layout) using a WebRender hit test result.
|
||||
|
@ -237,7 +246,8 @@ impl CompositorDisplayListInfo {
|
|||
pub fn new(
|
||||
viewport_size: LayoutSize,
|
||||
content_size: LayoutSize,
|
||||
pipeline_id: webrender_api::PipelineId,
|
||||
pipeline_id: PipelineId,
|
||||
epoch: Epoch,
|
||||
) -> Self {
|
||||
let mut scroll_tree = ScrollTree::default();
|
||||
let root_reference_frame_id = scroll_tree.add_scroll_tree_node(
|
||||
|
@ -257,6 +267,9 @@ impl CompositorDisplayListInfo {
|
|||
);
|
||||
|
||||
CompositorDisplayListInfo {
|
||||
pipeline_id,
|
||||
viewport_size,
|
||||
epoch,
|
||||
hit_test_info: Default::default(),
|
||||
scroll_tree,
|
||||
root_reference_frame_id,
|
||||
|
|
|
@ -1132,15 +1132,16 @@ pub enum WebrenderMsg {
|
|||
/// Perform a scroll operation.
|
||||
SendScrollNode(LayoutPoint, ExternalScrollId, ScrollClamping),
|
||||
/// Inform WebRender of a new display list for the given pipeline.
|
||||
SendDisplayList(
|
||||
webrender_api::Epoch,
|
||||
LayoutSize,
|
||||
webrender_api::PipelineId,
|
||||
LayoutSize,
|
||||
ipc::IpcBytesReceiver,
|
||||
BuiltDisplayListDescriptor,
|
||||
CompositorDisplayListInfo,
|
||||
),
|
||||
SendDisplayList {
|
||||
/// The [CompositorDisplayListInfo] that describes the display list being sent.
|
||||
display_list_info: CompositorDisplayListInfo,
|
||||
/// The content size of this display list as calculated by WebRender.
|
||||
content_size: LayoutSize,
|
||||
/// A descriptor of this display list used to construct this display list from raw data.
|
||||
display_list_descriptor: BuiltDisplayListDescriptor,
|
||||
/// An [ipc::IpcBytesReceiver] used to send the raw data of the display list.
|
||||
display_list_receiver: ipc::IpcBytesReceiver,
|
||||
},
|
||||
/// Perform a hit test operation. The result will be returned via
|
||||
/// the provided channel sender.
|
||||
HitTest(
|
||||
|
@ -1191,26 +1192,21 @@ impl WebrenderIpcSender {
|
|||
/// Inform WebRender of a new display list for the given pipeline.
|
||||
pub fn send_display_list(
|
||||
&self,
|
||||
epoch: Epoch,
|
||||
size: LayoutSize,
|
||||
display_list_info: CompositorDisplayListInfo,
|
||||
(pipeline, size2, list): (webrender_api::PipelineId, LayoutSize, BuiltDisplayList),
|
||||
(_, content_size, list): (webrender_api::PipelineId, LayoutSize, BuiltDisplayList),
|
||||
) {
|
||||
let (data, descriptor) = list.into_data();
|
||||
let (sender, receiver) = ipc::bytes_channel().unwrap();
|
||||
if let Err(e) = self.0.send(WebrenderMsg::SendDisplayList(
|
||||
webrender_api::Epoch(epoch.0),
|
||||
size,
|
||||
pipeline,
|
||||
size2,
|
||||
receiver,
|
||||
descriptor,
|
||||
let (display_list_data, display_list_descriptor) = list.into_data();
|
||||
let (display_list_sender, display_list_receiver) = ipc::bytes_channel().unwrap();
|
||||
if let Err(e) = self.0.send(WebrenderMsg::SendDisplayList {
|
||||
display_list_info,
|
||||
)) {
|
||||
content_size,
|
||||
display_list_descriptor,
|
||||
display_list_receiver,
|
||||
}) {
|
||||
warn!("Error sending display list: {}", e);
|
||||
}
|
||||
|
||||
if let Err(e) = sender.send(&data) {
|
||||
if let Err(e) = display_list_sender.send(&display_list_data) {
|
||||
warn!("Error sending display data: {}", e);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue