Closed Bug 1359658 Opened 7 years ago Closed 7 years ago

stylo: Animation-only dirty bit not cleared on elements in display:none subtree

Categories

(Core :: CSS Parsing and Computation, defect, P1)

defect

Tracking

()

RESOLVED FIXED
mozilla55
Tracking Status
firefox55 --- fixed

People

(Reporter: birtles, Assigned: birtles)

References

Details

Attachments

(3 files)

Attached file Test case
While working on SMIL I ran into an issue with display:none subtrees.

The issue is that if we have an element being animated it may cause its parent to have the animation dirty bit set on it. If we then make an ancestor display:none, during the next restyle we will skip it since in traverse_dom (or top_down_dom) we call `traversal.traverse_children` but `should_traverse_children` will return false for elements with a display:none parent. As a result we never call process_preorder/recalc_style_at on the element and the dirty bit remains. When we go to assert the tree is clean at the end of the traversal we fail because the dirty bit is still set.

The attached test case causes an assertion failure for me although I haven't applied it it to a completely clean check-out so it's possible there is something in my local working copy that triggers this.

To work around this I'm thinking of adding a check to recalc_style_at to change the part where we preprocess children to be something like:

  if traversal.should_traverse_children {
    ...(preprocess as usual)
  } else if we're in an animation-only restyle and the animation-only
    descendants dirty bit is set {
    go through descendants and clear animation-only dirty bit
  }

Hiro, does that make sense? Am I missing something?
Great, thank you!

(In reply to Hiroyuki Ikezoe (:hiro) from comment #1)
> I think we should clear animation dirty bit as well as normal dirty bit
> below places;
> 
> https://hg.mozilla.org/mozilla-central/file/3f0c8da53c5c/servo/components/
> style/traversal.rs#l664

I'm not sure changing this part makes sense. We already unconditionally clear the animation dirty bit just above if we are in an animation restyle. What is needed is to clear it for descendants too. However it would be odd to change this to clear the animation bit on descendants but only clear the other dirty bit for the current element.

However, this part...

> https://hg.mozilla.org/mozilla-central/file/3f0c8da53c5c/servo/components/
> style/traversal.rs#l779

... clear_descendant_data, is sometimes called earlier in restyle_style_at and does traverse children. Fixing this (to also clear the animation-only dirty descendants bit) is enough to fix this particular test case.

(In reply to Hiroyuki Ikezoe (:hiro) from comment #2)
> One more;
> https://hg.mozilla.org/mozilla-central/file/3f0c8da53c5c/servo/components/
> style/traversal.rs#l540

I don't have a test case that fails without this change but it makes sense to me to also extend this handling to the animation-only dirty descendants bit.
Assignee: nobody → bbirtles
Status: NEW → ASSIGNED
Comment on attachment 8861742 [details]
Bug 1359658 - Crashtest for clearing animation-only dirty descendants bit on display:none descendants;

https://reviewboard.mozilla.org/r/133728/#review136594

Thank you for finding this and quick fix!
Attachment #8861742 - Flags: review?(hikezoe) → review+
Pushed by bbirtles@mozilla.com:
https://hg.mozilla.org/integration/autoland/rev/3a56bcd82878
Crashtest for clearing animation-only dirty descendants bit on display:none descendants; r=hiro
https://hg.mozilla.org/mozilla-central/rev/3a56bcd82878
Status: ASSIGNED → RESOLVED
Closed: 7 years ago
Resolution: --- → FIXED
Target Milestone: --- → mozilla55
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: