OLD | NEW |
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 #if defined(OS_WIN) | 5 #if defined(OS_WIN) |
6 #include <windows.h> | 6 #include <windows.h> |
7 #endif | 7 #endif |
8 | 8 |
9 #include "content/common/gpu/gpu_channel.h" | 9 #include "content/common/gpu/gpu_channel.h" |
10 | 10 |
(...skipping 19 matching lines...) Expand all Loading... |
30 int renderer_id, | 30 int renderer_id, |
31 bool software) | 31 bool software) |
32 : gpu_channel_manager_(gpu_channel_manager), | 32 : gpu_channel_manager_(gpu_channel_manager), |
33 renderer_id_(renderer_id), | 33 renderer_id_(renderer_id), |
34 renderer_process_(base::kNullProcessHandle), | 34 renderer_process_(base::kNullProcessHandle), |
35 renderer_pid_(base::kNullProcessId), | 35 renderer_pid_(base::kNullProcessId), |
36 share_group_(new gfx::GLShareGroup), | 36 share_group_(new gfx::GLShareGroup), |
37 watchdog_(watchdog), | 37 watchdog_(watchdog), |
38 software_(software), | 38 software_(software), |
39 handle_messages_scheduled_(false), | 39 handle_messages_scheduled_(false), |
| 40 num_contexts_preferring_discrete_gpu_(0), |
40 task_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) { | 41 task_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) { |
41 DCHECK(gpu_channel_manager); | 42 DCHECK(gpu_channel_manager); |
42 DCHECK(renderer_id); | 43 DCHECK(renderer_id); |
43 const CommandLine* command_line = CommandLine::ForCurrentProcess(); | 44 const CommandLine* command_line = CommandLine::ForCurrentProcess(); |
44 log_messages_ = command_line->HasSwitch(switches::kLogPluginMessages); | 45 log_messages_ = command_line->HasSwitch(switches::kLogPluginMessages); |
45 disallowed_features_.multisampling = | 46 disallowed_features_.multisampling = |
46 command_line->HasSwitch(switches::kDisableGLMultisampling); | 47 command_line->HasSwitch(switches::kDisableGLMultisampling); |
47 disallowed_features_.driver_bug_workarounds = | 48 disallowed_features_.driver_bug_workarounds = |
48 command_line->HasSwitch(switches::kDisableGpuDriverBugWorkarounds); | 49 command_line->HasSwitch(switches::kDisableGpuDriverBugWorkarounds); |
49 } | 50 } |
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
160 | 161 |
161 void GpuChannel::CreateViewCommandBuffer( | 162 void GpuChannel::CreateViewCommandBuffer( |
162 gfx::PluginWindowHandle window, | 163 gfx::PluginWindowHandle window, |
163 int32 render_view_id, | 164 int32 render_view_id, |
164 const GPUCreateCommandBufferConfig& init_params, | 165 const GPUCreateCommandBufferConfig& init_params, |
165 int32* route_id) { | 166 int32* route_id) { |
166 *route_id = MSG_ROUTING_NONE; | 167 *route_id = MSG_ROUTING_NONE; |
167 content::GetContentClient()->SetActiveURL(init_params.active_url); | 168 content::GetContentClient()->SetActiveURL(init_params.active_url); |
168 | 169 |
169 #if defined(ENABLE_GPU) | 170 #if defined(ENABLE_GPU) |
| 171 WillCreateCommandBuffer(init_params.gpu_preference); |
| 172 |
170 GpuCommandBufferStub* share_group = stubs_.Lookup(init_params.share_group_id); | 173 GpuCommandBufferStub* share_group = stubs_.Lookup(init_params.share_group_id); |
171 | 174 |
172 *route_id = GenerateRouteID(); | 175 *route_id = GenerateRouteID(); |
173 scoped_ptr<GpuCommandBufferStub> stub(new GpuCommandBufferStub( | 176 scoped_ptr<GpuCommandBufferStub> stub(new GpuCommandBufferStub( |
174 this, | 177 this, |
175 share_group, | 178 share_group, |
176 window, | 179 window, |
177 gfx::Size(), | 180 gfx::Size(), |
178 disallowed_features_, | 181 disallowed_features_, |
179 init_params.allowed_extensions, | 182 init_params.allowed_extensions, |
180 init_params.attribs, | 183 init_params.attribs, |
| 184 init_params.gpu_preference, |
181 *route_id, | 185 *route_id, |
182 renderer_id_, | 186 renderer_id_, |
183 render_view_id, | 187 render_view_id, |
184 watchdog_, | 188 watchdog_, |
185 software_)); | 189 software_)); |
186 router_.AddRoute(*route_id, stub.get()); | 190 router_.AddRoute(*route_id, stub.get()); |
187 stubs_.AddWithID(stub.release(), *route_id); | 191 stubs_.AddWithID(stub.release(), *route_id); |
188 #endif // ENABLE_GPU | 192 #endif // ENABLE_GPU |
189 } | 193 } |
190 | 194 |
(...skipping 15 matching lines...) Expand all Loading... |
206 bool handled = true; | 210 bool handled = true; |
207 IPC_BEGIN_MESSAGE_MAP(GpuChannel, msg) | 211 IPC_BEGIN_MESSAGE_MAP(GpuChannel, msg) |
208 IPC_MESSAGE_HANDLER(GpuChannelMsg_Initialize, OnInitialize) | 212 IPC_MESSAGE_HANDLER(GpuChannelMsg_Initialize, OnInitialize) |
209 IPC_MESSAGE_HANDLER_DELAY_REPLY(GpuChannelMsg_CreateOffscreenCommandBuffer, | 213 IPC_MESSAGE_HANDLER_DELAY_REPLY(GpuChannelMsg_CreateOffscreenCommandBuffer, |
210 OnCreateOffscreenCommandBuffer) | 214 OnCreateOffscreenCommandBuffer) |
211 IPC_MESSAGE_HANDLER_DELAY_REPLY(GpuChannelMsg_DestroyCommandBuffer, | 215 IPC_MESSAGE_HANDLER_DELAY_REPLY(GpuChannelMsg_DestroyCommandBuffer, |
212 OnDestroyCommandBuffer) | 216 OnDestroyCommandBuffer) |
213 IPC_MESSAGE_HANDLER(GpuChannelMsg_CreateTransportTexture, | 217 IPC_MESSAGE_HANDLER(GpuChannelMsg_CreateTransportTexture, |
214 OnCreateTransportTexture) | 218 OnCreateTransportTexture) |
215 IPC_MESSAGE_HANDLER(GpuChannelMsg_Echo, OnEcho); | 219 IPC_MESSAGE_HANDLER(GpuChannelMsg_Echo, OnEcho); |
| 220 IPC_MESSAGE_HANDLER_DELAY_REPLY(GpuChannelMsg_WillGpuSwitchOccur, |
| 221 OnWillGpuSwitchOccur) |
| 222 IPC_MESSAGE_HANDLER(GpuChannelMsg_CloseChannel, OnCloseChannel) |
216 IPC_MESSAGE_UNHANDLED(handled = false) | 223 IPC_MESSAGE_UNHANDLED(handled = false) |
217 IPC_END_MESSAGE_MAP() | 224 IPC_END_MESSAGE_MAP() |
218 DCHECK(handled) << msg.type(); | 225 DCHECK(handled) << msg.type(); |
219 return handled; | 226 return handled; |
220 } | 227 } |
221 | 228 |
222 void GpuChannel::HandleMessage() { | 229 void GpuChannel::HandleMessage() { |
223 handle_messages_scheduled_ = false; | 230 handle_messages_scheduled_ = false; |
224 if (!IsScheduled()) | 231 if (!IsScheduled()) |
225 return; | 232 return; |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
264 } | 271 } |
265 | 272 |
266 void GpuChannel::AddRoute(int32 route_id, IPC::Channel::Listener* listener) { | 273 void GpuChannel::AddRoute(int32 route_id, IPC::Channel::Listener* listener) { |
267 router_.AddRoute(route_id, listener); | 274 router_.AddRoute(route_id, listener); |
268 } | 275 } |
269 | 276 |
270 void GpuChannel::RemoveRoute(int32 route_id) { | 277 void GpuChannel::RemoveRoute(int32 route_id) { |
271 router_.RemoveRoute(route_id); | 278 router_.RemoveRoute(route_id); |
272 } | 279 } |
273 | 280 |
| 281 bool GpuChannel::ShouldPreferDiscreteGpu() const { |
| 282 return num_contexts_preferring_discrete_gpu_ > 0; |
| 283 } |
| 284 |
274 void GpuChannel::OnInitialize(base::ProcessHandle renderer_process) { | 285 void GpuChannel::OnInitialize(base::ProcessHandle renderer_process) { |
275 // Initialize should only happen once. | 286 // Initialize should only happen once. |
276 DCHECK(!renderer_process_); | 287 DCHECK(!renderer_process_); |
277 | 288 |
278 // Verify that the renderer has passed its own process handle. | 289 // Verify that the renderer has passed its own process handle. |
279 if (base::GetProcId(renderer_process) == renderer_pid_) | 290 if (base::GetProcId(renderer_process) == renderer_pid_) |
280 renderer_process_ = renderer_process; | 291 renderer_process_ = renderer_process; |
281 } | 292 } |
282 | 293 |
283 void GpuChannel::OnCreateOffscreenCommandBuffer( | 294 void GpuChannel::OnCreateOffscreenCommandBuffer( |
284 const gfx::Size& size, | 295 const gfx::Size& size, |
285 const GPUCreateCommandBufferConfig& init_params, | 296 const GPUCreateCommandBufferConfig& init_params, |
286 IPC::Message* reply_message) { | 297 IPC::Message* reply_message) { |
287 int32 route_id = MSG_ROUTING_NONE; | 298 int32 route_id = MSG_ROUTING_NONE; |
288 | 299 |
289 content::GetContentClient()->SetActiveURL(init_params.active_url); | 300 content::GetContentClient()->SetActiveURL(init_params.active_url); |
290 #if defined(ENABLE_GPU) | 301 #if defined(ENABLE_GPU) |
| 302 WillCreateCommandBuffer(init_params.gpu_preference); |
| 303 |
291 GpuCommandBufferStub* share_group = stubs_.Lookup(init_params.share_group_id); | 304 GpuCommandBufferStub* share_group = stubs_.Lookup(init_params.share_group_id); |
292 | 305 |
293 route_id = GenerateRouteID(); | 306 route_id = GenerateRouteID(); |
294 | 307 |
295 scoped_ptr<GpuCommandBufferStub> stub(new GpuCommandBufferStub( | 308 scoped_ptr<GpuCommandBufferStub> stub(new GpuCommandBufferStub( |
296 this, | 309 this, |
297 share_group, | 310 share_group, |
298 gfx::kNullPluginWindow, | 311 gfx::kNullPluginWindow, |
299 size, | 312 size, |
300 disallowed_features_, | 313 disallowed_features_, |
301 init_params.allowed_extensions, | 314 init_params.allowed_extensions, |
302 init_params.attribs, | 315 init_params.attribs, |
| 316 init_params.gpu_preference, |
303 route_id, | 317 route_id, |
304 0, 0, watchdog_, | 318 0, 0, watchdog_, |
305 software_)); | 319 software_)); |
306 router_.AddRoute(route_id, stub.get()); | 320 router_.AddRoute(route_id, stub.get()); |
307 stubs_.AddWithID(stub.release(), route_id); | 321 stubs_.AddWithID(stub.release(), route_id); |
308 TRACE_EVENT1("gpu", "GpuChannel::OnCreateOffscreenCommandBuffer", | 322 TRACE_EVENT1("gpu", "GpuChannel::OnCreateOffscreenCommandBuffer", |
309 "route_id", route_id); | 323 "route_id", route_id); |
310 #endif | 324 #endif |
311 | 325 |
312 GpuChannelMsg_CreateOffscreenCommandBuffer::WriteReplyParams( | 326 GpuChannelMsg_CreateOffscreenCommandBuffer::WriteReplyParams( |
313 reply_message, | 327 reply_message, |
314 route_id); | 328 route_id); |
315 Send(reply_message); | 329 Send(reply_message); |
316 } | 330 } |
317 | 331 |
318 void GpuChannel::OnDestroyCommandBuffer(int32 route_id, | 332 void GpuChannel::OnDestroyCommandBuffer(int32 route_id, |
319 IPC::Message* reply_message) { | 333 IPC::Message* reply_message) { |
320 #if defined(ENABLE_GPU) | 334 #if defined(ENABLE_GPU) |
321 TRACE_EVENT1("gpu", "GpuChannel::OnDestroyCommandBuffer", | 335 TRACE_EVENT1("gpu", "GpuChannel::OnDestroyCommandBuffer", |
322 "route_id", route_id); | 336 "route_id", route_id); |
323 if (router_.ResolveRoute(route_id)) { | 337 if (router_.ResolveRoute(route_id)) { |
324 GpuCommandBufferStub* stub = stubs_.Lookup(route_id); | 338 GpuCommandBufferStub* stub = stubs_.Lookup(route_id); |
325 bool need_reschedule = (stub && !stub->IsScheduled()); | 339 bool need_reschedule = (stub && !stub->IsScheduled()); |
| 340 gfx::GpuPreference gpu_preference = |
| 341 stub ? stub->gpu_preference() : gfx::PreferIntegratedGpu; |
326 router_.RemoveRoute(route_id); | 342 router_.RemoveRoute(route_id); |
327 stubs_.Remove(route_id); | 343 stubs_.Remove(route_id); |
328 // In case the renderer is currently blocked waiting for a sync reply from | 344 // In case the renderer is currently blocked waiting for a sync reply from |
329 // the stub, we need to make sure to reschedule the GpuChannel here. | 345 // the stub, we need to make sure to reschedule the GpuChannel here. |
330 if (need_reschedule) | 346 if (need_reschedule) |
331 OnScheduled(); | 347 OnScheduled(); |
| 348 DidDestroyCommandBuffer(gpu_preference); |
332 } | 349 } |
333 #endif | 350 #endif |
334 | 351 |
335 if (reply_message) | 352 if (reply_message) |
336 Send(reply_message); | 353 Send(reply_message); |
337 } | 354 } |
338 | 355 |
339 void GpuChannel::OnCreateTransportTexture(int32 context_route_id, | 356 void GpuChannel::OnCreateTransportTexture(int32 context_route_id, |
340 int32 host_id) { | 357 int32 host_id) { |
341 #if defined(ENABLE_GPU) | 358 #if defined(ENABLE_GPU) |
(...skipping 10 matching lines...) Expand all Loading... |
352 host_id, route_id); | 369 host_id, route_id); |
353 Send(msg); | 370 Send(msg); |
354 #endif | 371 #endif |
355 } | 372 } |
356 | 373 |
357 void GpuChannel::OnEcho(const IPC::Message& message) { | 374 void GpuChannel::OnEcho(const IPC::Message& message) { |
358 TRACE_EVENT0("gpu", "GpuCommandBufferStub::OnEcho"); | 375 TRACE_EVENT0("gpu", "GpuCommandBufferStub::OnEcho"); |
359 Send(new IPC::Message(message)); | 376 Send(new IPC::Message(message)); |
360 } | 377 } |
361 | 378 |
| 379 void GpuChannel::OnWillGpuSwitchOccur(bool is_creating_context, |
| 380 gfx::GpuPreference gpu_preference, |
| 381 IPC::Message* reply_message) { |
| 382 TRACE_EVENT0("gpu", "GpuChannel::OnWillGpuSwitchOccur"); |
| 383 |
| 384 bool will_switch_occur = false; |
| 385 |
| 386 if (gpu_preference == gfx::PreferDiscreteGpu && |
| 387 gfx::GLContext::SupportsDualGpus()) { |
| 388 if (is_creating_context) { |
| 389 will_switch_occur = !num_contexts_preferring_discrete_gpu_; |
| 390 } else { |
| 391 will_switch_occur = (num_contexts_preferring_discrete_gpu_ == 1); |
| 392 } |
| 393 } |
| 394 |
| 395 GpuChannelMsg_WillGpuSwitchOccur::WriteReplyParams( |
| 396 reply_message, |
| 397 will_switch_occur); |
| 398 Send(reply_message); |
| 399 } |
| 400 |
| 401 void GpuChannel::OnCloseChannel() { |
| 402 gpu_channel_manager_->RemoveChannel(renderer_id_); |
| 403 // At this point "this" is deleted! |
| 404 } |
| 405 |
362 bool GpuChannel::Init(base::MessageLoopProxy* io_message_loop, | 406 bool GpuChannel::Init(base::MessageLoopProxy* io_message_loop, |
363 base::WaitableEvent* shutdown_event) { | 407 base::WaitableEvent* shutdown_event) { |
364 // Check whether we're already initialized. | 408 // Check whether we're already initialized. |
365 if (channel_.get()) | 409 if (channel_.get()) |
366 return true; | 410 return true; |
367 | 411 |
368 // Map renderer ID to a (single) channel to that process. | 412 // Map renderer ID to a (single) channel to that process. |
369 std::string channel_name = GetChannelName(); | 413 std::string channel_name = GetChannelName(); |
370 channel_.reset(new IPC::SyncChannel( | 414 channel_.reset(new IPC::SyncChannel( |
371 channel_name, | 415 channel_name, |
372 IPC::Channel::MODE_SERVER, | 416 IPC::Channel::MODE_SERVER, |
373 this, | 417 this, |
374 io_message_loop, | 418 io_message_loop, |
375 false, | 419 false, |
376 shutdown_event)); | 420 shutdown_event)); |
377 | 421 |
378 return true; | 422 return true; |
379 } | 423 } |
380 | 424 |
| 425 void GpuChannel::WillCreateCommandBuffer(gfx::GpuPreference gpu_preference) { |
| 426 if (gpu_preference == gfx::PreferDiscreteGpu) |
| 427 ++num_contexts_preferring_discrete_gpu_; |
| 428 } |
| 429 |
| 430 void GpuChannel::DidDestroyCommandBuffer(gfx::GpuPreference gpu_preference) { |
| 431 if (gpu_preference == gfx::PreferDiscreteGpu) |
| 432 --num_contexts_preferring_discrete_gpu_; |
| 433 DCHECK_GE(num_contexts_preferring_discrete_gpu_, 0); |
| 434 } |
| 435 |
381 std::string GpuChannel::GetChannelName() { | 436 std::string GpuChannel::GetChannelName() { |
382 return StringPrintf("%d.r%d.gpu", base::GetCurrentProcId(), renderer_id_); | 437 return StringPrintf("%d.r%d.gpu", base::GetCurrentProcId(), renderer_id_); |
383 } | 438 } |
384 | 439 |
385 #if defined(OS_POSIX) | 440 #if defined(OS_POSIX) |
386 int GpuChannel::TakeRendererFileDescriptor() { | 441 int GpuChannel::TakeRendererFileDescriptor() { |
387 if (!channel_.get()) { | 442 if (!channel_.get()) { |
388 NOTREACHED(); | 443 NOTREACHED(); |
389 return -1; | 444 return -1; |
390 } | 445 } |
391 return channel_->TakeClientFileDescriptor(); | 446 return channel_->TakeClientFileDescriptor(); |
392 } | 447 } |
393 #endif // defined(OS_POSIX) | 448 #endif // defined(OS_POSIX) |
OLD | NEW |