| 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/memory/ptr_util.h" | 8 #include "base/memory/ptr_util.h" |
| 9 #include "base/message_loop/message_loop.h" | 9 #include "base/message_loop/message_loop.h" |
| 10 #include "base/power_monitor/power_monitor_device_source.h" | 10 #include "base/power_monitor/power_monitor_device_source.h" |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 45 | 45 |
| 46 } // namespace | 46 } // namespace |
| 47 | 47 |
| 48 namespace ui { | 48 namespace ui { |
| 49 | 49 |
| 50 GpuMain::GpuMain(mojom::GpuMainRequest request) | 50 GpuMain::GpuMain(mojom::GpuMainRequest request) |
| 51 : gpu_thread_("GpuThread"), | 51 : gpu_thread_("GpuThread"), |
| 52 io_thread_("GpuIOThread"), | 52 io_thread_("GpuIOThread"), |
| 53 compositor_thread_("DisplayCompositorThread"), | 53 compositor_thread_("DisplayCompositorThread"), |
| 54 power_monitor_(base::MakeUnique<base::PowerMonitorDeviceSource>()), | 54 power_monitor_(base::MakeUnique<base::PowerMonitorDeviceSource>()), |
| 55 binding_(this, std::move(request)) { | 55 binding_(this) { |
| 56 base::Thread::Options thread_options; | 56 base::Thread::Options thread_options; |
| 57 | 57 |
| 58 #if defined(OS_WIN) | 58 #if defined(OS_WIN) |
| 59 thread_options.message_loop_type = base::MessageLoop::TYPE_DEFAULT; | 59 thread_options.message_loop_type = base::MessageLoop::TYPE_DEFAULT; |
| 60 #elif defined(USE_X11) | 60 #elif defined(USE_X11) |
| 61 thread_options.message_pump_factory = base::Bind(&CreateMessagePumpX11); | 61 thread_options.message_pump_factory = base::Bind(&CreateMessagePumpX11); |
| 62 #elif defined(USE_OZONE) | 62 #elif defined(USE_OZONE) |
| 63 // The MessageLoop type required depends on the Ozone platform selected at | 63 // The MessageLoop type required depends on the Ozone platform selected at |
| 64 // runtime. | 64 // runtime. |
| 65 thread_options.message_loop_type = | 65 thread_options.message_loop_type = |
| (...skipping 19 matching lines...) Expand all Loading... |
| 85 #if defined(OS_ANDROID) || defined(OS_CHROMEOS) | 85 #if defined(OS_ANDROID) || defined(OS_CHROMEOS) |
| 86 // TODO(reveman): Remove this in favor of setting it explicitly for each type | 86 // TODO(reveman): Remove this in favor of setting it explicitly for each type |
| 87 // of process. | 87 // of process. |
| 88 thread_options.priority = base::ThreadPriority::DISPLAY; | 88 thread_options.priority = base::ThreadPriority::DISPLAY; |
| 89 #endif | 89 #endif |
| 90 CHECK(io_thread_.StartWithOptions(thread_options)); | 90 CHECK(io_thread_.StartWithOptions(thread_options)); |
| 91 | 91 |
| 92 // Start the compositor thread. | 92 // Start the compositor thread. |
| 93 compositor_thread_.Start(); | 93 compositor_thread_.Start(); |
| 94 compositor_thread_task_runner_ = compositor_thread_.task_runner(); | 94 compositor_thread_task_runner_ = compositor_thread_.task_runner(); |
| 95 |
| 96 // |this| will outlive the gpu thread and so it's safe to use |
| 97 // base::Unretained here. |
| 98 gpu_thread_task_runner_->PostTask( |
| 99 FROM_HERE, |
| 100 base::Bind(&GpuMain::InitOnGpuThread, base::Unretained(this), |
| 101 io_thread_.task_runner(), compositor_thread_task_runner_)); |
| 102 gpu_thread_task_runner_->PostTask( |
| 103 FROM_HERE, base::Bind(&GpuMain::BindOnGpu, base::Unretained(this), |
| 104 base::Passed(std::move(request)))); |
| 95 } | 105 } |
| 96 | 106 |
| 97 GpuMain::~GpuMain() { | 107 GpuMain::~GpuMain() { |
| 98 // Unretained() is OK here since the thread/task runner is owned by |this|. | 108 // Unretained() is OK here since the thread/task runner is owned by |this|. |
| 99 compositor_thread_task_runner_->PostTask( | 109 compositor_thread_task_runner_->PostTask( |
| 100 FROM_HERE, | 110 FROM_HERE, |
| 101 base::Bind(&GpuMain::TearDownOnCompositorThread, base::Unretained(this))); | 111 base::Bind(&GpuMain::TearDownOnCompositorThread, base::Unretained(this))); |
| 102 | 112 |
| 103 // Block the main thread until the compositor thread terminates which blocks | 113 // Block the main thread until the compositor thread terminates which blocks |
| 104 // on the gpu thread. The Stop must be initiated from here instead of the gpu | 114 // on the gpu thread. The Stop must be initiated from here instead of the gpu |
| 105 // thread to avoid deadlock. | 115 // thread to avoid deadlock. |
| 106 compositor_thread_.Stop(); | 116 compositor_thread_.Stop(); |
| 107 | 117 |
| 108 gpu_thread_task_runner_->PostTask( | 118 gpu_thread_task_runner_->PostTask( |
| 109 FROM_HERE, | 119 FROM_HERE, |
| 110 base::Bind(&GpuMain::TearDownOnGpuThread, base::Unretained(this))); | 120 base::Bind(&GpuMain::TearDownOnGpuThread, base::Unretained(this))); |
| 111 gpu_thread_.Stop(); | 121 gpu_thread_.Stop(); |
| 112 io_thread_.Stop(); | 122 io_thread_.Stop(); |
| 113 } | 123 } |
| 114 | 124 |
| 115 void GpuMain::OnStart() { | |
| 116 // |this| will outlive the gpu thread and so it's safe to use | |
| 117 // base::Unretained here. | |
| 118 gpu_thread_task_runner_->PostTask( | |
| 119 FROM_HERE, | |
| 120 base::Bind(&GpuMain::InitOnGpuThread, base::Unretained(this), | |
| 121 io_thread_.task_runner(), compositor_thread_task_runner_)); | |
| 122 } | |
| 123 | |
| 124 void GpuMain::CreateGpuService(mojom::GpuServiceRequest request, | 125 void GpuMain::CreateGpuService(mojom::GpuServiceRequest request, |
| 125 mojom::GpuHostPtr gpu_host, | 126 mojom::GpuHostPtr gpu_host, |
| 126 const gpu::GpuPreferences& preferences, | 127 const gpu::GpuPreferences& preferences, |
| 127 mojo::ScopedSharedBufferHandle activity_flags) { | 128 mojo::ScopedSharedBufferHandle activity_flags) { |
| 128 // |this| will outlive the gpu thread and so it's safe to use | 129 DCHECK(gpu_thread_task_runner_->BelongsToCurrentThread()); |
| 129 // base::Unretained here. | 130 CreateGpuServiceOnGpuThread( |
| 130 gpu_thread_task_runner_->PostTask( | 131 std::move(request), std::move(gpu_host), preferences, |
| 131 FROM_HERE, | 132 gpu::GpuProcessActivityFlags(std::move(activity_flags))); |
| 132 base::Bind(&GpuMain::CreateGpuServiceOnGpuThread, base::Unretained(this), | |
| 133 base::Passed(std::move(request)), | |
| 134 base::Passed(gpu_host.PassInterface()), preferences, | |
| 135 base::Passed( | |
| 136 gpu::GpuProcessActivityFlags(std::move(activity_flags))))); | |
| 137 } | 133 } |
| 138 | 134 |
| 139 void GpuMain::CreateFrameSinkManager( | 135 void GpuMain::CreateFrameSinkManager( |
| 140 cc::mojom::FrameSinkManagerRequest request, | 136 cc::mojom::FrameSinkManagerRequest request, |
| 141 cc::mojom::FrameSinkManagerClientPtr client) { | 137 cc::mojom::FrameSinkManagerClientPtr client) { |
| 142 if (!gpu_service_) { | 138 DCHECK(gpu_thread_task_runner_->BelongsToCurrentThread()); |
| 139 if (!gpu_service_ || !gpu_service_->is_initialized()) { |
| 143 pending_frame_sink_manager_request_ = std::move(request); | 140 pending_frame_sink_manager_request_ = std::move(request); |
| 144 pending_frame_sink_manager_client_info_ = client.PassInterface(); | 141 pending_frame_sink_manager_client_info_ = client.PassInterface(); |
| 145 return; | 142 return; |
| 146 } | 143 } |
| 147 CreateFrameSinkManagerInternal(std::move(request), client.PassInterface()); | 144 CreateFrameSinkManagerInternal(std::move(request), client.PassInterface()); |
| 148 } | 145 } |
| 149 | 146 |
| 147 void GpuMain::BindOnGpu(mojom::GpuMainRequest request) { |
| 148 binding_.Bind(std::move(request)); |
| 149 } |
| 150 |
| 150 void GpuMain::InitOnGpuThread( | 151 void GpuMain::InitOnGpuThread( |
| 151 scoped_refptr<base::SingleThreadTaskRunner> io_runner, | 152 scoped_refptr<base::SingleThreadTaskRunner> io_runner, |
| 152 scoped_refptr<base::SingleThreadTaskRunner> compositor_runner) { | 153 scoped_refptr<base::SingleThreadTaskRunner> compositor_runner) { |
| 153 gpu_init_.reset(new gpu::GpuInit()); | 154 gpu_init_.reset(new gpu::GpuInit()); |
| 154 gpu_init_->set_sandbox_helper(this); | 155 gpu_init_->set_sandbox_helper(this); |
| 155 bool success = gpu_init_->InitializeAndStartSandbox( | 156 bool success = gpu_init_->InitializeAndStartSandbox( |
| 156 *base::CommandLine::ForCurrentProcess()); | 157 *base::CommandLine::ForCurrentProcess()); |
| 157 if (!success) | 158 if (!success) |
| 158 return; | 159 return; |
| 159 | 160 |
| 160 gpu_service_ = base::MakeUnique<GpuService>( | 161 gpu_service_ = base::MakeUnique<GpuService>( |
| 161 gpu_init_->gpu_info(), gpu_init_->TakeWatchdogThread(), io_runner, | 162 gpu_init_->gpu_info(), gpu_init_->TakeWatchdogThread(), io_runner, |
| 162 gpu_init_->gpu_feature_info()); | 163 gpu_init_->gpu_feature_info()); |
| 163 } | 164 } |
| 164 | 165 |
| 165 void GpuMain::CreateFrameSinkManagerInternal( | 166 void GpuMain::CreateFrameSinkManagerInternal( |
| 166 cc::mojom::FrameSinkManagerRequest request, | 167 cc::mojom::FrameSinkManagerRequest request, |
| 167 cc::mojom::FrameSinkManagerClientPtrInfo client_info) { | 168 cc::mojom::FrameSinkManagerClientPtrInfo client_info) { |
| 168 DCHECK(!gpu_command_service_); | 169 DCHECK(!gpu_command_service_); |
| 169 DCHECK(gpu_service_); | 170 DCHECK(gpu_service_); |
| 171 DCHECK(gpu_thread_task_runner_->BelongsToCurrentThread()); |
| 170 gpu_command_service_ = new gpu::GpuInProcessThreadService( | 172 gpu_command_service_ = new gpu::GpuInProcessThreadService( |
| 171 gpu_thread_task_runner_, gpu_service_->sync_point_manager(), | 173 gpu_thread_task_runner_, gpu_service_->sync_point_manager(), |
| 172 gpu_service_->mailbox_manager(), gpu_service_->share_group()); | 174 gpu_service_->mailbox_manager(), gpu_service_->share_group()); |
| 173 | 175 |
| 174 gpu::ImageFactory* image_factory = gpu_service_->gpu_image_factory(); | 176 gpu::ImageFactory* image_factory = gpu_service_->gpu_image_factory(); |
| 175 mojom::GpuServicePtr gpu_service; | 177 mojom::GpuServicePtr gpu_service; |
| 176 mojom::GpuServiceRequest gpu_service_request(&gpu_service); | 178 mojom::GpuServiceRequest gpu_service_request(&gpu_service); |
| 177 | 179 |
| 178 if (gpu_thread_task_runner_->BelongsToCurrentThread()) { | 180 // If the FrameSinkManager creation was delayed because GpuService had not |
| 179 // If the FrameSinkManager creation was delayed because GpuService had not | 181 // been created yet, then this is called, in gpu thread, right after |
| 180 // been created yet, then this is called, in gpu thread, right after | 182 // GpuService is created. |
| 181 // GpuService is created. | 183 BindGpuInternalOnGpuThread(std::move(gpu_service_request)); |
| 182 BindGpuInternalOnGpuThread(std::move(gpu_service_request)); | |
| 183 } else { | |
| 184 gpu_thread_task_runner_->PostTask( | |
| 185 FROM_HERE, | |
| 186 base::Bind(&GpuMain::BindGpuInternalOnGpuThread, base::Unretained(this), | |
| 187 base::Passed(std::move(gpu_service_request)))); | |
| 188 } | |
| 189 | |
| 190 compositor_thread_task_runner_->PostTask( | 184 compositor_thread_task_runner_->PostTask( |
| 191 FROM_HERE, base::Bind(&GpuMain::CreateFrameSinkManagerOnCompositorThread, | 185 FROM_HERE, base::Bind(&GpuMain::CreateFrameSinkManagerOnCompositorThread, |
| 192 base::Unretained(this), image_factory, | 186 base::Unretained(this), image_factory, |
| 193 base::Passed(gpu_service.PassInterface()), | 187 base::Passed(gpu_service.PassInterface()), |
| 194 base::Passed(std::move(request)), | 188 base::Passed(std::move(request)), |
| 195 base::Passed(std::move(client_info)))); | 189 base::Passed(std::move(client_info)))); |
| 196 } | 190 } |
| 197 | 191 |
| 198 void GpuMain::CreateFrameSinkManagerOnCompositorThread( | 192 void GpuMain::CreateFrameSinkManagerOnCompositorThread( |
| 199 gpu::ImageFactory* image_factory, | 193 gpu::ImageFactory* image_factory, |
| (...skipping 17 matching lines...) Expand all Loading... |
| 217 frame_sink_manager_->Connect(std::move(request), std::move(client)); | 211 frame_sink_manager_->Connect(std::move(request), std::move(client)); |
| 218 } | 212 } |
| 219 | 213 |
| 220 void GpuMain::TearDownOnCompositorThread() { | 214 void GpuMain::TearDownOnCompositorThread() { |
| 221 frame_sink_manager_.reset(); | 215 frame_sink_manager_.reset(); |
| 222 display_provider_.reset(); | 216 display_provider_.reset(); |
| 223 gpu_internal_.reset(); | 217 gpu_internal_.reset(); |
| 224 } | 218 } |
| 225 | 219 |
| 226 void GpuMain::TearDownOnGpuThread() { | 220 void GpuMain::TearDownOnGpuThread() { |
| 221 binding_.Close(); |
| 227 gpu_service_.reset(); | 222 gpu_service_.reset(); |
| 228 gpu_memory_buffer_factory_.reset(); | 223 gpu_memory_buffer_factory_.reset(); |
| 229 gpu_init_.reset(); | 224 gpu_init_.reset(); |
| 230 } | 225 } |
| 231 | 226 |
| 232 void GpuMain::CreateGpuServiceOnGpuThread( | 227 void GpuMain::CreateGpuServiceOnGpuThread( |
| 233 mojom::GpuServiceRequest request, | 228 mojom::GpuServiceRequest request, |
| 234 mojom::GpuHostPtrInfo gpu_host_info, | 229 mojom::GpuHostPtr gpu_host, |
| 235 const gpu::GpuPreferences& preferences, | 230 const gpu::GpuPreferences& preferences, |
| 236 gpu::GpuProcessActivityFlags activity_flags) { | 231 gpu::GpuProcessActivityFlags activity_flags) { |
| 237 mojom::GpuHostPtr gpu_host; | |
| 238 gpu_host.Bind(std::move(gpu_host_info)); | |
| 239 gpu_service_->UpdateGPUInfoFromPreferences(preferences); | 232 gpu_service_->UpdateGPUInfoFromPreferences(preferences); |
| 240 gpu_service_->InitializeWithHost(std::move(gpu_host), | 233 gpu_service_->InitializeWithHost(std::move(gpu_host), |
| 241 std::move(activity_flags)); | 234 std::move(activity_flags)); |
| 242 gpu_service_->Bind(std::move(request)); | 235 gpu_service_->Bind(std::move(request)); |
| 243 | 236 |
| 244 if (pending_frame_sink_manager_request_.is_pending()) { | 237 if (pending_frame_sink_manager_request_.is_pending()) { |
| 245 CreateFrameSinkManagerInternal( | 238 CreateFrameSinkManagerInternal( |
| 246 std::move(pending_frame_sink_manager_request_), | 239 std::move(pending_frame_sink_manager_request_), |
| 247 std::move(pending_frame_sink_manager_client_info_)); | 240 std::move(pending_frame_sink_manager_client_info_)); |
| 248 } | 241 } |
| 249 } | 242 } |
| 250 | 243 |
| 251 void GpuMain::BindGpuInternalOnGpuThread(mojom::GpuServiceRequest request) { | 244 void GpuMain::BindGpuInternalOnGpuThread(mojom::GpuServiceRequest request) { |
| 252 gpu_service_->Bind(std::move(request)); | 245 gpu_service_->Bind(std::move(request)); |
| 253 } | 246 } |
| 254 | 247 |
| 255 void GpuMain::PreSandboxStartup() { | 248 void GpuMain::PreSandboxStartup() { |
| 256 // TODO(sad): https://crbug.com/645602 | 249 // TODO(sad): https://crbug.com/645602 |
| 257 } | 250 } |
| 258 | 251 |
| 259 bool GpuMain::EnsureSandboxInitialized( | 252 bool GpuMain::EnsureSandboxInitialized( |
| 260 gpu::GpuWatchdogThread* watchdog_thread) { | 253 gpu::GpuWatchdogThread* watchdog_thread) { |
| 261 // TODO(sad): https://crbug.com/645602 | 254 // TODO(sad): https://crbug.com/645602 |
| 262 return true; | 255 return true; |
| 263 } | 256 } |
| 264 | 257 |
| 265 } // namespace ui | 258 } // namespace ui |
| OLD | NEW |