Index: content/common/gpu/gpu_channel.cc |
=================================================================== |
--- content/common/gpu/gpu_channel.cc (revision 105158) |
+++ content/common/gpu/gpu_channel.cc (working copy) |
@@ -37,6 +37,7 @@ |
watchdog_(watchdog), |
software_(software), |
handle_messages_scheduled_(false), |
+ num_contexts_preferring_discrete_gpu_(0), |
task_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) { |
DCHECK(gpu_channel_manager); |
DCHECK(renderer_id); |
@@ -167,6 +168,8 @@ |
content::GetContentClient()->SetActiveURL(init_params.active_url); |
#if defined(ENABLE_GPU) |
+ WillCreateCommandBuffer(init_params.gpu_preference); |
+ |
GpuCommandBufferStub* share_group = stubs_.Lookup(init_params.share_group_id); |
*route_id = GenerateRouteID(); |
@@ -178,6 +181,7 @@ |
disallowed_features_, |
init_params.allowed_extensions, |
init_params.attribs, |
+ init_params.gpu_preference, |
*route_id, |
renderer_id_, |
render_view_id, |
@@ -213,6 +217,9 @@ |
IPC_MESSAGE_HANDLER(GpuChannelMsg_CreateTransportTexture, |
OnCreateTransportTexture) |
IPC_MESSAGE_HANDLER(GpuChannelMsg_Echo, OnEcho); |
+ IPC_MESSAGE_HANDLER_DELAY_REPLY(GpuChannelMsg_WillGpuSwitchOccur, |
+ OnWillGpuSwitchOccur) |
+ IPC_MESSAGE_HANDLER(GpuChannelMsg_CloseChannel, OnCloseChannel) |
IPC_MESSAGE_UNHANDLED(handled = false) |
IPC_END_MESSAGE_MAP() |
DCHECK(handled) << msg.type(); |
@@ -271,6 +278,10 @@ |
router_.RemoveRoute(route_id); |
} |
+bool GpuChannel::ShouldPreferDiscreteGpu() const { |
+ return num_contexts_preferring_discrete_gpu_ > 0; |
+} |
+ |
void GpuChannel::OnInitialize(base::ProcessHandle renderer_process) { |
// Initialize should only happen once. |
DCHECK(!renderer_process_); |
@@ -288,6 +299,8 @@ |
content::GetContentClient()->SetActiveURL(init_params.active_url); |
#if defined(ENABLE_GPU) |
+ WillCreateCommandBuffer(init_params.gpu_preference); |
+ |
GpuCommandBufferStub* share_group = stubs_.Lookup(init_params.share_group_id); |
route_id = GenerateRouteID(); |
@@ -300,6 +313,7 @@ |
disallowed_features_, |
init_params.allowed_extensions, |
init_params.attribs, |
+ init_params.gpu_preference, |
route_id, |
0, 0, watchdog_, |
software_)); |
@@ -323,12 +337,15 @@ |
if (router_.ResolveRoute(route_id)) { |
GpuCommandBufferStub* stub = stubs_.Lookup(route_id); |
bool need_reschedule = (stub && !stub->IsScheduled()); |
+ gfx::GpuPreference gpu_preference = |
+ stub ? stub->gpu_preference() : gfx::PreferIntegratedGpu; |
router_.RemoveRoute(route_id); |
stubs_.Remove(route_id); |
// In case the renderer is currently blocked waiting for a sync reply from |
// the stub, we need to make sure to reschedule the GpuChannel here. |
if (need_reschedule) |
OnScheduled(); |
+ DidDestroyCommandBuffer(gpu_preference); |
} |
#endif |
@@ -359,6 +376,33 @@ |
Send(new IPC::Message(message)); |
} |
+void GpuChannel::OnWillGpuSwitchOccur(bool is_creating_context, |
+ gfx::GpuPreference gpu_preference, |
+ IPC::Message* reply_message) { |
+ TRACE_EVENT0("gpu", "GpuChannel::OnWillGpuSwitchOccur"); |
+ |
+ bool will_switch_occur = false; |
+ |
+ if (gpu_preference == gfx::PreferDiscreteGpu && |
+ gfx::GLContext::SupportsDualGpus()) { |
+ if (is_creating_context) { |
+ will_switch_occur = !num_contexts_preferring_discrete_gpu_; |
+ } else { |
+ will_switch_occur = (num_contexts_preferring_discrete_gpu_ == 1); |
+ } |
+ } |
+ |
+ GpuChannelMsg_WillGpuSwitchOccur::WriteReplyParams( |
+ reply_message, |
+ will_switch_occur); |
+ Send(reply_message); |
+} |
+ |
+void GpuChannel::OnCloseChannel() { |
+ gpu_channel_manager_->RemoveChannel(renderer_id_); |
+ // At this point "this" is deleted! |
+} |
+ |
bool GpuChannel::Init(base::MessageLoopProxy* io_message_loop, |
base::WaitableEvent* shutdown_event) { |
// Check whether we're already initialized. |
@@ -378,6 +422,17 @@ |
return true; |
} |
+void GpuChannel::WillCreateCommandBuffer(gfx::GpuPreference gpu_preference) { |
+ if (gpu_preference == gfx::PreferDiscreteGpu) |
+ ++num_contexts_preferring_discrete_gpu_; |
+} |
+ |
+void GpuChannel::DidDestroyCommandBuffer(gfx::GpuPreference gpu_preference) { |
+ if (gpu_preference == gfx::PreferDiscreteGpu) |
+ --num_contexts_preferring_discrete_gpu_; |
+ DCHECK_GE(num_contexts_preferring_discrete_gpu_, 0); |
+} |
+ |
std::string GpuChannel::GetChannelName() { |
return StringPrintf("%d.r%d.gpu", base::GetCurrentProcId(), renderer_id_); |
} |