New issue
Advanced search Search tips
Note: Color blocks (like or ) mean that a user may not be available. Tooltip shows the reason.

Issue 713913 link

Starred by 1 user

Issue metadata

Status: Available
Owner: ----
Cc:
Components:
EstimatedDays: ----
NextAction: ----
OS: All
Pri: 3
Type: Bug



Sign in to add a comment

Layout overflow incorrectly not updated during composited transform animation

Project Member Reported by wangxianzhu@chromium.org, Apr 20 2017

Issue description

For the following test case:
<!DOCTYPE html>
<style>
@keyframes Rotation{
  0% { transform: rotate(0deg) }
  100% { transform: rotate(360deg) }
}
</style>
<div style="height: 200px; overflow: auto; background: local linear-gradient(yellow, red)">
  <div style="animation: Rotation 12s infinite; background: blue; width: 500px; height: 100px"></div>
</div>

during the animation, we don't update document lifecycles, though the animating div's style is changing which should affect layout overflow (and in turn the attachment-local background and scrollbars) of the containing block. (However, If I move mouse in the window, there will be life cycle updates and repaints of the container background and scrollbars. I guess this is because of hit testing.)

I guess it's an optimization not to schedule lifecycle updates during transform animation. However, we should not skip lifecycle updates if the animation affects other paintings (e.g. container background and scrollars in the test case).

Can anyone point me where the optimization is implemented?
 
transform-animation.html
327 bytes View Download
Maybe nothing is scheduling a frame during this particular animation?
Does Blink receive regular updates of where the transform is?

Comment 2 by pdr@chromium.org, Apr 28 2017

Cc: wkorman@chromium.org
Walter, any guesses what might be going on here?
Cc: alancutter@chromium.org suzyh@chromium.org
AFAIK this is just how composited animations are currently implemented. When offloaded to compositor they likely don't request/pump frames on their own behalf at all under any circumstances. Opacity does not request Blink frames while animating either AFAIK. See attached sample composited opacity animation.

There are two obvious approaches, (1) is essentially doing what is mentioned in c#1 above:

1. Add logic to inform Blink of style updates and request frame periodically during composited animations. This would add overhead and code complexity that today is absent. Blink would need to set/drive whether it's needed, if we don't just do it all the time. How often, and under what circumstances, would we call back into Blink? Do we just pass back percent-elapsed, or the actual current state set by compositor? Animations do call back into Blink to notify when started, finished, aborted, see blink::Animation::NotifyAnimation*.

2. Don't allow animations that may need this to become composited in the first place. This seems like it would be challenging to get right. For example a single page with a rotated box could have a transform/scale on it that at varying points should push a Blink frame to update frame view scrollbars when they need to be shown because element now extends outside of viewport. We'd need to, when determining whether to start animation on compositor, project/scrutinize the element state (position, size) during full animation circuit to determine if this was necessary. That is actually a simple case. Covering all possible analysis of web feasible layout options to determine whether an animation will affect other paintings seems crazy hard. We would surely want to instead use some rough heuristic and live with edge cases?

I could be wrong on above due to still-nascent time working in area. Adding more animation folk to comment further.
opacity.html
234 bytes View Download
To be clear, I believe the answers to question in c#1 are: (a) Correct, and, (b) no, not AFAIK.
Relevant discussion on www-style:

https://lists.w3.org/Archives/Public/www-style/2016Feb/0029.html

This is not implemented correctly. We could "fix" it easily enough
by disallowing composited scrolling for direct children of potential scrollers.

Comment 6 by pdr@chromium.org, Apr 28 2017

It looks like Firefox has the same bug. Quite surprising that two independent implementations did this. I do think it is a bug, albeit a P3.
Labels: -Pri-2 Pri-3
Summary: Layout overflow incorrectly not updated during composited transform animation (was: Missing document life cycle updates during transform animation)
It would be really great for layout overflow not to depend on child transform.
I wonder if it's possible to achieve that. Would be good to use-count it.
I have some first-hand knowledge on this issue.

This is an ancient behavior inherited from WebKit to include both transformed and un-transformed layout overflow from children. (As described by #5) The behavior isn't all that unreasonable, because transform worked like position:relative in the sense that it affects hit-testing. A strong hint that transform does more than a pure visual effect.

Then things changed when impl-side animation was introduced. In the beginning changing transform would trigger a full layout. In early 2014 someone (abarth@?) removed the layout invalidation, resulting in  crbug.com/338698 . I changed it to a simplified layout, but still too slow  crbug.com/352460 . Later I wrote a fast path to update layout overflow. The fast path is still updated recently.

I doubt we could change behavior at this point. IIRC we discussed the possibility before I implemented the fast path. Also we did get a bunch of bug reports whenever I broke the scroll extent expanding behavior.

Comment 10 by pdr@chromium.org, May 3 2017

Is there somewhere we could document this surprising behavior?

Do you know why Gecko has the same bug?
The question is not just where to document, but also what to document... My two cents is that the level of convergence guarantee should be part of the CSS transform/animation spec.

The behavior itself is kind of arbitrary and subject to change. We only made a weak guarantee of eventual convergence. (i.e. Once Blink gets into an idle state, layout overflow should get updated within finite amount of time.) In other words, infinite animation may starve layout overflow update.

We used to not optimize Blink so well that layout overflow still gets updated on every commit. I guess we "fixed" that at some point. ¯\_(ツ)_/¯

I believe Gecko faced the same trade-off and made the same conclusion (or mimicked ours).

Comment 12 by suzyh@chromium.org, Jun 13 2017

Cc: -suzyh@chromium.org
Re #8,9 accounting for transformed position seems to also be spec'd so we'd have to change this too: "the extent of the overflow area takes into account transformed elements. This behavior is similar to what happens when elements are offset via relative positioning." https://drafts.csswg.org/css-transforms/#transform-rendering.

I could imagine frameworks using transforms to implement their own layout since it doesn't incur browser layout or repainting.

I wonder if we could only pump main frames for animation frames which we know are likely to affect overflow size? e.g. anytime something extends beyond current overflow bounds or used to touch previous overflow bounds trigger a new main frame / relayout.
Labels: Hotlist-Interop

Sign in to add a comment