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

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: Some final cleanup before review. Created 9 years, 11 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) 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 GPUBlacklistTestResult { 37 enum GPUBlacklistTestResult {
32 BLOCKED, 38 BLOCKED,
33 ALLOWED, 39 ALLOWED,
34 BLACKLIST_TEST_RESULT_MAX 40 BLACKLIST_TEST_RESULT_MAX
35 }; 41 };
36 42
37 enum GPUProcessLifetimeEvent { 43 enum GPUProcessLifetimeEvent {
38 LAUNCED, 44 LAUNCED,
(...skipping 25 matching lines...) Expand all
64 static int g_gpu_crash_count = 0; 70 static int g_gpu_crash_count = 0;
65 // Maximum number of times the gpu process is allowed to crash in a session. 71 // Maximum number of times the gpu process is allowed to crash in a session.
66 // Once this limit is reached, any request to launch the gpu process will fail. 72 // Once this limit is reached, any request to launch the gpu process will fail.
67 static const int kGpuMaxCrashCount = 3; 73 static const int kGpuMaxCrashCount = 3;
68 74
69 void RouteOnUIThread(const IPC::Message& message) { 75 void RouteOnUIThread(const IPC::Message& message) {
70 BrowserThread::PostTask(BrowserThread::UI, 76 BrowserThread::PostTask(BrowserThread::UI,
71 FROM_HERE, 77 FROM_HERE,
72 new RouteOnUIThreadTask(message)); 78 new RouteOnUIThreadTask(message));
73 } 79 }
80
81 bool SendDelayedMsg(IPC::Message* reply_msg) {
82 return GpuProcessHost::Get()->Send(reply_msg);
83 }
84
85 bool SendDelayedMsg(IPC::Message* reply, RenderMessageFilter* filter) {
86 return filter->Send(reply);
87 }
88
74 } // anonymous namespace 89 } // anonymous namespace
75 90
76 class GpuMainThread : public base::Thread { 91 class GpuMainThread : public base::Thread {
77 public: 92 public:
78 explicit GpuMainThread(const std::string& channel_id) 93 explicit GpuMainThread(const std::string& channel_id)
79 : base::Thread("CrGpuMain"), 94 : base::Thread("CrGpuMain"),
80 channel_id_(channel_id) { 95 channel_id_(channel_id) {
81 } 96 }
82 97
83 ~GpuMainThread() { 98 ~GpuMainThread() {
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
180 } else { 195 } else {
181 SendEstablishChannelReply(IPC::ChannelHandle(), GPUInfo(), filter); 196 SendEstablishChannelReply(IPC::ChannelHandle(), GPUInfo(), filter);
182 } 197 }
183 } 198 }
184 199
185 void GpuProcessHost::Synchronize(IPC::Message* reply, 200 void GpuProcessHost::Synchronize(IPC::Message* reply,
186 RenderMessageFilter* filter) { 201 RenderMessageFilter* filter) {
187 DCHECK(CalledOnValidThread()); 202 DCHECK(CalledOnValidThread());
188 203
189 if (Send(new GpuMsg_Synchronize())) { 204 if (Send(new GpuMsg_Synchronize())) {
190 queued_synchronization_replies_.push(SynchronizationRequest(reply, filter)); 205 queued_synchronization_replies_.push(DelayedReply(reply, filter));
191 } else { 206 } else {
192 SendSynchronizationReply(reply, filter); 207 SendDelayedMsg(reply, filter);
193 } 208 }
194 } 209 }
195 210
211 class CVCBThreadHopping {
212 public:
213 // Send the request for a command buffer from the IO thread and
214 // queue that we are expecting a response.
215 static void DispatchIPCAndQueueReply(
apatrick 2011/01/26 19:50:05 Can't these just be free functions?
jonathan.backer 2011/01/26 20:42:17 I need to access GpuProcessHost internals. I opted
216 gfx::PluginWindowHandle view,
217 int32 render_view_id,
218 int32 renderer_id,
219 const GPUCreateCommandBufferConfig& init_params,
220 IPC::Message* reply,
221 scoped_refptr<RenderMessageFilter> filter);
222
223 // Get a window for the command buffer that we're creating.
224 static void GetViewWindow(
225 int32 render_view_id,
226 int32 renderer_id,
227 const GPUCreateCommandBufferConfig& init_params,
228 IPC::Message* reply,
229 scoped_refptr<RenderMessageFilter> filter);
230 };
231
232 void CVCBThreadHopping::DispatchIPCAndQueueReply(
233 gfx::PluginWindowHandle view,
234 int32 render_view_id,
235 int32 renderer_id,
236 const GPUCreateCommandBufferConfig& init_params,
237 IPC::Message* reply,
238 scoped_refptr<RenderMessageFilter> filter) {
239 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
240 GpuProcessHost* host = GpuProcessHost::Get();
241
242 if (view != gfx::kNullPluginWindow &&
243 SendDelayedMsg(new GpuMsg_CreateViewCommandBuffer(
244 view, render_view_id, renderer_id, init_params))) {
245 host->create_command_buffer_replies_.push(
246 GpuProcessHost::DelayedReply(reply, filter));
247 } else {
248 int32 route_id = MSG_ROUTING_NONE;
249 ViewHostMsg_CreateViewCommandBuffer::WriteReplyParams(reply, route_id);
250 SendDelayedMsg(reply, filter);
251 }
252 }
253
254 void CVCBThreadHopping::GetViewWindow(
255 int32 render_view_id,
256 int32 renderer_id,
257 const GPUCreateCommandBufferConfig& init_params,
258 IPC::Message* reply,
259 scoped_refptr<RenderMessageFilter> filter) {
260 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
apatrick 2011/01/26 19:50:05 As a general rule, all the code in this file shoul
jonathan.backer 2011/01/26 20:42:17 I understand. I did it this way because I didn't w
261 gfx::PluginWindowHandle window = gfx::kNullPluginWindow;
262 RenderViewHost* host = RenderViewHost::FromID(renderer_id,
263 render_view_id);
264 #if defined(OS_LINUX)
265 gfx::NativeViewId view = NULL;
266 if (host)
267 view = gfx::IdFromNativeView(host->view()->GetNativeView());
268
269 // Lock the window that we will draw into.
270 GtkNativeViewManager* manager = GtkNativeViewManager::GetInstance();
271 if (!manager->GetPermanentXIDForId(&window, view)) {
272 DLOG(ERROR) << "Can't find XID for view id " << view;
273 }
274 #elif defined(OS_MACOSX)
275 // On Mac OS X we currently pass a (fake) PluginWindowHandle for the
276 // window that we draw to.
277 window = host->view()->AllocateFakePluginWindowHandle(
278 /*opaque=*/true, /*root=*/true);
279 #elif defined(OS_WIN)
280 // Create a window that we will overlay.
281 window = host->view()->GetCompositorHostWindow();
282 #endif
283
284 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, NewRunnableFunction(
285 &CVCBThreadHopping::DispatchIPCAndQueueReply,
286 window, render_view_id, renderer_id, init_params, reply, filter));
287 }
288
289 void GpuProcessHost::CreateViewCommandBuffer(
290 int32 render_view_id,
291 int32 renderer_id,
292 const GPUCreateCommandBufferConfig& init_params,
293 IPC::Message* reply,
294 RenderMessageFilter* filter) {
295 DCHECK(CalledOnValidThread());
296
297 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, NewRunnableFunction(
298 &CVCBThreadHopping::GetViewWindow,
299 render_view_id, renderer_id, init_params, reply,
300 static_cast<scoped_refptr<RenderMessageFilter> > (filter)));
301 }
302
303
196 GpuProcessHost::ChannelRequest::ChannelRequest(RenderMessageFilter* filter) 304 GpuProcessHost::ChannelRequest::ChannelRequest(RenderMessageFilter* filter)
197 : filter(filter) { 305 : filter(filter) {
198 } 306 }
199 307
200 GpuProcessHost::ChannelRequest::~ChannelRequest() {} 308 GpuProcessHost::ChannelRequest::~ChannelRequest() {}
201 309
202 GpuProcessHost::SynchronizationRequest::SynchronizationRequest( 310 GpuProcessHost::DelayedReply::DelayedReply(
203 IPC::Message* reply, 311 IPC::Message* reply,
204 RenderMessageFilter* filter) 312 RenderMessageFilter* filter)
205 : reply(reply), 313 : reply(reply),
206 filter(filter) { 314 filter(filter) {
207 } 315 }
208 316
209 GpuProcessHost::SynchronizationRequest::~SynchronizationRequest() {} 317 GpuProcessHost::DelayedReply::~DelayedReply() {}
210 318
211 bool GpuProcessHost::OnControlMessageReceived(const IPC::Message& message) { 319 bool GpuProcessHost::OnControlMessageReceived(const IPC::Message& message) {
212 DCHECK(CalledOnValidThread()); 320 DCHECK(CalledOnValidThread());
213 321
214 IPC_BEGIN_MESSAGE_MAP(GpuProcessHost, message) 322 IPC_BEGIN_MESSAGE_MAP(GpuProcessHost, message)
215 IPC_MESSAGE_HANDLER(GpuHostMsg_ChannelEstablished, OnChannelEstablished) 323 IPC_MESSAGE_HANDLER(GpuHostMsg_ChannelEstablished, OnChannelEstablished)
216 IPC_MESSAGE_HANDLER(GpuHostMsg_SynchronizeReply, OnSynchronizeReply) 324 IPC_MESSAGE_HANDLER(GpuHostMsg_SynchronizeReply, OnSynchronizeReply)
325 IPC_MESSAGE_HANDLER(GpuHostMsg_CommandBufferCreated, OnCommandBufferCreated)
217 // If the IO thread does not handle the message then automatically route it 326 // If the IO thread does not handle the message then automatically route it
218 // to the UI thread. The UI thread will report an error if it does not 327 // to the UI thread. The UI thread will report an error if it does not
219 // handle it. 328 // handle it.
220 IPC_MESSAGE_UNHANDLED(RouteOnUIThread(message)) 329 IPC_MESSAGE_UNHANDLED(RouteOnUIThread(message))
221 IPC_END_MESSAGE_MAP() 330 IPC_END_MESSAGE_MAP()
222 331
223 return true; 332 return true;
224 } 333 }
225 334
226 void GpuProcessHost::OnChannelEstablished( 335 void GpuProcessHost::OnChannelEstablished(
(...skipping 20 matching lines...) Expand all
247 UMA_HISTOGRAM_ENUMERATION("GPU.BlacklistTestResults", 356 UMA_HISTOGRAM_ENUMERATION("GPU.BlacklistTestResults",
248 test_result, BLACKLIST_TEST_RESULT_MAX); 357 test_result, BLACKLIST_TEST_RESULT_MAX);
249 blacklist_result_recorded_ = true; 358 blacklist_result_recorded_ = true;
250 } 359 }
251 sent_requests_.pop(); 360 sent_requests_.pop();
252 } 361 }
253 362
254 void GpuProcessHost::OnSynchronizeReply() { 363 void GpuProcessHost::OnSynchronizeReply() {
255 // Guard against race conditions in abrupt GPU process termination. 364 // Guard against race conditions in abrupt GPU process termination.
256 if (queued_synchronization_replies_.size() > 0) { 365 if (queued_synchronization_replies_.size() > 0) {
257 const SynchronizationRequest& request = 366 const DelayedReply& request =
258 queued_synchronization_replies_.front(); 367 queued_synchronization_replies_.front();
259 SendSynchronizationReply(request.reply, request.filter); 368 SendDelayedMsg(request.reply, request.filter);
260 queued_synchronization_replies_.pop(); 369 queued_synchronization_replies_.pop();
261 } 370 }
262 } 371 }
263 372
373 void GpuProcessHost::OnCommandBufferCreated(const int32 route_id) {
374 if (create_command_buffer_replies_.size() > 0) {
375 const DelayedReply& request =
376 create_command_buffer_replies_.front();
377 ViewHostMsg_CreateViewCommandBuffer::WriteReplyParams(
378 request.reply, route_id);
379 SendDelayedMsg(request.reply, request.filter);
380 create_command_buffer_replies_.pop();
381 }
382 }
383
264 void GpuProcessHost::SendEstablishChannelReply( 384 void GpuProcessHost::SendEstablishChannelReply(
265 const IPC::ChannelHandle& channel, 385 const IPC::ChannelHandle& channel,
266 const GPUInfo& gpu_info, 386 const GPUInfo& gpu_info,
267 RenderMessageFilter* filter) { 387 RenderMessageFilter* filter) {
268 ViewMsg_GpuChannelEstablished* message = 388 ViewMsg_GpuChannelEstablished* message =
269 new ViewMsg_GpuChannelEstablished(channel, gpu_info); 389 new ViewMsg_GpuChannelEstablished(channel, gpu_info);
270 // If the renderer process is performing synchronous initialization, 390 // If the renderer process is performing synchronous initialization,
271 // it needs to handle this message before receiving the reply for 391 // it needs to handle this message before receiving the reply for
272 // the synchronous ViewHostMsg_SynchronizeGpu message. 392 // the synchronous ViewHostMsg_SynchronizeGpu message.
273 message->set_unblock(true); 393 message->set_unblock(true);
274 filter->Send(message); 394 filter->Send(message);
275 } 395 }
276 396
277 // Sends the response for synchronization request to the renderer.
278 void GpuProcessHost::SendSynchronizationReply(
279 IPC::Message* reply,
280 RenderMessageFilter* filter) {
281 filter->Send(reply);
282 }
283
284 void GpuProcessHost::SendOutstandingReplies() { 397 void GpuProcessHost::SendOutstandingReplies() {
285 // First send empty channel handles for all EstablishChannel requests. 398 // First send empty channel handles for all EstablishChannel requests.
286 while (!sent_requests_.empty()) { 399 while (!sent_requests_.empty()) {
287 const ChannelRequest& request = sent_requests_.front(); 400 const ChannelRequest& request = sent_requests_.front();
288 SendEstablishChannelReply(IPC::ChannelHandle(), GPUInfo(), request.filter); 401 SendEstablishChannelReply(IPC::ChannelHandle(), GPUInfo(), request.filter);
289 sent_requests_.pop(); 402 sent_requests_.pop();
290 } 403 }
291 404
292 // Now unblock all renderers waiting for synchronization replies. 405 // Now unblock all renderers waiting for synchronization replies.
293 while (!queued_synchronization_replies_.empty()) { 406 while (!queued_synchronization_replies_.empty()) {
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
400 const CommandLine& browser_command_line = *CommandLine::ForCurrentProcess(); 513 const CommandLine& browser_command_line = *CommandLine::ForCurrentProcess();
401 if (browser_command_line.HasSwitch(switches::kIgnoreGpuBlacklist) || 514 if (browser_command_line.HasSwitch(switches::kIgnoreGpuBlacklist) ||
402 blacklist->LoadGpuBlacklist(gpu_blacklist_json.as_string(), true)) { 515 blacklist->LoadGpuBlacklist(gpu_blacklist_json.as_string(), true)) {
403 gpu_blacklist_.reset(blacklist); 516 gpu_blacklist_.reset(blacklist);
404 return true; 517 return true;
405 } 518 }
406 delete blacklist; 519 delete blacklist;
407 return false; 520 return false;
408 } 521 }
409 522
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698