Closed Bug 944564 Opened 8 years ago Closed 7 years ago

[B2G] Page transition in Homescreen can't reach 60fps stably.

Categories

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

ARM
Gonk (Firefox OS)
defect

Tracking

()

RESOLVED WONTFIX

People

(Reporter: vlin, Assigned: mchang)

References

Details

(Keywords: perf, Whiteboard: [c=uniformity p=0 s=2014.08.15 u=])

Attachments

(1 file)

There's no paiting for page transition between two Homescreen pages. The cost for graphics basically includes input event transmission, restyling and composition. According to profiling, there's no bottleneck in restyling or composition, but 3 problems makes frame being dropped randomly.

1.
Sometimes ProcessRestyles() is missed(not called) even touch event is received and tick is fired.
observers.Length() == 0
http://mxr.mozilla.org/mozilla-central/source/layout/base/nsRefreshDriver.cpp#1133
http://mxr.mozilla.org/mozilla-central/source/layout/base/nsRefreshDriver.cpp#1152
mStyleFlushObservers.Length() == 0 => AddStyleFlushObserver is not called in time for this Tick (need further breakdown)

2.
Input event sometimes being queued in B2G main thread when B2G is busy.(e.g GC is ongoing) Then it can't be transmitted to Homescreen in time.

3.
Timer for nsRefreshDriver sometimes lags a lot.
Whiteboard: [FFOS_perf]
1: Ideally most frames (or even no frames) should restyle the page. ProcessRestyles is only called if there was a CSS changes, otherwise it's skipped. We want to avoid it entirely each frame if possible.

2&3 is serious.
(In reply to Benoit Girard (:BenWa) from comment #1)
> 1: Ideally most frames (or even no frames) should restyle the page.
> ProcessRestyles is only called if there was a CSS changes, otherwise it's
> skipped. We want to avoid it entirely each frame if possible.
> 
> 2&3 is serious.

1:
I have no much idea about CSS, but for translating attribute it's supposed to change style 60 times in 1 second in order to animate with 60fps, right ?

2:
I heard only main thread can do IPC in our IPDL design. If it's true, once main thread is busy it will be a bottleneck for IPC. And I also heard there's a plan to break the limitation ?
Flags: needinfo?(bgirard)
Component: General → Graphics: Layers
Product: Firefox OS → Core
What is the framerate now (what device) and how is it being measured?
Keywords: perf
Whiteboard: [FFOS_perf] → [FFOS_perf] [c=effect p= s= u=]
(In reply to Vincent Lin[:vincentlin] from comment #2)
> (In reply to Benoit Girard (:BenWa) from comment #1)
> > 1: Ideally most frames (or even no frames) should restyle the page.
> > ProcessRestyles is only called if there was a CSS changes, otherwise it's
> > skipped. We want to avoid it entirely each frame if possible.
> > 
> > 2&3 is serious.
> 
> 1:
> I have no much idea about CSS, but for translating attribute it's supposed
> to change style 60 times in 1 second in order to animate with 60fps, right ?

A transition on a property that gets OMTAnimation will only require a call to ProcessRestyles when it is started. In profiles where we OMTAnimation properly the main thread go to sleep entirely. Of course lowering the cost of the intial ProcessRestyles to build the OMTAnimation is important and I've been pushing in the rendering meets for us to staff and fix bug 862276.

> 
> 2:
> I heard only main thread can do IPC in our IPDL design. If it's true, once
> main thread is busy it will be a bottleneck for IPC. And I also heard
> there's a plan to break the limitation ?

That's not the case. For example video is decoded in a decoder thread and send directly to the compositor via IPC. This wont hit the main thread. Currently the biggest restriction is anything that needs to reflow is currently stuck to the main thread. However for input events they still have to hit the b2g main thread currently because that's where the events are dispatched. Bug 930939 would fix that limitation.
Flags: needinfo?(bgirard)
(In reply to Milan Sreckovic [:milan] from comment #3)
> What is the framerate now (what device) and how is it being measured?

FlatFish is around 50~55fps. The 55fps bound is due to the touch event reporting rate from driver. I've opened Bug 941984 for this.

N4 is 55~60fps. No touch driver issue, but 3 problems addressed in this bug makes the variation.

I measured it mainly by enabling "showing FPS" in developer options with assistance of log at RecvUpdateNoSwap and CompositorParent::Composite.
Depends on: 862276
Depends on: input-thread
No longer depends on: 862276
Blocks: 862276
No longer blocks: 862276
Assignee: nobody → vlin
Assignee: vlin → nobody
Priority: -- → P1
Whiteboard: [FFOS_perf] [c=effect p= s= u=] → [c=effect p= s= u=]
FxOS Perf P1 as this has a direct negative impact on Frame Uniformity.
Whiteboard: [c=effect p= s= u=] → [c=uniformity p= s= u=]
Assignee: nobody → mchang
Status: NEW → ASSIGNED
Whiteboard: [c=uniformity p= s= u=] → [c=uniformity p=5 s= u=]
1) No overpainting
2) No reflows!
3) Might be able to remove one layer 

Profile:
https://people.mozilla.org/~bgirard/cleopatra/#report=60a05a1293a47c0f70a096d0c1569509fa11d0fc

We spend most of the time in CSS:ProcessRestyles
Blocks: 935345
Depends on: 931668
Page transitions + scrolling is a lot jerkier if you do a slow drag. Me having a finger and being human adds some noise but it is noticeably jerkier than my iphone. 

Profile up: https://people.mozilla.org/~bgirard/cleopatra/#report=8024b8c5ad2293f741cbd0d32739ae80b9f2912d

Also dominated by CSS::ProcessRestyles / CSS::ComputeStyleChangeFor.
Here's a breakdown of a single homescreen swipe measuring time between nsRefreshDriver::Tick. All times measured in milliseconds. We see that we often break our 16 ms budget. Trying to investigate where time is spent in each tick.

85.781738
30.130009
29.351668
4.283333
16.281664
17.284999
16.283334
16.633334
16.180000
17.623334
16.274999
16.346667
17.451667
16.211666
16.278334
17.571667
16.281666
16.195000
17.868334
16.326666
78.166667
14.425000
7.283333
309.145000
27.963334
Show those profiles to dbaron.
Flags: needinfo?(dbaron)
I'm hoping bug 931668 will be ready for testing really soon now, and we'll be able to see whether the homescreen is hitting the new fast-path, or, if not, figure out what we can do about getting it on the fast path.

I think bug 977991 will also help here; I can try to reorder the work I'm doing in bug 960465 to get the parts that bug 977991 depends on in sooner rather than later.
Flags: needinfo?(dbaron)
I've rebased bug 931668 and put some initial numbers and profiles in that bug. We drop some ProcessRestyles from ~70 ms to ~30ms, which is a big improvement. We still need to have some improvements to get into our 16ms budget.
I'd rather have that analysis here than there (that bug is about one piece of work that we're doing; this bug can be about figuring out what else we ought to do).

I think it's worth figuring out why some ticks are particularly slow.  Is gaia still doing attribute changes that trigger restyling during the homescreen swipe?  (I thought we fixed those last year.)
I think it's also worth discussing larger changes, such as restructuring the homescreen so that the panning happens via panning a scrollable area rather than by changing transforms.  That depends, in turn, on having scroll snapping support finished and turned on.
Here's a profile using the following orangutan that one of our partners is using to measure frame uniformity:

https://people.mozilla.org/~bgirard/cleopatra/#report=5e729f7f6d65c3b0d562f5f3851c94b643a4d9b9

The orangutan script is:
drag 200 1800 1200 1800 50 180

This is done on a nexus 4.

As for homescreen changes, I concur. I was playing around with the pan function and it tries to predict the velocity of the pan. For slow scrolls, it actually predicts wrong by a couple of pixels. I noticed that I perceive it to be smoother if I just use the actual touch X axis rather than a prediction. I'm looking more into that.

Our partner wants to use vsync triggered refresh in bug 980241. I think android, does that also.

What do you mean by triggering restyling during the homescreen swipe? At the moment, if we're swiping a middle homescreen page, we do 3x transforms on 3 different pages. This can also be optimized a bit. We're seeing some time spent in JS to concat strings which get flattened on every frame refresh.
On a per tick basis while panning the homescreen, we're spending this much time on each section. Our budget is ~16.6ms per frame.

1) ~3-5ms on a style layout flush
2) .25 - .5 ms calling window.requestAnimationFrame to do the pan - This can probably be optimized. It doesn't show up as a dominating factor, but setting a transform involves annoying string concatenation and flattening. It'd be nice to optimize this by enabling setting transforms / translates without string manipulation.
3) ~2-6 ms on nsViewManager->ProcessPendingUpdates().

Near the last frame when we have a 60ms tick delay, and we're snapping the current page, we spend 50ms in layout::flush and 7 ms in nsViewManager->ProcessPendingUpdates. Still digging on ways to optimize (1) and (3).

Altering the homescreen app itself to disable prediction on slow scrolls helps a lot on a hamachi.
There is a reason we transform 3 page-sized frames instead of using 1 transform. We only pre-render frames that aren't much larger than the screen.
Target Milestone: --- → 1.5 S2 (23may)
Priority: P1 → P4
See Also: → 974381
Priority: P4 → P1
Priority: P1 → P2
Target Milestone: 2.0 S2 (23may) → ---
Since the new homescreen uses APZ, we don't transform anything to scroll the screen anymore. Marking as WONTFIX.
Status: ASSIGNED → RESOLVED
Closed: 7 years ago
Resolution: --- → WONTFIX
Whiteboard: [c=uniformity p=5 s= u=] → [c=uniformity p=0 s=2014.08.15 u=]
You need to log in before you can comment on or make changes to this bug.