15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gl/gpu_switching_manager.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/command_line.h" 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h" 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gl/gl_switches.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_MACOSX) 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/mac/mac_util.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gl/gl_context_cgl.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif // OS_MACOSX 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace ui { 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GpuSwitchingManager* GpuSwitchingManager::GetInstance() { 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return Singleton<GpuSwitchingManager>::get(); 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GpuSwitchingManager::GpuSwitchingManager() 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : gpu_switching_option_(gfx::PreferIntegratedGpu), 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gpu_switching_option_set_(false), 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) supports_dual_gpus_(false), 272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) supports_dual_gpus_set_(false), 282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gpu_count_(0) { 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_MACOSX) 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) discrete_pixel_format_ = NULL; 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif // OS_MACOSX 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GpuSwitchingManager::~GpuSwitchingManager() { 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_MACOSX) 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (discrete_pixel_format_) 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CGLReleasePixelFormat(discrete_pixel_format_); 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif // OS_MACOSX 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuSwitchingManager::ForceUseOfIntegratedGpu() { 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(SupportsDualGpus()); 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (gpu_switching_option_set_) { 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(gpu_switching_option_, gfx::PreferIntegratedGpu); 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gpu_switching_option_ = gfx::PreferIntegratedGpu; 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gpu_switching_option_set_ = true; 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuSwitchingManager::ForceUseOfDiscreteGpu() { 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(SupportsDualGpus()); 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (gpu_switching_option_set_) { 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(gpu_switching_option_, gfx::PreferDiscreteGpu); 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gpu_switching_option_ = gfx::PreferDiscreteGpu; 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gpu_switching_option_set_ = true; 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_MACOSX) 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Create a pixel format that lasts the lifespan of Chrome, so Chrome 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // stays on the discrete GPU. 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SwitchToDiscreteGpuMac(); 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif // OS_MACOSX 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool GpuSwitchingManager::SupportsDualGpus() { 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!supports_dual_gpus_set_) { 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const CommandLine& command_line = *CommandLine::ForCurrentProcess(); 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool flag = false; 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (command_line.HasSwitch(switches::kSupportsDualGpus)) { 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // GPU process, flag is passed down from browser process. 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string flag_string = command_line.GetSwitchValueASCII( 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switches::kSupportsDualGpus); 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (flag_string == "true") { 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) flag = true; 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (flag_string == "false") { 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) flag = false; 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTIMPLEMENTED(); 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Browser process. 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We only compute this flag in the browser process. 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_MACOSX) 852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) flag = (gpu_count_ == 2); 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (flag && command_line.HasSwitch(switches::kUseGL) && 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) command_line.GetSwitchValueASCII(switches::kUseGL) != 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::kGLImplementationDesktopName) 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) flag = false; 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (flag && !base::mac::IsOSLionOrLater()) 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) flag = false; 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif // OS_MACOSX 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) supports_dual_gpus_ = flag; 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) supports_dual_gpus_set_ = true; 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return supports_dual_gpus_; 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void GpuSwitchingManager::SetGpuCount(size_t gpu_count) { 1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gpu_count_ = gpu_count; 1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)gfx::GpuPreference GpuSwitchingManager::AdjustGpuPreference( 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::GpuPreference gpu_preference) { 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!gpu_switching_option_set_) 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return gpu_preference; 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return gpu_switching_option_; 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_MACOSX) 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuSwitchingManager::SwitchToDiscreteGpuMac() { 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (discrete_pixel_format_) 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CGLPixelFormatAttribute attribs[1]; 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) attribs[0] = static_cast<CGLPixelFormatAttribute>(0); 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GLint num_pixel_formats = 0; 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CGLChoosePixelFormat(attribs, &discrete_pixel_format_, &num_pixel_formats); 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif // OS_MACOSX 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace ui 124