1// Copyright (c) 2012 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include "ui/gl/gpu_switching_manager.h" 6 7#include "base/command_line.h" 8#include "base/logging.h" 9#include "ui/gl/gl_switches.h" 10 11#if defined(OS_MACOSX) 12#include "base/mac/mac_util.h" 13#include "ui/gl/gl_context_cgl.h" 14#endif // OS_MACOSX 15 16namespace ui { 17 18// static 19GpuSwitchingManager* GpuSwitchingManager::GetInstance() { 20 return Singleton<GpuSwitchingManager>::get(); 21} 22 23GpuSwitchingManager::GpuSwitchingManager() 24 : gpu_switching_option_(gfx::PreferIntegratedGpu), 25 gpu_switching_option_set_(false), 26 supports_dual_gpus_(false), 27 supports_dual_gpus_set_(false), 28 gpu_count_(0) { 29#if defined(OS_MACOSX) 30 discrete_pixel_format_ = NULL; 31#endif // OS_MACOSX 32} 33 34GpuSwitchingManager::~GpuSwitchingManager() { 35#if defined(OS_MACOSX) 36 if (discrete_pixel_format_) 37 CGLReleasePixelFormat(discrete_pixel_format_); 38#endif // OS_MACOSX 39} 40 41void GpuSwitchingManager::ForceUseOfIntegratedGpu() { 42 DCHECK(SupportsDualGpus()); 43 if (gpu_switching_option_set_) { 44 DCHECK_EQ(gpu_switching_option_, gfx::PreferIntegratedGpu); 45 } else { 46 gpu_switching_option_ = gfx::PreferIntegratedGpu; 47 gpu_switching_option_set_ = true; 48 } 49} 50 51void GpuSwitchingManager::ForceUseOfDiscreteGpu() { 52 DCHECK(SupportsDualGpus()); 53 if (gpu_switching_option_set_) { 54 DCHECK_EQ(gpu_switching_option_, gfx::PreferDiscreteGpu); 55 } else { 56 gpu_switching_option_ = gfx::PreferDiscreteGpu; 57 gpu_switching_option_set_ = true; 58#if defined(OS_MACOSX) 59 // Create a pixel format that lasts the lifespan of Chrome, so Chrome 60 // stays on the discrete GPU. 61 SwitchToDiscreteGpuMac(); 62#endif // OS_MACOSX 63 } 64} 65 66bool GpuSwitchingManager::SupportsDualGpus() { 67 if (!supports_dual_gpus_set_) { 68 const CommandLine& command_line = *CommandLine::ForCurrentProcess(); 69 bool flag = false; 70 if (command_line.HasSwitch(switches::kSupportsDualGpus)) { 71 // GPU process, flag is passed down from browser process. 72 std::string flag_string = command_line.GetSwitchValueASCII( 73 switches::kSupportsDualGpus); 74 if (flag_string == "true") { 75 flag = true; 76 } else if (flag_string == "false") { 77 flag = false; 78 } else { 79 NOTIMPLEMENTED(); 80 } 81 } else { 82 // Browser process. 83 // We only compute this flag in the browser process. 84#if defined(OS_MACOSX) 85 flag = (gpu_count_ == 2); 86 if (flag && command_line.HasSwitch(switches::kUseGL) && 87 command_line.GetSwitchValueASCII(switches::kUseGL) != 88 gfx::kGLImplementationDesktopName) 89 flag = false; 90 91 if (flag && !base::mac::IsOSLionOrLater()) 92 flag = false; 93#endif // OS_MACOSX 94 } 95 supports_dual_gpus_ = flag; 96 supports_dual_gpus_set_ = true; 97 } 98 return supports_dual_gpus_; 99} 100 101void GpuSwitchingManager::SetGpuCount(size_t gpu_count) { 102 gpu_count_ = gpu_count; 103} 104 105gfx::GpuPreference GpuSwitchingManager::AdjustGpuPreference( 106 gfx::GpuPreference gpu_preference) { 107 if (!gpu_switching_option_set_) 108 return gpu_preference; 109 return gpu_switching_option_; 110} 111 112#if defined(OS_MACOSX) 113void GpuSwitchingManager::SwitchToDiscreteGpuMac() { 114 if (discrete_pixel_format_) 115 return; 116 CGLPixelFormatAttribute attribs[1]; 117 attribs[0] = static_cast<CGLPixelFormatAttribute>(0); 118 GLint num_pixel_formats = 0; 119 CGLChoosePixelFormat(attribs, &discrete_pixel_format_, &num_pixel_formats); 120} 121#endif // OS_MACOSX 122 123} // namespace ui 124