Home | History | Annotate | Download | only in gl
      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
     19 GpuSwitchingManager* GpuSwitchingManager::GetInstance() {
     20   return Singleton<GpuSwitchingManager>::get();
     21 }
     22 
     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 
     34 GpuSwitchingManager::~GpuSwitchingManager() {
     35 #if defined(OS_MACOSX)
     36   if (discrete_pixel_format_)
     37     CGLReleasePixelFormat(discrete_pixel_format_);
     38 #endif  // OS_MACOSX
     39 }
     40 
     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 
     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 
     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 
    101 void GpuSwitchingManager::SetGpuCount(size_t gpu_count) {
    102   gpu_count_ = gpu_count;
    103 }
    104 
    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)
    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