Commit dc8a048f authored by kylechar's avatar kylechar Committed by Commit Bot

viz: Add shared main thread context provider code.

In VizProcessTransportFactory we already have a context provider that is
shared on the main thread. It's used for all ui::Compositors already.
Implement VizProcessTransportFactory::SharedMainThreadContextProvider()
to return that context provider.

Bug: 776050
Change-Id: Ie113fab9d2b49042f173138e4f9f143b191ae848
Reviewed-on: https://chromium-review.googlesource.com/827687
Commit-Queue: kylechar <kylechar@chromium.org>
Reviewed-by: default avatardanakj <danakj@chromium.org>
Cr-Commit-Position: refs/heads/master@{#526721}
parent 178aeca9
...@@ -72,18 +72,12 @@ scoped_refptr<ui::ContextProviderCommandBuffer> CreateContextProviderImpl( ...@@ -72,18 +72,12 @@ scoped_refptr<ui::ContextProviderCommandBuffer> CreateContextProviderImpl(
gpu::SharedMemoryLimits(), attributes, nullptr /* share_context */, type); gpu::SharedMemoryLimits(), attributes, nullptr /* share_context */, type);
} }
bool CheckContextLost(viz::ContextProvider* context_provider) { bool IsContextLost(viz::ContextProvider* context_provider) {
if (!context_provider)
return false;
return context_provider->ContextGL()->GetGraphicsResetStatusKHR() != return context_provider->ContextGL()->GetGraphicsResetStatusKHR() !=
GL_NO_ERROR; GL_NO_ERROR;
} }
bool CheckWorkerContextLost(viz::RasterContextProvider* context_provider) { bool IsWorkerContextLost(viz::RasterContextProvider* context_provider) {
if (!context_provider)
return false;
viz::RasterContextProvider::ScopedRasterContextLock lock(context_provider); viz::RasterContextProvider::ScopedRasterContextLock lock(context_provider);
return lock.RasterInterface()->GetGraphicsResetStatusKHR() != GL_NO_ERROR; return lock.RasterInterface()->GetGraphicsResetStatusKHR() != GL_NO_ERROR;
} }
...@@ -124,6 +118,9 @@ VizProcessTransportFactory::VizProcessTransportFactory( ...@@ -124,6 +118,9 @@ VizProcessTransportFactory::VizProcessTransportFactory(
} }
VizProcessTransportFactory::~VizProcessTransportFactory() { VizProcessTransportFactory::~VizProcessTransportFactory() {
if (main_context_provider_)
main_context_provider_->RemoveObserver(this);
task_graph_runner_->Shutdown(); task_graph_runner_->Shutdown();
} }
...@@ -183,8 +180,15 @@ void VizProcessTransportFactory::CreateLayerTreeFrameSink( ...@@ -183,8 +180,15 @@ void VizProcessTransportFactory::CreateLayerTreeFrameSink(
scoped_refptr<viz::ContextProvider> scoped_refptr<viz::ContextProvider>
VizProcessTransportFactory::SharedMainThreadContextProvider() { VizProcessTransportFactory::SharedMainThreadContextProvider() {
NOTIMPLEMENTED(); if (is_gpu_compositing_disabled_)
return nullptr; return nullptr;
if (!main_context_provider_) {
CreateContextProviders(
gpu_channel_establish_factory_->EstablishGpuChannelSync());
}
return main_context_provider_;
} }
void VizProcessTransportFactory::RemoveCompositor(ui::Compositor* compositor) { void VizProcessTransportFactory::RemoveCompositor(ui::Compositor* compositor) {
...@@ -338,8 +342,7 @@ VizProcessTransportFactory::GetContextFactoryPrivate() { ...@@ -338,8 +342,7 @@ VizProcessTransportFactory::GetContextFactoryPrivate() {
} }
viz::GLHelper* VizProcessTransportFactory::GetGLHelper() { viz::GLHelper* VizProcessTransportFactory::GetGLHelper() {
// TODO(kylechar): Figure out if GLHelper in the host process makes sense. NOTREACHED(); // Readback happens in the GPU process and this isn't used.
NOTREACHED();
return nullptr; return nullptr;
} }
...@@ -367,8 +370,11 @@ void VizProcessTransportFactory::CompositingModeFallbackToSoftware() { ...@@ -367,8 +370,11 @@ void VizProcessTransportFactory::CompositingModeFallbackToSoftware() {
OnLostMainThreadSharedContext(); OnLostMainThreadSharedContext();
// Drop our reference on the gpu contexts for the compositors. // Drop our reference on the gpu contexts for the compositors.
shared_worker_context_provider_ = nullptr; worker_context_provider_ = nullptr;
compositor_context_provider_ = nullptr; if (main_context_provider_) {
main_context_provider_->RemoveObserver(this);
main_context_provider_ = nullptr;
}
// Here we remove the FrameSink from every compositor that needs to fall back // Here we remove the FrameSink from every compositor that needs to fall back
// to software compositing. // to software compositing.
...@@ -394,11 +400,19 @@ void VizProcessTransportFactory::CompositingModeFallbackToSoftware() { ...@@ -394,11 +400,19 @@ void VizProcessTransportFactory::CompositingModeFallbackToSoftware() {
} }
} }
void VizProcessTransportFactory::OnContextLost() {
// TODO(kylechar): If the context is lost but the GPU process hasn't crashed
// then CompositorFrameSink data in HostFrameSinkManager (browser process) and
// FrameSinkManagerImpl (GPU process) needs to be cleaned up.
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE,
base::BindOnce(&VizProcessTransportFactory::OnLostMainThreadSharedContext,
weak_ptr_factory_.GetWeakPtr()));
}
void VizProcessTransportFactory::OnGpuProcessLost() { void VizProcessTransportFactory::OnGpuProcessLost() {
// Reconnect HostFrameSinkManager to new GPU process. // Reconnect HostFrameSinkManager to new GPU process.
ConnectHostFrameSinkManager(); ConnectHostFrameSinkManager();
OnLostMainThreadSharedContext();
} }
void VizProcessTransportFactory::OnEstablishedGpuChannel( void VizProcessTransportFactory::OnEstablishedGpuChannel(
...@@ -429,8 +443,6 @@ void VizProcessTransportFactory::OnEstablishedGpuChannel( ...@@ -429,8 +443,6 @@ void VizProcessTransportFactory::OnEstablishedGpuChannel(
compositor->widget()); compositor->widget());
#endif #endif
// TODO(crbug.com/776050): Deal with context loss.
// Create interfaces for a root CompositorFrameSink. // Create interfaces for a root CompositorFrameSink.
viz::mojom::CompositorFrameSinkAssociatedPtrInfo sink_info; viz::mojom::CompositorFrameSinkAssociatedPtrInfo sink_info;
viz::mojom::CompositorFrameSinkAssociatedRequest sink_request = viz::mojom::CompositorFrameSinkAssociatedRequest sink_request =
...@@ -476,9 +488,8 @@ void VizProcessTransportFactory::OnEstablishedGpuChannel( ...@@ -476,9 +488,8 @@ void VizProcessTransportFactory::OnEstablishedGpuChannel(
scoped_refptr<viz::RasterContextProvider> worker_context; scoped_refptr<viz::RasterContextProvider> worker_context;
if (gpu_compositing) { if (gpu_compositing) {
// Only pass the contexts to the compositor if it will use gpu compositing. // Only pass the contexts to the compositor if it will use gpu compositing.
compositor_context = compositor_context_provider_; compositor_context = main_context_provider_;
if (shared_worker_context_provider_) worker_context = worker_context_provider_;
worker_context = shared_worker_context_provider_;
} }
compositor->SetLayerTreeFrameSink( compositor->SetLayerTreeFrameSink(
std::make_unique<viz::ClientLayerTreeFrameSink>( std::make_unique<viz::ClientLayerTreeFrameSink>(
...@@ -499,38 +510,46 @@ bool VizProcessTransportFactory::CreateContextProviders( ...@@ -499,38 +510,46 @@ bool VizProcessTransportFactory::CreateContextProviders(
constexpr bool kCompositorContextSupportsGLES2 = true; constexpr bool kCompositorContextSupportsGLES2 = true;
constexpr bool kCompositorContextSupportsRaster = false; constexpr bool kCompositorContextSupportsRaster = false;
if (CheckContextLost(compositor_context_provider_.get())) if (main_context_provider_ && IsContextLost(main_context_provider_.get())) {
compositor_context_provider_ = nullptr; main_context_provider_->RemoveObserver(this);
main_context_provider_ = nullptr;
}
if (CheckWorkerContextLost(shared_worker_context_provider_.get())) if (worker_context_provider_ &&
shared_worker_context_provider_ = nullptr; IsWorkerContextLost(worker_context_provider_.get()))
worker_context_provider_ = nullptr;
if (!shared_worker_context_provider_) { if (!worker_context_provider_) {
shared_worker_context_provider_ = CreateContextProviderImpl( worker_context_provider_ = CreateContextProviderImpl(
gpu_channel_host, GetGpuMemoryBufferManager(), gpu_channel_host, GetGpuMemoryBufferManager(),
kSharedWorkerContextSupportsLocking, kSharedWorkerContextSupportsGLES2, kSharedWorkerContextSupportsLocking, kSharedWorkerContextSupportsGLES2,
kSharedWorkerContextSupportsRaster, kSharedWorkerContextSupportsRaster,
ui::command_buffer_metrics::BROWSER_WORKER_CONTEXT); ui::command_buffer_metrics::BROWSER_WORKER_CONTEXT);
auto result = shared_worker_context_provider_->BindToCurrentThread(); // Don't observer context loss on |worker_context_provider_| here, that is
// already observered by LayerTreeFrameSink. The lost context will be caught
// when recreating LayerTreeFrameSink(s).
auto result = worker_context_provider_->BindToCurrentThread();
if (result != gpu::ContextResult::kSuccess) { if (result != gpu::ContextResult::kSuccess) {
shared_worker_context_provider_ = nullptr; worker_context_provider_ = nullptr;
return false; return false;
} }
} }
if (!compositor_context_provider_) { if (!main_context_provider_) {
compositor_context_provider_ = CreateContextProviderImpl( main_context_provider_ = CreateContextProviderImpl(
std::move(gpu_channel_host), GetGpuMemoryBufferManager(), std::move(gpu_channel_host), GetGpuMemoryBufferManager(),
kCompositorContextSupportsLocking, kCompositorContextSupportsGLES2, kCompositorContextSupportsLocking, kCompositorContextSupportsGLES2,
kCompositorContextSupportsRaster, kCompositorContextSupportsRaster,
ui::command_buffer_metrics::UI_COMPOSITOR_CONTEXT); ui::command_buffer_metrics::UI_COMPOSITOR_CONTEXT);
compositor_context_provider_->SetDefaultTaskRunner(resize_task_runner_); main_context_provider_->SetDefaultTaskRunner(resize_task_runner_);
main_context_provider_->AddObserver(this);
auto result = compositor_context_provider_->BindToCurrentThread(); auto result = main_context_provider_->BindToCurrentThread();
if (result != gpu::ContextResult::kSuccess) { if (result != gpu::ContextResult::kSuccess) {
compositor_context_provider_ = nullptr; main_context_provider_->RemoveObserver(this);
shared_worker_context_provider_ = nullptr; main_context_provider_ = nullptr;
worker_context_provider_ = nullptr;
return false; return false;
} }
} }
...@@ -539,8 +558,13 @@ bool VizProcessTransportFactory::CreateContextProviders( ...@@ -539,8 +558,13 @@ bool VizProcessTransportFactory::CreateContextProviders(
} }
void VizProcessTransportFactory::OnLostMainThreadSharedContext() { void VizProcessTransportFactory::OnLostMainThreadSharedContext() {
// TODO(danakj): When we implement making the shared context, we'll also // It's possible that |main_context_provider_| was already reset in
// have to recreate it here before calling OnLostResources(). // OnEstablishedGpuChannel(), so check if it's lost before resetting here.
if (main_context_provider_ && IsContextLost(main_context_provider_.get())) {
main_context_provider_->RemoveObserver(this);
main_context_provider_ = nullptr;
}
for (auto& observer : observer_list_) for (auto& observer : observer_list_)
observer.OnLostResources(); observer.OnLostResources();
} }
......
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#include "base/macros.h" #include "base/macros.h"
#include "build/build_config.h" #include "build/build_config.h"
#include "components/viz/common/display/renderer_settings.h" #include "components/viz/common/display/renderer_settings.h"
#include "components/viz/common/gpu/context_lost_observer.h"
#include "components/viz/common/surfaces/frame_sink_id_allocator.h" #include "components/viz/common/surfaces/frame_sink_id_allocator.h"
#include "content/browser/compositor/image_transport_factory.h" #include "content/browser/compositor/image_transport_factory.h"
#include "content/browser/compositor/in_process_display_client.h" #include "content/browser/compositor/in_process_display_client.h"
...@@ -51,7 +52,8 @@ namespace content { ...@@ -51,7 +52,8 @@ namespace content {
class VizProcessTransportFactory : public ui::ContextFactory, class VizProcessTransportFactory : public ui::ContextFactory,
public ui::ContextFactoryPrivate, public ui::ContextFactoryPrivate,
public ImageTransportFactory, public ImageTransportFactory,
public viz::mojom::CompositingModeWatcher { public viz::mojom::CompositingModeWatcher,
public viz::ContextLostObserver {
public: public:
VizProcessTransportFactory( VizProcessTransportFactory(
gpu::GpuChannelEstablishFactory* gpu_channel_establish_factory, gpu::GpuChannelEstablishFactory* gpu_channel_establish_factory,
...@@ -112,6 +114,9 @@ class VizProcessTransportFactory : public ui::ContextFactory, ...@@ -112,6 +114,9 @@ class VizProcessTransportFactory : public ui::ContextFactory,
// viz::mojom::CompositingModeWatcher implementation. // viz::mojom::CompositingModeWatcher implementation.
void CompositingModeFallbackToSoftware() override; void CompositingModeFallbackToSoftware() override;
// viz::ContextLostObserver implementation.
void OnContextLost() override;
private: private:
struct CompositorData { struct CompositorData {
CompositorData(); CompositorData();
...@@ -157,12 +162,16 @@ class VizProcessTransportFactory : public ui::ContextFactory, ...@@ -157,12 +162,16 @@ class VizProcessTransportFactory : public ui::ContextFactory,
base::flat_map<ui::Compositor*, CompositorData> compositor_data_map_; base::flat_map<ui::Compositor*, CompositorData> compositor_data_map_;
bool is_gpu_compositing_disabled_ = false; bool is_gpu_compositing_disabled_ = false;
// TODO(kylechar): Call OnContextLost() on observers when GPU crashes.
base::ObserverList<ui::ContextFactoryObserver> observer_list_; base::ObserverList<ui::ContextFactoryObserver> observer_list_;
std::unique_ptr<viz::ClientSharedBitmapManager> shared_bitmap_manager_; std::unique_ptr<viz::ClientSharedBitmapManager> shared_bitmap_manager_;
scoped_refptr<viz::RasterContextProvider> shared_worker_context_provider_;
scoped_refptr<ui::ContextProviderCommandBuffer> compositor_context_provider_; // ContextProvider used on worker threads for rasterization.
scoped_refptr<viz::RasterContextProvider> worker_context_provider_;
// ContextProvider used on the main thread. Shared by ui::Compositors and also
// returned from GetSharedMainThreadContextProvider().
scoped_refptr<ui::ContextProviderCommandBuffer> main_context_provider_;
viz::FrameSinkIdAllocator frame_sink_id_allocator_; viz::FrameSinkIdAllocator frame_sink_id_allocator_;
std::unique_ptr<cc::SingleThreadTaskGraphRunner> task_graph_runner_; std::unique_ptr<cc::SingleThreadTaskGraphRunner> task_graph_runner_;
......
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