mirror of
https://github.com/servo/servo.git
synced 2025-08-06 14:10:11 +01:00
script: Allow reflows that do not produce display lists (#37186)
This change has two parts which depend on each other: 1. An early exit in the layout process, which allows for skipping display list construction entirely when nothing would change. 2. A simplification and unification of the way that "fake" animation frames are triggered. Now this happens on an entire ScriptThread at once and is based on whether or not any Pipeline triggered a display list update. Animations are never canceled in the compositor when the Pipeline isn't updating, instead the fake animation frame is triggered far enough in the future that an unexpected compositor tick will cancel it. This could happen, for instance, if some other Pipeline in some other ScriptThread produced a new display list for a tick. This makes everything simpler about these ticks. The goal is that in a future change the ScriptThread-based animation ticks will be made more generic so that they can throttle the number of "update the rendering" calls triggered by script. This should make Servo do a lot less work when moving the cursor over a page. Before it would constantly produce new display lists. Fixes: #17029. Testing: This should not cause any web observable changes. The fact that all WPT tests keep passing is the test for this change. Signed-off-by: Martin Robinson <mrobinson@igalia.com> Co-authored-by: Oriol Brufau <obrufau@igalia.com>
This commit is contained in:
parent
29fc878e15
commit
23acb623c8
11 changed files with 257 additions and 234 deletions
|
@ -2143,7 +2143,7 @@ impl Window {
|
|||
/// no reflow is performed. If reflow is suppressed, no reflow will be performed for ForDisplay
|
||||
/// goals.
|
||||
///
|
||||
/// Returns true if layout actually happened, false otherwise.
|
||||
/// Returns true if layout actually happened and it sent a new display list to the renderer.
|
||||
///
|
||||
/// NOTE: This method should almost never be called directly! Layout and rendering updates should
|
||||
/// happen as part of the HTML event loop via *update the rendering*.
|
||||
|
@ -2309,16 +2309,21 @@ impl Window {
|
|||
document.update_animations_post_reflow();
|
||||
self.update_constellation_epoch();
|
||||
|
||||
true
|
||||
results.built_display_list
|
||||
}
|
||||
|
||||
/// Reflows the page if it's possible to do so and the page is dirty. Returns true if layout
|
||||
/// actually happened, false otherwise.
|
||||
/// actually happened and produced a new display list, false otherwise.
|
||||
///
|
||||
/// NOTE: This method should almost never be called directly! Layout and rendering updates
|
||||
/// should happen as part of the HTML event loop via *update the rendering*. Currerntly, the
|
||||
/// only exceptions are script queries and scroll requests.
|
||||
pub(crate) fn reflow(&self, reflow_goal: ReflowGoal, can_gc: CanGc) -> bool {
|
||||
// Never reflow inactive Documents.
|
||||
if !self.Document().is_fully_active() {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Count the pending web fonts before layout, in case a font loads during the layout.
|
||||
let waiting_for_web_fonts_to_load = self.font_context.web_fonts_still_loading() != 0;
|
||||
|
||||
|
@ -2497,9 +2502,7 @@ impl Window {
|
|||
value: String,
|
||||
can_gc: CanGc,
|
||||
) -> Option<ServoArc<Font>> {
|
||||
if !self.layout_reflow(QueryMsg::ResolvedFontStyleQuery, can_gc) {
|
||||
return None;
|
||||
}
|
||||
self.layout_reflow(QueryMsg::ResolvedFontStyleQuery, can_gc);
|
||||
|
||||
let document = self.Document();
|
||||
let animations = document.animations().sets.clone();
|
||||
|
@ -2519,25 +2522,19 @@ impl Window {
|
|||
}
|
||||
|
||||
pub(crate) fn content_box_query(&self, node: &Node, can_gc: CanGc) -> Option<UntypedRect<Au>> {
|
||||
if !self.layout_reflow(QueryMsg::ContentBox, can_gc) {
|
||||
return None;
|
||||
}
|
||||
self.layout_reflow(QueryMsg::ContentBox, can_gc);
|
||||
self.content_box_query_unchecked(node)
|
||||
}
|
||||
|
||||
pub(crate) fn content_boxes_query(&self, node: &Node, can_gc: CanGc) -> Vec<UntypedRect<Au>> {
|
||||
if !self.layout_reflow(QueryMsg::ContentBoxes, can_gc) {
|
||||
return vec![];
|
||||
}
|
||||
self.layout_reflow(QueryMsg::ContentBoxes, can_gc);
|
||||
self.layout
|
||||
.borrow()
|
||||
.query_content_boxes(node.to_trusted_node_address())
|
||||
}
|
||||
|
||||
pub(crate) fn client_rect_query(&self, node: &Node, can_gc: CanGc) -> UntypedRect<i32> {
|
||||
if !self.layout_reflow(QueryMsg::ClientRectQuery, can_gc) {
|
||||
return Rect::zero();
|
||||
}
|
||||
self.layout_reflow(QueryMsg::ClientRectQuery, can_gc);
|
||||
self.layout
|
||||
.borrow()
|
||||
.query_client_rect(node.to_trusted_node_address())
|
||||
|
@ -2550,9 +2547,7 @@ impl Window {
|
|||
node: Option<&Node>,
|
||||
can_gc: CanGc,
|
||||
) -> UntypedRect<i32> {
|
||||
if !self.layout_reflow(QueryMsg::ScrollingAreaQuery, can_gc) {
|
||||
return Rect::zero();
|
||||
}
|
||||
self.layout_reflow(QueryMsg::ScrollingAreaQuery, can_gc);
|
||||
self.layout
|
||||
.borrow()
|
||||
.query_scrolling_area(node.map(Node::to_trusted_node_address))
|
||||
|
@ -2603,9 +2598,7 @@ impl Window {
|
|||
property: PropertyId,
|
||||
can_gc: CanGc,
|
||||
) -> DOMString {
|
||||
if !self.layout_reflow(QueryMsg::ResolvedStyleQuery, can_gc) {
|
||||
return DOMString::new();
|
||||
}
|
||||
self.layout_reflow(QueryMsg::ResolvedStyleQuery, can_gc);
|
||||
|
||||
let document = self.Document();
|
||||
let animations = document.animations().sets.clone();
|
||||
|
@ -2640,10 +2633,7 @@ impl Window {
|
|||
node: &Node,
|
||||
can_gc: CanGc,
|
||||
) -> (Option<DomRoot<Element>>, UntypedRect<Au>) {
|
||||
if !self.layout_reflow(QueryMsg::OffsetParentQuery, can_gc) {
|
||||
return (None, Rect::zero());
|
||||
}
|
||||
|
||||
self.layout_reflow(QueryMsg::OffsetParentQuery, can_gc);
|
||||
let response = self
|
||||
.layout
|
||||
.borrow()
|
||||
|
@ -2661,9 +2651,7 @@ impl Window {
|
|||
point_in_node: UntypedPoint2D<f32>,
|
||||
can_gc: CanGc,
|
||||
) -> Option<usize> {
|
||||
if !self.layout_reflow(QueryMsg::TextIndexQuery, can_gc) {
|
||||
return None;
|
||||
}
|
||||
self.layout_reflow(QueryMsg::TextIndexQuery, can_gc);
|
||||
self.layout
|
||||
.borrow()
|
||||
.query_text_indext(node.to_opaque(), point_in_node)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue