Closed Bug 775452 (multi-apzc) Opened 8 years ago Closed 6 years ago

Support multiple asynchronously-panned subframes


(Core :: Panning and Zooming, defect)

Not set



blocking-kilimanjaro ?
blocking-basecamp -


(Reporter: cjones, Assigned: kats)


(Blocks 1 open bug, )


(Whiteboard: [tech-p1])

I think xul-fennec may have been the first browser to do this, but since then everyone else has caught up.  We're temporarily behind again.

We can build on the new AsyncPanZoomController and the code we implemented for xul-fennec to do this.  We assign IDs to scrollable frames, create an apzc for them, set that apzc on their Layers, and request repaints by frame ID.  We'll want to batch the repaint requests by top-level content frame (mozbrowser), to avoid perf issues and glitchy gfx.
Brad says we shipped Firefox for Android without this and that it's not awful :)  Not a blocker for now.
blocking-basecamp: ? → -
Blocks: 775739
Alias: multi-apzc
Major content use case and needed for competitive parity.  Best way to reliably get 60fps scrolling in something like contacts list.
Whiteboard: [tech-p1]
Before making a plan for apzc, we should revisit the prior art from xul-fennec, since we'll want to build on similar principles and reuse some of the code.  A lot of it is still in the tree as a reference.  Some DNA that lives on from that is LAYER_ACTIVE_FORCE, and FrameMetrics::*Scrollable() helpers.

Original work was bug 605618 and bug 618975.

The way things worked was pretty elegantly simple, IMHO.
 1. On the content side, scrollable frames we wanted to be async-pannable were assigned a special ID [1] to their IContent.  Gecko did this "automatically" according to simple heuristics.
 2. FrameLayerBuild gave async-pannable frames their own layer.  We tagged those layers with the magic ID, through FrameMetrics.  All this was forwarded to the "compositor thread".
 3. Upon receiving touchstart, the "UI thread" would perform a hit test using the FrameMetrics in the shadow layer tree [2].  The display list for the hit test was built "in reverse" from the shadow tree.  A stack of scrollable frames under the point was returned to the caller.
 4. The frontend chose a victim frame to pan.  The frontend would set up a displayport for the victim frame [3] and change its scroll offset by sending message-manager messages to content-side FE JS.
 5. Content-side FE code would look up the right elements to pan/set displayport by looking them up through the magic ID [4].  Then it would manipulate the DOMElement(s) appropriately.

The "diff" I want to apply for apzc is fairly minimal
 1. Same.
 2. Same.
 3. Same, except that the code performing the hit test will be APZC.  Because we'll want to use this for fennec, where the UI thread is java, we can't reuse "native" display-list hit testing.  (AFAIK.)  There's a catch here in that we need to create new APZCs for newly-seen async-pannable layers [1], and "GC" old ones that no longer appear in the tree.
 4. Same, except we'll choose a victim APZC and set it as the event-series "capturer".  Dump input events into apzc and run existing code.
 5. Same, except that the content agent will be the gecko content controller.  I'm not sure yet whether it will be better to share one for all frames in a window or have one per scrollable frame.

A complication that will arise on b2g is that we'll have OOP async pan-zoom frames that contain other async pan-zoom frames ... that live in other processes.  And recursively :D.  The above plan should work fine for all those case though.

[1] APZCs are fairly heavy-weight so we may want to do something smarter, but we can revisit that later.
The reason this is tracked independently of bug 775456 is that we could make all scrollable frames async pan-zoom by default in some contexts, like xul-fennec used to.  mobilesafari behavior is opt-in for subframes, though.
Does someone have an example URL where this would apply?
If we choose to make it default for subframes, or just iframes, (which is what we would do while developing the feature), this works

If we choose opt-in for non-iframe subframes, then use the same page but make some frames -moz-overflow-scroll:touch or whatever magical CSS incantation we choose in bug 775456.
Duplicate of this bug: 864438
Depends on: 864441, 864447
Adding bug 776030 as a dependency. With respect to Fennec, I've discussed this with BenWa and Brad, and it looks like the plan is to ensure any work that happens here is compatible with Fennec, which we can test locally once bug 776030 is done. We may need to do some additional work on the Fennec <-> APZC glue as we go along, but the idea is to be able to test async subframe panning without actually turning on APZC in Fennec in Nightly. Later, once we have fully tested APZC in Fennec and made sure it is ready for prime-time, we can turn it on and we'll get the async subframe panning along with it.
Depends on: apz-fennec
Depends on: 890279
Depends on: 890280
No longer depends on: 880024
Depends on: 891384
OS: Linux → All
Hardware: x86_64 → All
Depends on: 893872
Depends on: 894288
Depends on: 894619
Blocks: 898049
No longer blocks: 775739
No longer depends on: 881451
Depends on: 906877
This is pretty much done now.
Assignee: nobody → bugmail.mozilla
Blocks: 906877
Closed: 6 years ago
Component: Graphics: Layers → Panning and Zooming
No longer depends on: 898075, 906877, 907179, 912700
Resolution: --- → FIXED
Duplicate of this bug: 775739
The comments in gfx/layers/FrameMetrics.h should probably be updated since they directly reference this bug and I assume are no longer true?
Flags: needinfo?(bugmail.mozilla)
Thanks for catching that, I filed bug 930903 to fix it.
Flags: needinfo?(bugmail.mozilla)
You need to log in before you can comment on or make changes to this bug.