The renderer compositor can run in Gpu or software mode. As can the display compositor. Normally these should match, but we have vague or no real synchronization between these two. If a GpuChannel can't be made, then they will agree and both fall back to software. If one process manages to make a context but the other doesn't, they'll disagree. The browser tries 4 times to make a GpuChannel, the renderer tries once.
Then if a context is made:
- It might be for swiftshader, in which case the compositor will not use gpu.
- The compositor might not use it anyway if --disable-gpu-compositing was passed from the browser at renderer startup.
If a context was not made:
- The compositor will fall back to software. But other clients could potentially make a context successfully afterward and be unable to tell that they're now doing the wrong thing. Or the right thing, but the renderer's doing the wrong thing.
We need some global coordination so that all processes and clients agree.
https://chromium-review.googlesource.com/c/chromium/src/+/703979 took a first stab at this in the renderer process before diving further into the problem between the display compositor and the renderer process. In that, we made RenderThreadImpl report Gpu/Software compositing mode, and required you to hold a context to know, so we could lose the context if it changed.
But there's some problems here:
- If any context failed to be made, clients would then assume software compositing. So we needed to actually use software compositing, and drop any other contexts.
- That's esp bad if they failed to make a context with some options but could succeed with other options!
- No synchronization with the browser ui/display.
- Very aggressive fallback to software, on any failure at all recreating the compositor context. This relates to sync with the display, but we could easily end up in software compositing for no real good reason.
If all cc clients that submit resources instead used CompositorFrameSink and submitted there instead, we could move the problem of clients to be a more similar problem to that of the cc compositors, but I don't think this actually makes much easier to solve.
What we want is that when RenderThreadImpl returns a context, it knows if the client should be producing compositor frames in gpu or software resources. This requires a round trip to the display compositor at least once, doing it on every time a client makes a context would be sad, so I don't think we want to tie this to any interface that each client would have (like CompositorFrameSink or something).
We can make a global service CompositingModeWatcher that RenderThreadImpl listens to. The implementation would be connected to the viz::Display to know what mode it's using. When clients ask RenderThreadImpl for a context they would also find out the mode. They can also observe the RenderThreadImpl to hear about mode changes. Then we can change the mode without losing the GL contexts in the process needlessly for things that don't care.
Few problems to solve here:
- There's a race with clients to ask for a context and RenderThreadImpl knowing what mode to report. We don't want to just guess GPU mode, cuz clients can do all sorts of stuff based on that knowledge and would lose state when it changed (or do big workarounds to preserve state o no). If we put the CompositingModeWatcher on the IO thread, then RenderThreadImpl can use a WaitableEvent to block until it hears a mode come the first time. Future mode changes would be posted from the IO to the main thread and signaled to listeners.
- cc can be signaled through the LayerTreeFrameSink, but would need a pointer to it and post to the compositor thread to let it know. We could lose the compositor context, but would that impact other contexts? It's in a share group with the compositor worker context (not a problem) and not with others, but I'm not sure?
- We want clients to be strongly encouraged to watch this mode in the code. We can make sure they are watching by asking for a watcher/observer client when making a context.
Others?
Comment 1 by danakj@chromium.org
, Oct 6 2017