New issue
Advanced search Search tips

Issue 819474 link

Starred by 2 users

Issue metadata

Status: Started
Owner:
Cc:
Components:
EstimatedDays: ----
NextAction: ----
OS: ----
Pri: 2
Type: Task

Blocking:
issue 844406



Sign in to add a comment

Compositing mode decision improvements

Project Member Reported by kylec...@chromium.org, Mar 7 2018

Issue description

I'm going to try and summarize a discussion with piman and danakj around how compositing mode decisions can be improved. By default the compositing mode is GPU accelerated and under some circumstances we fallback to software compositing:

1. Flags --disable-gpu or --disable-gpu-compositing are passed in.
2. The GPU is blacklisted.
3. The GPU process crashes too many times.
4. GpuChannel creation fails.
5. There is a fatal error creating a ContextProvider for browser.
6. There is a fatal error creating a ContextProvider for display compositor.

The browser, renderer and display compositor all need to know what compositing mode to use. This is handled by CompositorModeReporterImpl now. There is a message pipe, mojom::CompositingModeWatcher, from browser to all renderers that is used at most once to signal falling back from GPU to software compositing.

The idea is to move the decision making closer to the GPU process and reduce IPC overhead. We can get rid of the the extra message pipes and include the compositing mode along with the GpuChannel when it's requested. The renderer and browser will request a GpuChannel and get back a bool for GPU or software compositing.

All GpuChannel requests go through the browser, so the browser can persist any decisions made in the GPU process past GPU process crashes. This means that if the GPU process decides it has to use software compositing and later crashes, the browser can restart the GPU process in software compositing mode.

For cases 1 and 2 above the initial request for a GpuChannel will say software compositing. GpuFeatureInfo will be set appropriately on GPU process startup.

For case 3 when the GPU process crashes clients will request new GpuChannels. GpuProcessHost will have started the browser up in software compositing mode and the GpuChannel request will say software compositing.

For cases 4-6 the failure can happen either in the GPU process or browser process. In either case, the GPU process needs to be notified to switch to software compositing and then close all GpuChannels. GpuChannelManager should be able to close the GpuChannels, so I guess it needs to find out. Clients will request new GpuChannels and they will say software compositing.

For the case where there is no GPU process, GpuDataManager on the browser IO thread will know this. GpuChannel requests happen via the browser IO thread, so the request can return immediately with nullptr GpuChannelHost and say software compositing. This should also be applicable to OOP-D where even if there is a GPU process GpuDataManager will know there is no SwiftShader and we're using software compositing, which saves an IPC hop.

If the browser has a fatal error and needs to switch the GPU to software compositing we can do two things. We can add an IPC so that GPU gest notified, drops GpuChannels and says software compositing for all new GpuChannels. Alternatively, the browser can also set GpuDataManager to software compositing and then kill the GPU process. The GPU process will restart in software compositing mode which should be identical in effect.
 
This shouldn't be too much work to implement. For now, I think cases 4-6 can be handled via the browser process. The error might occur in the GPU process, but that error is routed back to the browser process and received by [Gpu|Viz]ProcessTransportFactory. The FooProcessTransportFactory will PostTask to GpuProcessHost to switch to software compositing mode. The browser GpuChannel will be lost and FooProcessTransportFactory will request a new GpuChannel. The new GpuChannel request will come back saying to use software compositing.

In the future if the kFatalError occurred in the GPU process we can avoid two IPC hops by switching to software compositing and then dropping GpuChannels. This will be required for OOP-D case 6, although that will still require a thread hop from VizCompositorThread to CrGpuMain.

Steps:
1. Unify OOP-D disabled and enabled cases in how they use CompositingModeReporterImpl. Also make CreateRootCompositorFrameSink() requests always include the compositing mode. Some of the unification isn't necessary but I already have this CL essentially written and it'll make the next step easier.
2. Replace CompositingModeReporter/CompositingModeWatcher with extra data on the GpuChannel request response. Add GpuProcessHost method to switch compositing modes (and maybe some mojom::GpuService and GpuServiceImpl changes).
3. Add a way for GpuDisplayProvider to get GpuChannelManager to switch to software compositing.
4. Other optimizations (maybe?)

I'll wait for piman/danakj to see if they agree.
LGTM 

> 4. GpuChannel creation fails.

nit: You say this later but this is only for the browser process. The renderer can fail too but it always retries until its told explicitly.

> Add GpuProcessHost method to switch compositing modes 

Did you mean GpuDataManager?
> Did you mean GpuDataManager?

I mean both kind of? GpuProcessHost is what interacts with the GPU process so it's going to be involved. It will need to change values in GpuDataManager too. There might not be GpuProcessHost instance though, so it will probably need to be a static function on GpuProcessHost that first changes GpuDataManager and then talks to the GpuProcessHost instance if there is one.
ok cool thanks
Project Member

Comment 5 by bugdroid1@chromium.org, Mar 7 2018

The following revision refers to this bug:
  https://chromium.googlesource.com/chromium/src.git/+/7cb0b3a36f2bea7a70d86cb923a77a07732a6e24

commit 7cb0b3a36f2bea7a70d86cb923a77a07732a6e24
Author: kylechar <kylechar@chromium.org>
Date: Wed Mar 07 22:19:46 2018

viz: Fix software compositing fallback.

Make VizProcessTransportFactory software fallback work similar to
GpuProcessTransportFactory software fallback. The major change here is
that VizProcessTransportFactory includes the compositing mode in
RootCompositorFrameSinkParams and code is unified.

Delete ForwardingCompositingModeReporterImpl as it's no longer needed.

Bug: 819474,  730660 
Cq-Include-Trybots: master.tryserver.chromium.android:android_optional_gpu_tests_rel
Change-Id: I2b6f53b41e4e0ac599fda0e3abeae77cfd69f0a9
Reviewed-on: https://chromium-review.googlesource.com/938329
Reviewed-by: Tom Sepez <tsepez@chromium.org>
Reviewed-by: Sadrul Chowdhury <sadrul@chromium.org>
Reviewed-by: Antoine Labour <piman@chromium.org>
Reviewed-by: danakj <danakj@chromium.org>
Commit-Queue: kylechar <kylechar@chromium.org>
Cr-Commit-Position: refs/heads/master@{#541607}
[modify] https://crrev.com/7cb0b3a36f2bea7a70d86cb923a77a07732a6e24/components/viz/host/BUILD.gn
[delete] https://crrev.com/82d6a7b47d69152cf6bd7cbc5985c5891de71a8d/components/viz/host/forwarding_compositing_mode_reporter_impl.cc
[delete] https://crrev.com/82d6a7b47d69152cf6bd7cbc5985c5891de71a8d/components/viz/host/forwarding_compositing_mode_reporter_impl.h
[modify] https://crrev.com/7cb0b3a36f2bea7a70d86cb923a77a07732a6e24/components/viz/service/display_embedder/display_provider.h
[modify] https://crrev.com/7cb0b3a36f2bea7a70d86cb923a77a07732a6e24/components/viz/service/display_embedder/gpu_display_provider.cc
[modify] https://crrev.com/7cb0b3a36f2bea7a70d86cb923a77a07732a6e24/components/viz/service/display_embedder/gpu_display_provider.h
[modify] https://crrev.com/7cb0b3a36f2bea7a70d86cb923a77a07732a6e24/components/viz/service/frame_sinks/frame_sink_manager_impl.cc
[modify] https://crrev.com/7cb0b3a36f2bea7a70d86cb923a77a07732a6e24/components/viz/service/main/viz_main_impl.cc
[modify] https://crrev.com/7cb0b3a36f2bea7a70d86cb923a77a07732a6e24/components/viz/service/main/viz_main_impl.h
[modify] https://crrev.com/7cb0b3a36f2bea7a70d86cb923a77a07732a6e24/components/viz/test/test_display_provider.cc
[modify] https://crrev.com/7cb0b3a36f2bea7a70d86cb923a77a07732a6e24/components/viz/test/test_display_provider.h
[modify] https://crrev.com/7cb0b3a36f2bea7a70d86cb923a77a07732a6e24/content/browser/browser_main_loop.cc
[modify] https://crrev.com/7cb0b3a36f2bea7a70d86cb923a77a07732a6e24/content/browser/browser_main_loop.h
[modify] https://crrev.com/7cb0b3a36f2bea7a70d86cb923a77a07732a6e24/content/browser/compositor/viz_process_transport_factory.cc
[modify] https://crrev.com/7cb0b3a36f2bea7a70d86cb923a77a07732a6e24/content/browser/compositor/viz_process_transport_factory.h
[modify] https://crrev.com/7cb0b3a36f2bea7a70d86cb923a77a07732a6e24/content/browser/gpu/gpu_process_host.cc
[modify] https://crrev.com/7cb0b3a36f2bea7a70d86cb923a77a07732a6e24/content/browser/gpu/gpu_process_host.h
[modify] https://crrev.com/7cb0b3a36f2bea7a70d86cb923a77a07732a6e24/services/ui/ws/window_server.cc
[modify] https://crrev.com/7cb0b3a36f2bea7a70d86cb923a77a07732a6e24/services/viz/privileged/interfaces/compositing/frame_sink_manager.mojom
[modify] https://crrev.com/7cb0b3a36f2bea7a70d86cb923a77a07732a6e24/services/viz/privileged/interfaces/viz_main.mojom

Cc: zmo@chromium.org
+zmo FYI
Blocking: 827210
Blocking: -827210
Blocking: 844406
Status: Started (was: Assigned)
Cc: samans@chromium.org
Labels: -M-67 M-69
I'm trying to wrap my head around all the places we store compositing mode state. The hardware accelerated state is also very related. There are four GPU states related to hardware acceleration and compositing:

1. Hardware accelerated GPU compositing + hardware accelerated WebGL.
2. Software compositing + hardware accelerated WebGL.
3. Software compositing + SwiftShader WebGL.
4. Software compositing and WebGL disabled.

The hardware accelerated part of (1) and (2) can actually be SwiftShader if --use-gl=swiftshader is passed in. That is really only used for testing and I don't think it's necessarily an important distinction.

Unfortunately there are multiple places where compositing mode state gets stored that makes this complicated.

i. Flag --disable-gpu. If this flag is passed to the browser then it's forced into state (3) if SwiftShader is available or or (4) if not on startup. 
ii. Flag --disable-gpu-compositing. If this flag is passed to the browser it's forced into state (2) on startup.
iii. GpuFeatureInfo::status[GPU_FEATURE_TYPE_GPU_COMPOSITING]. GpuFeatureInfo class gets generated in the GPU process on initialization and the canonical GPU process copy is stored in GpuServiceImpl::gpu_feature_info_. The value is set based on the blacklist. GpuFeatureInfo is passed back to the browser when GPU is initialized and the canonical browser process copy is stored in GpuDataManagerImplPrivate::gpu_feature_info_. The browser copy is overwritten every time the GPU process is restarted. Copies of GpuFeatureInfo are also stored in related classes like GpuChannelHost and ContextProvider.
iv. GpuDataManagerImp[Private]::HardwareAccelerationEnabled(). If --disable-gpu is provided then this is toggled to false on startup. Otherwise this gets toggled to false if the GPU process fails to initialize OR if the GPU process crashes more than 3 times (recently) while in states (1) or (2). When this is toggled false the GPU is started in states (3) or (4).
v. ImageTransportFactory::IsGpuCompositingDisabled(). This gets set to false if --disable-gpu or --disable-gpu-compositing is provided. It can also get toggled false later if GpuFeatureInfo::status[GPU_FEATURE_TYPE_GPU_COMPOSITING] != kGpuFeatureStatusEnabled. So this is the only thing that is always toggled for GPU compositing to be disabled.
vi. CompositingModeReporterImpl::gpu_. This is an extension of ImageTransportFactory::IsGpuCompositingDisabled() since it's only set to false when ImageTransportFactory state changes. Each renderer has an IPC pipe to the browser process and if GPU compositing gets disabled after startup then an IPC is sent to the renderer to tell it to drop GpuChannel and switch to software compositing. If ImageTransportFactory::IsGpuCompositingDisabled() is false when the renderer process is started instead --disable-gpu-compositing gets append to the renderer command line and CompositingModeReporterImpl isn't used.

There are a couple other places where compositing mode state gets stored but I think that is only for reporting to the user, for example in about://gpu.
I talked with danakj/zmo offline yesterday and I'll try to summarize the plan here:

1. Put bool |disable_gpu_compositing_| in either GpuDataManagerImpl[Private] or GpuProcessHost. This bool will be the source of truth with an accessor usable from UI and IO threads. It will also have a function to disable GPU compositing.
2. Update GpuFeatureInfo::status[GPU_FEATURE_TYPE_GPU_COMPOSITING] based on the source of truth.
3. Remove ImageTransportFactory bool and just check the source of truth.
4. Drop all existing gpu channels on software compositing fallback.
5. Remove CompositingModeReporterImpl and have the renderer check GpuFeatureInfo::status[GPU_FEATURE_TYPE_GPU_COMPOSITING] instead.
FWIW I'm okay with 4+5 but they prevent the renderer from doing something less drastic than dropping channels if we wanted to make fallback not destroy contexts that aren't related to compositing.

Sign in to add a comment