OLD | NEW |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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 "chrome/browser/gpu_process_host_ui_shim.h" | 5 #include "chrome/browser/gpu_process_host_ui_shim.h" |
6 | 6 |
7 #include "app/app_switches.h" | 7 #include "app/app_switches.h" |
8 #include "app/gfx/gl/gl_implementation.h" | 8 #include "app/gfx/gl/gl_implementation.h" |
9 #include "base/command_line.h" | 9 #include "base/command_line.h" |
10 #include "base/id_map.h" | 10 #include "base/id_map.h" |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
101 | 101 |
102 RenderWidgetHostView* view = NULL; | 102 RenderWidgetHostView* view = NULL; |
103 if (host) | 103 if (host) |
104 view = host->view(); | 104 view = host->view(); |
105 | 105 |
106 return view; | 106 return view; |
107 } | 107 } |
108 | 108 |
109 GpuProcessHostUIShim::GpuProcessHostUIShim() | 109 GpuProcessHostUIShim::GpuProcessHostUIShim() |
110 : host_id_(++g_last_host_id), | 110 : host_id_(++g_last_host_id), |
| 111 gpu_process_(NULL), |
111 gpu_feature_flags_set_(false) { | 112 gpu_feature_flags_set_(false) { |
112 g_hosts_by_id.AddWithID(this, host_id_); | 113 g_hosts_by_id.AddWithID(this, host_id_); |
113 } | 114 } |
114 | 115 |
115 // static | 116 // static |
116 GpuProcessHostUIShim* GpuProcessHostUIShim::GetForRenderer(int renderer_id) { | 117 GpuProcessHostUIShim* GpuProcessHostUIShim::GetForRenderer(int renderer_id) { |
117 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 118 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
118 | 119 |
119 // The current policy is to ignore the renderer ID and use a single GPU | 120 // The current policy is to ignore the renderer ID and use a single GPU |
120 // process for all renderers. Later this will be extended to allow the | 121 // process for all renderers. Later this will be extended to allow the |
(...skipping 19 matching lines...) Expand all Loading... |
140 return ui_shim; | 141 return ui_shim; |
141 } | 142 } |
142 | 143 |
143 // static | 144 // static |
144 void GpuProcessHostUIShim::Destroy(int host_id) { | 145 void GpuProcessHostUIShim::Destroy(int host_id) { |
145 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 146 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
146 delete FromID(host_id); | 147 delete FromID(host_id); |
147 } | 148 } |
148 | 149 |
149 // static | 150 // static |
| 151 void GpuProcessHostUIShim::NotifyGpuProcessLaunched( |
| 152 int host_id, |
| 153 base::ProcessHandle gpu_process) { |
| 154 DCHECK(gpu_process); |
| 155 |
| 156 GpuProcessHostUIShim* ui_shim = FromID(host_id); |
| 157 DCHECK(ui_shim); |
| 158 |
| 159 ui_shim->gpu_process_ = gpu_process; |
| 160 } |
| 161 |
| 162 // static |
150 GpuProcessHostUIShim* GpuProcessHostUIShim::FromID(int host_id) { | 163 GpuProcessHostUIShim* GpuProcessHostUIShim::FromID(int host_id) { |
151 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 164 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
152 if (host_id == 0) | 165 if (host_id == 0) |
153 return NULL; | 166 return NULL; |
154 | 167 |
155 return g_hosts_by_id.Lookup(host_id); | 168 return g_hosts_by_id.Lookup(host_id); |
156 } | 169 } |
157 | 170 |
158 bool GpuProcessHostUIShim::Send(IPC::Message* msg) { | 171 bool GpuProcessHostUIShim::Send(IPC::Message* msg) { |
159 DCHECK(CalledOnValidThread()); | 172 DCHECK(CalledOnValidThread()); |
160 | 173 |
161 BrowserThread::PostTask(BrowserThread::IO, | 174 BrowserThread::PostTask(BrowserThread::IO, |
162 FROM_HERE, | 175 FROM_HERE, |
163 new SendOnIOThreadTask(host_id_, msg)); | 176 new SendOnIOThreadTask(host_id_, msg)); |
164 return true; | 177 return true; |
165 } | 178 } |
166 | 179 |
167 // Post a Task to execute callbacks on a error conditions in order to | 180 // Post a Task to execute callbacks on a error conditions in order to |
168 // clear the call stacks (and aid debugging). | 181 // clear the call stacks (and aid debugging). |
169 namespace { | 182 namespace { |
170 | 183 |
171 void EstablishChannelCallbackDispatcher( | 184 void EstablishChannelCallbackDispatcher( |
172 GpuProcessHostUIShim::EstablishChannelCallback* callback, | 185 GpuProcessHostUIShim::EstablishChannelCallback* callback, |
173 const IPC::ChannelHandle& channel_handle, | 186 const IPC::ChannelHandle& channel_handle, |
| 187 base::ProcessHandle gpu_renderer_process, |
174 const GPUInfo& gpu_info) { | 188 const GPUInfo& gpu_info) { |
175 scoped_ptr<GpuProcessHostUIShim::EstablishChannelCallback> | 189 scoped_ptr<GpuProcessHostUIShim::EstablishChannelCallback> |
176 wrapped_callback(callback); | 190 wrapped_callback(callback); |
177 wrapped_callback->Run(channel_handle, gpu_info); | 191 wrapped_callback->Run(channel_handle, gpu_renderer_process, gpu_info); |
178 } | 192 } |
179 | 193 |
180 void EstablishChannelError( | 194 void EstablishChannelError( |
181 GpuProcessHostUIShim::EstablishChannelCallback* callback, | 195 GpuProcessHostUIShim::EstablishChannelCallback* callback, |
182 const IPC::ChannelHandle& channel_handle, | 196 const IPC::ChannelHandle& channel_handle, |
| 197 base::ProcessHandle gpu_renderer_process, |
183 const GPUInfo& gpu_info) { | 198 const GPUInfo& gpu_info) { |
184 BrowserThread::PostTask( | 199 BrowserThread::PostTask( |
185 BrowserThread::UI, FROM_HERE, | 200 BrowserThread::UI, FROM_HERE, |
186 NewRunnableFunction(&EstablishChannelCallbackDispatcher, | 201 NewRunnableFunction(&EstablishChannelCallbackDispatcher, |
187 callback, channel_handle, gpu_info)); | 202 callback, |
| 203 channel_handle, |
| 204 gpu_renderer_process, |
| 205 gpu_info)); |
188 } | 206 } |
189 | 207 |
190 void SynchronizeCallbackDispatcher( | 208 void SynchronizeCallbackDispatcher( |
191 GpuProcessHostUIShim::SynchronizeCallback* callback) { | 209 GpuProcessHostUIShim::SynchronizeCallback* callback) { |
192 scoped_ptr<GpuProcessHostUIShim::SynchronizeCallback> | 210 scoped_ptr<GpuProcessHostUIShim::SynchronizeCallback> |
193 wrapped_callback(callback); | 211 wrapped_callback(callback); |
194 wrapped_callback->Run(); | 212 wrapped_callback->Run(); |
195 } | 213 } |
196 | 214 |
197 void SynchronizeError( | 215 void SynchronizeError( |
(...skipping 20 matching lines...) Expand all Loading... |
218 callback, route_id)); | 236 callback, route_id)); |
219 } | 237 } |
220 | 238 |
221 } // namespace | 239 } // namespace |
222 | 240 |
223 void GpuProcessHostUIShim::SendOutstandingReplies() { | 241 void GpuProcessHostUIShim::SendOutstandingReplies() { |
224 // First send empty channel handles for all EstablishChannel requests. | 242 // First send empty channel handles for all EstablishChannel requests. |
225 while (!channel_requests_.empty()) { | 243 while (!channel_requests_.empty()) { |
226 linked_ptr<EstablishChannelCallback> callback = channel_requests_.front(); | 244 linked_ptr<EstablishChannelCallback> callback = channel_requests_.front(); |
227 channel_requests_.pop(); | 245 channel_requests_.pop(); |
228 EstablishChannelError(callback.release(), IPC::ChannelHandle(), GPUInfo()); | 246 EstablishChannelError(callback.release(), |
| 247 IPC::ChannelHandle(), |
| 248 NULL, |
| 249 GPUInfo()); |
229 } | 250 } |
230 | 251 |
231 // Now unblock all renderers waiting for synchronization replies. | 252 // Now unblock all renderers waiting for synchronization replies. |
232 while (!synchronize_requests_.empty()) { | 253 while (!synchronize_requests_.empty()) { |
233 linked_ptr<SynchronizeCallback> callback = synchronize_requests_.front(); | 254 linked_ptr<SynchronizeCallback> callback = synchronize_requests_.front(); |
234 synchronize_requests_.pop(); | 255 synchronize_requests_.pop(); |
235 SynchronizeError(callback.release()); | 256 SynchronizeError(callback.release()); |
236 } | 257 } |
237 } | 258 } |
238 | 259 |
239 bool GpuProcessHostUIShim::OnMessageReceived(const IPC::Message& message) { | 260 bool GpuProcessHostUIShim::OnMessageReceived(const IPC::Message& message) { |
240 DCHECK(CalledOnValidThread()); | 261 DCHECK(CalledOnValidThread()); |
241 | 262 |
242 if (message.routing_id() != MSG_ROUTING_CONTROL) | 263 if (message.routing_id() != MSG_ROUTING_CONTROL) |
243 return false; | 264 return false; |
244 | 265 |
245 return OnControlMessageReceived(message); | 266 return OnControlMessageReceived(message); |
246 } | 267 } |
247 | 268 |
248 void GpuProcessHostUIShim::EstablishGpuChannel( | 269 void GpuProcessHostUIShim::EstablishGpuChannel( |
249 int renderer_id, EstablishChannelCallback *callback) { | 270 int renderer_id, |
| 271 EstablishChannelCallback *callback) { |
250 DCHECK(CalledOnValidThread()); | 272 DCHECK(CalledOnValidThread()); |
251 linked_ptr<EstablishChannelCallback> wrapped_callback(callback); | 273 linked_ptr<EstablishChannelCallback> wrapped_callback(callback); |
252 | 274 |
253 // If GPU features are already blacklisted, no need to establish the channel. | 275 // If GPU features are already blacklisted, no need to establish the channel. |
254 if (gpu_feature_flags_.flags() != 0) { | 276 if (gpu_feature_flags_.flags() != 0) { |
255 EstablishChannelError( | 277 EstablishChannelError( |
256 wrapped_callback.release(), IPC::ChannelHandle(), GPUInfo()); | 278 wrapped_callback.release(), IPC::ChannelHandle(), NULL, GPUInfo()); |
257 return; | 279 return; |
258 } | 280 } |
259 | 281 |
260 if (Send(new GpuMsg_EstablishChannel(renderer_id))) { | 282 if (Send(new GpuMsg_EstablishChannel(renderer_id))) { |
261 channel_requests_.push(wrapped_callback); | 283 channel_requests_.push(wrapped_callback); |
262 } else { | 284 } else { |
263 EstablishChannelError( | 285 EstablishChannelError( |
264 wrapped_callback.release(), IPC::ChannelHandle(), GPUInfo()); | 286 wrapped_callback.release(), IPC::ChannelHandle(), NULL, GPUInfo()); |
265 } | 287 } |
266 } | 288 } |
267 | 289 |
268 void GpuProcessHostUIShim::Synchronize(SynchronizeCallback* callback) { | 290 void GpuProcessHostUIShim::Synchronize(SynchronizeCallback* callback) { |
269 DCHECK(CalledOnValidThread()); | 291 DCHECK(CalledOnValidThread()); |
270 linked_ptr<SynchronizeCallback> wrapped_callback(callback); | 292 linked_ptr<SynchronizeCallback> wrapped_callback(callback); |
271 | 293 |
272 if (Send(new GpuMsg_Synchronize())) { | 294 if (Send(new GpuMsg_Synchronize())) { |
273 synchronize_requests_.push(wrapped_callback); | 295 synchronize_requests_.push(wrapped_callback); |
274 } else { | 296 } else { |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
333 } | 355 } |
334 | 356 |
335 const GPUInfo& GpuProcessHostUIShim::gpu_info() const { | 357 const GPUInfo& GpuProcessHostUIShim::gpu_info() const { |
336 DCHECK(CalledOnValidThread()); | 358 DCHECK(CalledOnValidThread()); |
337 return gpu_info_; | 359 return gpu_info_; |
338 } | 360 } |
339 | 361 |
340 GpuProcessHostUIShim::~GpuProcessHostUIShim() { | 362 GpuProcessHostUIShim::~GpuProcessHostUIShim() { |
341 DCHECK(CalledOnValidThread()); | 363 DCHECK(CalledOnValidThread()); |
342 g_hosts_by_id.Remove(host_id_); | 364 g_hosts_by_id.Remove(host_id_); |
| 365 |
| 366 #if defined(OS_WIN) |
| 367 if (gpu_process_) |
| 368 CloseHandle(gpu_process_); |
| 369 #endif |
343 } | 370 } |
344 | 371 |
345 bool GpuProcessHostUIShim::Init() { | 372 bool GpuProcessHostUIShim::Init() { |
346 return LoadGpuBlacklist(); | 373 return LoadGpuBlacklist(); |
347 } | 374 } |
348 | 375 |
349 void GpuProcessHostUIShim::AddCustomLogMessage(int level, | 376 void GpuProcessHostUIShim::AddCustomLogMessage(int level, |
350 const std::string& header, | 377 const std::string& header, |
351 const std::string& message) { | 378 const std::string& message) { |
352 OnLogMessage(level, header, message); | 379 OnLogMessage(level, header, message); |
(...skipping 30 matching lines...) Expand all Loading... |
383 #endif | 410 #endif |
384 IPC_MESSAGE_UNHANDLED_ERROR() | 411 IPC_MESSAGE_UNHANDLED_ERROR() |
385 IPC_END_MESSAGE_MAP() | 412 IPC_END_MESSAGE_MAP() |
386 | 413 |
387 return true; | 414 return true; |
388 } | 415 } |
389 | 416 |
390 void GpuProcessHostUIShim::OnChannelEstablished( | 417 void GpuProcessHostUIShim::OnChannelEstablished( |
391 const IPC::ChannelHandle& channel_handle, | 418 const IPC::ChannelHandle& channel_handle, |
392 const GPUInfo& gpu_info) { | 419 const GPUInfo& gpu_info) { |
| 420 // The GPU process should have launched at this point and this object should |
| 421 // have been notified of its process handle. |
| 422 DCHECK(gpu_process_); |
| 423 |
393 uint32 max_entry_id = gpu_blacklist_->max_entry_id(); | 424 uint32 max_entry_id = gpu_blacklist_->max_entry_id(); |
394 // max_entry_id can be zero if we failed to load the GPU blacklist, don't | 425 // max_entry_id can be zero if we failed to load the GPU blacklist, don't |
395 // bother with histograms then. | 426 // bother with histograms then. |
396 if (channel_handle.name.size() != 0 && !gpu_feature_flags_set_ && | 427 if (channel_handle.name.size() != 0 && !gpu_feature_flags_set_ && |
397 max_entry_id != 0) | 428 max_entry_id != 0) |
398 { | 429 { |
399 gpu_feature_flags_set_ = true; | 430 gpu_feature_flags_set_ = true; |
400 | 431 |
401 const CommandLine& browser_command_line = *CommandLine::ForCurrentProcess(); | 432 const CommandLine& browser_command_line = *CommandLine::ForCurrentProcess(); |
402 if (!browser_command_line.HasSwitch(switches::kIgnoreGpuBlacklist) && | 433 if (!browser_command_line.HasSwitch(switches::kIgnoreGpuBlacklist) && |
(...skipping 19 matching lines...) Expand all Loading... |
422 } | 453 } |
423 } | 454 } |
424 } | 455 } |
425 linked_ptr<EstablishChannelCallback> callback = channel_requests_.front(); | 456 linked_ptr<EstablishChannelCallback> callback = channel_requests_.front(); |
426 channel_requests_.pop(); | 457 channel_requests_.pop(); |
427 | 458 |
428 // Currently if any of the GPU features are blacklisted, we don't establish a | 459 // Currently if any of the GPU features are blacklisted, we don't establish a |
429 // GPU channel. | 460 // GPU channel. |
430 if (gpu_feature_flags_.flags() != 0) { | 461 if (gpu_feature_flags_.flags() != 0) { |
431 Send(new GpuMsg_CloseChannel(channel_handle)); | 462 Send(new GpuMsg_CloseChannel(channel_handle)); |
432 EstablishChannelError(callback.release(), IPC::ChannelHandle(), gpu_info); | 463 EstablishChannelError(callback.release(), |
| 464 IPC::ChannelHandle(), |
| 465 NULL, |
| 466 gpu_info); |
433 AddCustomLogMessage(logging::LOG_WARNING, "WARNING", "GPU is blacklisted."); | 467 AddCustomLogMessage(logging::LOG_WARNING, "WARNING", "GPU is blacklisted."); |
434 } else { | 468 return; |
435 callback->Run(channel_handle, gpu_info); | |
436 } | 469 } |
| 470 |
| 471 callback->Run(channel_handle, gpu_process_, gpu_info); |
437 } | 472 } |
438 | 473 |
439 void GpuProcessHostUIShim::OnSynchronizeReply() { | 474 void GpuProcessHostUIShim::OnSynchronizeReply() { |
440 // Guard against race conditions in abrupt GPU process termination. | 475 // Guard against race conditions in abrupt GPU process termination. |
441 if (synchronize_requests_.size() > 0) { | 476 if (synchronize_requests_.size() > 0) { |
442 linked_ptr<SynchronizeCallback> callback(synchronize_requests_.front()); | 477 linked_ptr<SynchronizeCallback> callback(synchronize_requests_.front()); |
443 synchronize_requests_.pop(); | 478 synchronize_requests_.pop(); |
444 callback->Run(); | 479 callback->Run(); |
445 } | 480 } |
446 } | 481 } |
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
589 static const base::StringPiece gpu_blacklist_json( | 624 static const base::StringPiece gpu_blacklist_json( |
590 ResourceBundle::GetSharedInstance().GetRawDataResource( | 625 ResourceBundle::GetSharedInstance().GetRawDataResource( |
591 IDR_GPU_BLACKLIST)); | 626 IDR_GPU_BLACKLIST)); |
592 gpu_blacklist_.reset(new GpuBlacklist()); | 627 gpu_blacklist_.reset(new GpuBlacklist()); |
593 if (gpu_blacklist_->LoadGpuBlacklist(gpu_blacklist_json.as_string(), true)) | 628 if (gpu_blacklist_->LoadGpuBlacklist(gpu_blacklist_json.as_string(), true)) |
594 return true; | 629 return true; |
595 gpu_blacklist_.reset(NULL); | 630 gpu_blacklist_.reset(NULL); |
596 return false; | 631 return false; |
597 } | 632 } |
598 | 633 |
OLD | NEW |