Commit 88cafd30 authored by danakj's avatar danakj Committed by Commit Bot

viz: Drop and recreate LayerTreeFrameSinks when fallback to software

This sets up the VizProcessTransportFactory to respond to the notice
that it should use software compositing. In that case it will call
OnLostMainThreadSharedContext() and release all the FrameSinks from
ui::Compositors. These compositors then make a new LayerTreeFrameSink
coming back to the VizProcessTransportFactory.

Also eliminate the call to EstablishGpuChannel if software compositing
is being used, and jump right to OnEstablishedGpuChannel() with a null
GpuChannelHost.

R=kylechar@chromium.org

Bug: 730660
Change-Id: I54feb3be3b27993c8b87a3ee30a210e540b2b1c8
Reviewed-on: https://chromium-review.googlesource.com/789553
Commit-Queue: danakj <danakj@chromium.org>
Reviewed-by: default avatarkylechar <kylechar@chromium.org>
Cr-Commit-Position: refs/heads/master@{#520135}
parent e82c931d
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
#include "content/browser/gpu/gpu_process_host.h" #include "content/browser/gpu/gpu_process_host.h"
#include "content/common/gpu_stream_constants.h" #include "content/common/gpu_stream_constants.h"
#include "content/public/common/content_client.h" #include "content/public/common/content_client.h"
#include "content/public/common/content_switches.h"
#include "gpu/command_buffer/client/gles2_interface.h" #include "gpu/command_buffer/client/gles2_interface.h"
#include "gpu/command_buffer/common/context_result.h" #include "gpu/command_buffer/common/context_result.h"
#include "gpu/ipc/client/gpu_channel_host.h" #include "gpu/ipc/client/gpu_channel_host.h"
...@@ -90,10 +91,17 @@ VizProcessTransportFactory::VizProcessTransportFactory( ...@@ -90,10 +91,17 @@ VizProcessTransportFactory::VizProcessTransportFactory(
base::BindRepeating(&VizProcessTransportFactory::OnGpuProcessLost, base::BindRepeating(&VizProcessTransportFactory::OnGpuProcessLost,
weak_ptr_factory_.GetWeakPtr())); weak_ptr_factory_.GetWeakPtr()));
// Make |this| a CompositingModeWatcher for the |forwarding_mode_reporter_|. base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
viz::mojom::CompositingModeWatcherPtr watcher_ptr; if (command_line->HasSwitch(switches::kDisableGpu) ||
compositing_mode_watcher_binding_.Bind(mojo::MakeRequest(&watcher_ptr)); command_line->HasSwitch(switches::kDisableGpuCompositing)) {
forwarding_mode_reporter_->AddCompositingModeWatcher(std::move(watcher_ptr)); CompositingModeFallbackToSoftware();
} else {
// Make |this| a CompositingModeWatcher for the |forwarding_mode_reporter_|.
viz::mojom::CompositingModeWatcherPtr watcher_ptr;
compositing_mode_watcher_binding_.Bind(mojo::MakeRequest(&watcher_ptr));
forwarding_mode_reporter_->AddCompositingModeWatcher(
std::move(watcher_ptr));
}
} }
VizProcessTransportFactory::~VizProcessTransportFactory() { VizProcessTransportFactory::~VizProcessTransportFactory() {
...@@ -140,9 +148,13 @@ void VizProcessTransportFactory::ConnectHostFrameSinkManager() { ...@@ -140,9 +148,13 @@ void VizProcessTransportFactory::ConnectHostFrameSinkManager() {
void VizProcessTransportFactory::CreateLayerTreeFrameSink( void VizProcessTransportFactory::CreateLayerTreeFrameSink(
base::WeakPtr<ui::Compositor> compositor) { base::WeakPtr<ui::Compositor> compositor) {
gpu_channel_establish_factory_->EstablishGpuChannel(base::Bind( if (is_gpu_compositing_disabled_ || compositor->force_software_compositor()) {
&VizProcessTransportFactory::CreateLayerTreeFrameSinkForGpuChannel, OnEstablishedGpuChannel(compositor, nullptr);
weak_ptr_factory_.GetWeakPtr(), compositor)); return;
}
gpu_channel_establish_factory_->EstablishGpuChannel(
base::Bind(&VizProcessTransportFactory::OnEstablishedGpuChannel,
weak_ptr_factory_.GetWeakPtr(), compositor));
} }
scoped_refptr<viz::ContextProvider> scoped_refptr<viz::ContextProvider>
...@@ -269,14 +281,7 @@ viz::FrameSinkManagerImpl* VizProcessTransportFactory::GetFrameSinkManager() { ...@@ -269,14 +281,7 @@ viz::FrameSinkManagerImpl* VizProcessTransportFactory::GetFrameSinkManager() {
} }
bool VizProcessTransportFactory::IsGpuCompositingDisabled() { bool VizProcessTransportFactory::IsGpuCompositingDisabled() {
// TODO(crbug.com/730660): Needs to listen to CompositingModeReporter. return is_gpu_compositing_disabled_;
// TODO(crbug.com/730660): And needs to be false if --disable-gpu-compositing,
// which in non-viz land blacklists it via GpuDataManagerImplPrivate's
// CanUseGpuBrowserCompositor(). We'll need to pass the flag to the viz
// process probably when we try to get CanUseGpuBrowserCompositor() to be
// decided there.
NOTIMPLEMENTED();
return false;
} }
ui::ContextFactory* VizProcessTransportFactory::GetContextFactory() { ui::ContextFactory* VizProcessTransportFactory::GetContextFactory() {
...@@ -303,31 +308,70 @@ void VizProcessTransportFactory::SetCompositorSuspendedForRecycle( ...@@ -303,31 +308,70 @@ void VizProcessTransportFactory::SetCompositorSuspendedForRecycle(
#endif #endif
void VizProcessTransportFactory::CompositingModeFallbackToSoftware() { void VizProcessTransportFactory::CompositingModeFallbackToSoftware() {
// TODO(crbug.com/730660): Make the UI compositors fallback to software. // This may happen multiple times, since when the viz process (re)starts, it
NOTIMPLEMENTED(); // will send this notification if gpu is disabled.
if (is_gpu_compositing_disabled_)
return;
// Change the result of IsGpuCompositingDisabled() before notifying anything.
is_gpu_compositing_disabled_ = true;
// Consumers of the shared main thread context aren't CompositingModeWatchers,
// so inform them about the compositing mode switch by acting like the context
// was lost. This also destroys the contexts since they aren't created when
// gpu compositing isn't being used.
OnLostMainThreadSharedContext();
// Here we remove the FrameSink from every compositor that needs to fall back
// to software compositing.
//
// Releasing the FrameSink from the compositor will remove it from
// |compositor_data_map_|, so we can't do that while iterating though the
// collection.
std::vector<ui::Compositor*> to_release;
to_release.reserve(compositor_data_map_.size());
for (auto& pair : compositor_data_map_) {
ui::Compositor* compositor = pair.first;
if (!compositor->force_software_compositor())
to_release.push_back(compositor);
}
for (ui::Compositor* compositor : to_release) {
// Compositor expects to be not visible when releasing its FrameSink.
bool visible = compositor->IsVisible();
compositor->SetVisible(false);
gfx::AcceleratedWidget widget = compositor->ReleaseAcceleratedWidget();
compositor->SetAcceleratedWidget(widget);
if (visible)
compositor->SetVisible(true);
}
} }
void VizProcessTransportFactory::OnGpuProcessLost() { void VizProcessTransportFactory::OnGpuProcessLost() {
// Reconnect HostFrameSinkManager to new GPU process. // Reconnect HostFrameSinkManager to new GPU process.
ConnectHostFrameSinkManager(); ConnectHostFrameSinkManager();
for (auto& observer : observer_list_) OnLostMainThreadSharedContext();
observer.OnLostResources();
} }
void VizProcessTransportFactory::CreateLayerTreeFrameSinkForGpuChannel( void VizProcessTransportFactory::OnEstablishedGpuChannel(
base::WeakPtr<ui::Compositor> compositor_weak_ptr, base::WeakPtr<ui::Compositor> compositor_weak_ptr,
scoped_refptr<gpu::GpuChannelHost> gpu_channel_host) { scoped_refptr<gpu::GpuChannelHost> gpu_channel_host) {
ui::Compositor* compositor = compositor_weak_ptr.get(); ui::Compositor* compositor = compositor_weak_ptr.get();
if (!compositor) if (!compositor)
return; return;
if (!CreateContextProviders(std::move(gpu_channel_host))) { if (!gpu_channel_host ||
!CreateContextProviders(std::move(gpu_channel_host))) {
// TODO(kylechar): Retry ContextProvider creation if it failed. // TODO(kylechar): Retry ContextProvider creation if it failed.
NOTIMPLEMENTED(); NOTIMPLEMENTED();
return; return;
} }
// TODO(crbug.com/730660): If is_gpu_compositing_disabled_ then make a
// software-based CompositorFrameSink.
// TODO(crbug.com/730660): If compositor->force_software_compositor() then
// make a software-based CompositorFrameSink.
// TODO(crbug.com/776050): Deal with context loss. // TODO(crbug.com/776050): Deal with context loss.
// Create interfaces for a root CompositorFrameSink. // Create interfaces for a root CompositorFrameSink.
...@@ -348,6 +392,8 @@ void VizProcessTransportFactory::CreateLayerTreeFrameSinkForGpuChannel( ...@@ -348,6 +392,8 @@ void VizProcessTransportFactory::CreateLayerTreeFrameSinkForGpuChannel(
#endif #endif
// Creates the viz end of the root CompositorFrameSink. // Creates the viz end of the root CompositorFrameSink.
// TODO(crbug.com/730660): If compositor->force_software_compositor() then
// make a software-based RootCompositorFrameSink.
GetHostFrameSinkManager()->CreateRootCompositorFrameSink( GetHostFrameSinkManager()->CreateRootCompositorFrameSink(
compositor->frame_sink_id(), surface_handle, renderer_settings_, compositor->frame_sink_id(), surface_handle, renderer_settings_,
std::move(sink_request), std::move(client), std::move(sink_request), std::move(client),
...@@ -411,6 +457,13 @@ bool VizProcessTransportFactory::CreateContextProviders( ...@@ -411,6 +457,13 @@ bool VizProcessTransportFactory::CreateContextProviders(
return true; return true;
} }
void VizProcessTransportFactory::OnLostMainThreadSharedContext() {
// TODO(danakj): When we implement making the shared context, we'll also
// have to recreate it here before calling OnLostResources().
for (auto& observer : observer_list_)
observer.OnLostResources();
}
VizProcessTransportFactory::CompositorData::CompositorData() = default; VizProcessTransportFactory::CompositorData::CompositorData() = default;
VizProcessTransportFactory::CompositorData::CompositorData( VizProcessTransportFactory::CompositorData::CompositorData(
CompositorData&& other) = default; CompositorData&& other) = default;
......
...@@ -127,7 +127,7 @@ class VizProcessTransportFactory : public ui::ContextFactory, ...@@ -127,7 +127,7 @@ class VizProcessTransportFactory : public ui::ContextFactory,
// Finishes creation of LayerTreeFrameSink after GPU channel has been // Finishes creation of LayerTreeFrameSink after GPU channel has been
// established. // established.
void CreateLayerTreeFrameSinkForGpuChannel( void OnEstablishedGpuChannel(
base::WeakPtr<ui::Compositor> compositor_weak_ptr, base::WeakPtr<ui::Compositor> compositor_weak_ptr,
scoped_refptr<gpu::GpuChannelHost> gpu_channel); scoped_refptr<gpu::GpuChannelHost> gpu_channel);
...@@ -137,6 +137,8 @@ class VizProcessTransportFactory : public ui::ContextFactory, ...@@ -137,6 +137,8 @@ class VizProcessTransportFactory : public ui::ContextFactory,
bool CreateContextProviders( bool CreateContextProviders(
scoped_refptr<gpu::GpuChannelHost> gpu_channel_host); scoped_refptr<gpu::GpuChannelHost> gpu_channel_host);
void OnLostMainThreadSharedContext();
gpu::GpuChannelEstablishFactory* const gpu_channel_establish_factory_; gpu::GpuChannelEstablishFactory* const gpu_channel_establish_factory_;
scoped_refptr<base::SingleThreadTaskRunner> const resize_task_runner_; scoped_refptr<base::SingleThreadTaskRunner> const resize_task_runner_;
// Acts as a proxy from the mojo connection to the authoritive // Acts as a proxy from the mojo connection to the authoritive
...@@ -147,6 +149,7 @@ class VizProcessTransportFactory : public ui::ContextFactory, ...@@ -147,6 +149,7 @@ class VizProcessTransportFactory : public ui::ContextFactory,
viz::ForwardingCompositingModeReporterImpl* const forwarding_mode_reporter_; viz::ForwardingCompositingModeReporterImpl* const forwarding_mode_reporter_;
base::flat_map<ui::Compositor*, CompositorData> compositor_data_map_; base::flat_map<ui::Compositor*, CompositorData> compositor_data_map_;
bool is_gpu_compositing_disabled_ = false;
// TODO(kylechar): Call OnContextLost() on observers when GPU crashes. // TODO(kylechar): Call OnContextLost() on observers when GPU crashes.
base::ObserverList<ui::ContextFactoryObserver> observer_list_; base::ObserverList<ui::ContextFactoryObserver> observer_list_;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment