aboutsummaryrefslogtreecommitdiffstats
path: root/components/script/dom
diff options
context:
space:
mode:
authorEmilio Cobos Álvarez <ecoal95@gmail.com>2016-08-30 16:37:37 -0700
committerEmilio Cobos Álvarez <ecoal95@gmail.com>2016-08-30 17:01:03 -0700
commitfd9cd2f1036a580eba85dc65c11125a0bc85fb17 (patch)
tree2cf745b208f82a696e87006746a36881044a7853 /components/script/dom
parent1fcc447941b23fb54963f9590219387695e73cb6 (diff)
downloadservo-fd9cd2f1036a580eba85dc65c11125a0bc85fb17.tar.gz
servo-fd9cd2f1036a580eba85dc65c11125a0bc85fb17.zip
layout: Keep track of whether we've deferred the painting of the document due to
a script query. This will, rather unfortunately, mean that we might repaint two times if we've deferred a paint, then get an out-of-band reflow. Still seemed better than not suppressing paints at all. Fixes #13131
Diffstat (limited to 'components/script/dom')
-rw-r--r--components/script/dom/document.rs23
-rw-r--r--components/script/dom/window.rs6
2 files changed, 26 insertions, 3 deletions
diff --git a/components/script/dom/document.rs b/components/script/dom/document.rs
index cbd4b2ac253..58995645c27 100644
--- a/components/script/dom/document.rs
+++ b/components/script/dom/document.rs
@@ -221,6 +221,9 @@ pub struct Document {
/// For each element that has had a state or attribute change since the last restyle,
/// track the original condition of the element.
modified_elements: DOMRefCell<HashMap<JS<Element>, ElementSnapshot>>,
+ /// This flag will be true if layout suppressed a reflow attempt that was
+ /// needed in order for the page to be painted.
+ needs_paint: Cell<bool>,
/// http://w3c.github.io/touch-events/#dfn-active-touch-point
active_touch_points: DOMRefCell<Vec<JS<Touch>>>,
/// Navigation Timing properties:
@@ -376,6 +379,10 @@ impl Document {
}
}
+ pub fn needs_paint(&self) -> bool {
+ self.needs_paint.get()
+ }
+
pub fn needs_reflow(&self) -> bool {
// FIXME: This should check the dirty bit on the document,
// not the document element. Needs some layout changes to make
@@ -384,7 +391,8 @@ impl Document {
Some(root) => {
root.upcast::<Node>().is_dirty() ||
root.upcast::<Node>().has_dirty_descendants() ||
- !self.modified_elements.borrow().is_empty()
+ !self.modified_elements.borrow().is_empty() ||
+ self.needs_paint()
}
None => false,
}
@@ -1602,6 +1610,8 @@ pub enum DocumentSource {
pub trait LayoutDocumentHelpers {
unsafe fn is_html_document_for_layout(&self) -> bool;
unsafe fn drain_modified_elements(&self) -> Vec<(LayoutJS<Element>, ElementSnapshot)>;
+ unsafe fn needs_paint_from_layout(&self);
+ unsafe fn will_paint(&self);
}
#[allow(unsafe_code)]
@@ -1618,6 +1628,16 @@ impl LayoutDocumentHelpers for LayoutJS<Document> {
let result = elements.drain().map(|(k, v)| (k.to_layout(), v)).collect();
result
}
+
+ #[inline]
+ unsafe fn needs_paint_from_layout(&self) {
+ (*self.unsafe_get()).needs_paint.set(true)
+ }
+
+ #[inline]
+ unsafe fn will_paint(&self) {
+ (*self.unsafe_get()).needs_paint.set(false)
+ }
}
/// https://url.spec.whatwg.org/#network-scheme
@@ -1723,6 +1743,7 @@ impl Document {
base_element: Default::default(),
appropriate_template_contents_owner_document: Default::default(),
modified_elements: DOMRefCell::new(HashMap::new()),
+ needs_paint: Cell::new(false),
active_touch_points: DOMRefCell::new(Vec::new()),
dom_loading: Cell::new(Default::default()),
dom_interactive: Cell::new(Default::default()),
diff --git a/components/script/dom/window.rs b/components/script/dom/window.rs
index cd00390a305..b6bf6a35643 100644
--- a/components/script/dom/window.rs
+++ b/components/script/dom/window.rs
@@ -1200,9 +1200,11 @@ impl Window {
if !for_display || self.Document().needs_reflow() {
issued_reflow = self.force_reflow(goal, query_type, reason);
- // If window_size is `None`, we don't reflow, so the document stays dirty.
- // Otherwise, we shouldn't need a reflow immediately after a reflow.
+ // If window_size is `None`, we don't reflow, so the document stays
+ // dirty. Otherwise, we shouldn't need a reflow immediately after a
+ // reflow, except if we're waiting for a deferred paint.
assert!(!self.Document().needs_reflow() ||
+ (!for_display && self.Document().needs_paint()) ||
self.window_size.get().is_none() ||
self.suppress_reflow.get());
} else {