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.
5 #include "ui/gl/gpu_switching_manager.h"
7 #include "base/command_line.h"
8 #include "base/logging.h"
9 #include "ui/gl/gl_switches.h"
11 #if defined(OS_MACOSX)
12 #include "base/mac/mac_util.h"
13 #include "ui/gl/gl_context_cgl.h"
19 GpuSwitchingManager
* GpuSwitchingManager::GetInstance() {
20 return Singleton
<GpuSwitchingManager
>::get();
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),
29 #if defined(OS_MACOSX)
30 discrete_pixel_format_
= NULL
;
34 GpuSwitchingManager::~GpuSwitchingManager() {
35 #if defined(OS_MACOSX)
36 if (discrete_pixel_format_
)
37 CGLReleasePixelFormat(discrete_pixel_format_
);
41 void GpuSwitchingManager::ForceUseOfIntegratedGpu() {
42 DCHECK(SupportsDualGpus());
43 if (gpu_switching_option_set_
) {
44 DCHECK_EQ(gpu_switching_option_
, gfx::PreferIntegratedGpu
);
46 gpu_switching_option_
= gfx::PreferIntegratedGpu
;
47 gpu_switching_option_set_
= true;
51 void GpuSwitchingManager::ForceUseOfDiscreteGpu() {
52 DCHECK(SupportsDualGpus());
53 if (gpu_switching_option_set_
) {
54 DCHECK_EQ(gpu_switching_option_
, gfx::PreferDiscreteGpu
);
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();
66 bool GpuSwitchingManager::SupportsDualGpus() {
67 if (!supports_dual_gpus_set_
) {
68 const CommandLine
& command_line
= *CommandLine::ForCurrentProcess();
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") {
76 } else if (flag_string
== "false") {
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
)
91 if (flag
&& !base::mac::IsOSLionOrLater())
95 supports_dual_gpus_
= flag
;
96 supports_dual_gpus_set_
= true;
98 return supports_dual_gpus_
;
101 void GpuSwitchingManager::SetGpuCount(size_t gpu_count
) {
102 gpu_count_
= gpu_count
;
105 void GpuSwitchingManager::AddObserver(GpuSwitchingObserver
* observer
) {
106 observer_list_
.AddObserver(observer
);
109 void GpuSwitchingManager::RemoveObserver(GpuSwitchingObserver
* observer
) {
110 observer_list_
.RemoveObserver(observer
);
113 void GpuSwitchingManager::NotifyGpuSwitched() {
114 FOR_EACH_OBSERVER(GpuSwitchingObserver
, observer_list_
, OnGpuSwitched());
117 gfx::GpuPreference
GpuSwitchingManager::AdjustGpuPreference(
118 gfx::GpuPreference gpu_preference
) {
119 if (!gpu_switching_option_set_
)
120 return gpu_preference
;
121 return gpu_switching_option_
;
124 #if defined(OS_MACOSX)
125 void GpuSwitchingManager::SwitchToDiscreteGpuMac() {
126 if (discrete_pixel_format_
)
128 CGLPixelFormatAttribute attribs
[1];
129 attribs
[0] = static_cast<CGLPixelFormatAttribute
>(0);
130 GLint num_pixel_formats
= 0;
131 CGLChoosePixelFormat(attribs
, &discrete_pixel_format_
, &num_pixel_formats
);