Chromium Code Reviews| Index: services/ui/gpu/gpu_main.cc |
| diff --git a/services/ui/gpu/gpu_main.cc b/services/ui/gpu/gpu_main.cc |
| index b41369f45d85a834243b8cf3a351427c97496280..83bab38e0ce6256edcbcdb8c98b9f49c7f0a29d6 100644 |
| --- a/services/ui/gpu/gpu_main.cc |
| +++ b/services/ui/gpu/gpu_main.cc |
| @@ -7,6 +7,7 @@ |
| #include "base/command_line.h" |
| #include "base/message_loop/message_loop.h" |
| #include "gpu/ipc/common/gpu_memory_buffer_support.h" |
| +#include "gpu/ipc/gpu_in_process_thread_service.h" |
| #include "gpu/ipc/service/gpu_memory_buffer_factory.h" |
| #include "gpu/ipc/service/gpu_watchdog_thread.h" |
| #include "services/ui/gpu/gpu_service_internal.h" |
| @@ -36,15 +37,23 @@ std::unique_ptr<base::MessagePump> CreateMessagePumpMac() { |
| } |
| #endif // defined(OS_MACOSX) |
| +using CreateGpuServiceCallback = base::Callback<void(const gpu::GPUInfo&)>; |
| +void CallCreateGpuServiceCallbackOnOriginThread( |
| + const CreateGpuServiceCallback& callback, |
| + const gpu::GPUInfo& gpu_info) { |
| + if (!callback.is_null()) |
| + callback.Run(gpu_info); |
| +} |
| + |
| } // namespace |
| namespace ui { |
| -GpuMain::GpuMain() |
| +GpuMain::GpuMain(mojom::GpuMainRequest request) |
| : gpu_thread_("GpuThread"), |
| io_thread_("GpuIOThread"), |
| compositor_thread_("DisplayCompositorThread"), |
| - weak_factory_(this) { |
| + binding_(this, std::move(request)) { |
| base::Thread::Options thread_options; |
| #if defined(OS_WIN) |
| @@ -86,6 +95,7 @@ GpuMain::~GpuMain() { |
| compositor_thread_.task_runner()->PostTask( |
| FROM_HERE, |
| base::Bind(&GpuMain::TearDownOnCompositorThread, base::Unretained(this))); |
| + |
| // Block the main thread until the compositor thread terminates which blocks |
| // on the gpu thread. The Stop must be initiated from here instead of the gpu |
| // thread to avoid deadlock. |
| @@ -99,17 +109,34 @@ GpuMain::~GpuMain() { |
| } |
| void GpuMain::OnStart() { |
| + // The client thread will outlive the gpu thread and so it's safe to use |
|
sadrul
2016/11/30 21:05:55
Did you mean s/The client thread/|this|/?
Fady Samuel
2016/11/30 22:53:20
Done.
|
| + // base::Unretained here. |
| gpu_thread_.task_runner()->PostTask( |
| FROM_HERE, |
| - base::Bind(&GpuMain::InitOnGpuThread, weak_factory_.GetWeakPtr(), |
| + base::Bind(&GpuMain::InitOnGpuThread, base::Unretained(this), |
| io_thread_.task_runner(), compositor_thread_.task_runner())); |
| } |
| -void GpuMain::Create(mojom::GpuServiceInternalRequest request) { |
| +void GpuMain::CreateGpuService(mojom::GpuServiceInternalRequest request, |
| + const CreateGpuServiceCallback& callback) { |
| + // The client thread will outlive the gpu thread and so it's safe to use |
|
sadrul
2016/11/30 21:05:55
ditto
Fady Samuel
2016/11/30 22:53:20
Done.
|
| + // base::Unretained here. |
| gpu_thread_.task_runner()->PostTask( |
| FROM_HERE, |
| - base::Bind(&GpuMain::CreateOnGpuThread, weak_factory_.GetWeakPtr(), |
| - base::Passed(std::move(request)))); |
| + base::Bind(&GpuMain::CreateGpuServiceOnGpuThread, base::Unretained(this), |
| + base::Passed(std::move(request)), |
| + base::ThreadTaskRunnerHandle::Get(), callback)); |
| +} |
| + |
| +void GpuMain::CreateDisplayCompositor( |
| + cc::mojom::DisplayCompositorRequest request, |
| + cc::mojom::DisplayCompositorClientPtr client) { |
| + if (!gpu_service_internal_) { |
| + pending_display_compositor_request_ = std::move(request); |
| + pending_display_compositor_client_info_ = client.PassInterface(); |
| + return; |
| + } |
| + CreateDisplayCompositorInternal(std::move(request), client.PassInterface()); |
| } |
| void GpuMain::InitOnGpuThread( |
| @@ -119,20 +146,67 @@ void GpuMain::InitOnGpuThread( |
| gpu_init_->set_sandbox_helper(this); |
| bool success = gpu_init_->InitializeAndStartSandbox( |
| *base::CommandLine::ForCurrentProcess()); |
| - if (success) { |
| - if (gpu::GetNativeGpuMemoryBufferType() != gfx::EMPTY_BUFFER) { |
| - gpu_memory_buffer_factory_ = |
| - gpu::GpuMemoryBufferFactory::CreateNativeType(); |
| - } |
| - gpu_service_internal_.reset(new GpuServiceInternal( |
| - gpu_init_->gpu_info(), gpu_init_->TakeWatchdogThread(), |
| - gpu_memory_buffer_factory_.get(), io_runner, compositor_runner)); |
| + if (!success) |
| + return; |
| + |
| + if (gpu::GetNativeGpuMemoryBufferType() != gfx::EMPTY_BUFFER) { |
| + gpu_memory_buffer_factory_ = |
| + gpu::GpuMemoryBufferFactory::CreateNativeType(); |
| } |
| + |
| + gpu_service_internal_ = base::MakeUnique<GpuServiceInternal>( |
| + gpu_init_->gpu_info(), gpu_init_->TakeWatchdogThread(), |
| + gpu_memory_buffer_factory_.get(), io_runner); |
| + gpu_service_internal_->Initialize(); |
| +} |
| + |
| +void GpuMain::CreateDisplayCompositorInternal( |
| + cc::mojom::DisplayCompositorRequest request, |
| + cc::mojom::DisplayCompositorClientPtrInfo client_info) { |
| + gpu_command_service_ = new gpu::GpuInProcessThreadService( |
|
sadrul
2016/11/30 21:13:14
Do we want to DCHECK() here that these don't alrea
Fady Samuel
2016/11/30 22:53:20
Done.
|
| + gpu_thread_.task_runner(), gpu_service_internal_->sync_point_manager(), |
| + gpu_service_internal_->mailbox_manager(), |
| + gpu_service_internal_->share_group()); |
| + |
| + // |gpu_memory_buffer_factory_| is null in tests. |
| + gpu::ImageFactory* image_factory = |
| + gpu_memory_buffer_factory_ ? gpu_memory_buffer_factory_->AsImageFactory() |
| + : nullptr; |
| + |
| + mojom::GpuServiceInternalPtr gpu_service; |
| + mojom::GpuServiceInternalRequest gpu_service_request = |
| + mojo::GetProxy(&gpu_service); |
| + |
| + CreateGpuService(std::move(gpu_service_request), CreateGpuServiceCallback()); |
| + |
| + compositor_thread_.task_runner()->PostTask( |
| + FROM_HERE, base::Bind(&GpuMain::CreateDisplayCompositorOnCompositorThread, |
| + base::Unretained(this), image_factory, |
| + base::Passed(gpu_service.PassInterface()), |
| + base::Passed(std::move(request)), |
| + base::Passed(std::move(client_info)))); |
| +} |
| + |
| +void GpuMain::CreateDisplayCompositorOnCompositorThread( |
| + gpu::ImageFactory* image_factory, |
| + mojom::GpuServiceInternalPtrInfo gpu_service_info, |
| + cc::mojom::DisplayCompositorRequest request, |
| + cc::mojom::DisplayCompositorClientPtrInfo client_info) { |
| + DCHECK(!display_compositor_); |
| + cc::mojom::DisplayCompositorClientPtr client; |
| + client.Bind(std::move(client_info)); |
| + |
| + gpu_internal_.Bind(std::move(gpu_service_info)); |
| + |
| + display_compositor_ = base::MakeUnique<DisplayCompositor>( |
| + gpu_command_service_, base::MakeUnique<MusGpuMemoryBufferManager>( |
| + gpu_internal_.get(), 1 /* client_id */), |
| + image_factory, std::move(request), std::move(client)); |
| } |
| void GpuMain::TearDownOnCompositorThread() { |
| - if (gpu_service_internal_) |
| - gpu_service_internal_->DestroyDisplayCompositor(); |
| + display_compositor_.reset(); |
| + gpu_internal_.reset(); |
| } |
| void GpuMain::TearDownOnGpuThread() { |
| @@ -141,9 +215,24 @@ void GpuMain::TearDownOnGpuThread() { |
| gpu_init_.reset(); |
| } |
| -void GpuMain::CreateOnGpuThread(mojom::GpuServiceInternalRequest request) { |
| +void GpuMain::CreateGpuServiceOnGpuThread( |
| + mojom::GpuServiceInternalRequest request, |
| + scoped_refptr<base::SingleThreadTaskRunner> origin_runner, |
| + const CreateGpuServiceCallback& callback) { |
| if (gpu_service_internal_) |
|
sadrul
2016/11/30 21:13:14
Maybe add a comment mentioning when this can be nu
Fady Samuel
2016/11/30 22:53:20
I don't think it can be actually because we create
|
| - gpu_service_internal_->Add(std::move(request)); |
| + gpu_service_internal_->Bind(std::move(request)); |
| + |
| + if (pending_display_compositor_request_.is_pending()) { |
| + CreateDisplayCompositorInternal( |
| + std::move(pending_display_compositor_request_), |
| + std::move(pending_display_compositor_client_info_)); |
| + } |
| + |
| + if (!callback.is_null()) { |
| + origin_runner->PostTask( |
| + FROM_HERE, base::Bind(&CallCreateGpuServiceCallbackOnOriginThread, |
|
sadrul
2016/11/30 21:05:55
Maybe just 'base::Bind(callback, gpu_info)' here?
Fady Samuel
2016/11/30 22:53:20
Done.
|
| + callback, gpu_service_internal_->gpu_info())); |
| + } |
| } |
| void GpuMain::PreSandboxStartup() { |