mirror of
https://github.com/servo/servo.git
synced 2025-08-05 13:40:08 +01:00
Auto merge of #23940 - servo:fix-layout-2020, r=emilio
Always send epochs to webrender in layout 2020 <!-- Reviewable:start --> This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/23940) <!-- Reviewable:end -->
This commit is contained in:
commit
b01a4d0e29
1 changed files with 56 additions and 134 deletions
|
@ -37,7 +37,7 @@ use histogram::Histogram;
|
||||||
use ipc_channel::ipc::{self, IpcReceiver, IpcSender};
|
use ipc_channel::ipc::{self, IpcReceiver, IpcSender};
|
||||||
use ipc_channel::router::ROUTER;
|
use ipc_channel::router::ROUTER;
|
||||||
use layout::context::LayoutContext;
|
use layout::context::LayoutContext;
|
||||||
use layout::display_list::items::OpaqueNode;
|
use layout::display_list::items::{DisplayList, OpaqueNode};
|
||||||
use layout::display_list::{IndexableText, WebRenderDisplayListConverter};
|
use layout::display_list::{IndexableText, WebRenderDisplayListConverter};
|
||||||
use layout::flow::{Flow, GetBaseFlow};
|
use layout::flow::{Flow, GetBaseFlow};
|
||||||
use layout::flow_ref::FlowRef;
|
use layout::flow_ref::FlowRef;
|
||||||
|
@ -772,7 +772,7 @@ impl LayoutThread {
|
||||||
|| self.handle_reflow(&mut data, possibly_locked_rw_data),
|
|| self.handle_reflow(&mut data, possibly_locked_rw_data),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
Msg::TickAnimations => self.tick_all_animations(possibly_locked_rw_data),
|
Msg::TickAnimations => self.tick_all_animations(),
|
||||||
Msg::SetScrollStates(new_scroll_states) => {
|
Msg::SetScrollStates(new_scroll_states) => {
|
||||||
self.set_scroll_states(new_scroll_states, possibly_locked_rw_data);
|
self.set_scroll_states(new_scroll_states, possibly_locked_rw_data);
|
||||||
},
|
},
|
||||||
|
@ -803,7 +803,7 @@ impl LayoutThread {
|
||||||
sender.send(self.epoch.get()).unwrap();
|
sender.send(self.epoch.get()).unwrap();
|
||||||
},
|
},
|
||||||
Msg::AdvanceClockMs(how_many, do_tick) => {
|
Msg::AdvanceClockMs(how_many, do_tick) => {
|
||||||
self.handle_advance_clock_ms(how_many, possibly_locked_rw_data, do_tick);
|
self.handle_advance_clock_ms(how_many, do_tick);
|
||||||
},
|
},
|
||||||
Msg::GetWebFontLoadState(sender) => {
|
Msg::GetWebFontLoadState(sender) => {
|
||||||
let _rw_data = possibly_locked_rw_data.lock();
|
let _rw_data = possibly_locked_rw_data.lock();
|
||||||
|
@ -957,15 +957,10 @@ impl LayoutThread {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Advances the animation clock of the document.
|
/// Advances the animation clock of the document.
|
||||||
fn handle_advance_clock_ms<'a, 'b>(
|
fn handle_advance_clock_ms<'a, 'b>(&mut self, how_many_ms: i32, tick_animations: bool) {
|
||||||
&mut self,
|
|
||||||
how_many_ms: i32,
|
|
||||||
possibly_locked_rw_data: &mut RwData<'a, 'b>,
|
|
||||||
tick_animations: bool,
|
|
||||||
) {
|
|
||||||
self.timer.increment(how_many_ms as f64 / 1000.0);
|
self.timer.increment(how_many_ms as f64 / 1000.0);
|
||||||
if tick_animations {
|
if tick_animations {
|
||||||
self.tick_all_animations(possibly_locked_rw_data);
|
self.tick_all_animations();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -978,86 +973,6 @@ impl LayoutThread {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Computes the stacking-relative positions of all flows and, if the painting is dirty and the
|
|
||||||
/// reflow type need it, builds the display list.
|
|
||||||
fn compute_abs_pos_and_build_display_list(
|
|
||||||
&self,
|
|
||||||
reflow_goal: &ReflowGoal,
|
|
||||||
document: Option<&ServoLayoutDocument>,
|
|
||||||
layout_root: &mut dyn Flow,
|
|
||||||
rw_data: &mut LayoutThreadData,
|
|
||||||
) {
|
|
||||||
let (metadata, sender) = (self.profiler_metadata(), self.time_profiler_chan.clone());
|
|
||||||
profile(
|
|
||||||
profile_time::ProfilerCategory::LayoutDispListBuild,
|
|
||||||
metadata.clone(),
|
|
||||||
sender.clone(),
|
|
||||||
|| {
|
|
||||||
if layout_root
|
|
||||||
.base()
|
|
||||||
.restyle_damage
|
|
||||||
.contains(ServoRestyleDamage::REPAINT) ||
|
|
||||||
rw_data.display_list.is_none()
|
|
||||||
{
|
|
||||||
layout_root
|
|
||||||
.mut_base()
|
|
||||||
.restyle_damage
|
|
||||||
.remove(ServoRestyleDamage::REPAINT);
|
|
||||||
}
|
|
||||||
|
|
||||||
if !reflow_goal.needs_display() {
|
|
||||||
// Defer the paint step until the next ForDisplay.
|
|
||||||
//
|
|
||||||
// We need to tell the document about this so it doesn't
|
|
||||||
// incorrectly suppress reflows. See #13131.
|
|
||||||
document
|
|
||||||
.expect("No document in a non-display reflow?")
|
|
||||||
.needs_paint_from_layout();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if let Some(document) = document {
|
|
||||||
document.will_paint();
|
|
||||||
}
|
|
||||||
|
|
||||||
let display_list = rw_data.display_list.as_mut().unwrap();
|
|
||||||
|
|
||||||
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 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);
|
|
||||||
|
|
||||||
let mut txn = webrender_api::Transaction::new();
|
|
||||||
txn.set_display_list(
|
|
||||||
webrender_api::Epoch(epoch.0),
|
|
||||||
None,
|
|
||||||
viewport_size,
|
|
||||||
builder.finalize(),
|
|
||||||
true,
|
|
||||||
);
|
|
||||||
txn.generate_frame();
|
|
||||||
self.webrender_api
|
|
||||||
.send_transaction(self.webrender_document, txn);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// The high-level routine that performs layout threads.
|
/// The high-level routine that performs layout threads.
|
||||||
fn handle_reflow<'a, 'b>(
|
fn handle_reflow<'a, 'b>(
|
||||||
&mut self,
|
&mut self,
|
||||||
|
@ -1362,14 +1277,7 @@ impl LayoutThread {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Perform post-style recalculation layout passes.
|
// Perform post-style recalculation layout passes.
|
||||||
if let Some(mut root_flow) = self.root_flow.borrow().clone() {
|
self.perform_post_style_recalc_layout_passes(&data.reflow_goal, Some(&document));
|
||||||
self.perform_post_style_recalc_layout_passes(
|
|
||||||
&mut root_flow,
|
|
||||||
&data.reflow_goal,
|
|
||||||
Some(&document),
|
|
||||||
&mut rw_data,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
self.first_reflow.set(false);
|
self.first_reflow.set(false);
|
||||||
self.respond_to_query_if_necessary(&data.reflow_goal, &mut *rw_data, &mut layout_context);
|
self.respond_to_query_if_necessary(&data.reflow_goal, &mut *rw_data, &mut layout_context);
|
||||||
|
@ -1481,12 +1389,11 @@ impl LayoutThread {
|
||||||
rw_data.scroll_offsets = layout_scroll_states
|
rw_data.scroll_offsets = layout_scroll_states
|
||||||
}
|
}
|
||||||
|
|
||||||
fn tick_all_animations<'a, 'b>(&mut self, possibly_locked_rw_data: &mut RwData<'a, 'b>) {
|
fn tick_all_animations<'a, 'b>(&mut self) {
|
||||||
let mut rw_data = possibly_locked_rw_data.lock();
|
self.tick_animations();
|
||||||
self.tick_animations(&mut rw_data);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn tick_animations(&mut self, rw_data: &mut LayoutThreadData) {
|
fn tick_animations(&mut self) {
|
||||||
if self.relayout_event {
|
if self.relayout_event {
|
||||||
println!(
|
println!(
|
||||||
"**** pipeline={}\tForDisplay\tSpecial\tAnimationTick",
|
"**** pipeline={}\tForDisplay\tSpecial\tAnimationTick",
|
||||||
|
@ -1494,10 +1401,7 @@ impl LayoutThread {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(mut root_flow) = self.root_flow.borrow().clone() {
|
if let Some(author_shared_lock) = self.document_shared_lock.clone() {
|
||||||
// Unwrap here should not panic since self.root_flow is only ever set to Some(_)
|
|
||||||
// in handle_reflow() where self.document_shared_lock is as well.
|
|
||||||
let author_shared_lock = self.document_shared_lock.clone().unwrap();
|
|
||||||
let author_guard = author_shared_lock.read();
|
let author_guard = author_shared_lock.read();
|
||||||
let ua_or_user_guard = UA_STYLESHEETS.shared_lock.read();
|
let ua_or_user_guard = UA_STYLESHEETS.shared_lock.read();
|
||||||
let _guards = StylesheetGuards {
|
let _guards = StylesheetGuards {
|
||||||
|
@ -1505,46 +1409,64 @@ impl LayoutThread {
|
||||||
ua_or_user: &ua_or_user_guard,
|
ua_or_user: &ua_or_user_guard,
|
||||||
};
|
};
|
||||||
|
|
||||||
self.perform_post_style_recalc_layout_passes(
|
self.perform_post_style_recalc_layout_passes(&ReflowGoal::TickAnimations, None);
|
||||||
&mut root_flow,
|
|
||||||
&ReflowGoal::TickAnimations,
|
|
||||||
None,
|
|
||||||
&mut *rw_data,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn perform_post_style_recalc_layout_passes(
|
fn perform_post_style_recalc_layout_passes(
|
||||||
&self,
|
&self,
|
||||||
root_flow: &mut FlowRef,
|
|
||||||
reflow_goal: &ReflowGoal,
|
reflow_goal: &ReflowGoal,
|
||||||
document: Option<&ServoLayoutDocument>,
|
document: Option<&ServoLayoutDocument>,
|
||||||
rw_data: &mut LayoutThreadData,
|
|
||||||
) {
|
) {
|
||||||
profile(
|
if !reflow_goal.needs_display() {
|
||||||
profile_time::ProfilerCategory::LayoutRestyleDamagePropagation,
|
// Defer the paint step until the next ForDisplay.
|
||||||
self.profiler_metadata(),
|
//
|
||||||
self.time_profiler_chan.clone(),
|
// We need to tell the document about this so it doesn't
|
||||||
|| {},
|
// incorrectly suppress reflows. See #13131.
|
||||||
|
document
|
||||||
|
.expect("No document in a non-display reflow?")
|
||||||
|
.needs_paint_from_layout();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if let Some(document) = document {
|
||||||
|
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(),
|
||||||
);
|
);
|
||||||
|
|
||||||
self.perform_post_main_layout_passes(root_flow, reflow_goal, document, rw_data);
|
let mut epoch = self.epoch.get();
|
||||||
}
|
epoch.next();
|
||||||
|
self.epoch.set(epoch);
|
||||||
|
|
||||||
fn perform_post_main_layout_passes(
|
let viewport_size = webrender_api::units::LayoutSize::from_untyped(viewport_size);
|
||||||
&self,
|
|
||||||
mut root_flow: &mut FlowRef,
|
// Observe notifications about rendered frames if needed right before
|
||||||
reflow_goal: &ReflowGoal,
|
// sending the display list to WebRender in order to set time related
|
||||||
document: Option<&ServoLayoutDocument>,
|
// Progressive Web Metrics.
|
||||||
rw_data: &mut LayoutThreadData,
|
self.paint_time_metrics
|
||||||
) {
|
.maybe_observe_paint_time(self, epoch, &display_list);
|
||||||
// Build the display list if necessary, and send it to the painter.
|
|
||||||
self.compute_abs_pos_and_build_display_list(
|
let mut txn = webrender_api::Transaction::new();
|
||||||
reflow_goal,
|
txn.set_display_list(
|
||||||
document,
|
webrender_api::Epoch(epoch.0),
|
||||||
FlowRef::deref_mut(&mut root_flow),
|
None,
|
||||||
rw_data,
|
viewport_size,
|
||||||
|
builder.finalize(),
|
||||||
|
true,
|
||||||
);
|
);
|
||||||
|
txn.generate_frame();
|
||||||
|
self.webrender_api
|
||||||
|
.send_transaction(self.webrender_document, txn);
|
||||||
|
|
||||||
self.generation.set(self.generation.get() + 1);
|
self.generation.set(self.generation.get() + 1);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue