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..7b14ea5ed61bbdceff8c65ab2e23947b7df184a6 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" |
@@ -40,11 +41,11 @@ std::unique_ptr<base::MessagePump> CreateMessagePumpMac() { |
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 +87,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 +101,34 @@ GpuMain::~GpuMain() { |
} |
void GpuMain::OnStart() { |
+ // |this| will outlive the gpu thread and so it's safe to use |
+ // 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) { |
+ // |this| will outlive the gpu thread and so it's safe to use |
+ // 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 +138,68 @@ 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) { |
+ DCHECK(!gpu_command_service_); |
+ gpu_command_service_ = new gpu::GpuInProcessThreadService( |
+ 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 +208,22 @@ void GpuMain::TearDownOnGpuThread() { |
gpu_init_.reset(); |
} |
-void GpuMain::CreateOnGpuThread(mojom::GpuServiceInternalRequest request) { |
- if (gpu_service_internal_) |
- gpu_service_internal_->Add(std::move(request)); |
+void GpuMain::CreateGpuServiceOnGpuThread( |
+ mojom::GpuServiceInternalRequest request, |
+ scoped_refptr<base::SingleThreadTaskRunner> origin_runner, |
+ const CreateGpuServiceCallback& callback) { |
+ 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(callback, gpu_service_internal_->gpu_info())); |
+ } |
} |
void GpuMain::PreSandboxStartup() { |