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( |
(...skipping 13 matching lines...) Expand all Loading... |
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 |
39 } // namespace | 40 } // namespace |
40 | 41 |
41 namespace ui { | 42 namespace ui { |
42 | 43 |
43 GpuMain::GpuMain() | 44 GpuMain::GpuMain(mojom::GpuMainRequest request) |
44 : gpu_thread_("GpuThread"), | 45 : gpu_thread_("GpuThread"), |
45 io_thread_("GpuIOThread"), | 46 io_thread_("GpuIOThread"), |
46 compositor_thread_("DisplayCompositorThread"), | 47 compositor_thread_("DisplayCompositorThread"), |
47 weak_factory_(this) { | 48 binding_(this, std::move(request)) { |
48 base::Thread::Options thread_options; | 49 base::Thread::Options thread_options; |
49 | 50 |
50 #if defined(OS_WIN) | 51 #if defined(OS_WIN) |
51 thread_options.message_pump_factory = base::Bind(&CreateMessagePumpWin); | 52 thread_options.message_pump_factory = base::Bind(&CreateMessagePumpWin); |
52 #elif defined(USE_X11) | 53 #elif defined(USE_X11) |
53 thread_options.message_pump_factory = base::Bind(&CreateMessagePumpX11); | 54 thread_options.message_pump_factory = base::Bind(&CreateMessagePumpX11); |
54 #elif defined(USE_OZONE) | 55 #elif defined(USE_OZONE) |
55 thread_options.message_loop_type = base::MessageLoop::TYPE_UI; | 56 thread_options.message_loop_type = base::MessageLoop::TYPE_UI; |
56 #elif defined(OS_LINUX) | 57 #elif defined(OS_LINUX) |
57 thread_options.message_loop_type = base::MessageLoop::TYPE_DEFAULT; | 58 thread_options.message_loop_type = base::MessageLoop::TYPE_DEFAULT; |
(...skipping 21 matching lines...) Expand all Loading... |
79 | 80 |
80 // Start the compositor thread. | 81 // Start the compositor thread. |
81 compositor_thread_.Start(); | 82 compositor_thread_.Start(); |
82 } | 83 } |
83 | 84 |
84 GpuMain::~GpuMain() { | 85 GpuMain::~GpuMain() { |
85 // Unretained() is OK here since the thread/task runner is owned by |this|. | 86 // Unretained() is OK here since the thread/task runner is owned by |this|. |
86 compositor_thread_.task_runner()->PostTask( | 87 compositor_thread_.task_runner()->PostTask( |
87 FROM_HERE, | 88 FROM_HERE, |
88 base::Bind(&GpuMain::TearDownOnCompositorThread, base::Unretained(this))); | 89 base::Bind(&GpuMain::TearDownOnCompositorThread, base::Unretained(this))); |
| 90 |
89 // Block the main thread until the compositor thread terminates which blocks | 91 // 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 | 92 // on the gpu thread. The Stop must be initiated from here instead of the gpu |
91 // thread to avoid deadlock. | 93 // thread to avoid deadlock. |
92 compositor_thread_.Stop(); | 94 compositor_thread_.Stop(); |
93 | 95 |
94 gpu_thread_.task_runner()->PostTask( | 96 gpu_thread_.task_runner()->PostTask( |
95 FROM_HERE, | 97 FROM_HERE, |
96 base::Bind(&GpuMain::TearDownOnGpuThread, base::Unretained(this))); | 98 base::Bind(&GpuMain::TearDownOnGpuThread, base::Unretained(this))); |
97 gpu_thread_.Stop(); | 99 gpu_thread_.Stop(); |
98 io_thread_.Stop(); | 100 io_thread_.Stop(); |
99 } | 101 } |
100 | 102 |
101 void GpuMain::OnStart() { | 103 void GpuMain::OnStart() { |
| 104 // |this| will outlive the gpu thread and so it's safe to use |
| 105 // base::Unretained here. |
102 gpu_thread_.task_runner()->PostTask( | 106 gpu_thread_.task_runner()->PostTask( |
103 FROM_HERE, | 107 FROM_HERE, |
104 base::Bind(&GpuMain::InitOnGpuThread, weak_factory_.GetWeakPtr(), | 108 base::Bind(&GpuMain::InitOnGpuThread, base::Unretained(this), |
105 io_thread_.task_runner(), compositor_thread_.task_runner())); | 109 io_thread_.task_runner(), compositor_thread_.task_runner())); |
106 } | 110 } |
107 | 111 |
108 void GpuMain::Create(mojom::GpuServiceInternalRequest request) { | 112 void GpuMain::CreateGpuService(mojom::GpuServiceInternalRequest request, |
| 113 const CreateGpuServiceCallback& callback) { |
| 114 // |this| will outlive the gpu thread and so it's safe to use |
| 115 // base::Unretained here. |
109 gpu_thread_.task_runner()->PostTask( | 116 gpu_thread_.task_runner()->PostTask( |
110 FROM_HERE, | 117 FROM_HERE, |
111 base::Bind(&GpuMain::CreateOnGpuThread, weak_factory_.GetWeakPtr(), | 118 base::Bind(&GpuMain::CreateGpuServiceOnGpuThread, base::Unretained(this), |
112 base::Passed(std::move(request)))); | 119 base::Passed(std::move(request)), |
| 120 base::ThreadTaskRunnerHandle::Get(), callback)); |
| 121 } |
| 122 |
| 123 void GpuMain::CreateDisplayCompositor( |
| 124 cc::mojom::DisplayCompositorRequest request, |
| 125 cc::mojom::DisplayCompositorClientPtr client) { |
| 126 if (!gpu_service_internal_) { |
| 127 pending_display_compositor_request_ = std::move(request); |
| 128 pending_display_compositor_client_info_ = client.PassInterface(); |
| 129 return; |
| 130 } |
| 131 CreateDisplayCompositorInternal(std::move(request), client.PassInterface()); |
113 } | 132 } |
114 | 133 |
115 void GpuMain::InitOnGpuThread( | 134 void GpuMain::InitOnGpuThread( |
116 scoped_refptr<base::SingleThreadTaskRunner> io_runner, | 135 scoped_refptr<base::SingleThreadTaskRunner> io_runner, |
117 scoped_refptr<base::SingleThreadTaskRunner> compositor_runner) { | 136 scoped_refptr<base::SingleThreadTaskRunner> compositor_runner) { |
118 gpu_init_.reset(new gpu::GpuInit()); | 137 gpu_init_.reset(new gpu::GpuInit()); |
119 gpu_init_->set_sandbox_helper(this); | 138 gpu_init_->set_sandbox_helper(this); |
120 bool success = gpu_init_->InitializeAndStartSandbox( | 139 bool success = gpu_init_->InitializeAndStartSandbox( |
121 *base::CommandLine::ForCurrentProcess()); | 140 *base::CommandLine::ForCurrentProcess()); |
122 if (success) { | 141 if (!success) |
123 if (gpu::GetNativeGpuMemoryBufferType() != gfx::EMPTY_BUFFER) { | 142 return; |
124 gpu_memory_buffer_factory_ = | 143 |
125 gpu::GpuMemoryBufferFactory::CreateNativeType(); | 144 if (gpu::GetNativeGpuMemoryBufferType() != gfx::EMPTY_BUFFER) { |
126 } | 145 gpu_memory_buffer_factory_ = |
127 gpu_service_internal_.reset(new GpuServiceInternal( | 146 gpu::GpuMemoryBufferFactory::CreateNativeType(); |
128 gpu_init_->gpu_info(), gpu_init_->TakeWatchdogThread(), | |
129 gpu_memory_buffer_factory_.get(), io_runner, compositor_runner)); | |
130 } | 147 } |
| 148 |
| 149 gpu_service_internal_ = base::MakeUnique<GpuServiceInternal>( |
| 150 gpu_init_->gpu_info(), gpu_init_->TakeWatchdogThread(), |
| 151 gpu_memory_buffer_factory_.get(), io_runner); |
| 152 gpu_service_internal_->Initialize(); |
| 153 } |
| 154 |
| 155 void GpuMain::CreateDisplayCompositorInternal( |
| 156 cc::mojom::DisplayCompositorRequest request, |
| 157 cc::mojom::DisplayCompositorClientPtrInfo client_info) { |
| 158 DCHECK(!gpu_command_service_); |
| 159 gpu_command_service_ = new gpu::GpuInProcessThreadService( |
| 160 gpu_thread_.task_runner(), gpu_service_internal_->sync_point_manager(), |
| 161 gpu_service_internal_->mailbox_manager(), |
| 162 gpu_service_internal_->share_group()); |
| 163 |
| 164 // |gpu_memory_buffer_factory_| is null in tests. |
| 165 gpu::ImageFactory* image_factory = |
| 166 gpu_memory_buffer_factory_ ? gpu_memory_buffer_factory_->AsImageFactory() |
| 167 : nullptr; |
| 168 |
| 169 mojom::GpuServiceInternalPtr gpu_service; |
| 170 mojom::GpuServiceInternalRequest gpu_service_request = |
| 171 mojo::GetProxy(&gpu_service); |
| 172 |
| 173 CreateGpuService(std::move(gpu_service_request), CreateGpuServiceCallback()); |
| 174 |
| 175 compositor_thread_.task_runner()->PostTask( |
| 176 FROM_HERE, base::Bind(&GpuMain::CreateDisplayCompositorOnCompositorThread, |
| 177 base::Unretained(this), image_factory, |
| 178 base::Passed(gpu_service.PassInterface()), |
| 179 base::Passed(std::move(request)), |
| 180 base::Passed(std::move(client_info)))); |
| 181 } |
| 182 |
| 183 void GpuMain::CreateDisplayCompositorOnCompositorThread( |
| 184 gpu::ImageFactory* image_factory, |
| 185 mojom::GpuServiceInternalPtrInfo gpu_service_info, |
| 186 cc::mojom::DisplayCompositorRequest request, |
| 187 cc::mojom::DisplayCompositorClientPtrInfo client_info) { |
| 188 DCHECK(!display_compositor_); |
| 189 cc::mojom::DisplayCompositorClientPtr client; |
| 190 client.Bind(std::move(client_info)); |
| 191 |
| 192 gpu_internal_.Bind(std::move(gpu_service_info)); |
| 193 |
| 194 display_compositor_ = base::MakeUnique<DisplayCompositor>( |
| 195 gpu_command_service_, base::MakeUnique<MusGpuMemoryBufferManager>( |
| 196 gpu_internal_.get(), 1 /* client_id */), |
| 197 image_factory, std::move(request), std::move(client)); |
131 } | 198 } |
132 | 199 |
133 void GpuMain::TearDownOnCompositorThread() { | 200 void GpuMain::TearDownOnCompositorThread() { |
134 if (gpu_service_internal_) | 201 display_compositor_.reset(); |
135 gpu_service_internal_->DestroyDisplayCompositor(); | 202 gpu_internal_.reset(); |
136 } | 203 } |
137 | 204 |
138 void GpuMain::TearDownOnGpuThread() { | 205 void GpuMain::TearDownOnGpuThread() { |
139 gpu_service_internal_.reset(); | 206 gpu_service_internal_.reset(); |
140 gpu_memory_buffer_factory_.reset(); | 207 gpu_memory_buffer_factory_.reset(); |
141 gpu_init_.reset(); | 208 gpu_init_.reset(); |
142 } | 209 } |
143 | 210 |
144 void GpuMain::CreateOnGpuThread(mojom::GpuServiceInternalRequest request) { | 211 void GpuMain::CreateGpuServiceOnGpuThread( |
145 if (gpu_service_internal_) | 212 mojom::GpuServiceInternalRequest request, |
146 gpu_service_internal_->Add(std::move(request)); | 213 scoped_refptr<base::SingleThreadTaskRunner> origin_runner, |
| 214 const CreateGpuServiceCallback& callback) { |
| 215 gpu_service_internal_->Bind(std::move(request)); |
| 216 |
| 217 if (pending_display_compositor_request_.is_pending()) { |
| 218 CreateDisplayCompositorInternal( |
| 219 std::move(pending_display_compositor_request_), |
| 220 std::move(pending_display_compositor_client_info_)); |
| 221 } |
| 222 |
| 223 if (!callback.is_null()) { |
| 224 origin_runner->PostTask( |
| 225 FROM_HERE, base::Bind(callback, gpu_service_internal_->gpu_info())); |
| 226 } |
147 } | 227 } |
148 | 228 |
149 void GpuMain::PreSandboxStartup() { | 229 void GpuMain::PreSandboxStartup() { |
150 // TODO(sad): https://crbug.com/645602 | 230 // TODO(sad): https://crbug.com/645602 |
151 } | 231 } |
152 | 232 |
153 bool GpuMain::EnsureSandboxInitialized( | 233 bool GpuMain::EnsureSandboxInitialized( |
154 gpu::GpuWatchdogThread* watchdog_thread) { | 234 gpu::GpuWatchdogThread* watchdog_thread) { |
155 // TODO(sad): https://crbug.com/645602 | 235 // TODO(sad): https://crbug.com/645602 |
156 return true; | 236 return true; |
157 } | 237 } |
158 | 238 |
159 } // namespace ui | 239 } // namespace ui |
OLD | NEW |