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

Side by Side Diff: content/common/gpu/gpu_channel.cc

Issue 8233027: Support dynamic switching between integrated and discrete GPUs on Mac OS X. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: '' Created 9 years, 2 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 #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
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
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
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
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
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_;
stuartmorgan 2011/10/12 07:13:24 Is it worth DCHECKING here that it's not negative?
Ken Russell (switch to Gerrit) 2011/10/12 22:39:42 Sure. Added.
433 }
434
381 std::string GpuChannel::GetChannelName() { 435 std::string GpuChannel::GetChannelName() {
382 return StringPrintf("%d.r%d.gpu", base::GetCurrentProcId(), renderer_id_); 436 return StringPrintf("%d.r%d.gpu", base::GetCurrentProcId(), renderer_id_);
383 } 437 }
384 438
385 #if defined(OS_POSIX) 439 #if defined(OS_POSIX)
386 int GpuChannel::TakeRendererFileDescriptor() { 440 int GpuChannel::TakeRendererFileDescriptor() {
387 if (!channel_.get()) { 441 if (!channel_.get()) {
388 NOTREACHED(); 442 NOTREACHED();
389 return -1; 443 return -1;
390 } 444 }
391 return channel_->TakeClientFileDescriptor(); 445 return channel_->TakeClientFileDescriptor();
392 } 446 }
393 #endif // defined(OS_POSIX) 447 #endif // defined(OS_POSIX)
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698