mirror of
https://github.com/servo/servo.git
synced 2025-06-12 18:34:39 +00:00
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
This commit is contained in:
parent
1fcc447941
commit
fd9cd2f103
6 changed files with 106 additions and 52 deletions
|
@ -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()),
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -405,6 +405,14 @@ impl<'ld> TDocument for ServoLayoutDocument<'ld> {
|
|||
let elements = unsafe { self.document.drain_modified_elements() };
|
||||
elements.into_iter().map(|(el, snapshot)| (ServoLayoutElement::from_layout_js(el), snapshot)).collect()
|
||||
}
|
||||
|
||||
fn needs_paint_from_layout(&self) {
|
||||
unsafe { self.document.needs_paint_from_layout(); }
|
||||
}
|
||||
|
||||
fn will_paint(&self) {
|
||||
unsafe { self.document.will_paint(); }
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ld> ServoLayoutDocument<'ld> {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue