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

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

Issue 7054005: Fix gpu acceleration with --in-process-gpu (Closed) Base URL: http://git.chromium.org/git/chromium.git@trunk
Patch Set: cleanup Created 9 years, 7 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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/gpu_process_host.h" 5 #include "content/browser/gpu/gpu_process_host.h"
6 6
7 #include "base/command_line.h" 7 #include "base/command_line.h"
8 #include "base/debug/trace_event.h" 8 #include "base/debug/trace_event.h"
9 #include "base/memory/ref_counted.h" 9 #include "base/memory/ref_counted.h"
10 #include "base/metrics/histogram.h" 10 #include "base/metrics/histogram.h"
11 #include "base/process_util.h" 11 #include "base/process_util.h"
12 #include "base/string_piece.h" 12 #include "base/string_piece.h"
13 #include "chrome/browser/tab_contents/render_view_host_delegate_helper.h" 13 #include "chrome/browser/tab_contents/render_view_host_delegate_helper.h"
14 #include "chrome/common/chrome_switches.h" 14 #include "chrome/common/chrome_switches.h"
15 #include "chrome/common/render_messages.h" 15 #include "chrome/common/render_messages.h"
16 #include "content/browser/browser_thread.h" 16 #include "content/browser/browser_thread.h"
17 #include "content/browser/gpu/gpu_data_manager.h" 17 #include "content/browser/gpu/gpu_data_manager.h"
18 #include "content/browser/gpu/gpu_process_host_ui_shim.h" 18 #include "content/browser/renderer_host/render_process_host.h"
19 #include "content/browser/renderer_host/render_widget_host.h" 19 #include "content/browser/renderer_host/render_widget_host.h"
20 #include "content/browser/renderer_host/render_widget_host_view.h" 20 #include "content/browser/renderer_host/render_widget_host_view.h"
21 #include "content/common/gpu/gpu_messages.h" 21 #include "content/common/gpu/gpu_messages.h"
22 #include "ipc/ipc_channel_handle.h"
23 #include "ipc/ipc_switches.h" 22 #include "ipc/ipc_switches.h"
24 #include "media/base/media_switches.h" 23 #include "media/base/media_switches.h"
25 #include "ui/gfx/gl/gl_context.h" 24 #include "ui/gfx/gl/gl_context.h"
26 #include "ui/gfx/gl/gl_switches.h" 25 #include "ui/gfx/gl/gl_switches.h"
27 26
28 #if defined(OS_LINUX)
29 #include "ui/gfx/gtk_native_view_id_manager.h"
30 #endif // defined(OS_LINUX)
31
32 namespace { 27 namespace {
33 28
34 enum GPUProcessLifetimeEvent { 29 enum GPUProcessLifetimeEvent {
35 LAUNCHED, 30 LAUNCHED,
36 DIED_FIRST_TIME, 31 DIED_FIRST_TIME,
37 DIED_SECOND_TIME, 32 DIED_SECOND_TIME,
38 DIED_THIRD_TIME, 33 DIED_THIRD_TIME,
39 DIED_FOURTH_TIME, 34 DIED_FOURTH_TIME,
40 GPU_PROCESS_LIFETIME_EVENT_MAX 35 GPU_PROCESS_LIFETIME_EVENT_MAX
41 }; 36 };
42 37
43 // A global map from GPU process host ID to GpuProcessHost. 38 // A global map from GPU process host ID to GpuProcessHost.
44 static IDMap<GpuProcessHost> g_hosts_by_id; 39 static IDMap<GpuProcessHost> g_hosts_by_id;
45 40
46 // Number of times the gpu process has crashed in the current browser session. 41 // Number of times the gpu process has crashed in the current browser session.
47 static int g_gpu_crash_count = 0; 42 static int g_gpu_crash_count = 0;
48 43
49 // Maximum number of times the gpu process is allowed to crash in a session. 44 // Maximum number of times the gpu process is allowed to crash in a session.
50 // Once this limit is reached, any request to launch the gpu process will fail. 45 // Once this limit is reached, any request to launch the gpu process will fail.
51 static const int kGpuMaxCrashCount = 3; 46 static const int kGpuMaxCrashCount = 3;
52 47
53 int g_last_host_id = 0; 48 int g_last_host_id = 0;
54 49
55 #if defined(OS_LINUX)
56
57 class ReleasePermanentXIDDispatcher: public Task {
58 public:
59 explicit ReleasePermanentXIDDispatcher(gfx::PluginWindowHandle surface);
60 void Run();
61 private:
62 gfx::PluginWindowHandle surface_;
63 };
64
65 ReleasePermanentXIDDispatcher::ReleasePermanentXIDDispatcher(
66 gfx::PluginWindowHandle surface)
67 : surface_(surface) {
68 }
69
70 void ReleasePermanentXIDDispatcher::Run() {
71 GtkNativeViewManager* manager = GtkNativeViewManager::GetInstance();
72 manager->ReleasePermanentXID(surface_);
73 }
74
75 #endif
76
77 void SendGpuProcessMessage(int renderer_id, 50 void SendGpuProcessMessage(int renderer_id,
78 content::CauseForGpuLaunch cause, 51 content::CauseForGpuLaunch cause,
79 IPC::Message* message) { 52 IPC::Message* message) {
80 GpuProcessHost* host = GpuProcessHost::GetForRenderer( 53 GpuProcessHost* host = GpuProcessHost::GetForRenderer(
81 renderer_id, cause); 54 renderer_id, cause);
82 if (host) { 55 if (host) {
83 host->Send(message); 56 host->Send(message);
84 } else { 57 } else {
85 delete message; 58 delete message;
86 } 59 }
87 } 60 }
88 61
89 } // anonymous namespace 62 } // anonymous namespace
90 63
91 #if defined(OS_LINUX)
92 // Used to put a lock on surfaces so that the window to which the GPU
93 // process is drawing to doesn't disappear while it is drawing when
94 // a tab is closed.
95 class GpuProcessHost::SurfaceRef {
96 public:
97 explicit SurfaceRef(gfx::PluginWindowHandle surface);
98 ~SurfaceRef();
99 private:
100 gfx::PluginWindowHandle surface_;
101 };
102
103 GpuProcessHost::SurfaceRef::SurfaceRef(gfx::PluginWindowHandle surface)
104 : surface_(surface) {
105 GtkNativeViewManager* manager = GtkNativeViewManager::GetInstance();
106 if (!manager->AddRefPermanentXID(surface_)) {
107 LOG(ERROR) << "Surface " << surface << " cannot be referenced.";
108 }
109 }
110
111 GpuProcessHost::SurfaceRef::~SurfaceRef() {
112 BrowserThread::PostTask(BrowserThread::UI,
113 FROM_HERE,
114 new ReleasePermanentXIDDispatcher(surface_));
115 }
116 #endif // defined(OS_LINUX)
117
118 // static 64 // static
119 GpuProcessHost* GpuProcessHost::GetForRenderer( 65 GpuProcessHost* GpuProcessHost::GetForRenderer(
120 int renderer_id, content::CauseForGpuLaunch cause) { 66 int renderer_id, content::CauseForGpuLaunch cause) {
121 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 67 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
122 68
123 // Don't grant further access to GPU if it is not allowed. 69 // Don't grant further access to GPU if it is not allowed.
124 GpuDataManager* gpu_data_manager = GpuDataManager::GetInstance(); 70 GpuDataManager* gpu_data_manager = GpuDataManager::GetInstance();
125 if (gpu_data_manager != NULL && !gpu_data_manager->GpuAccessAllowed()) 71 if (gpu_data_manager != NULL && !gpu_data_manager->GpuAccessAllowed())
126 return NULL; 72 return NULL;
127 73
128 // The current policy is to ignore the renderer ID and use a single GPU 74 // The current policy is to ignore the renderer ID and use a single GPU
129 // process for all renderers. Later this will be extended to allow the 75 // process for all renderers. Later this will be extended to allow the
130 // use of multiple GPU processes. 76 // use of multiple GPU processes.
131 if (!g_hosts_by_id.IsEmpty()) { 77 if (!g_hosts_by_id.IsEmpty()) {
132 IDMap<GpuProcessHost>::iterator it(&g_hosts_by_id); 78 IDMap<GpuProcessHost>::iterator it(&g_hosts_by_id);
133 return it.GetCurrentValue(); 79 return it.GetCurrentValue();
134 } 80 }
135 81
136 if (cause == content::CAUSE_FOR_GPU_LAUNCH_NO_LAUNCH) 82 if (cause == content::CAUSE_FOR_GPU_LAUNCH_NO_LAUNCH)
137 return NULL; 83 return NULL;
138 84
139 int host_id; 85 int host_id = ++g_last_host_id;
140 /* TODO(apatrick): this is currently broken because this function is called on
141 the IO thread from GpuMessageFilter, and we don't have an IO thread object
142 when running the GPU code in the browser at the moment.
143 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kSingleProcess) ||
144 CommandLine::ForCurrentProcess()->HasSwitch(switches::kInProcessGPU)) {
145 if (!g_browser_process->gpu_thread())
146 return NULL;
147
148 // Initialize GL on the GPU thread.
149 // TODO(apatrick): Handle failure to initialize (asynchronously).
150 if (!BrowserThread::PostTask(
151 BrowserThread::GPU,
152 FROM_HERE,
153 NewRunnableFunction(&gfx::GLContext::InitializeOneOff))) {
154 return NULL;
155 }
156
157 host_id = 0;
158 } else {
159 host_id = ++g_last_host_id;
160 }
161 */
162 host_id = ++g_last_host_id;
163 86
164 UMA_HISTOGRAM_ENUMERATION("GPU.GPUProcessLaunchCause", 87 UMA_HISTOGRAM_ENUMERATION("GPU.GPUProcessLaunchCause",
165 cause, 88 cause,
166 content::CAUSE_FOR_GPU_LAUNCH_MAX_ENUM); 89 content::CAUSE_FOR_GPU_LAUNCH_MAX_ENUM);
167 90
168 GpuProcessHost* host = new GpuProcessHost(host_id); 91 GpuProcessHost* host = new GpuProcessHost(host_id);
169 if (host->Init()) 92 if (host->Init())
170 return host; 93 return host;
171 94
172 delete host; 95 delete host;
(...skipping 18 matching lines...) Expand all
191 return NULL; 114 return NULL;
192 115
193 return g_hosts_by_id.Lookup(host_id); 116 return g_hosts_by_id.Lookup(host_id);
194 } 117 }
195 118
196 GpuProcessHost::GpuProcessHost(int host_id) 119 GpuProcessHost::GpuProcessHost(int host_id)
197 : BrowserChildProcessHost(GPU_PROCESS), 120 : BrowserChildProcessHost(GPU_PROCESS),
198 host_id_(host_id), 121 host_id_(host_id),
199 gpu_process_(base::kNullProcessHandle) { 122 gpu_process_(base::kNullProcessHandle) {
200 g_hosts_by_id.AddWithID(this, host_id_); 123 g_hosts_by_id.AddWithID(this, host_id_);
201 if (host_id == 0) 124 DCHECK(host_id);
202 gpu_process_ = base::GetCurrentProcessHandle(); 125 message_hub_.reset(new GpuMessageHub(host_id));
203
204 // Post a task to create the corresponding GpuProcessHostUIShim. The
205 // GpuProcessHostUIShim will be destroyed if either the browser exits,
206 // in which case it calls GpuProcessHostUIShim::DestroyAll, or the
207 // GpuProcessHost is destroyed, which happens when the corresponding GPU
208 // process terminates or fails to launch.
209 BrowserThread::PostTask(
210 BrowserThread::UI,
211 FROM_HERE,
212 NewRunnableFunction(&GpuProcessHostUIShim::Create, host_id));
213 } 126 }
214 127
215 GpuProcessHost::~GpuProcessHost() { 128 GpuProcessHost::~GpuProcessHost() {
216 DCHECK(CalledOnValidThread()); 129 DCHECK(CalledOnValidThread());
217 #if defined(OS_WIN) 130 #if defined(OS_WIN)
218 if (gpu_process_) 131 if (gpu_process_)
219 CloseHandle(gpu_process_); 132 CloseHandle(gpu_process_);
220 #endif 133 #endif
221 134
222 // In case we never started, clean up. 135 // In case we never started, clean up.
223 while (!queued_messages_.empty()) { 136 while (!queued_messages_.empty()) {
224 delete queued_messages_.front(); 137 delete queued_messages_.front();
225 queued_messages_.pop(); 138 queued_messages_.pop();
226 } 139 }
227 140
228 g_hosts_by_id.Remove(host_id_); 141 g_hosts_by_id.Remove(host_id_);
229
230 BrowserThread::PostTask(BrowserThread::UI,
231 FROM_HERE,
232 NewRunnableFunction(GpuProcessHostUIShim::Destroy,
233 host_id_));
234 } 142 }
235 143
236 bool GpuProcessHost::Init() { 144 bool GpuProcessHost::Init() {
237 if (!CreateChannel()) 145 if (!CreateChannel())
238 return false; 146 return false;
239 147
240 if (!LaunchGpuProcess()) 148 if (!LaunchGpuProcess())
241 return false; 149 return false;
242 150
243 return Send(new GpuMsg_Initialize()); 151 return Send(new GpuMsg_Initialize());
244 } 152 }
245 153
246 void GpuProcessHost::RouteOnUIThread(const IPC::Message& message) {
247 BrowserThread::PostTask(
248 BrowserThread::UI,
249 FROM_HERE,
250 new RouteToGpuProcessHostUIShimTask(host_id_, message));
251 }
252
253 bool GpuProcessHost::Send(IPC::Message* msg) { 154 bool GpuProcessHost::Send(IPC::Message* msg) {
254 DCHECK(CalledOnValidThread()); 155 DCHECK(CalledOnValidThread());
255 if (opening_channel()) { 156 if (opening_channel()) {
256 queued_messages_.push(msg); 157 queued_messages_.push(msg);
257 return true; 158 return true;
258 } 159 }
259 160
260 return BrowserChildProcessHost::Send(msg); 161 return BrowserChildProcessHost::Send(msg);
261 } 162 }
262 163
263 bool GpuProcessHost::OnMessageReceived(const IPC::Message& message) { 164 bool GpuProcessHost::OnMessageReceived(const IPC::Message& message) {
264 DCHECK(CalledOnValidThread()); 165 DCHECK(CalledOnValidThread());
265 IPC_BEGIN_MESSAGE_MAP(GpuProcessHost, message) 166 DCHECK(message_hub_.get());
266 IPC_MESSAGE_HANDLER(GpuHostMsg_ChannelEstablished, OnChannelEstablished) 167 return message_hub_->OnMessageReceived(message);
267 IPC_MESSAGE_HANDLER(GpuHostMsg_SynchronizeReply, OnSynchronizeReply)
268 IPC_MESSAGE_HANDLER(GpuHostMsg_CommandBufferCreated, OnCommandBufferCreated)
269 IPC_MESSAGE_HANDLER(GpuHostMsg_DestroyCommandBuffer, OnDestroyCommandBuffer)
270 IPC_MESSAGE_HANDLER(GpuHostMsg_GraphicsInfoCollected,
271 OnGraphicsInfoCollected)
272 IPC_MESSAGE_UNHANDLED(RouteOnUIThread(message))
273 IPC_END_MESSAGE_MAP()
274
275 return true;
276 } 168 }
277 169
278 void GpuProcessHost::OnChannelConnected(int32 peer_pid) { 170 void GpuProcessHost::OnChannelConnected(int32 peer_pid) {
279 while (!queued_messages_.empty()) { 171 while (!queued_messages_.empty()) {
280 Send(queued_messages_.front()); 172 Send(queued_messages_.front());
281 queued_messages_.pop(); 173 queued_messages_.pop();
282 } 174 }
283 } 175 }
284 176
285 void GpuProcessHost::EstablishGpuChannel(
286 int renderer_id,
287 EstablishChannelCallback *callback) {
288 DCHECK(CalledOnValidThread());
289 TRACE_EVENT0("gpu", "GpuProcessHostUIShim::EstablishGpuChannel");
290 linked_ptr<EstablishChannelCallback> wrapped_callback(callback);
291
292 // If GPU features are already blacklisted, no need to establish the channel.
293 if (!GpuDataManager::GetInstance()->GpuAccessAllowed()) {
294 EstablishChannelError(
295 wrapped_callback.release(), IPC::ChannelHandle(),
296 base::kNullProcessHandle, GPUInfo());
297 return;
298 }
299
300 if (Send(new GpuMsg_EstablishChannel(renderer_id))) {
301 channel_requests_.push(wrapped_callback);
302 } else {
303 EstablishChannelError(
304 wrapped_callback.release(), IPC::ChannelHandle(),
305 base::kNullProcessHandle, GPUInfo());
306 }
307 }
308
309 void GpuProcessHost::Synchronize(SynchronizeCallback* callback) {
310 DCHECK(CalledOnValidThread());
311 linked_ptr<SynchronizeCallback> wrapped_callback(callback);
312
313 if (Send(new GpuMsg_Synchronize())) {
314 synchronize_requests_.push(wrapped_callback);
315 } else {
316 SynchronizeError(wrapped_callback.release());
317 }
318 }
319
320 void GpuProcessHost::CreateViewCommandBuffer(
321 gfx::PluginWindowHandle compositing_surface,
322 int32 render_view_id,
323 int32 renderer_id,
324 const GPUCreateCommandBufferConfig& init_params,
325 CreateCommandBufferCallback* callback) {
326 DCHECK(CalledOnValidThread());
327 linked_ptr<CreateCommandBufferCallback> wrapped_callback(callback);
328
329 #if defined(OS_LINUX)
330 ViewID view_id(renderer_id, render_view_id);
331
332 // There should only be one such command buffer (for the compositor). In
333 // practice, if the GPU process lost a context, GraphicsContext3D with
334 // associated command buffer and view surface will not be gone until new
335 // one is in place and all layers are reattached.
336 linked_ptr<SurfaceRef> surface_ref;
337 SurfaceRefMap::iterator it = surface_refs_.find(view_id);
338 if (it != surface_refs_.end())
339 surface_ref = (*it).second;
340 else
341 surface_ref.reset(new SurfaceRef(compositing_surface));
342 #endif // defined(OS_LINUX)
343
344 if (compositing_surface != gfx::kNullPluginWindow &&
345 Send(new GpuMsg_CreateViewCommandBuffer(
346 compositing_surface, render_view_id, renderer_id, init_params))) {
347 create_command_buffer_requests_.push(wrapped_callback);
348 #if defined(OS_LINUX)
349 surface_refs_.insert(std::pair<ViewID, linked_ptr<SurfaceRef> >(
350 view_id, surface_ref));
351 #endif // defined(OS_LINUX)
352 } else {
353 CreateCommandBufferError(wrapped_callback.release(), MSG_ROUTING_NONE);
354 }
355 }
356
357 void GpuProcessHost::OnChannelEstablished(
358 const IPC::ChannelHandle& channel_handle) {
359 // The GPU process should have launched at this point and this object should
360 // have been notified of its process handle.
361 DCHECK(gpu_process_);
362
363 linked_ptr<EstablishChannelCallback> callback = channel_requests_.front();
364 channel_requests_.pop();
365
366 // Currently if any of the GPU features are blacklisted, we don't establish a
367 // GPU channel.
368 if (!channel_handle.name.empty() &&
369 !GpuDataManager::GetInstance()->GpuAccessAllowed()) {
370 Send(new GpuMsg_CloseChannel(channel_handle));
371 EstablishChannelError(callback.release(),
372 IPC::ChannelHandle(),
373 base::kNullProcessHandle,
374 GPUInfo());
375 RouteOnUIThread(GpuHostMsg_OnLogMessage(
376 logging::LOG_WARNING,
377 "WARNING",
378 "Hardware acceleration is unavailable."));
379 return;
380 }
381
382 callback->Run(
383 channel_handle, gpu_process_, GpuDataManager::GetInstance()->gpu_info());
384 }
385
386 void GpuProcessHost::OnSynchronizeReply() {
387 // Guard against race conditions in abrupt GPU process termination.
388 if (!synchronize_requests_.empty()) {
389 linked_ptr<SynchronizeCallback> callback(synchronize_requests_.front());
390 synchronize_requests_.pop();
391 callback->Run();
392 }
393 }
394
395 void GpuProcessHost::OnCommandBufferCreated(const int32 route_id) {
396 if (!create_command_buffer_requests_.empty()) {
397 linked_ptr<CreateCommandBufferCallback> callback =
398 create_command_buffer_requests_.front();
399 create_command_buffer_requests_.pop();
400 if (route_id == MSG_ROUTING_NONE)
401 CreateCommandBufferError(callback.release(), route_id);
402 else
403 callback->Run(route_id);
404 }
405 }
406
407 void GpuProcessHost::OnDestroyCommandBuffer(
408 gfx::PluginWindowHandle window, int32 renderer_id,
409 int32 render_view_id) {
410 #if defined(OS_LINUX)
411 ViewID view_id(renderer_id, render_view_id);
412 SurfaceRefMap::iterator it = surface_refs_.find(view_id);
413 if (it != surface_refs_.end())
414 surface_refs_.erase(it);
415 #endif // defined(OS_LINUX)
416 }
417
418 void GpuProcessHost::OnGraphicsInfoCollected(const GPUInfo& gpu_info) {
419 GpuDataManager::GetInstance()->UpdateGpuInfo(gpu_info);
420 }
421
422 bool GpuProcessHost::CanShutdown() { 177 bool GpuProcessHost::CanShutdown() {
423 return true; 178 return true;
424 } 179 }
425 180
426 void GpuProcessHost::OnProcessLaunched() { 181 void GpuProcessHost::OnProcessLaunched() {
427 // Send the GPU process handle to the UI thread before it has to 182 // Send the GPU process handle to the UI thread before it has to
428 // respond to any requests to establish a GPU channel. The response 183 // respond to any requests to establish a GPU channel. The response
429 // to such requests require that the GPU process handle be known. 184 // to such requests require that the GPU process handle be known.
430 #if defined(OS_WIN) 185 #if defined(OS_WIN)
431 DuplicateHandle(base::GetCurrentProcessHandle(), 186 DuplicateHandle(base::GetCurrentProcessHandle(),
432 handle(), 187 handle(),
433 base::GetCurrentProcessHandle(), 188 base::GetCurrentProcessHandle(),
434 &gpu_process_, 189 &gpu_process_,
435 PROCESS_DUP_HANDLE, 190 PROCESS_DUP_HANDLE,
436 FALSE, 191 FALSE,
437 0); 192 0);
438 #else 193 #else
439 gpu_process_ = handle(); 194 gpu_process_ = handle();
440 #endif 195 #endif
196
197 DCHECK(message_hub_.get());
198 message_hub_->SetGPUProcess(gpu_process_);
441 } 199 }
442 200
443 void GpuProcessHost::OnChildDied() { 201 void GpuProcessHost::OnChildDied() {
444 SendOutstandingReplies(); 202 SendOutstandingReplies();
445 // Located in OnChildDied because OnProcessCrashed suffers from a race 203 // Located in OnChildDied because OnProcessCrashed suffers from a race
446 // condition on Linux. 204 // condition on Linux.
447 UMA_HISTOGRAM_ENUMERATION("GPU.GPUProcessLifetimeEvents", 205 UMA_HISTOGRAM_ENUMERATION("GPU.GPUProcessLifetimeEvents",
448 DIED_FIRST_TIME + g_gpu_crash_count, 206 DIED_FIRST_TIME + g_gpu_crash_count,
449 GPU_PROCESS_LIFETIME_EVENT_MAX); 207 GPU_PROCESS_LIFETIME_EVENT_MAX);
450 base::TerminationStatus status = GetChildTerminationStatus(NULL); 208 base::TerminationStatus status = GetChildTerminationStatus(NULL);
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
521 base::environment_vector(), 279 base::environment_vector(),
522 #endif 280 #endif
523 cmd_line); 281 cmd_line);
524 282
525 UMA_HISTOGRAM_ENUMERATION("GPU.GPUProcessLifetimeEvents", 283 UMA_HISTOGRAM_ENUMERATION("GPU.GPUProcessLifetimeEvents",
526 LAUNCHED, GPU_PROCESS_LIFETIME_EVENT_MAX); 284 LAUNCHED, GPU_PROCESS_LIFETIME_EVENT_MAX);
527 return true; 285 return true;
528 } 286 }
529 287
530 void GpuProcessHost::SendOutstandingReplies() { 288 void GpuProcessHost::SendOutstandingReplies() {
531 // First send empty channel handles for all EstablishChannel requests. 289 DCHECK(message_hub_.get());
532 while (!channel_requests_.empty()) { 290 message_hub_->SendOutstandingReplies();
533 linked_ptr<EstablishChannelCallback> callback = channel_requests_.front();
534 channel_requests_.pop();
535 EstablishChannelError(callback.release(),
536 IPC::ChannelHandle(),
537 base::kNullProcessHandle,
538 GPUInfo());
539 }
540
541 // Now unblock all renderers waiting for synchronization replies.
542 while (!synchronize_requests_.empty()) {
543 linked_ptr<SynchronizeCallback> callback = synchronize_requests_.front();
544 synchronize_requests_.pop();
545 SynchronizeError(callback.release());
546 }
547 } 291 }
548
549 void GpuProcessHost::EstablishChannelError(
550 EstablishChannelCallback* callback,
551 const IPC::ChannelHandle& channel_handle,
552 base::ProcessHandle renderer_process_for_gpu,
553 const GPUInfo& gpu_info) {
554 scoped_ptr<EstablishChannelCallback> wrapped_callback(callback);
555 wrapped_callback->Run(channel_handle, renderer_process_for_gpu, gpu_info);
556 }
557
558 void GpuProcessHost::CreateCommandBufferError(
559 CreateCommandBufferCallback* callback, int32 route_id) {
560 scoped_ptr<GpuProcessHost::CreateCommandBufferCallback>
561 wrapped_callback(callback);
562 callback->Run(route_id);
563 }
564
565 void GpuProcessHost::SynchronizeError(SynchronizeCallback* callback) {
566 scoped_ptr<SynchronizeCallback> wrapped_callback(callback);
567 wrapped_callback->Run();
568 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698