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

Side by Side Diff: chrome/browser/gpu_process_host.cc

Issue 6343006: Route IPC through browser when creating a viewable command buffer. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix nit. Created 9 years, 10 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
« no previous file with comments | « chrome/browser/gpu_process_host.h ('k') | chrome/browser/gpu_process_host_ui_shim.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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.h" 5 #include "chrome/browser/gpu_process_host.h"
6 6
7 #include "app/app_switches.h" 7 #include "app/app_switches.h"
8 #include "base/command_line.h" 8 #include "base/command_line.h"
9 #include "base/metrics/histogram.h" 9 #include "base/metrics/histogram.h"
10 #include "base/string_piece.h" 10 #include "base/string_piece.h"
11 #include "base/threading/thread.h" 11 #include "base/threading/thread.h"
12 #include "chrome/browser/browser_thread.h" 12 #include "chrome/browser/browser_thread.h"
13 #include "chrome/browser/gpu_blacklist.h" 13 #include "chrome/browser/gpu_blacklist.h"
14 #include "chrome/browser/gpu_process_host_ui_shim.h" 14 #include "chrome/browser/gpu_process_host_ui_shim.h"
15 #include "chrome/browser/renderer_host/render_message_filter.h" 15 #include "chrome/browser/renderer_host/render_message_filter.h"
16 #include "chrome/browser/renderer_host/render_view_host.h"
17 #include "chrome/browser/renderer_host/render_widget_host_view.h"
16 #include "chrome/browser/tab_contents/render_view_host_delegate_helper.h" 18 #include "chrome/browser/tab_contents/render_view_host_delegate_helper.h"
17 #include "chrome/common/chrome_switches.h" 19 #include "chrome/common/chrome_switches.h"
18 #include "chrome/common/gpu_feature_flags.h" 20 #include "chrome/common/gpu_feature_flags.h"
19 #include "chrome/common/gpu_info.h" 21 #include "chrome/common/gpu_info.h"
20 #include "chrome/common/gpu_messages.h" 22 #include "chrome/common/gpu_messages.h"
21 #include "chrome/common/render_messages.h" 23 #include "chrome/common/render_messages.h"
22 #include "chrome/gpu/gpu_thread.h" 24 #include "chrome/gpu/gpu_thread.h"
23 #include "grit/browser_resources.h" 25 #include "grit/browser_resources.h"
24 #include "ipc/ipc_channel_handle.h" 26 #include "ipc/ipc_channel_handle.h"
25 #include "ipc/ipc_switches.h" 27 #include "ipc/ipc_switches.h"
26 #include "media/base/media_switches.h" 28 #include "media/base/media_switches.h"
27 #include "ui/base/resource/resource_bundle.h" 29 #include "ui/base/resource/resource_bundle.h"
28 30
31 #if defined(OS_LINUX)
32 #include "gfx/gtk_native_view_id_manager.h"
33 #endif // defined(OS_LINUX)
34
29 namespace { 35 namespace {
30 36
31 enum GPUProcessLifetimeEvent { 37 enum GPUProcessLifetimeEvent {
32 LAUNCED, 38 LAUNCED,
33 CRASHED, 39 CRASHED,
34 GPU_PROCESS_LIFETIME_EVENT_MAX 40 GPU_PROCESS_LIFETIME_EVENT_MAX
35 }; 41 };
36 42
37 // Tasks used by this file 43 // Tasks used by this file
38 class RouteOnUIThreadTask : public Task { 44 class RouteOnUIThreadTask : public Task {
(...skipping 19 matching lines...) Expand all
58 static int g_gpu_crash_count = 0; 64 static int g_gpu_crash_count = 0;
59 // Maximum number of times the gpu process is allowed to crash in a session. 65 // Maximum number of times the gpu process is allowed to crash in a session.
60 // Once this limit is reached, any request to launch the gpu process will fail. 66 // Once this limit is reached, any request to launch the gpu process will fail.
61 static const int kGpuMaxCrashCount = 3; 67 static const int kGpuMaxCrashCount = 3;
62 68
63 void RouteOnUIThread(const IPC::Message& message) { 69 void RouteOnUIThread(const IPC::Message& message) {
64 BrowserThread::PostTask(BrowserThread::UI, 70 BrowserThread::PostTask(BrowserThread::UI,
65 FROM_HERE, 71 FROM_HERE,
66 new RouteOnUIThreadTask(message)); 72 new RouteOnUIThreadTask(message));
67 } 73 }
74
75 bool SendDelayedMsg(IPC::Message* reply_msg) {
76 return GpuProcessHost::Get()->Send(reply_msg);
77 }
78
79 bool SendDelayedMsg(IPC::Message* reply, RenderMessageFilter* filter) {
80 return filter->Send(reply);
81 }
82
68 } // anonymous namespace 83 } // anonymous namespace
69 84
70 class GpuMainThread : public base::Thread { 85 class GpuMainThread : public base::Thread {
71 public: 86 public:
72 explicit GpuMainThread(const std::string& channel_id) 87 explicit GpuMainThread(const std::string& channel_id)
73 : base::Thread("CrGpuMain"), 88 : base::Thread("CrGpuMain"),
74 channel_id_(channel_id) { 89 channel_id_(channel_id) {
75 } 90 }
76 91
77 ~GpuMainThread() { 92 ~GpuMainThread() {
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
174 } else { 189 } else {
175 SendEstablishChannelReply(IPC::ChannelHandle(), GPUInfo(), filter); 190 SendEstablishChannelReply(IPC::ChannelHandle(), GPUInfo(), filter);
176 } 191 }
177 } 192 }
178 193
179 void GpuProcessHost::Synchronize(IPC::Message* reply, 194 void GpuProcessHost::Synchronize(IPC::Message* reply,
180 RenderMessageFilter* filter) { 195 RenderMessageFilter* filter) {
181 DCHECK(CalledOnValidThread()); 196 DCHECK(CalledOnValidThread());
182 197
183 if (Send(new GpuMsg_Synchronize())) { 198 if (Send(new GpuMsg_Synchronize())) {
184 queued_synchronization_replies_.push(SynchronizationRequest(reply, filter)); 199 queued_synchronization_replies_.push(DelayedReply(reply, filter));
185 } else { 200 } else {
186 SendSynchronizationReply(reply, filter); 201 SendDelayedMsg(reply, filter);
187 } 202 }
188 } 203 }
189 204
205 class CVCBThreadHopping {
206 public:
207 // Send the request for a command buffer from the IO thread and
208 // queue that we are expecting a response.
209 static void DispatchIPCAndQueueReply(
210 gfx::PluginWindowHandle view,
211 int32 render_view_id,
212 int32 renderer_id,
213 const GPUCreateCommandBufferConfig& init_params,
214 IPC::Message* reply,
215 scoped_refptr<RenderMessageFilter> filter);
216
217 // Get a window for the command buffer that we're creating.
218 static void GetViewWindow(
219 int32 render_view_id,
220 int32 renderer_id,
221 const GPUCreateCommandBufferConfig& init_params,
222 IPC::Message* reply,
223 scoped_refptr<RenderMessageFilter> filter);
224 };
225
226 void CVCBThreadHopping::DispatchIPCAndQueueReply(
227 gfx::PluginWindowHandle view,
228 int32 render_view_id,
229 int32 renderer_id,
230 const GPUCreateCommandBufferConfig& init_params,
231 IPC::Message* reply,
232 scoped_refptr<RenderMessageFilter> filter) {
233 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
234 GpuProcessHost* host = GpuProcessHost::Get();
235
236 if (view != gfx::kNullPluginWindow &&
237 SendDelayedMsg(new GpuMsg_CreateViewCommandBuffer(
238 view, render_view_id, renderer_id, init_params))) {
239 host->create_command_buffer_replies_.push(
240 GpuProcessHost::DelayedReply(reply, filter));
241 } else {
242 int32 route_id = MSG_ROUTING_NONE;
243 ViewHostMsg_CreateViewCommandBuffer::WriteReplyParams(reply, route_id);
244 SendDelayedMsg(reply, filter);
245 }
246 }
247
248 void CVCBThreadHopping::GetViewWindow(
249 int32 render_view_id,
250 int32 renderer_id,
251 const GPUCreateCommandBufferConfig& init_params,
252 IPC::Message* reply,
253 scoped_refptr<RenderMessageFilter> filter) {
254 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
255 gfx::PluginWindowHandle window = gfx::kNullPluginWindow;
256 RenderViewHost* host = RenderViewHost::FromID(renderer_id,
257 render_view_id);
258 #if defined(OS_LINUX)
259 gfx::NativeViewId view = NULL;
260 if (host)
261 view = gfx::IdFromNativeView(host->view()->GetNativeView());
262
263 // Lock the window that we will draw into.
264 GtkNativeViewManager* manager = GtkNativeViewManager::GetInstance();
265 if (!manager->GetPermanentXIDForId(&window, view)) {
266 DLOG(ERROR) << "Can't find XID for view id " << view;
267 }
268 #elif defined(OS_MACOSX)
269 // On Mac OS X we currently pass a (fake) PluginWindowHandle for the
270 // window that we draw to.
271 window = host->view()->AllocateFakePluginWindowHandle(
272 /*opaque=*/true, /*root=*/true);
273 #elif defined(OS_WIN)
274 // Create a window that we will overlay.
275 window = host->view()->GetCompositorHostWindow();
276 #endif
277
278 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, NewRunnableFunction(
279 &CVCBThreadHopping::DispatchIPCAndQueueReply,
280 window, render_view_id, renderer_id, init_params, reply, filter));
281 }
282
283 void GpuProcessHost::CreateViewCommandBuffer(
284 int32 render_view_id,
285 int32 renderer_id,
286 const GPUCreateCommandBufferConfig& init_params,
287 IPC::Message* reply,
288 RenderMessageFilter* filter) {
289 DCHECK(CalledOnValidThread());
290
291 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, NewRunnableFunction(
292 &CVCBThreadHopping::GetViewWindow,
293 render_view_id, renderer_id, init_params, reply,
294 static_cast<scoped_refptr<RenderMessageFilter> > (filter)));
295 }
296
297
190 GpuProcessHost::ChannelRequest::ChannelRequest(RenderMessageFilter* filter) 298 GpuProcessHost::ChannelRequest::ChannelRequest(RenderMessageFilter* filter)
191 : filter(filter) { 299 : filter(filter) {
192 } 300 }
193 301
194 GpuProcessHost::ChannelRequest::~ChannelRequest() {} 302 GpuProcessHost::ChannelRequest::~ChannelRequest() {}
195 303
196 GpuProcessHost::SynchronizationRequest::SynchronizationRequest( 304 GpuProcessHost::DelayedReply::DelayedReply(
197 IPC::Message* reply, 305 IPC::Message* reply,
198 RenderMessageFilter* filter) 306 RenderMessageFilter* filter)
199 : reply(reply), 307 : reply(reply),
200 filter(filter) { 308 filter(filter) {
201 } 309 }
202 310
203 GpuProcessHost::SynchronizationRequest::~SynchronizationRequest() {} 311 GpuProcessHost::DelayedReply::~DelayedReply() {}
204 312
205 bool GpuProcessHost::OnControlMessageReceived(const IPC::Message& message) { 313 bool GpuProcessHost::OnControlMessageReceived(const IPC::Message& message) {
206 DCHECK(CalledOnValidThread()); 314 DCHECK(CalledOnValidThread());
207 315
208 IPC_BEGIN_MESSAGE_MAP(GpuProcessHost, message) 316 IPC_BEGIN_MESSAGE_MAP(GpuProcessHost, message)
209 IPC_MESSAGE_HANDLER(GpuHostMsg_ChannelEstablished, OnChannelEstablished) 317 IPC_MESSAGE_HANDLER(GpuHostMsg_ChannelEstablished, OnChannelEstablished)
210 IPC_MESSAGE_HANDLER(GpuHostMsg_SynchronizeReply, OnSynchronizeReply) 318 IPC_MESSAGE_HANDLER(GpuHostMsg_SynchronizeReply, OnSynchronizeReply)
319 IPC_MESSAGE_HANDLER(GpuHostMsg_CommandBufferCreated, OnCommandBufferCreated)
211 // If the IO thread does not handle the message then automatically route it 320 // If the IO thread does not handle the message then automatically route it
212 // to the UI thread. The UI thread will report an error if it does not 321 // to the UI thread. The UI thread will report an error if it does not
213 // handle it. 322 // handle it.
214 IPC_MESSAGE_UNHANDLED(RouteOnUIThread(message)) 323 IPC_MESSAGE_UNHANDLED(RouteOnUIThread(message))
215 IPC_END_MESSAGE_MAP() 324 IPC_END_MESSAGE_MAP()
216 325
217 return true; 326 return true;
218 } 327 }
219 328
220 void GpuProcessHost::OnChannelEstablished( 329 void GpuProcessHost::OnChannelEstablished(
(...skipping 28 matching lines...) Expand all
249 SendEstablishChannelReply(IPC::ChannelHandle(), gpu_info, request.filter); 358 SendEstablishChannelReply(IPC::ChannelHandle(), gpu_info, request.filter);
250 } else { 359 } else {
251 SendEstablishChannelReply(channel_handle, gpu_info, request.filter); 360 SendEstablishChannelReply(channel_handle, gpu_info, request.filter);
252 } 361 }
253 sent_requests_.pop(); 362 sent_requests_.pop();
254 } 363 }
255 364
256 void GpuProcessHost::OnSynchronizeReply() { 365 void GpuProcessHost::OnSynchronizeReply() {
257 // Guard against race conditions in abrupt GPU process termination. 366 // Guard against race conditions in abrupt GPU process termination.
258 if (queued_synchronization_replies_.size() > 0) { 367 if (queued_synchronization_replies_.size() > 0) {
259 const SynchronizationRequest& request = 368 const DelayedReply& request =
260 queued_synchronization_replies_.front(); 369 queued_synchronization_replies_.front();
261 SendSynchronizationReply(request.reply, request.filter); 370 SendDelayedMsg(request.reply, request.filter);
262 queued_synchronization_replies_.pop(); 371 queued_synchronization_replies_.pop();
263 } 372 }
264 } 373 }
265 374
375 void GpuProcessHost::OnCommandBufferCreated(const int32 route_id) {
376 if (create_command_buffer_replies_.size() > 0) {
377 const DelayedReply& request =
378 create_command_buffer_replies_.front();
379 ViewHostMsg_CreateViewCommandBuffer::WriteReplyParams(
380 request.reply, route_id);
381 SendDelayedMsg(request.reply, request.filter);
382 create_command_buffer_replies_.pop();
383 }
384 }
385
266 void GpuProcessHost::SendEstablishChannelReply( 386 void GpuProcessHost::SendEstablishChannelReply(
267 const IPC::ChannelHandle& channel, 387 const IPC::ChannelHandle& channel,
268 const GPUInfo& gpu_info, 388 const GPUInfo& gpu_info,
269 RenderMessageFilter* filter) { 389 RenderMessageFilter* filter) {
270 ViewMsg_GpuChannelEstablished* message = 390 ViewMsg_GpuChannelEstablished* message =
271 new ViewMsg_GpuChannelEstablished(channel, gpu_info); 391 new ViewMsg_GpuChannelEstablished(channel, gpu_info);
272 // If the renderer process is performing synchronous initialization, 392 // If the renderer process is performing synchronous initialization,
273 // it needs to handle this message before receiving the reply for 393 // it needs to handle this message before receiving the reply for
274 // the synchronous ViewHostMsg_SynchronizeGpu message. 394 // the synchronous ViewHostMsg_SynchronizeGpu message.
275 message->set_unblock(true); 395 message->set_unblock(true);
276 filter->Send(message); 396 filter->Send(message);
277 } 397 }
278 398
279 // Sends the response for synchronization request to the renderer.
280 void GpuProcessHost::SendSynchronizationReply(
281 IPC::Message* reply,
282 RenderMessageFilter* filter) {
283 filter->Send(reply);
284 }
285
286 void GpuProcessHost::SendOutstandingReplies() { 399 void GpuProcessHost::SendOutstandingReplies() {
287 // First send empty channel handles for all EstablishChannel requests. 400 // First send empty channel handles for all EstablishChannel requests.
288 while (!sent_requests_.empty()) { 401 while (!sent_requests_.empty()) {
289 const ChannelRequest& request = sent_requests_.front(); 402 const ChannelRequest& request = sent_requests_.front();
290 SendEstablishChannelReply(IPC::ChannelHandle(), GPUInfo(), request.filter); 403 SendEstablishChannelReply(IPC::ChannelHandle(), GPUInfo(), request.filter);
291 sent_requests_.pop(); 404 sent_requests_.pop();
292 } 405 }
293 406
294 // Now unblock all renderers waiting for synchronization replies. 407 // Now unblock all renderers waiting for synchronization replies.
295 while (!queued_synchronization_replies_.empty()) { 408 while (!queued_synchronization_replies_.empty()) {
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
402 const CommandLine& browser_command_line = *CommandLine::ForCurrentProcess(); 515 const CommandLine& browser_command_line = *CommandLine::ForCurrentProcess();
403 if (browser_command_line.HasSwitch(switches::kIgnoreGpuBlacklist) || 516 if (browser_command_line.HasSwitch(switches::kIgnoreGpuBlacklist) ||
404 blacklist->LoadGpuBlacklist(gpu_blacklist_json.as_string(), true)) { 517 blacklist->LoadGpuBlacklist(gpu_blacklist_json.as_string(), true)) {
405 gpu_blacklist_.reset(blacklist); 518 gpu_blacklist_.reset(blacklist);
406 return true; 519 return true;
407 } 520 }
408 delete blacklist; 521 delete blacklist;
409 return false; 522 return false;
410 } 523 }
411 524
OLDNEW
« no previous file with comments | « chrome/browser/gpu_process_host.h ('k') | chrome/browser/gpu_process_host_ui_shim.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698