Closed Bug 1471221 Opened 6 years ago Closed 6 years ago

Flicker at the end of Google expando animation demo

Categories

(Core :: Graphics: Layers, defect, P3)

Unspecified
Windows 10
defect

Tracking

()

RESOLVED FIXED
mozilla63
Performance Impact none
Tracking Status
firefox-esr52 --- unaffected
firefox-esr60 --- wontfix
firefox61 --- wontfix
firefox62 --- wontfix
firefox63 --- fixed

People

(Reporter: birtles, Assigned: jnicol)

References

()

Details

(Keywords: regression)

Attachments

(1 file)

URL: https://googlechromelabs.github.io/ui-element-samples/animated-clip/advanced/

At the end of the animation, the "Close" link flickers. It doesn't in Chrome.
Doesn't happen on WebRender.
I doesn't seem to flicker much on Linux for me, but on a low end Windows machine it flickers really noticeable.
I managed to get the regression range down to the following:
https://hg.mozilla.org/mozilla-central/pushloghtml?fromchange=587daa4bdc4b40b7053f4ca3b74723ca747f3b52&tochange=4d3de12dcdc539f14fcb06539da39fa7176c8955

Trying to bisect it further, however, I get content process crashes on startup. I'll need to build locally to bisect further.
Thanks to Hiro's help, I confirmed that this is regressed by advanced layers. If I set layers.mlgpu.dev-enabled to false, there is no flicker.

I'm seeing this on a Dell XPS 15 laptop and a Surface Pro (both of which use Intel HD graphics).

Kats, any ideas where to look?
Blocks: 1375743
Flags: needinfo?(bugmail)
Keywords: regression
OS: All → Windows 10
Hardware: All → Unspecified
I don't really know much about advanced layers, redirecting to Bas.
Flags: needinfo?(bugmail) → needinfo?(bas)
Whiteboard: [qf]
This seems less like a performance issue and more of a general graphics glitch. qf-'ing for now, please renominate if we're mistaken!
Whiteboard: [qf] → [qf-]
Jamie, would you know how to investigate about this regression related to advanced layers? Thanks!
Flags: needinfo?(jnicol)
Component: DOM: Animation → Graphics: Layers
Hi Ryan, would you happen to have any ideas about this regression from Advanced Layers?
Flags: needinfo?(rhunt)
Sorry, I forgot to reply. Bit I am looking in to this.
Assignee: nobody → jnicol
Flags: needinfo?(rhunt)
Flags: needinfo?(jnicol)
In Advanced Layers, we are very aggressive about computing the visible bounds for a container layer so that we only allocate the smallest necessary intermediate surface. See ContainerLayerMLGPU::OnPrepareToRender(). We AND together GetShadowVisibleRegion with ComputeIntermediateSurfaceBounds (which is the union of the children's visible bounds transformed in to the intermediate surface space).

The problem on this testcase, is that the contents of the menu have a compositor transform animation running. A child layer is asynchronously translated outwith the visible region of its parent, so it is clipped. When the transform finishes, the visible region of the parent is updated so it contains the child again. That's why we get a "flicker".

We could make the visible region calculation in FrameLayerBuilder take in to account the animation, but this would be less accurate as it would have to cover the entire duration of the animation rather than the value at the time of composition.

If ComputeIntermediateSurfaceBounds returns Some, then can we just use it directly instead of ANDing with mShadowVisibleRegion? Doesn't it calculate effectively the same thing as we did to set the visible region in FrameLayerBuilder, except it will take async transforms in to account?
Flags: needinfo?(matt.woodrow)
Right, so we have an issue where async transforms move a layer, but the ancestors of that layer don't get their shadow visible regions updated to account for the change.

For non-Advanced Layers we run LayerManagerComposite::PostProcessLayers, which walks the whole Layer tree and recomputes the shadow visible region for all layers from the leaves up.

Looking at the code, I think even ComputeIntermediateSurfaceBounds() could return the wrong area if there are two nested ContainerLayers with intermediate surfaces, and then an async transform within that.

The inner ContainerLayer would walk the children and get the new position for the async transform, but the outer ContainerLayer only descends down to layers that have an intermediate surface, so it'd grab the (wrong) shadow visible region from the inner.

If we stopped using mShadowVisibleRegion, and also made ComputeIntermediateSurfaceBounds/FindVisibleBounds descend through containers with an intermediate surface (maybe we could update their shadow visible region and flag it as being valid now?) then I think it would be ok.

Little bit worried about the perf cost of this though.
Flags: needinfo?(matt.woodrow)
Hello Jamie - Do you have an update on this bug? Thanks.
Flags: needinfo?(jnicol)
Advanced layers was calculating incorrect visible regions for
container layers with intermediate surfaces, as it was not taking
async transform animations in to account. Rather than recursing the
depth of the tree for each layer to calculate this in
OnPrepareToRender, do a single pre-pass at the start of the frame.
Comment on attachment 9004809 [details]
Bug 1471221 - Calculate intermediate surface bounds in advanced layers in pre-pass. r=mattwoodrow

Matt Woodrow (:mattwoodrow) has approved the revision.
Attachment #9004809 - Flags: review+
Pushed by jnicol@mozilla.com:
https://hg.mozilla.org/integration/autoland/rev/fc155fd5c1f0
Calculate intermediate surface bounds in advanced layers in pre-pass. r=mattwoodrow
https://hg.mozilla.org/mozilla-central/rev/fc155fd5c1f0
Status: NEW → RESOLVED
Closed: 6 years ago
Resolution: --- → FIXED
Target Milestone: --- → mozilla63
QA Whiteboard: [good first verify]
Flags: needinfo?(bas)
Flags: needinfo?(jnicol)
Performance Impact: --- → -
Whiteboard: [qf-]
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: