aboutsummaryrefslogtreecommitdiffstats
path: root/components/script/dom/document.rs
diff options
context:
space:
mode:
authorbors-servo <servo-ops@mozilla.com>2020-03-31 20:03:51 -0400
committerGitHub <noreply@github.com>2020-03-31 20:03:51 -0400
commitdd97e6d164457a3ebdb0be22bfa9ff76e251aced (patch)
tree40c41c7fd91204ef5a5b180290e9e1b5e7d3e6f2 /components/script/dom/document.rs
parent75ca3d8198520c1be5fa8218f8b238c7d319d78b (diff)
parent6ab7a50b31ae1551e28d1a67f396715fa560ced0 (diff)
downloadservo-dd97e6d164457a3ebdb0be22bfa9ff76e251aced.tar.gz
servo-dd97e6d164457a3ebdb0be22bfa9ff76e251aced.zip
Auto merge of #26076 - jdm:client-rect-cache, r=asajeffrey
Reduce unnecessary layout queries in babylon.js content Every frame, Babylon.js compares the width property of the webgl canvas element to its clientWidth. This incurs two layout operations every frame - one to get the dimensions of the element, and at the end of the frame to construct a display list and send that to webrender. These changes introduce the concept of cached layout values which are constructed from the result of layout queries. These cached values are automatically invalidated when a new layout operation takes place, but as long as only the query operations that stored a cached value are used and the DOM is not otherwise dirtied, the cached values will remain valid and no further layout operations will take place. --- - [x] `./mach build -d` does not report any errors - [x] `./mach test-tidy` does not report any errors - [x] These changes fix (part of) #26019 - [x] These changes do not require tests because we have no infrastructure to test whether or not reflow occurred.
Diffstat (limited to 'components/script/dom/document.rs')
-rw-r--r--components/script/dom/document.rs36
1 files changed, 28 insertions, 8 deletions
diff --git a/components/script/dom/document.rs b/components/script/dom/document.rs
index 1e60b3b79fc..d7ba280cdf8 100644
--- a/components/script/dom/document.rs
+++ b/components/script/dom/document.rs
@@ -588,16 +588,28 @@ impl Document {
self.needs_paint.get()
}
- pub fn needs_reflow(&self) -> bool {
+ pub fn needs_reflow(&self) -> Option<ReflowTriggerCondition> {
// FIXME: This should check the dirty bit on the document,
// not the document element. Needs some layout changes to make
// that workable.
- self.stylesheets.borrow().has_changed() ||
- self.GetDocumentElement().map_or(false, |root| {
- root.upcast::<Node>().has_dirty_descendants() ||
- !self.pending_restyles.borrow().is_empty() ||
- self.needs_paint()
- })
+ if self.stylesheets.borrow().has_changed() {
+ return Some(ReflowTriggerCondition::StylesheetsChanged);
+ }
+
+ let root = self.GetDocumentElement()?;
+ if root.upcast::<Node>().has_dirty_descendants() {
+ return Some(ReflowTriggerCondition::DirtyDescendants);
+ }
+
+ if !self.pending_restyles.borrow().is_empty() {
+ return Some(ReflowTriggerCondition::PendingRestyles);
+ }
+
+ if self.needs_paint() {
+ return Some(ReflowTriggerCondition::PaintPostponed);
+ }
+
+ None
}
/// Returns the first `base` element in the DOM that has an `href` attribute.
@@ -1683,7 +1695,7 @@ impl Document {
// is considered spurious, we need to ensure that the layout
// and compositor *do* tick the animation.
self.window
- .force_reflow(ReflowGoal::Full, ReflowReason::RequestAnimationFrame);
+ .force_reflow(ReflowGoal::Full, ReflowReason::RequestAnimationFrame, None);
}
// Only send the animation change state message after running any callbacks.
@@ -4954,3 +4966,11 @@ impl PendingScript {
.map(|result| (DomRoot::from_ref(&*self.element), result))
}
}
+
+#[derive(Clone, Copy, Debug, PartialEq)]
+pub enum ReflowTriggerCondition {
+ StylesheetsChanged,
+ DirtyDescendants,
+ PendingRestyles,
+ PaintPostponed,
+}