• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
16 namespace ui {
17 
18 // static
GetInstance()19 GpuSwitchingManager* GpuSwitchingManager::GetInstance() {
20   return Singleton<GpuSwitchingManager>::get();
21 }
22 
GpuSwitchingManager()23 GpuSwitchingManager::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 
~GpuSwitchingManager()34 GpuSwitchingManager::~GpuSwitchingManager() {
35 #if defined(OS_MACOSX)
36   if (discrete_pixel_format_)
37     CGLReleasePixelFormat(discrete_pixel_format_);
38 #endif  // OS_MACOSX
39 }
40 
ForceUseOfIntegratedGpu()41 void 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 
ForceUseOfDiscreteGpu()51 void 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 
SupportsDualGpus()66 bool 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 
SetGpuCount(size_t gpu_count)101 void GpuSwitchingManager::SetGpuCount(size_t gpu_count) {
102   gpu_count_ = gpu_count;
103 }
104 
AdjustGpuPreference(gfx::GpuPreference gpu_preference)105 gfx::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)
SwitchToDiscreteGpuMac()113 void 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