Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(374)

Side by Side Diff: content/browser/gpu/browser_gpu_channel_host_factory.cc

Issue 2805623002: gpu: Notify callbacks the reason for channel creation failure (Closed)
Patch Set: . Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
OLDNEW
« no previous file with comments | « content/browser/gpu/browser_gpu_channel_host_factory.h ('k') | content/browser/gpu/gpu_client.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698