OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 "content/browser/gpu/browser_gpu_channel_host_factory.h" | 5 #include "content/browser/gpu/browser_gpu_channel_host_factory.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/command_line.h" | 8 #include "base/command_line.h" |
9 #include "base/location.h" | 9 #include "base/location.h" |
10 #include "base/profiler/scoped_tracker.h" | 10 #include "base/profiler/scoped_tracker.h" |
(...skipping 21 matching lines...) Expand all Loading... |
32 #include "services/service_manager/runner/common/client_util.h" | 32 #include "services/service_manager/runner/common/client_util.h" |
33 | 33 |
34 namespace content { | 34 namespace content { |
35 | 35 |
36 BrowserGpuChannelHostFactory* BrowserGpuChannelHostFactory::instance_ = NULL; | 36 BrowserGpuChannelHostFactory* BrowserGpuChannelHostFactory::instance_ = NULL; |
37 | 37 |
38 class BrowserGpuChannelHostFactory::EstablishRequest | 38 class BrowserGpuChannelHostFactory::EstablishRequest |
39 : public base::RefCountedThreadSafe<EstablishRequest> { | 39 : public base::RefCountedThreadSafe<EstablishRequest> { |
40 public: | 40 public: |
41 static scoped_refptr<EstablishRequest> Create(int gpu_client_id, | 41 static scoped_refptr<EstablishRequest> Create(int gpu_client_id, |
42 uint64_t gpu_client_tracing_id, | 42 uint64_t gpu_client_tracing_id); |
43 int gpu_host_id); | |
44 void Wait(); | 43 void Wait(); |
45 void Cancel(); | 44 void Cancel(); |
46 | 45 |
47 int gpu_host_id() { return gpu_host_id_; } | |
48 IPC::ChannelHandle& channel_handle() { return channel_handle_; } | 46 IPC::ChannelHandle& channel_handle() { return channel_handle_; } |
49 gpu::GPUInfo gpu_info() { return gpu_info_; } | 47 gpu::GPUInfo gpu_info() { return gpu_info_; } |
50 | 48 |
51 private: | 49 private: |
52 friend class base::RefCountedThreadSafe<EstablishRequest>; | 50 friend class base::RefCountedThreadSafe<EstablishRequest>; |
53 explicit EstablishRequest(int gpu_client_id, | 51 explicit EstablishRequest(int gpu_client_id, uint64_t gpu_client_tracing_id); |
54 uint64_t gpu_client_tracing_id, | |
55 int gpu_host_id); | |
56 ~EstablishRequest() {} | 52 ~EstablishRequest() {} |
57 void EstablishOnIO(); | 53 void EstablishOnIO(); |
58 void OnEstablishedOnIO(const IPC::ChannelHandle& channel_handle, | 54 void OnEstablishedOnIO(const IPC::ChannelHandle& channel_handle, |
59 const gpu::GPUInfo& gpu_info); | 55 const gpu::GPUInfo& gpu_info, |
| 56 GpuProcessHost::EstablishChannelStatus status); |
60 void FinishOnIO(); | 57 void FinishOnIO(); |
61 void FinishOnMain(); | 58 void FinishOnMain(); |
62 | 59 |
63 base::WaitableEvent event_; | 60 base::WaitableEvent event_; |
64 const int gpu_client_id_; | 61 const int gpu_client_id_; |
65 const uint64_t gpu_client_tracing_id_; | 62 const uint64_t gpu_client_tracing_id_; |
66 int gpu_host_id_; | |
67 bool reused_gpu_process_; | |
68 IPC::ChannelHandle channel_handle_; | 63 IPC::ChannelHandle channel_handle_; |
69 gpu::GPUInfo gpu_info_; | 64 gpu::GPUInfo gpu_info_; |
70 bool finished_; | 65 bool finished_; |
71 scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_; | 66 scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_; |
72 }; | 67 }; |
73 | 68 |
74 scoped_refptr<BrowserGpuChannelHostFactory::EstablishRequest> | 69 scoped_refptr<BrowserGpuChannelHostFactory::EstablishRequest> |
75 BrowserGpuChannelHostFactory::EstablishRequest::Create( | 70 BrowserGpuChannelHostFactory::EstablishRequest::Create( |
76 int gpu_client_id, | 71 int gpu_client_id, |
77 uint64_t gpu_client_tracing_id, | 72 uint64_t gpu_client_tracing_id) { |
78 int gpu_host_id) { | |
79 scoped_refptr<EstablishRequest> establish_request = | 73 scoped_refptr<EstablishRequest> establish_request = |
80 new EstablishRequest(gpu_client_id, gpu_client_tracing_id, gpu_host_id); | 74 new EstablishRequest(gpu_client_id, gpu_client_tracing_id); |
81 scoped_refptr<base::SingleThreadTaskRunner> task_runner = | 75 scoped_refptr<base::SingleThreadTaskRunner> task_runner = |
82 BrowserThread::GetTaskRunnerForThread(BrowserThread::IO); | 76 BrowserThread::GetTaskRunnerForThread(BrowserThread::IO); |
83 // PostTask outside the constructor to ensure at least one reference exists. | 77 // PostTask outside the constructor to ensure at least one reference exists. |
84 task_runner->PostTask( | 78 task_runner->PostTask( |
85 FROM_HERE, | 79 FROM_HERE, |
86 base::Bind(&BrowserGpuChannelHostFactory::EstablishRequest::EstablishOnIO, | 80 base::Bind(&BrowserGpuChannelHostFactory::EstablishRequest::EstablishOnIO, |
87 establish_request)); | 81 establish_request)); |
88 return establish_request; | 82 return establish_request; |
89 } | 83 } |
90 | 84 |
91 BrowserGpuChannelHostFactory::EstablishRequest::EstablishRequest( | 85 BrowserGpuChannelHostFactory::EstablishRequest::EstablishRequest( |
92 int gpu_client_id, | 86 int gpu_client_id, |
93 uint64_t gpu_client_tracing_id, | 87 uint64_t gpu_client_tracing_id) |
94 int gpu_host_id) | |
95 : event_(base::WaitableEvent::ResetPolicy::AUTOMATIC, | 88 : event_(base::WaitableEvent::ResetPolicy::AUTOMATIC, |
96 base::WaitableEvent::InitialState::NOT_SIGNALED), | 89 base::WaitableEvent::InitialState::NOT_SIGNALED), |
97 gpu_client_id_(gpu_client_id), | 90 gpu_client_id_(gpu_client_id), |
98 gpu_client_tracing_id_(gpu_client_tracing_id), | 91 gpu_client_tracing_id_(gpu_client_tracing_id), |
99 gpu_host_id_(gpu_host_id), | |
100 reused_gpu_process_(false), | |
101 finished_(false), | 92 finished_(false), |
102 main_task_runner_(base::ThreadTaskRunnerHandle::Get()) {} | 93 main_task_runner_(base::ThreadTaskRunnerHandle::Get()) {} |
103 | 94 |
104 void BrowserGpuChannelHostFactory::EstablishRequest::EstablishOnIO() { | 95 void BrowserGpuChannelHostFactory::EstablishRequest::EstablishOnIO() { |
105 // TODO(pkasting): Remove ScopedTracker below once crbug.com/477117 is fixed. | 96 // TODO(pkasting): Remove ScopedTracker below once crbug.com/477117 is fixed. |
106 tracked_objects::ScopedTracker tracking_profile( | 97 tracked_objects::ScopedTracker tracking_profile( |
107 FROM_HERE_WITH_EXPLICIT_FUNCTION( | 98 FROM_HERE_WITH_EXPLICIT_FUNCTION( |
108 "477117 " | 99 "477117 " |
109 "BrowserGpuChannelHostFactory::EstablishRequest::EstablishOnIO")); | 100 "BrowserGpuChannelHostFactory::EstablishRequest::EstablishOnIO")); |
110 GpuProcessHost* host = GpuProcessHost::FromID(gpu_host_id_); | 101 GpuProcessHost* host = |
| 102 GpuProcessHost::Get(GpuProcessHost::GPU_PROCESS_KIND_SANDBOXED); |
111 if (!host) { | 103 if (!host) { |
112 host = GpuProcessHost::Get(GpuProcessHost::GPU_PROCESS_KIND_SANDBOXED); | 104 LOG(ERROR) << "Failed to launch GPU process."; |
113 if (!host) { | 105 FinishOnIO(); |
114 LOG(ERROR) << "Failed to launch GPU process."; | 106 return; |
115 FinishOnIO(); | |
116 return; | |
117 } | |
118 gpu_host_id_ = host->host_id(); | |
119 reused_gpu_process_ = false; | |
120 } else { | |
121 if (reused_gpu_process_) { | |
122 // We come here if we retried to establish the channel because of a | |
123 // failure in ChannelEstablishedOnIO, but we ended up with the same | |
124 // process ID, meaning the failure was not because of a channel error, | |
125 // but another reason. So fail now. | |
126 LOG(ERROR) << "Failed to create channel."; | |
127 FinishOnIO(); | |
128 return; | |
129 } | |
130 reused_gpu_process_ = true; | |
131 } | 107 } |
132 | 108 |
133 bool preempts = true; | 109 bool preempts = true; |
134 bool allow_view_command_buffers = true; | 110 bool allow_view_command_buffers = true; |
135 bool allow_real_time_streams = true; | 111 bool allow_real_time_streams = true; |
136 host->EstablishGpuChannel( | 112 host->EstablishGpuChannel( |
137 gpu_client_id_, gpu_client_tracing_id_, preempts, | 113 gpu_client_id_, gpu_client_tracing_id_, preempts, |
138 allow_view_command_buffers, allow_real_time_streams, | 114 allow_view_command_buffers, allow_real_time_streams, |
139 base::Bind( | 115 base::Bind( |
140 &BrowserGpuChannelHostFactory::EstablishRequest::OnEstablishedOnIO, | 116 &BrowserGpuChannelHostFactory::EstablishRequest::OnEstablishedOnIO, |
141 this)); | 117 this)); |
142 } | 118 } |
143 | 119 |
144 void BrowserGpuChannelHostFactory::EstablishRequest::OnEstablishedOnIO( | 120 void BrowserGpuChannelHostFactory::EstablishRequest::OnEstablishedOnIO( |
145 const IPC::ChannelHandle& channel_handle, | 121 const IPC::ChannelHandle& channel_handle, |
146 const gpu::GPUInfo& gpu_info) { | 122 const gpu::GPUInfo& gpu_info, |
147 if (!channel_handle.mojo_handle.is_valid() && reused_gpu_process_) { | 123 GpuProcessHost::EstablishChannelStatus status) { |
148 // We failed after re-using the GPU process, but it may have died in the | 124 if (!channel_handle.mojo_handle.is_valid() && |
149 // mean time. Retry to have a chance to create a fresh GPU process. | 125 status == GpuProcessHost::EstablishChannelStatus::GPU_HOST_INVALID) { |
150 DVLOG(1) << "Failed to create channel on existing GPU process. Trying to " | 126 DVLOG(1) << "Failed to create channel on existing GPU process. Trying to " |
151 "restart GPU process."; | 127 "restart GPU process."; |
152 EstablishOnIO(); | 128 EstablishOnIO(); |
153 } else { | 129 return; |
154 channel_handle_ = channel_handle; | |
155 gpu_info_ = gpu_info; | |
156 FinishOnIO(); | |
157 } | 130 } |
| 131 channel_handle_ = channel_handle; |
| 132 gpu_info_ = gpu_info; |
| 133 FinishOnIO(); |
158 } | 134 } |
159 | 135 |
160 void BrowserGpuChannelHostFactory::EstablishRequest::FinishOnIO() { | 136 void BrowserGpuChannelHostFactory::EstablishRequest::FinishOnIO() { |
161 event_.Signal(); | 137 event_.Signal(); |
162 main_task_runner_->PostTask( | 138 main_task_runner_->PostTask( |
163 FROM_HERE, | 139 FROM_HERE, |
164 base::Bind(&BrowserGpuChannelHostFactory::EstablishRequest::FinishOnMain, | 140 base::Bind(&BrowserGpuChannelHostFactory::EstablishRequest::FinishOnMain, |
165 this)); | 141 this)); |
166 } | 142 } |
167 | 143 |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
227 | 203 |
228 BrowserGpuChannelHostFactory::BrowserGpuChannelHostFactory() | 204 BrowserGpuChannelHostFactory::BrowserGpuChannelHostFactory() |
229 : gpu_client_id_(ChildProcessHostImpl::GenerateChildProcessUniqueId()), | 205 : gpu_client_id_(ChildProcessHostImpl::GenerateChildProcessUniqueId()), |
230 gpu_client_tracing_id_( | 206 gpu_client_tracing_id_( |
231 memory_instrumentation::mojom::kServiceTracingProcessId), | 207 memory_instrumentation::mojom::kServiceTracingProcessId), |
232 shutdown_event_(new base::WaitableEvent( | 208 shutdown_event_(new base::WaitableEvent( |
233 base::WaitableEvent::ResetPolicy::MANUAL, | 209 base::WaitableEvent::ResetPolicy::MANUAL, |
234 base::WaitableEvent::InitialState::NOT_SIGNALED)), | 210 base::WaitableEvent::InitialState::NOT_SIGNALED)), |
235 gpu_memory_buffer_manager_( | 211 gpu_memory_buffer_manager_( |
236 new BrowserGpuMemoryBufferManager(gpu_client_id_, | 212 new BrowserGpuMemoryBufferManager(gpu_client_id_, |
237 gpu_client_tracing_id_)), | 213 gpu_client_tracing_id_)) { |
238 gpu_host_id_(0) { | |
239 if (!base::CommandLine::ForCurrentProcess()->HasSwitch( | 214 if (!base::CommandLine::ForCurrentProcess()->HasSwitch( |
240 switches::kDisableGpuShaderDiskCache)) { | 215 switches::kDisableGpuShaderDiskCache)) { |
241 DCHECK(GetContentClient()); | 216 DCHECK(GetContentClient()); |
242 base::FilePath cache_dir = | 217 base::FilePath cache_dir = |
243 GetContentClient()->browser()->GetShaderDiskCacheDirectory(); | 218 GetContentClient()->browser()->GetShaderDiskCacheDirectory(); |
244 if (!cache_dir.empty()) { | 219 if (!cache_dir.empty()) { |
245 GetIOThreadTaskRunner()->PostTask( | 220 GetIOThreadTaskRunner()->PostTask( |
246 FROM_HERE, | 221 FROM_HERE, |
247 base::Bind( | 222 base::Bind( |
248 &BrowserGpuChannelHostFactory::InitializeShaderDiskCacheOnIO, | 223 &BrowserGpuChannelHostFactory::InitializeShaderDiskCacheOnIO, |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
284 DCHECK(!service_manager::ServiceManagerIsRemote()); | 259 DCHECK(!service_manager::ServiceManagerIsRemote()); |
285 if (gpu_channel_.get() && gpu_channel_->IsLost()) { | 260 if (gpu_channel_.get() && gpu_channel_->IsLost()) { |
286 DCHECK(!pending_request_.get()); | 261 DCHECK(!pending_request_.get()); |
287 // Recreate the channel if it has been lost. | 262 // Recreate the channel if it has been lost. |
288 gpu_channel_->DestroyChannel(); | 263 gpu_channel_->DestroyChannel(); |
289 gpu_channel_ = NULL; | 264 gpu_channel_ = NULL; |
290 } | 265 } |
291 | 266 |
292 if (!gpu_channel_.get() && !pending_request_.get()) { | 267 if (!gpu_channel_.get() && !pending_request_.get()) { |
293 // We should only get here if the context was lost. | 268 // We should only get here if the context was lost. |
294 pending_request_ = EstablishRequest::Create( | 269 pending_request_ = |
295 gpu_client_id_, gpu_client_tracing_id_, gpu_host_id_); | 270 EstablishRequest::Create(gpu_client_id_, gpu_client_tracing_id_); |
296 } | 271 } |
297 | 272 |
298 if (!callback.is_null()) { | 273 if (!callback.is_null()) { |
299 if (gpu_channel_.get()) | 274 if (gpu_channel_.get()) |
300 callback.Run(gpu_channel_); | 275 callback.Run(gpu_channel_); |
301 else | 276 else |
302 established_callbacks_.push_back(callback); | 277 established_callbacks_.push_back(callback); |
303 } | 278 } |
304 } | 279 } |
305 | 280 |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
342 // is fixed. | 317 // is fixed. |
343 tracked_objects::ScopedTracker tracking_profile1( | 318 tracked_objects::ScopedTracker tracking_profile1( |
344 FROM_HERE_WITH_EXPLICIT_FUNCTION( | 319 FROM_HERE_WITH_EXPLICIT_FUNCTION( |
345 "466866 BrowserGpuChannelHostFactory::GpuChannelEstablished1")); | 320 "466866 BrowserGpuChannelHostFactory::GpuChannelEstablished1")); |
346 GetContentClient()->SetGpuInfo(pending_request_->gpu_info()); | 321 GetContentClient()->SetGpuInfo(pending_request_->gpu_info()); |
347 gpu_channel_ = gpu::GpuChannelHost::Create( | 322 gpu_channel_ = gpu::GpuChannelHost::Create( |
348 this, gpu_client_id_, pending_request_->gpu_info(), | 323 this, gpu_client_id_, pending_request_->gpu_info(), |
349 pending_request_->channel_handle(), shutdown_event_.get(), | 324 pending_request_->channel_handle(), shutdown_event_.get(), |
350 gpu_memory_buffer_manager_.get()); | 325 gpu_memory_buffer_manager_.get()); |
351 } | 326 } |
352 gpu_host_id_ = pending_request_->gpu_host_id(); | |
353 pending_request_ = NULL; | 327 pending_request_ = NULL; |
354 | 328 |
355 // TODO(robliao): Remove ScopedTracker below once https://crbug.com/466866 is | 329 // TODO(robliao): Remove ScopedTracker below once https://crbug.com/466866 is |
356 // fixed. | 330 // fixed. |
357 tracked_objects::ScopedTracker tracking_profile2( | 331 tracked_objects::ScopedTracker tracking_profile2( |
358 FROM_HERE_WITH_EXPLICIT_FUNCTION( | 332 FROM_HERE_WITH_EXPLICIT_FUNCTION( |
359 "466866 BrowserGpuChannelHostFactory::GpuChannelEstablished2")); | 333 "466866 BrowserGpuChannelHostFactory::GpuChannelEstablished2")); |
360 | 334 |
361 std::vector<gpu::GpuChannelEstablishedCallback> established_callbacks; | 335 std::vector<gpu::GpuChannelEstablishedCallback> established_callbacks; |
362 established_callbacks_.swap(established_callbacks); | 336 established_callbacks_.swap(established_callbacks); |
363 for (auto& callback : established_callbacks) | 337 for (auto& callback : established_callbacks) |
364 callback.Run(gpu_channel_); | 338 callback.Run(gpu_channel_); |
365 } | 339 } |
366 | 340 |
367 // static | 341 // static |
368 void BrowserGpuChannelHostFactory::InitializeShaderDiskCacheOnIO( | 342 void BrowserGpuChannelHostFactory::InitializeShaderDiskCacheOnIO( |
369 int gpu_client_id, | 343 int gpu_client_id, |
370 const base::FilePath& cache_dir) { | 344 const base::FilePath& cache_dir) { |
371 GetShaderCacheFactorySingleton()->SetCacheInfo(gpu_client_id, cache_dir); | 345 GetShaderCacheFactorySingleton()->SetCacheInfo(gpu_client_id, cache_dir); |
372 } | 346 } |
373 | 347 |
374 } // namespace content | 348 } // namespace content |
OLD | NEW |