Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "services/ui/gpu/gpu_main.h" | 5 #include "services/ui/gpu/gpu_main.h" |
| 6 | 6 |
| 7 #include "base/command_line.h" | 7 #include "base/command_line.h" |
| 8 #include "base/message_loop/message_loop.h" | 8 #include "base/message_loop/message_loop.h" |
| 9 #include "gpu/ipc/common/gpu_memory_buffer_support.h" | 9 #include "gpu/ipc/common/gpu_memory_buffer_support.h" |
| 10 #include "gpu/ipc/gpu_in_process_thread_service.h" | |
| 10 #include "gpu/ipc/service/gpu_memory_buffer_factory.h" | 11 #include "gpu/ipc/service/gpu_memory_buffer_factory.h" |
| 11 #include "gpu/ipc/service/gpu_watchdog_thread.h" | 12 #include "gpu/ipc/service/gpu_watchdog_thread.h" |
| 12 #include "services/ui/gpu/gpu_service_internal.h" | 13 #include "services/ui/gpu/gpu_service_internal.h" |
| 13 | 14 |
| 14 namespace { | 15 namespace { |
| 15 | 16 |
| 16 #if defined(OS_WIN) | 17 #if defined(OS_WIN) |
| 17 std::unique_ptr<base::MessagePump> CreateMessagePumpWin() { | 18 std::unique_ptr<base::MessagePump> CreateMessagePumpWin() { |
| 18 base::MessagePumpForGpu::InitFactory(); | 19 base::MessagePumpForGpu::InitFactory(); |
| 19 return base::MessageLoop::CreateMessagePumpForType( | 20 return base::MessageLoop::CreateMessagePumpForType( |
| 20 base::MessageLoop::TYPE_UI); | 21 base::MessageLoop::TYPE_UI); |
| 21 } | 22 } |
| 22 #endif // defined(OS_WIN) | 23 #endif // defined(OS_WIN) |
| 23 | 24 |
| 24 #if defined(USE_X11) | 25 #if defined(USE_X11) |
| 25 std::unique_ptr<base::MessagePump> CreateMessagePumpX11() { | 26 std::unique_ptr<base::MessagePump> CreateMessagePumpX11() { |
| 26 // TODO(sad): This should create a TYPE_UI message pump, and create a | 27 // TODO(sad): This should create a TYPE_UI message pump, and create a |
| 27 // PlatformEventSource when gpu process split happens. | 28 // PlatformEventSource when gpu process split happens. |
| 28 return base::MessageLoop::CreateMessagePumpForType( | 29 return base::MessageLoop::CreateMessagePumpForType( |
| 29 base::MessageLoop::TYPE_DEFAULT); | 30 base::MessageLoop::TYPE_DEFAULT); |
| 30 } | 31 } |
| 31 #endif // defined(USE_X11) | 32 #endif // defined(USE_X11) |
| 32 | 33 |
| 33 #if defined(OS_MACOSX) | 34 #if defined(OS_MACOSX) |
| 34 std::unique_ptr<base::MessagePump> CreateMessagePumpMac() { | 35 std::unique_ptr<base::MessagePump> CreateMessagePumpMac() { |
| 35 return base::MakeUnique<base::MessagePumpCFRunLoop>(); | 36 return base::MakeUnique<base::MessagePumpCFRunLoop>(); |
| 36 } | 37 } |
| 37 #endif // defined(OS_MACOSX) | 38 #endif // defined(OS_MACOSX) |
| 38 | 39 |
| 40 using CreateGpuServiceCallback = base::Callback<void(const gpu::GPUInfo&)>; | |
| 41 void CallCreateGpuServiceCallbackOnOriginThread( | |
| 42 const CreateGpuServiceCallback& callback, | |
| 43 const gpu::GPUInfo& gpu_info) { | |
| 44 if (!callback.is_null()) | |
| 45 callback.Run(gpu_info); | |
| 46 } | |
| 47 | |
| 39 } // namespace | 48 } // namespace |
| 40 | 49 |
| 41 namespace ui { | 50 namespace ui { |
| 42 | 51 |
| 43 GpuMain::GpuMain() | 52 GpuMain::GpuMain(mojom::GpuMainRequest request) |
| 44 : gpu_thread_("GpuThread"), | 53 : gpu_thread_("GpuThread"), |
| 45 io_thread_("GpuIOThread"), | 54 io_thread_("GpuIOThread"), |
| 46 compositor_thread_("DisplayCompositorThread"), | 55 compositor_thread_("DisplayCompositorThread"), |
| 47 weak_factory_(this) { | 56 binding_(this, std::move(request)) { |
| 48 base::Thread::Options thread_options; | 57 base::Thread::Options thread_options; |
| 49 | 58 |
| 50 #if defined(OS_WIN) | 59 #if defined(OS_WIN) |
| 51 thread_options.message_pump_factory = base::Bind(&CreateMessagePumpWin); | 60 thread_options.message_pump_factory = base::Bind(&CreateMessagePumpWin); |
| 52 #elif defined(USE_X11) | 61 #elif defined(USE_X11) |
| 53 thread_options.message_pump_factory = base::Bind(&CreateMessagePumpX11); | 62 thread_options.message_pump_factory = base::Bind(&CreateMessagePumpX11); |
| 54 #elif defined(USE_OZONE) | 63 #elif defined(USE_OZONE) |
| 55 thread_options.message_loop_type = base::MessageLoop::TYPE_UI; | 64 thread_options.message_loop_type = base::MessageLoop::TYPE_UI; |
| 56 #elif defined(OS_LINUX) | 65 #elif defined(OS_LINUX) |
| 57 thread_options.message_loop_type = base::MessageLoop::TYPE_DEFAULT; | 66 thread_options.message_loop_type = base::MessageLoop::TYPE_DEFAULT; |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 79 | 88 |
| 80 // Start the compositor thread. | 89 // Start the compositor thread. |
| 81 compositor_thread_.Start(); | 90 compositor_thread_.Start(); |
| 82 } | 91 } |
| 83 | 92 |
| 84 GpuMain::~GpuMain() { | 93 GpuMain::~GpuMain() { |
| 85 // Unretained() is OK here since the thread/task runner is owned by |this|. | 94 // Unretained() is OK here since the thread/task runner is owned by |this|. |
| 86 compositor_thread_.task_runner()->PostTask( | 95 compositor_thread_.task_runner()->PostTask( |
| 87 FROM_HERE, | 96 FROM_HERE, |
| 88 base::Bind(&GpuMain::TearDownOnCompositorThread, base::Unretained(this))); | 97 base::Bind(&GpuMain::TearDownOnCompositorThread, base::Unretained(this))); |
| 98 | |
| 89 // Block the main thread until the compositor thread terminates which blocks | 99 // Block the main thread until the compositor thread terminates which blocks |
| 90 // on the gpu thread. The Stop must be initiated from here instead of the gpu | 100 // on the gpu thread. The Stop must be initiated from here instead of the gpu |
| 91 // thread to avoid deadlock. | 101 // thread to avoid deadlock. |
| 92 compositor_thread_.Stop(); | 102 compositor_thread_.Stop(); |
| 93 | 103 |
| 94 gpu_thread_.task_runner()->PostTask( | 104 gpu_thread_.task_runner()->PostTask( |
| 95 FROM_HERE, | 105 FROM_HERE, |
| 96 base::Bind(&GpuMain::TearDownOnGpuThread, base::Unretained(this))); | 106 base::Bind(&GpuMain::TearDownOnGpuThread, base::Unretained(this))); |
| 97 gpu_thread_.Stop(); | 107 gpu_thread_.Stop(); |
| 98 io_thread_.Stop(); | 108 io_thread_.Stop(); |
| 99 } | 109 } |
| 100 | 110 |
| 101 void GpuMain::OnStart() { | 111 void GpuMain::OnStart() { |
| 112 // 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.
| |
| 113 // base::Unretained here. | |
| 102 gpu_thread_.task_runner()->PostTask( | 114 gpu_thread_.task_runner()->PostTask( |
| 103 FROM_HERE, | 115 FROM_HERE, |
| 104 base::Bind(&GpuMain::InitOnGpuThread, weak_factory_.GetWeakPtr(), | 116 base::Bind(&GpuMain::InitOnGpuThread, base::Unretained(this), |
| 105 io_thread_.task_runner(), compositor_thread_.task_runner())); | 117 io_thread_.task_runner(), compositor_thread_.task_runner())); |
| 106 } | 118 } |
| 107 | 119 |
| 108 void GpuMain::Create(mojom::GpuServiceInternalRequest request) { | 120 void GpuMain::CreateGpuService(mojom::GpuServiceInternalRequest request, |
| 121 const CreateGpuServiceCallback& callback) { | |
| 122 // 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.
| |
| 123 // base::Unretained here. | |
| 109 gpu_thread_.task_runner()->PostTask( | 124 gpu_thread_.task_runner()->PostTask( |
| 110 FROM_HERE, | 125 FROM_HERE, |
| 111 base::Bind(&GpuMain::CreateOnGpuThread, weak_factory_.GetWeakPtr(), | 126 base::Bind(&GpuMain::CreateGpuServiceOnGpuThread, base::Unretained(this), |
| 112 base::Passed(std::move(request)))); | 127 base::Passed(std::move(request)), |
| 128 base::ThreadTaskRunnerHandle::Get(), callback)); | |
| 129 } | |
| 130 | |
| 131 void GpuMain::CreateDisplayCompositor( | |
| 132 cc::mojom::DisplayCompositorRequest request, | |
| 133 cc::mojom::DisplayCompositorClientPtr client) { | |
| 134 if (!gpu_service_internal_) { | |
| 135 pending_display_compositor_request_ = std::move(request); | |
| 136 pending_display_compositor_client_info_ = client.PassInterface(); | |
| 137 return; | |
| 138 } | |
| 139 CreateDisplayCompositorInternal(std::move(request), client.PassInterface()); | |
| 113 } | 140 } |
| 114 | 141 |
| 115 void GpuMain::InitOnGpuThread( | 142 void GpuMain::InitOnGpuThread( |
| 116 scoped_refptr<base::SingleThreadTaskRunner> io_runner, | 143 scoped_refptr<base::SingleThreadTaskRunner> io_runner, |
| 117 scoped_refptr<base::SingleThreadTaskRunner> compositor_runner) { | 144 scoped_refptr<base::SingleThreadTaskRunner> compositor_runner) { |
| 118 gpu_init_.reset(new gpu::GpuInit()); | 145 gpu_init_.reset(new gpu::GpuInit()); |
| 119 gpu_init_->set_sandbox_helper(this); | 146 gpu_init_->set_sandbox_helper(this); |
| 120 bool success = gpu_init_->InitializeAndStartSandbox( | 147 bool success = gpu_init_->InitializeAndStartSandbox( |
| 121 *base::CommandLine::ForCurrentProcess()); | 148 *base::CommandLine::ForCurrentProcess()); |
| 122 if (success) { | 149 if (!success) |
| 123 if (gpu::GetNativeGpuMemoryBufferType() != gfx::EMPTY_BUFFER) { | 150 return; |
| 124 gpu_memory_buffer_factory_ = | 151 |
| 125 gpu::GpuMemoryBufferFactory::CreateNativeType(); | 152 if (gpu::GetNativeGpuMemoryBufferType() != gfx::EMPTY_BUFFER) { |
| 126 } | 153 gpu_memory_buffer_factory_ = |
| 127 gpu_service_internal_.reset(new GpuServiceInternal( | 154 gpu::GpuMemoryBufferFactory::CreateNativeType(); |
| 128 gpu_init_->gpu_info(), gpu_init_->TakeWatchdogThread(), | |
| 129 gpu_memory_buffer_factory_.get(), io_runner, compositor_runner)); | |
| 130 } | 155 } |
| 156 | |
| 157 gpu_service_internal_ = base::MakeUnique<GpuServiceInternal>( | |
| 158 gpu_init_->gpu_info(), gpu_init_->TakeWatchdogThread(), | |
| 159 gpu_memory_buffer_factory_.get(), io_runner); | |
| 160 gpu_service_internal_->Initialize(); | |
| 161 } | |
| 162 | |
| 163 void GpuMain::CreateDisplayCompositorInternal( | |
| 164 cc::mojom::DisplayCompositorRequest request, | |
| 165 cc::mojom::DisplayCompositorClientPtrInfo client_info) { | |
| 166 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.
| |
| 167 gpu_thread_.task_runner(), gpu_service_internal_->sync_point_manager(), | |
| 168 gpu_service_internal_->mailbox_manager(), | |
| 169 gpu_service_internal_->share_group()); | |
| 170 | |
| 171 // |gpu_memory_buffer_factory_| is null in tests. | |
| 172 gpu::ImageFactory* image_factory = | |
| 173 gpu_memory_buffer_factory_ ? gpu_memory_buffer_factory_->AsImageFactory() | |
| 174 : nullptr; | |
| 175 | |
| 176 mojom::GpuServiceInternalPtr gpu_service; | |
| 177 mojom::GpuServiceInternalRequest gpu_service_request = | |
| 178 mojo::GetProxy(&gpu_service); | |
| 179 | |
| 180 CreateGpuService(std::move(gpu_service_request), CreateGpuServiceCallback()); | |
| 181 | |
| 182 compositor_thread_.task_runner()->PostTask( | |
| 183 FROM_HERE, base::Bind(&GpuMain::CreateDisplayCompositorOnCompositorThread, | |
| 184 base::Unretained(this), image_factory, | |
| 185 base::Passed(gpu_service.PassInterface()), | |
| 186 base::Passed(std::move(request)), | |
| 187 base::Passed(std::move(client_info)))); | |
| 188 } | |
| 189 | |
| 190 void GpuMain::CreateDisplayCompositorOnCompositorThread( | |
| 191 gpu::ImageFactory* image_factory, | |
| 192 mojom::GpuServiceInternalPtrInfo gpu_service_info, | |
| 193 cc::mojom::DisplayCompositorRequest request, | |
| 194 cc::mojom::DisplayCompositorClientPtrInfo client_info) { | |
| 195 DCHECK(!display_compositor_); | |
| 196 cc::mojom::DisplayCompositorClientPtr client; | |
| 197 client.Bind(std::move(client_info)); | |
| 198 | |
| 199 gpu_internal_.Bind(std::move(gpu_service_info)); | |
| 200 | |
| 201 display_compositor_ = base::MakeUnique<DisplayCompositor>( | |
| 202 gpu_command_service_, base::MakeUnique<MusGpuMemoryBufferManager>( | |
| 203 gpu_internal_.get(), 1 /* client_id */), | |
| 204 image_factory, std::move(request), std::move(client)); | |
| 131 } | 205 } |
| 132 | 206 |
| 133 void GpuMain::TearDownOnCompositorThread() { | 207 void GpuMain::TearDownOnCompositorThread() { |
| 134 if (gpu_service_internal_) | 208 display_compositor_.reset(); |
| 135 gpu_service_internal_->DestroyDisplayCompositor(); | 209 gpu_internal_.reset(); |
| 136 } | 210 } |
| 137 | 211 |
| 138 void GpuMain::TearDownOnGpuThread() { | 212 void GpuMain::TearDownOnGpuThread() { |
| 139 gpu_service_internal_.reset(); | 213 gpu_service_internal_.reset(); |
| 140 gpu_memory_buffer_factory_.reset(); | 214 gpu_memory_buffer_factory_.reset(); |
| 141 gpu_init_.reset(); | 215 gpu_init_.reset(); |
| 142 } | 216 } |
| 143 | 217 |
| 144 void GpuMain::CreateOnGpuThread(mojom::GpuServiceInternalRequest request) { | 218 void GpuMain::CreateGpuServiceOnGpuThread( |
| 219 mojom::GpuServiceInternalRequest request, | |
| 220 scoped_refptr<base::SingleThreadTaskRunner> origin_runner, | |
| 221 const CreateGpuServiceCallback& callback) { | |
| 145 if (gpu_service_internal_) | 222 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
| |
| 146 gpu_service_internal_->Add(std::move(request)); | 223 gpu_service_internal_->Bind(std::move(request)); |
| 224 | |
| 225 if (pending_display_compositor_request_.is_pending()) { | |
| 226 CreateDisplayCompositorInternal( | |
| 227 std::move(pending_display_compositor_request_), | |
| 228 std::move(pending_display_compositor_client_info_)); | |
| 229 } | |
| 230 | |
| 231 if (!callback.is_null()) { | |
| 232 origin_runner->PostTask( | |
| 233 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.
| |
| 234 callback, gpu_service_internal_->gpu_info())); | |
| 235 } | |
| 147 } | 236 } |
| 148 | 237 |
| 149 void GpuMain::PreSandboxStartup() { | 238 void GpuMain::PreSandboxStartup() { |
| 150 // TODO(sad): https://crbug.com/645602 | 239 // TODO(sad): https://crbug.com/645602 |
| 151 } | 240 } |
| 152 | 241 |
| 153 bool GpuMain::EnsureSandboxInitialized( | 242 bool GpuMain::EnsureSandboxInitialized( |
| 154 gpu::GpuWatchdogThread* watchdog_thread) { | 243 gpu::GpuWatchdogThread* watchdog_thread) { |
| 155 // TODO(sad): https://crbug.com/645602 | 244 // TODO(sad): https://crbug.com/645602 |
| 156 return true; | 245 return true; |
| 157 } | 246 } |
| 158 | 247 |
| 159 } // namespace ui | 248 } // namespace ui |
| OLD | NEW |