• David Bokan's avatar
    [ScrollUnification] HitTest plumbing and event flow · 63c7d741
    David Bokan authored
    This CL implements the compositor-thread<->main-thread routing and flow
    for cases that need to be main thread hit tested under scroll
    unification. Scroll unification is a project to remove all gesture
    scroll handling from Blink and rely solely on the compositor gesture
    handler.
    
    Design doc: https://docs.google.com/document/d/1smLAXs-DSLLmkEt4FIPP7PVglJXOcwRc7A5G0SEwxaY/edit
    
    Today, some scrollers cannot be scrolled on the compositor thread.
    There's a few primary reasons why this can happen:
    
      - The scroller is not backed by a cc::Layer so we can't hit test it.
      - Unreliable hit test in the presence of squashing layers
      - The scroller has a main thread scrolling reason. It has a cc::Layer
        and we can hit test it but, because of style reasons, scrolling it
        from the compositor would produce incorrect results.
    
    Under scroll unification, if the compositor can determine the correct
    ScrollNode to use, it can perform these kinds scrolls by mutating just
    the scroll node, then wait on a BeginMainFrame and commit to repaint the
    layers and update the property trees, just like today's main thread
    scrolling but without invoking the input handling code paths in Blink.
    
    In https://crrev.com/c/2089973 we made it so that the entire scroll tree
    is passed to the compositor. Thus, the first two cases above can be
    addressed by asking the main thread for the element_id of the ScrollNode
    to use. This CL implements the plumbing for this functionality.
    
    Background:
    
    When a gesture scroll begin (GSB) arrives, it first hits the
    WidgetInputHandlerManager. This will first dispatch to the compositor by
    passing it to InputHandlerProxy. In turn, InputHandlerProxy calls
    LayerTreeHostImpl::ScrollBegin. If LTHI determines it cannot handle the
    scroll, IHP returns into WIHM (via callback) which can queue events to
    the MainThreadEventQueue bound for Blink:
    
                               DID_NOT_HANDLE
                           v----------<---------+
                           |                    |
    GSB+-------------------v-------+            +
    -->+ WidgetInputHandlerManager +-->InputHandlerProxy<->LayerTreeHostImpl
       +---------------------------+
                GSB  |
                     v
       +-------------+-------------+
       |           BLINK           |
       +---------------------------+
    
    Today, if the IHP returns event disposition DID_NOT_HANDLE to indicate
    that the compositor didn't consume the event, WIHM will forward the
    event and further events in the same sequence to Blink. The compositor
    will not be involved in handling these events.
    
    Changes in this CL:
    
    In this CL, we add a new compositor event disposition
    REQUIRES_MAIN_THREAD_HIT_TEST. This indicates to
    WidgetInputHandlerManager that the compositor can handle the scroll but
    it cannot resolve the ScrollNode and requests that the WIHM provide the
    element_id of the scroller at the event's position. Conceptually, a
    scroll has started as far as IHP is concerned; however, while we're
    waiting on the WIHM to provide an element_id, the compositor thread
    event queue is blocked. This ensures any incoming scrolls are queued and
    coalesced until the scrolling can truly begin. Note: Only gestures like
    Scroll and Pinch are processed in the queue; other events will be
    dispatched directly to the compositor as usual.
    
    When WIHM receives a REQUIRES_MAIN_THREAD_HIT_TEST disposition, it will
    post a task to Blink. However, unlike DID_NOT_HANDLE, the event isn't
    passed to Blink, WIHM will keep it and redispatch it to IHP when Blink
    replies.
    
    When Blink responds, WIHM passes the original event, as well as the
    Blink-provided element_id back to IHP. This once again calls
    LTHI::ScrollBegin, this time providing a ScrollNode element id so that
    hit testing isn't required. The queue is now unblocked and flushed.
    Subsequent scroll update events will be routed to the LTHI as if we are
    in a traditional compositor scroll:
    
                          REQUEST_MAIN_THREAD_HIT_TEST
                            v---------<---------+
                            |                   |
    GSB +-------------------v------+            +
    --->+ WidgetInputHandlerManager+-->InputHandlerProxy<->LayerTreeHostImpl
        +----+---+-----------------+                              ^
             |   ^                                                |
     HitTest |   +---------------------->InputHandlerProxy::      |
             |   |                       ContinueScrollBegin+-----+
             |   | element_id
       +-----v---+-------+
       |     BLINK       |
       +-----------------+
    
    This CL doesn't yet implement the logic in LayerTreeHostImpl to return a
    REQUEST_MAIN_THREAD_HIT_TEST, hence this path isn't yet "live". Instead
    we leave some TODOs for a follow up CL.
    
    Bug: 1047182
    Change-Id: I68a0ec3dddc23c7344ddbfc334f1e25618e43404
    Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2199610
    Commit-Queue: David Bokan <bokan@chromium.org>
    Reviewed-by: default avatarPhilip Rogers <pdr@chromium.org>
    Reviewed-by: default avatarRobert Flack <flackr@chromium.org>
    Reviewed-by: default avatarNavid Zolghadr <nzolghadr@chromium.org>
    Cr-Commit-Position: refs/heads/master@{#771249}
    63c7d741
element_id.cc 1.15 KB