Add a new “viz” thread in browser process. Render thread, UI thread, renderer compositor are allowed to block on viz thread (blocking in reverse direction not allowed).
Split viz service:
viz::mojomCompositorFrameSink implementation, which handles SubmitCompositorFrame and BeginFrame requests from viz clients, will live on the new viz thread. There is no gpu command buffer client on this thread.
Aggregate and DrawAndSwap on render thread. This thread can block on viz thread if needed to wait for CompositorFrames to arrive. The gpu command buffer client continues to live on this thread.
FrameSinkManagerImpl - state tracking for frames becomes lock protected and shared between viz and render threads. As long as viz and RT does not block while holding the lock, there should be no deadlocks. Note there are other possible synchronization schemes such as blocking viz thread while RT accesses shared data. What makes sense will probably fall out during implementation.
Reuse chrome’s hit testing code. Viz thread can send AggregatedHitTestRegion to UI thread, same as chrome.
The real begin frame source continues to live on UI thread. UI blocks on viz, then viz sends out begin frames and blocks on clients (note this is begin frame in the synchronous compositor sense, ie viz does not expect a SubmitCompsitorFrame as a consequence; see deadline scheduler discussion below). Can optimize this as block UI until a single client returns has damage, or all clients returns no damage.
Initially block waiting for all frames to match existing behavior. Can consider other policies if result is not ideal for performance.