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 |