mirror of
https://github.com/servo/servo.git
synced 2025-08-03 04:30:10 +01:00
Always send epochs to webrender in layout 2020
This commit is contained in:
parent
b6cdf93198
commit
6876245858
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::router::ROUTER;
|
||||
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::flow::{Flow, GetBaseFlow};
|
||||
use layout::flow_ref::FlowRef;
|
||||
|
@ -772,7 +772,7 @@ impl LayoutThread {
|
|||
|| 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) => {
|
||||
self.set_scroll_states(new_scroll_states, possibly_locked_rw_data);
|
||||
},
|
||||
|
@ -803,7 +803,7 @@ impl LayoutThread {
|
|||
sender.send(self.epoch.get()).unwrap();
|
||||
},
|
||||
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) => {
|
||||
let _rw_data = possibly_locked_rw_data.lock();
|
||||
|
@ -957,15 +957,10 @@ impl LayoutThread {
|
|||
}
|
||||
|
||||
/// Advances the animation clock of the document.
|
||||
fn handle_advance_clock_ms<'a, 'b>(
|
||||
&mut self,
|
||||
how_many_ms: i32,
|
||||
possibly_locked_rw_data: &mut RwData<'a, 'b>,
|
||||
tick_animations: bool,
|
||||
) {
|
||||
fn handle_advance_clock_ms<'a, 'b>(&mut self, how_many_ms: i32, tick_animations: bool) {
|
||||
self.timer.increment(how_many_ms as f64 / 1000.0);
|
||||
if tick_animations {
|
||||
self.tick_all_animations(possibly_locked_rw_data);
|
||||
self.tick_all_animations();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -978,86 +973,6 @@ impl LayoutThread {
|
|||
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.
|
||||
fn handle_reflow<'a, 'b>(
|
||||
&mut self,
|
||||
|
@ -1362,14 +1277,7 @@ impl LayoutThread {
|
|||
}
|
||||
|
||||
// Perform post-style recalculation layout passes.
|
||||
if let Some(mut root_flow) = self.root_flow.borrow().clone() {
|
||||
self.perform_post_style_recalc_layout_passes(
|
||||
&mut root_flow,
|
||||
&data.reflow_goal,
|
||||
Some(&document),
|
||||
&mut rw_data,
|
||||
);
|
||||
}
|
||||
self.perform_post_style_recalc_layout_passes(&data.reflow_goal, Some(&document));
|
||||
|
||||
self.first_reflow.set(false);
|
||||
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
|
||||
}
|
||||
|
||||
fn tick_all_animations<'a, 'b>(&mut self, possibly_locked_rw_data: &mut RwData<'a, 'b>) {
|
||||
let mut rw_data = possibly_locked_rw_data.lock();
|
||||
self.tick_animations(&mut rw_data);
|
||||
fn tick_all_animations<'a, 'b>(&mut self) {
|
||||
self.tick_animations();
|
||||
}
|
||||
|
||||
fn tick_animations(&mut self, rw_data: &mut LayoutThreadData) {
|
||||
fn tick_animations(&mut self) {
|
||||
if self.relayout_event {
|
||||
println!(
|
||||
"**** pipeline={}\tForDisplay\tSpecial\tAnimationTick",
|
||||
|
@ -1494,10 +1401,7 @@ impl LayoutThread {
|
|||
);
|
||||
}
|
||||
|
||||
if let Some(mut root_flow) = self.root_flow.borrow().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();
|
||||
if let Some(author_shared_lock) = self.document_shared_lock.clone() {
|
||||
let author_guard = author_shared_lock.read();
|
||||
let ua_or_user_guard = UA_STYLESHEETS.shared_lock.read();
|
||||
let _guards = StylesheetGuards {
|
||||
|
@ -1505,46 +1409,64 @@ impl LayoutThread {
|
|||
ua_or_user: &ua_or_user_guard,
|
||||
};
|
||||
|
||||
self.perform_post_style_recalc_layout_passes(
|
||||
&mut root_flow,
|
||||
&ReflowGoal::TickAnimations,
|
||||
None,
|
||||
&mut *rw_data,
|
||||
);
|
||||
self.perform_post_style_recalc_layout_passes(&ReflowGoal::TickAnimations, None);
|
||||
}
|
||||
}
|
||||
|
||||
fn perform_post_style_recalc_layout_passes(
|
||||
&self,
|
||||
root_flow: &mut FlowRef,
|
||||
reflow_goal: &ReflowGoal,
|
||||
document: Option<&ServoLayoutDocument>,
|
||||
rw_data: &mut LayoutThreadData,
|
||||
) {
|
||||
profile(
|
||||
profile_time::ProfilerCategory::LayoutRestyleDamagePropagation,
|
||||
self.profiler_metadata(),
|
||||
self.time_profiler_chan.clone(),
|
||||
|| {},
|
||||
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 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(
|
||||
&self,
|
||||
mut root_flow: &mut FlowRef,
|
||||
reflow_goal: &ReflowGoal,
|
||||
document: Option<&ServoLayoutDocument>,
|
||||
rw_data: &mut LayoutThreadData,
|
||||
) {
|
||||
// Build the display list if necessary, and send it to the painter.
|
||||
self.compute_abs_pos_and_build_display_list(
|
||||
reflow_goal,
|
||||
document,
|
||||
FlowRef::deref_mut(&mut root_flow),
|
||||
rw_data,
|
||||
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);
|
||||
|
||||
self.generation.set(self.generation.get() + 1);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue