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(
gpu::SharedMemoryLimits(), attributes, nullptr /* share_context */, type);
}
bool CheckContextLost(viz::ContextProvider* context_provider) {
if (!context_provider)
return false;
bool IsContextLost(viz::ContextProvider* context_provider) {
return context_provider->ContextGL()->GetGraphicsResetStatusKHR() !=
GL_NO_ERROR;
}
bool CheckWorkerContextLost(viz::RasterContextProvider* context_provider) {
if (!context_provider)
return false;
bool IsWorkerContextLost(viz::RasterContextProvider* context_provider) {
viz::RasterContextProvider::ScopedRasterContextLock lock(context_provider);
return lock.RasterInterface()->GetGraphicsResetStatusKHR() != GL_NO_ERROR;
}
......@@ -124,6 +118,9 @@ VizProcessTransportFactory::VizProcessTransportFactory(
}
VizProcessTransportFactory::~VizProcessTransportFactory() {
if (main_context_provider_)
main_context_provider_->RemoveObserver(this);
task_graph_runner_->Shutdown();
}
......@@ -183,8 +180,15 @@ void VizProcessTransportFactory::CreateLayerTreeFrameSink(
scoped_refptr<viz::ContextProvider>
VizProcessTransportFactory::SharedMainThreadContextProvider() {
NOTIMPLEMENTED();
return nullptr;
if (is_gpu_compositing_disabled_)
return nullptr;
if (!main_context_provider_) {
CreateContextProviders(
gpu_channel_establish_factory_->EstablishGpuChannelSync());
}
return main_context_provider_;
}
void VizProcessTransportFactory::RemoveCompositor(ui::Compositor* compositor) {
......@@ -338,8 +342,7 @@ VizProcessTransportFactory::GetContextFactoryPrivate() {
}
viz::GLHelper* VizProcessTransportFactory::GetGLHelper() {
// TODO(kylechar): Figure out if GLHelper in the host process makes sense.
NOTREACHED();
NOTREACHED(); // Readback happens in the GPU process and this isn't used.
return nullptr;
}
......@@ -367,8 +370,11 @@ void VizProcessTransportFactory::CompositingModeFallbackToSoftware() {
OnLostMainThreadSharedContext();
// Drop our reference on the gpu contexts for the compositors.
shared_worker_context_provider_ = nullptr;
compositor_context_provider_ = nullptr;
worker_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
// to software compositing.
......@@ -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() {
// Reconnect HostFrameSinkManager to new GPU process.
ConnectHostFrameSinkManager();
OnLostMainThreadSharedContext();
}
void VizProcessTransportFactory::OnEstablishedGpuChannel(
......@@ -429,8 +443,6 @@ void VizProcessTransportFactory::OnEstablishedGpuChannel(
compositor->widget());
#endif
// TODO(crbug.com/776050): Deal with context loss.
// Create interfaces for a root CompositorFrameSink.
viz::mojom::CompositorFrameSinkAssociatedPtrInfo sink_info;
viz::mojom::CompositorFrameSinkAssociatedRequest sink_request =
......@@ -476,9 +488,8 @@ void VizProcessTransportFactory::OnEstablishedGpuChannel(
scoped_refptr<viz::RasterContextProvider> worker_context;
if (gpu_compositing) {
// Only pass the contexts to the compositor if it will use gpu compositing.
compositor_context = compositor_context_provider_;
if (shared_worker_context_provider_)
worker_context = shared_worker_context_provider_;
compositor_context = main_context_provider_;
worker_context = worker_context_provider_;
}
compositor->SetLayerTreeFrameSink(
std::make_unique<viz::ClientLayerTreeFrameSink>(
......@@ -499,38 +510,46 @@ bool VizProcessTransportFactory::CreateContextProviders(
constexpr bool kCompositorContextSupportsGLES2 = true;
constexpr bool kCompositorContextSupportsRaster = false;
if (CheckContextLost(compositor_context_provider_.get()))
compositor_context_provider_ = nullptr;
if (main_context_provider_ && IsContextLost(main_context_provider_.get())) {
main_context_provider_->RemoveObserver(this);
main_context_provider_ = nullptr;
}
if (CheckWorkerContextLost(shared_worker_context_provider_.get()))
shared_worker_context_provider_ = nullptr;
if (worker_context_provider_ &&
IsWorkerContextLost(worker_context_provider_.get()))
worker_context_provider_ = nullptr;
if (!shared_worker_context_provider_) {
shared_worker_context_provider_ = CreateContextProviderImpl(
if (!worker_context_provider_) {
worker_context_provider_ = CreateContextProviderImpl(
gpu_channel_host, GetGpuMemoryBufferManager(),
kSharedWorkerContextSupportsLocking, kSharedWorkerContextSupportsGLES2,
kSharedWorkerContextSupportsRaster,
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) {
shared_worker_context_provider_ = nullptr;
worker_context_provider_ = nullptr;
return false;
}
}
if (!compositor_context_provider_) {
compositor_context_provider_ = CreateContextProviderImpl(
if (!main_context_provider_) {
main_context_provider_ = CreateContextProviderImpl(
std::move(gpu_channel_host), GetGpuMemoryBufferManager(),
kCompositorContextSupportsLocking, kCompositorContextSupportsGLES2,
kCompositorContextSupportsRaster,
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) {
compositor_context_provider_ = nullptr;
shared_worker_context_provider_ = nullptr;
main_context_provider_->RemoveObserver(this);
main_context_provider_ = nullptr;
worker_context_provider_ = nullptr;
return false;
}
}
......@@ -539,8 +558,13 @@ bool VizProcessTransportFactory::CreateContextProviders(
}
void VizProcessTransportFactory::OnLostMainThreadSharedContext() {
// TODO(danakj): When we implement making the shared context, we'll also
// have to recreate it here before calling OnLostResources().
// It's possible that |main_context_provider_| was already reset in
// 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_)
observer.OnLostResources();
}
......
......@@ -11,6 +11,7 @@
#include "base/macros.h"
#include "build/build_config.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 "content/browser/compositor/image_transport_factory.h"
#include "content/browser/compositor/in_process_display_client.h"
......@@ -51,7 +52,8 @@ namespace content {
class VizProcessTransportFactory : public ui::ContextFactory,
public ui::ContextFactoryPrivate,
public ImageTransportFactory,
public viz::mojom::CompositingModeWatcher {
public viz::mojom::CompositingModeWatcher,
public viz::ContextLostObserver {
public:
VizProcessTransportFactory(
gpu::GpuChannelEstablishFactory* gpu_channel_establish_factory,
......@@ -112,6 +114,9 @@ class VizProcessTransportFactory : public ui::ContextFactory,
// viz::mojom::CompositingModeWatcher implementation.
void CompositingModeFallbackToSoftware() override;
// viz::ContextLostObserver implementation.
void OnContextLost() override;
private:
struct CompositorData {
CompositorData();
......@@ -157,12 +162,16 @@ class VizProcessTransportFactory : public ui::ContextFactory,
base::flat_map<ui::Compositor*, CompositorData> compositor_data_map_;
bool is_gpu_compositing_disabled_ = false;
// TODO(kylechar): Call OnContextLost() on observers when GPU crashes.
base::ObserverList<ui::ContextFactoryObserver> observer_list_;
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_;
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