Roll src/third_party/WebKit d9c6159:8139f33 (svn 201974:201975)
[chromium-blink-merge.git] / ui / gl / gpu_switching_manager.cc
blob36ad7adde2ab26bd31c8628c5075511f5430c947
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 <OpenGL/OpenGL.h>
13 #include "base/mac/mac_util.h"
14 #include "ui/gl/gl_context_cgl.h"
15 #endif // OS_MACOSX
17 namespace ui {
19 struct GpuSwitchingManager::PlatformSpecific {
20 #if defined(OS_MACOSX)
21 CGLPixelFormatObj discrete_pixel_format;
22 #endif // OS_MACOSX
25 // static
26 GpuSwitchingManager* GpuSwitchingManager::GetInstance() {
27 return Singleton<GpuSwitchingManager>::get();
30 GpuSwitchingManager::GpuSwitchingManager()
31 : gpu_switching_option_(gfx::PreferIntegratedGpu),
32 gpu_switching_option_set_(false),
33 supports_dual_gpus_(false),
34 supports_dual_gpus_set_(false),
35 platform_specific_(new PlatformSpecific) {
36 #if defined(OS_MACOSX)
37 platform_specific_->discrete_pixel_format = nullptr;
38 #endif // OS_MACOSX
41 GpuSwitchingManager::~GpuSwitchingManager() {
42 #if defined(OS_MACOSX)
43 if (platform_specific_->discrete_pixel_format)
44 CGLReleasePixelFormat(platform_specific_->discrete_pixel_format);
45 #endif // OS_MACOSX
48 void GpuSwitchingManager::ForceUseOfIntegratedGpu() {
49 DCHECK(SupportsDualGpus());
50 if (gpu_switching_option_set_) {
51 DCHECK_EQ(gpu_switching_option_, gfx::PreferIntegratedGpu);
52 } else {
53 gpu_switching_option_ = gfx::PreferIntegratedGpu;
54 gpu_switching_option_set_ = true;
58 void GpuSwitchingManager::ForceUseOfDiscreteGpu() {
59 DCHECK(SupportsDualGpus());
60 if (gpu_switching_option_set_) {
61 DCHECK_EQ(gpu_switching_option_, gfx::PreferDiscreteGpu);
62 } else {
63 gpu_switching_option_ = gfx::PreferDiscreteGpu;
64 gpu_switching_option_set_ = true;
65 #if defined(OS_MACOSX)
66 // Create a pixel format that lasts the lifespan of Chrome, so Chrome
67 // stays on the discrete GPU.
68 SwitchToDiscreteGpuMac();
69 #endif // OS_MACOSX
73 bool GpuSwitchingManager::SupportsDualGpus() {
74 if (!supports_dual_gpus_set_) {
75 const base::CommandLine& command_line =
76 *base::CommandLine::ForCurrentProcess();
77 bool flag = false;
78 if (command_line.HasSwitch(switches::kSupportsDualGpus)) {
79 // GPU process, flag is passed down from browser process.
80 std::string flag_string = command_line.GetSwitchValueASCII(
81 switches::kSupportsDualGpus);
82 if (flag_string == "true") {
83 flag = true;
84 } else if (flag_string == "false") {
85 flag = false;
86 } else {
87 NOTIMPLEMENTED();
89 } else {
90 // Browser process.
91 // We only compute this flag in the browser process.
92 #if defined(OS_MACOSX)
93 flag = (vendor_ids_.size() == 2);
94 if (flag && command_line.HasSwitch(switches::kUseGL) &&
95 command_line.GetSwitchValueASCII(switches::kUseGL) !=
96 gfx::kGLImplementationDesktopName)
97 flag = false;
99 if (flag && !base::mac::IsOSLionOrLater())
100 flag = false;
102 if (flag) {
103 // Only advertise that we have two GPUs to the rest of
104 // Chrome's code if we find an Intel GPU and some other
105 // vendor's GPU. Otherwise we don't understand the
106 // configuration and don't deal well with it (an example being
107 // the dual AMD GPUs in recent Mac Pros).
108 const uint32 intel = 0x8086;
109 flag = ((vendor_ids_[0] == intel && vendor_ids_[1] != intel) ||
110 (vendor_ids_[0] != intel && vendor_ids_[1] == intel));
112 #endif // OS_MACOSX
114 supports_dual_gpus_ = flag;
115 supports_dual_gpus_set_ = true;
117 return supports_dual_gpus_;
120 void GpuSwitchingManager::SetGpuVendorIds(
121 const std::vector<uint32>& vendor_ids) {
122 vendor_ids_ = vendor_ids;
125 void GpuSwitchingManager::AddObserver(GpuSwitchingObserver* observer) {
126 observer_list_.AddObserver(observer);
129 void GpuSwitchingManager::RemoveObserver(GpuSwitchingObserver* observer) {
130 observer_list_.RemoveObserver(observer);
133 void GpuSwitchingManager::NotifyGpuSwitched() {
134 FOR_EACH_OBSERVER(GpuSwitchingObserver, observer_list_, OnGpuSwitched());
137 gfx::GpuPreference GpuSwitchingManager::AdjustGpuPreference(
138 gfx::GpuPreference gpu_preference) {
139 if (!gpu_switching_option_set_)
140 return gpu_preference;
141 return gpu_switching_option_;
144 #if defined(OS_MACOSX)
145 void GpuSwitchingManager::SwitchToDiscreteGpuMac() {
146 if (platform_specific_->discrete_pixel_format)
147 return;
148 CGLPixelFormatAttribute attribs[1];
149 attribs[0] = static_cast<CGLPixelFormatAttribute>(0);
150 GLint num_pixel_formats = 0;
151 CGLChoosePixelFormat(attribs, &platform_specific_->discrete_pixel_format,
152 &num_pixel_formats);
154 #endif // OS_MACOSX
156 } // namespace ui