diff options
author | zmo@chromium.org <zmo@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-09-21 21:09:28 +0000 |
---|---|---|
committer | zmo@chromium.org <zmo@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-09-21 21:09:28 +0000 |
commit | 4d6593245d07ac90faf0027f7bf45725e7cc3aff (patch) | |
tree | d0178cd81844ba12355bc56dc9e10e8f2ccacf71 | |
parent | 19cfda967ded48c88c7f8527fd8fcc6c6fbb9760 (diff) | |
download | chromium_src-4d6593245d07ac90faf0027f7bf45725e7cc3aff.zip chromium_src-4d6593245d07ac90faf0027f7bf45725e7cc3aff.tar.gz chromium_src-4d6593245d07ac90faf0027f7bf45725e7cc3aff.tar.bz2 |
Implement blacklist's force GPU capability in dual GPU machines.
This is part 2. In part one we implement the semantics in blacklist. Now we hook it up with the "real" forcing code.
For now we only hook it up with Mac CGL port.
BUG=140114,131276,111720
TEST=tree
Review URL: https://codereview.chromium.org/10909221
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@158076 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | chrome/browser/ui/webui/gpu_internals_ui.cc | 6 | ||||
-rw-r--r-- | content/browser/gpu/gpu_blacklist.cc | 6 | ||||
-rw-r--r-- | content/browser/gpu/gpu_blacklist.h | 3 | ||||
-rw-r--r-- | content/browser/gpu/gpu_blacklist_unittest.cc | 6 | ||||
-rw-r--r-- | content/browser/gpu/gpu_data_manager_impl.cc | 25 | ||||
-rw-r--r-- | content/browser/gpu/gpu_process_host.cc | 1 | ||||
-rw-r--r-- | content/browser/gpu/gpu_util.cc | 33 | ||||
-rw-r--r-- | content/browser/gpu/gpu_util.h | 5 | ||||
-rw-r--r-- | content/browser/gpu/gpu_util_unittest.cc | 34 | ||||
-rw-r--r-- | content/content_common.gypi | 1 | ||||
-rw-r--r-- | content/gpu/gpu_main.cc | 11 | ||||
-rw-r--r-- | content/public/browser/gpu_data_manager.h | 1 | ||||
-rw-r--r-- | content/public/common/gpu_feature_type.h | 7 | ||||
-rw-r--r-- | content/public/common/gpu_switching_option.h | 23 | ||||
-rw-r--r-- | ui/gl/gl.gyp | 2 | ||||
-rw-r--r-- | ui/gl/gl_context_cgl.cc | 15 | ||||
-rw-r--r-- | ui/gl/gl_context_cgl.h | 7 | ||||
-rw-r--r-- | ui/gl/gl_context_mac.mm | 3 | ||||
-rw-r--r-- | ui/gl/gl_switches.cc | 9 | ||||
-rw-r--r-- | ui/gl/gl_switches.h | 9 | ||||
-rw-r--r-- | ui/gl/gpu_switching_manager.cc | 40 | ||||
-rw-r--r-- | ui/gl/gpu_switching_manager.h | 44 |
22 files changed, 234 insertions, 57 deletions
diff --git a/chrome/browser/ui/webui/gpu_internals_ui.cc b/chrome/browser/ui/webui/gpu_internals_ui.cc index 91c535c..9ada4d0 100644 --- a/chrome/browser/ui/webui/gpu_internals_ui.cc +++ b/chrome/browser/ui/webui/gpu_internals_ui.cc @@ -345,13 +345,13 @@ Value* GetFeatureStatus() { gpu_info.optimus || gpu_info.amd_switchable) { std::string gpu_switching; switch (GpuDataManager::GetInstance()->GetGpuSwitchingOption()) { - case content::GPU_SWITCHING_AUTOMATIC: + case content::GPU_SWITCHING_OPTION_AUTOMATIC: gpu_switching = "gpu_switching_automatic"; break; - case content::GPU_SWITCHING_FORCE_DISCRETE: + case content::GPU_SWITCHING_OPTION_FORCE_DISCRETE: gpu_switching = "gpu_switching_force_discrete"; break; - case content::GPU_SWITCHING_FORCE_INTEGRATED: + case content::GPU_SWITCHING_OPTION_FORCE_INTEGRATED: gpu_switching = "gpu_switching_force_integrated"; break; default: diff --git a/content/browser/gpu/gpu_blacklist.cc b/content/browser/gpu/gpu_blacklist.cc index e36ec77..97d133f49 100644 --- a/content/browser/gpu/gpu_blacklist.cc +++ b/content/browser/gpu/gpu_blacklist.cc @@ -794,7 +794,7 @@ bool GpuBlacklist::GpuBlacklistEntry::SetGpuSwitchingOption( const std::string& switching_string) { GpuSwitchingOption switching = gpu_util::StringToGpuSwitchingOption( switching_string); - if (switching == content::GPU_SWITCHING_UNKNOWN) + if (switching == content::GPU_SWITCHING_OPTION_UNKNOWN) return false; decision_.gpu_switching = switching; return true; @@ -1036,7 +1036,7 @@ GpuBlacklist::Decision GpuBlacklist::MakeBlacklistDecision( const content::GPUInfo& gpu_info) { active_entries_.clear(); int type = 0; - GpuSwitchingOption switching = content::GPU_SWITCHING_AUTOMATIC; + GpuSwitchingOption switching = content::GPU_SWITCHING_OPTION_AUTOMATIC; if (os == kOsAny) os = GetOsType(); @@ -1056,7 +1056,7 @@ GpuBlacklist::Decision GpuBlacklist::MakeBlacklistDecision( if (!blacklist_[i]->disabled()) { type |= blacklist_[i]->GetGpuFeatureType(); if (blacklist_[i]->GetGpuSwitchingOption() != - content::GPU_SWITCHING_AUTOMATIC) + content::GPU_SWITCHING_OPTION_AUTOMATIC) switching = blacklist_[i]->GetGpuSwitchingOption(); } active_entries_.push_back(blacklist_[i]); diff --git a/content/browser/gpu/gpu_blacklist.h b/content/browser/gpu/gpu_blacklist.h index 2193f29..10bc12e 100644 --- a/content/browser/gpu/gpu_blacklist.h +++ b/content/browser/gpu/gpu_blacklist.h @@ -16,6 +16,7 @@ #include "build/build_config.h" #include "content/common/content_export.h" #include "content/public/common/gpu_feature_type.h" +#include "content/public/common/gpu_switching_option.h" class Version; @@ -47,7 +48,7 @@ class CONTENT_EXPORT GpuBlacklist { Decision() : blacklisted_features(content::GPU_FEATURE_TYPE_UNKNOWN), - gpu_switching(content::GPU_SWITCHING_AUTOMATIC) { + gpu_switching(content::GPU_SWITCHING_OPTION_UNKNOWN) { } }; diff --git a/content/browser/gpu/gpu_blacklist_unittest.cc b/content/browser/gpu/gpu_blacklist_unittest.cc index 888b4cc..427967a 100644 --- a/content/browser/gpu/gpu_blacklist_unittest.cc +++ b/content/browser/gpu/gpu_blacklist_unittest.cc @@ -1032,7 +1032,7 @@ TEST_F(GpuBlacklistTest, GpuSwitching) { GpuSwitchingOption switching = blacklist->MakeBlacklistDecision( GpuBlacklist::kOsMacosx, &os_version, gpu_info()).gpu_switching; - EXPECT_EQ(switching, content::GPU_SWITCHING_FORCE_DISCRETE); + EXPECT_EQ(switching, content::GPU_SWITCHING_OPTION_FORCE_DISCRETE); std::vector<uint32> entries; bool disabled = false; blacklist->GetDecisionEntries(entries, disabled); @@ -1045,7 +1045,7 @@ TEST_F(GpuBlacklistTest, GpuSwitching) { switching = blacklist->MakeBlacklistDecision( GpuBlacklist::kOsWin, &os_version, gpu_info()).gpu_switching; - EXPECT_EQ(switching, content::GPU_SWITCHING_FORCE_INTEGRATED); + EXPECT_EQ(switching, content::GPU_SWITCHING_OPTION_FORCE_INTEGRATED); blacklist->GetDecisionEntries(entries, disabled); EXPECT_EQ(entries.size(), 1u); EXPECT_EQ(entries[0], 2u); @@ -1056,7 +1056,7 @@ TEST_F(GpuBlacklistTest, GpuSwitching) { switching = blacklist->MakeBlacklistDecision( GpuBlacklist::kOsLinux, &os_version, gpu_info()).gpu_switching; - EXPECT_EQ(switching, content::GPU_SWITCHING_AUTOMATIC); + EXPECT_EQ(switching, content::GPU_SWITCHING_OPTION_AUTOMATIC); blacklist->GetDecisionEntries(entries, disabled); EXPECT_EQ(entries.size(), 1u); EXPECT_EQ(entries[0], 3u); diff --git a/content/browser/gpu/gpu_data_manager_impl.cc b/content/browser/gpu/gpu_data_manager_impl.cc index b6f2f7f..877b288 100644 --- a/content/browser/gpu/gpu_data_manager_impl.cc +++ b/content/browser/gpu/gpu_data_manager_impl.cc @@ -69,7 +69,7 @@ GpuDataManagerImpl::GpuDataManagerImpl() : complete_gpu_info_already_requested_(false), gpu_feature_type_(content::GPU_FEATURE_TYPE_UNKNOWN), preliminary_gpu_feature_type_(content::GPU_FEATURE_TYPE_UNKNOWN), - gpu_switching_(content::GPU_SWITCHING_AUTOMATIC), + gpu_switching_(content::GPU_SWITCHING_OPTION_AUTOMATIC), observer_list_(new GpuDataManagerObserverList), software_rendering_(false), card_blacklisted_(false), @@ -81,6 +81,14 @@ GpuDataManagerImpl::GpuDataManagerImpl() } if (command_line->HasSwitch(switches::kDisableGpu)) BlacklistCard(); + if (command_line->HasSwitch(switches::kGpuSwitching)) { + std::string option_string = command_line->GetSwitchValueASCII( + switches::kGpuSwitching); + GpuSwitchingOption option = gpu_util::StringToGpuSwitchingOption( + option_string); + if (option != content::GPU_SWITCHING_OPTION_UNKNOWN) + gpu_switching_ = option; + } } void GpuDataManagerImpl::Initialize() { @@ -175,7 +183,8 @@ void GpuDataManagerImpl::UpdateGpuInfo(const content::GPUInfo& gpu_info) { decision.blacklisted_features); } UpdateBlacklistedFeatures(decision.blacklisted_features); - gpu_switching_ = decision.gpu_switching; + if (decision.gpu_switching != content::GPU_SWITCHING_OPTION_UNKNOWN) + gpu_switching_ = decision.gpu_switching; } { @@ -337,6 +346,18 @@ void GpuDataManagerImpl::AppendGpuCommandLine( } else if (!use_gl.empty()) { command_line->AppendSwitchASCII(switches::kUseGL, use_gl); } + switch (gpu_switching_) { + case content::GPU_SWITCHING_OPTION_FORCE_DISCRETE: + command_line->AppendSwitchASCII(switches::kGpuSwitching, + switches::kGpuSwitchingOptionNameForceDiscrete); + break; + case content::GPU_SWITCHING_OPTION_FORCE_INTEGRATED: + command_line->AppendSwitchASCII(switches::kGpuSwitching, + switches::kGpuSwitchingOptionNameForceIntegrated); + break; + default: + break; + } if (!swiftshader_path.empty()) command_line->AppendSwitchPath(switches::kSwiftShaderPath, diff --git a/content/browser/gpu/gpu_process_host.cc b/content/browser/gpu/gpu_process_host.cc index c49a1f1..d0bd323 100644 --- a/content/browser/gpu/gpu_process_host.cc +++ b/content/browser/gpu/gpu_process_host.cc @@ -835,6 +835,7 @@ bool GpuProcessHost::LaunchGpuProcess(const std::string& channel_id) { #endif switches::kGpuNoContextLost, switches::kGpuStartupDialog, + switches::kGpuSwitching, switches::kLoggingLevel, switches::kNoSandbox, switches::kTestGLLib, diff --git a/content/browser/gpu/gpu_util.cc b/content/browser/gpu/gpu_util.cc index 7b53fee..91b42c3 100644 --- a/content/browser/gpu/gpu_util.cc +++ b/content/browser/gpu/gpu_util.cc @@ -13,6 +13,7 @@ #include "base/version.h" #include "content/browser/gpu/gpu_blacklist.h" #include "content/public/common/content_switches.h" +#include "ui/gl/gl_switches.h" using content::GpuFeatureType; using content::GpuSwitchingOption; @@ -30,11 +31,6 @@ const char kGpuFeatureNameAcceleratedVideoDecode[] = "accelerated_video_decode"; const char kGpuFeatureNameAll[] = "all"; const char kGpuFeatureNameUnknown[] = "unknown"; -const char kGpuSwitchingNameAutomatic[] = "automatic"; -const char kGpuSwitchingNameForceIntegrated[] = "force_integrated"; -const char kGpuSwitchingNameForceDiscrete[] = "force_discrete"; -const char kGpuSwitchingNameUnknown[] = "unknown"; - enum GpuFeatureStatus { kGpuFeatureEnabled = 0, kGpuFeatureBlacklisted = 1, @@ -141,13 +137,26 @@ std::string GpuFeatureTypeToString(GpuFeatureType type) { GpuSwitchingOption StringToGpuSwitchingOption( const std::string& switching_string) { - if (switching_string == kGpuSwitchingNameAutomatic) - return content::GPU_SWITCHING_AUTOMATIC; - if (switching_string == kGpuSwitchingNameForceIntegrated) - return content::GPU_SWITCHING_FORCE_INTEGRATED; - if (switching_string == kGpuSwitchingNameForceDiscrete) - return content::GPU_SWITCHING_FORCE_DISCRETE; - return content::GPU_SWITCHING_UNKNOWN; + if (switching_string == switches::kGpuSwitchingOptionNameAutomatic) + return content::GPU_SWITCHING_OPTION_AUTOMATIC; + if (switching_string == switches::kGpuSwitchingOptionNameForceIntegrated) + return content::GPU_SWITCHING_OPTION_FORCE_INTEGRATED; + if (switching_string == switches::kGpuSwitchingOptionNameForceDiscrete) + return content::GPU_SWITCHING_OPTION_FORCE_DISCRETE; + return content::GPU_SWITCHING_OPTION_UNKNOWN; +} + +std::string GpuSwitchingOptionToString(GpuSwitchingOption option) { + switch (option) { + case content::GPU_SWITCHING_OPTION_AUTOMATIC: + return switches::kGpuSwitchingOptionNameAutomatic; + case content::GPU_SWITCHING_OPTION_FORCE_INTEGRATED: + return switches::kGpuSwitchingOptionNameForceIntegrated; + case content::GPU_SWITCHING_OPTION_FORCE_DISCRETE: + return switches::kGpuSwitchingOptionNameForceDiscrete; + default: + return "unknown"; + } } void UpdateStats(const GpuBlacklist* blacklist, diff --git a/content/browser/gpu/gpu_util.h b/content/browser/gpu/gpu_util.h index 98c8197..e2cbead 100644 --- a/content/browser/gpu/gpu_util.h +++ b/content/browser/gpu/gpu_util.h @@ -11,6 +11,7 @@ #include "build/build_config.h" #include "content/common/content_export.h" #include "content/public/common/gpu_feature_type.h" +#include "content/public/common/gpu_switching_option.h" class GpuBlacklist; @@ -32,6 +33,10 @@ CONTENT_EXPORT std::string GpuFeatureTypeToString( CONTENT_EXPORT content::GpuSwitchingOption StringToGpuSwitchingOption( const std::string& switching_string); +// Gets a string version of a GpuSwitchingOption. +CONTENT_EXPORT std::string GpuSwitchingOptionToString( + content::GpuSwitchingOption option); + // Send UMA histograms about the enabled features. CONTENT_EXPORT void UpdateStats( const GpuBlacklist* blacklist, uint32 blacklisted_features); diff --git a/content/browser/gpu/gpu_util_unittest.cc b/content/browser/gpu/gpu_util_unittest.cc index b13b7a0..9568570 100644 --- a/content/browser/gpu/gpu_util_unittest.cc +++ b/content/browser/gpu/gpu_util_unittest.cc @@ -4,6 +4,7 @@ #include "content/browser/gpu/gpu_util.h" #include "testing/gtest/include/gtest/gtest.h" +#include "ui/gl/gl_switches.h" using content::GpuFeatureType; @@ -88,13 +89,32 @@ TEST(GpuUtilsTest, GpuFeatureTypeToString) { TEST(GpuUtilsTest, GpuSwitchingOptionFromString) { // Test StringToGpuSwitchingOption. - EXPECT_EQ(gpu_util::StringToGpuSwitchingOption("automatic"), - content::GPU_SWITCHING_AUTOMATIC); - EXPECT_EQ(gpu_util::StringToGpuSwitchingOption("force_discrete"), - content::GPU_SWITCHING_FORCE_DISCRETE); - EXPECT_EQ(gpu_util::StringToGpuSwitchingOption("force_integrated"), - content::GPU_SWITCHING_FORCE_INTEGRATED); + EXPECT_EQ(gpu_util::StringToGpuSwitchingOption( + switches::kGpuSwitchingOptionNameAutomatic), + content::GPU_SWITCHING_OPTION_AUTOMATIC); + EXPECT_EQ(gpu_util::StringToGpuSwitchingOption( + switches::kGpuSwitchingOptionNameForceDiscrete), + content::GPU_SWITCHING_OPTION_FORCE_DISCRETE); + EXPECT_EQ(gpu_util::StringToGpuSwitchingOption( + switches::kGpuSwitchingOptionNameForceIntegrated), + content::GPU_SWITCHING_OPTION_FORCE_INTEGRATED); EXPECT_EQ(gpu_util::StringToGpuSwitchingOption("xxx"), - content::GPU_SWITCHING_UNKNOWN); + content::GPU_SWITCHING_OPTION_UNKNOWN); +} + +TEST(GpuUtilsTest, GpuSwitchingOptionToString) { + // Test GpuSwitchingOptionToString. + EXPECT_STREQ( + gpu_util::GpuSwitchingOptionToString( + content::GPU_SWITCHING_OPTION_AUTOMATIC).c_str(), + switches::kGpuSwitchingOptionNameAutomatic); + EXPECT_STREQ( + gpu_util::GpuSwitchingOptionToString( + content::GPU_SWITCHING_OPTION_FORCE_DISCRETE).c_str(), + switches::kGpuSwitchingOptionNameForceDiscrete); + EXPECT_STREQ( + gpu_util::GpuSwitchingOptionToString( + content::GPU_SWITCHING_OPTION_FORCE_INTEGRATED).c_str(), + switches::kGpuSwitchingOptionNameForceIntegrated); } diff --git a/content/content_common.gypi b/content/content_common.gypi index 07f4c9d..38b5d1e 100644 --- a/content/content_common.gypi +++ b/content/content_common.gypi @@ -51,6 +51,7 @@ 'public/common/gpu_memory_stats.cc', 'public/common/gpu_memory_stats.h', 'public/common/gpu_performance_stats.h', + 'public/common/gpu_switching_option.h', 'public/common/injection_test_mac.h', 'public/common/injection_test_win.h', 'public/common/javascript_message_type.h', diff --git a/content/gpu/gpu_main.cc b/content/gpu/gpu_main.cc index 5e71bc2..be8b154 100644 --- a/content/gpu/gpu_main.cc +++ b/content/gpu/gpu_main.cc @@ -22,10 +22,12 @@ #include "content/gpu/gpu_process.h" #include "content/public/common/content_client.h" #include "content/public/common/content_switches.h" +#include "content/public/common/gpu_switching_option.h" #include "content/public/common/main_function_params.h" #include "crypto/hmac.h" #include "ui/gl/gl_surface.h" #include "ui/gl/gl_switches.h" +#include "ui/gl/gpu_switching_manager.h" #if defined(OS_WIN) #include "content/common/gpu/media/dxva_video_decode_accelerator.h" @@ -73,6 +75,15 @@ int GpuMain(const content::MainFunctionParams& parameters) { #endif } + if (command_line.HasSwitch(switches::kGpuSwitching)) { + std::string option = command_line.GetSwitchValueASCII( + switches::kGpuSwitching); + if (option == switches::kGpuSwitchingOptionNameForceDiscrete) + gfx::GpuSwitchingManager::GetInstance()->ForceUseOfDiscreteGpu(); + else if (option == switches::kGpuSwitchingOptionNameForceIntegrated) + gfx::GpuSwitchingManager::GetInstance()->ForceUseOfIntegratedGpu(); + } + // Initialization of the OpenGL bindings may fail, in which case we // will need to tear down this process. However, we can not do so // safely until the IPC channel is set up, because the detection of diff --git a/content/public/browser/gpu_data_manager.h b/content/public/browser/gpu_data_manager.h index 0c81eec..3a61e23 100644 --- a/content/public/browser/gpu_data_manager.h +++ b/content/public/browser/gpu_data_manager.h @@ -9,6 +9,7 @@ #include "content/common/content_export.h" #include "content/public/common/gpu_feature_type.h" +#include "content/public/common/gpu_switching_option.h" class FilePath; diff --git a/content/public/common/gpu_feature_type.h b/content/public/common/gpu_feature_type.h index e494be4..5900ec0 100644 --- a/content/public/common/gpu_feature_type.h +++ b/content/public/common/gpu_feature_type.h @@ -31,13 +31,6 @@ enum GpuFeatureType { GPU_FEATURE_TYPE_UNKNOWN = 0 }; -enum GpuSwitchingOption { - GPU_SWITCHING_AUTOMATIC, - GPU_SWITCHING_FORCE_INTEGRATED, - GPU_SWITCHING_FORCE_DISCRETE, - GPU_SWITCHING_UNKNOWN -}; - } // namespace content #endif // CONTENT_PUBLIC_COMMON_GPU_FEATURE_TYPE_H_ diff --git a/content/public/common/gpu_switching_option.h b/content/public/common/gpu_switching_option.h new file mode 100644 index 0000000..647d0cc --- /dev/null +++ b/content/public/common/gpu_switching_option.h @@ -0,0 +1,23 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CONTENT_PUBLIC_COMMON_GPU_SWITCHING_OPTION_H_ +#define CONTENT_PUBLIC_COMMON_GPU_SWITCHING_OPTION_H_ + +#include "build/build_config.h" +#include "content/common/content_export.h" + +namespace content { + +enum GpuSwitchingOption { + GPU_SWITCHING_OPTION_AUTOMATIC, + GPU_SWITCHING_OPTION_FORCE_INTEGRATED, + GPU_SWITCHING_OPTION_FORCE_DISCRETE, + GPU_SWITCHING_OPTION_UNKNOWN +}; + +} // namespace content + +#endif // CONTENT_PUBLIC_COMMON_GPU_SWITCHING_OPTION_H_ + diff --git a/ui/gl/gl.gyp b/ui/gl/gl.gyp index 99bd59a..85e4303 100644 --- a/ui/gl/gl.gyp +++ b/ui/gl/gl.gyp @@ -76,6 +76,8 @@ 'gl_surface_osmesa.h', 'gl_switches.cc', 'gl_switches.h', + 'gpu_switching_manager.cc', + 'gpu_switching_manager.h', 'scoped_make_current.cc', 'scoped_make_current.h', '<(gl_binding_output_dir)/gl_bindings_autogen_gl.cc', diff --git a/ui/gl/gl_context_cgl.cc b/ui/gl/gl_context_cgl.cc index 1f79ea0..503888d 100644 --- a/ui/gl/gl_context_cgl.cc +++ b/ui/gl/gl_context_cgl.cc @@ -13,6 +13,7 @@ #include "ui/gl/gl_bindings.h" #include "ui/gl/gl_implementation.h" #include "ui/gl/gl_surface_cgl.h" +#include "ui/gl/gpu_switching_manager.h" namespace gfx { @@ -27,6 +28,9 @@ bool GLContextCGL::Initialize(GLSurface* compatible_surface, GpuPreference gpu_preference) { DCHECK(compatible_surface); + gpu_preference = GpuSwitchingManager::GetInstance()->AdjustGpuPreference( + gpu_preference); + GLContextCGL* share_context = share_group() ? static_cast<GLContextCGL*>(share_group()->GetContext()) : NULL; @@ -216,17 +220,6 @@ GpuPreference GLContextCGL::GetGpuPreference() { return gpu_preference_; } -void GLContextCGL::ForceUseOfDiscreteGPU() { - static CGLPixelFormatObj format = NULL; - if (format) - return; - CGLPixelFormatAttribute attribs[1]; - attribs[0] = static_cast<CGLPixelFormatAttribute>(0); - GLint num_pixel_formats = 0; - CGLChoosePixelFormat(attribs, &format, &num_pixel_formats); - // format is deliberately leaked. -} - void ScopedCGLDestroyRendererInfo::operator()(CGLRendererInfoObj x) const { CGLDestroyRendererInfo(x); } diff --git a/ui/gl/gl_context_cgl.h b/ui/gl/gl_context_cgl.h index 49bc346..3e4e3c1 100644 --- a/ui/gl/gl_context_cgl.h +++ b/ui/gl/gl_context_cgl.h @@ -34,15 +34,8 @@ class GLContextCGL : public GLContext { virtual ~GLContextCGL(); private: - // Expose ForceUseOfDiscreteGPU only to GLContext implementation. - friend class GLContext; - GpuPreference GetGpuPreference(); - // Helper for dual-GPU support on systems where this is necessary - // for stability reasons. - static void ForceUseOfDiscreteGPU(); - void* context_; GpuPreference gpu_preference_; diff --git a/ui/gl/gl_context_mac.mm b/ui/gl/gl_context_mac.mm index a2df392..25b13e7 100644 --- a/ui/gl/gl_context_mac.mm +++ b/ui/gl/gl_context_mac.mm @@ -16,6 +16,7 @@ #include "ui/gl/gl_implementation.h" #include "ui/gl/gl_surface.h" #include "ui/gl/gl_switches.h" +#include "ui/gl/gpu_switching_manager.h" #if defined(USE_AURA) #include "ui/gl/gl_context_nsview.h" @@ -156,7 +157,7 @@ bool GLContext::SupportsDualGpus() { switches::kDisableGpuSwitching); if (forcibly_disable) { - GLContextCGL::ForceUseOfDiscreteGPU(); + GpuSwitchingManager::GetInstance()->ForceUseOfDiscreteGpu(); return false; } diff --git a/ui/gl/gl_switches.cc b/ui/gl/gl_switches.cc index d30c958..d65fd46 100644 --- a/ui/gl/gl_switches.cc +++ b/ui/gl/gl_switches.cc @@ -48,8 +48,17 @@ const char kGpuNoContextLost[] = "gpu-no-context-lost"; // Simulates a slow GPU. const char kGpuSwapDelay[] = "gpu-swap-delay"; +// Overwrite the default GPU automatic switching behavior to force on +// integrated GPU or discrete GPU. +const char kGpuSwitching[] = "gpu-switching"; + +const char kGpuSwitchingOptionNameForceIntegrated[] = "force_integrated"; +const char kGpuSwitchingOptionNameForceDiscrete[] = "force_discrete"; +const char kGpuSwitchingOptionNameAutomatic[] = "automatic"; + // Flag used for Linux tests: for desktop GL bindings, try to load this GL // library first, but fall back to regular library if loading fails. const char kTestGLLib[] = "test-gl-lib"; } // namespace switches + diff --git a/ui/gl/gl_switches.h b/ui/gl/gl_switches.h index 7d8706e..e7bdcb1 100644 --- a/ui/gl/gl_switches.h +++ b/ui/gl/gl_switches.h @@ -29,6 +29,15 @@ GL_EXPORT extern const char kEnableGPUServiceLogging[]; GL_EXPORT extern const char kEnableGPUClientLogging[]; GL_EXPORT extern const char kGpuNoContextLost[]; GL_EXPORT extern const char kGpuSwapDelay[]; + +GL_EXPORT extern const char kGpuSwitching[]; + +// The GPU switching names that can be passed to --gpu-switching. +GL_EXPORT extern const char kGpuSwitchingOptionNameForceIntegrated[]; +GL_EXPORT extern const char kGpuSwitchingOptionNameForceDiscrete[]; +// The last one (automatic) is not used as commandline switch option. +GL_EXPORT extern const char kGpuSwitchingOptionNameAutomatic[]; + GL_EXPORT extern const char kUseGL[]; GL_EXPORT extern const char kSwiftShaderPath[]; GL_EXPORT extern const char kTestGLLib[]; diff --git a/ui/gl/gpu_switching_manager.cc b/ui/gl/gpu_switching_manager.cc new file mode 100644 index 0000000..6fa8db9 --- /dev/null +++ b/ui/gl/gpu_switching_manager.cc @@ -0,0 +1,40 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ui/gl/gpu_switching_manager.h" + +#include "base/logging.h" + +namespace gfx { + +// static +GpuSwitchingManager* GpuSwitchingManager::GetInstance() { + return Singleton<GpuSwitchingManager>::get(); +} + +GpuSwitchingManager::GpuSwitchingManager() { +} + +GpuSwitchingManager::~GpuSwitchingManager() { +} + +void GpuSwitchingManager::ForceUseOfIntegratedGpu() { + gpu_switching_option_.clear(); + gpu_switching_option_.push_back(PreferIntegratedGpu); +} + +void GpuSwitchingManager::ForceUseOfDiscreteGpu() { + gpu_switching_option_.clear(); + gpu_switching_option_.push_back(PreferDiscreteGpu); +} + +GpuPreference GpuSwitchingManager::AdjustGpuPreference( + GpuPreference gpu_preference) { + if (gpu_switching_option_.size() == 0) + return gpu_preference; + DCHECK_EQ(gpu_switching_option_.size(), 1u); + return gpu_switching_option_[0]; +} + +} // namespace gfx diff --git a/ui/gl/gpu_switching_manager.h b/ui/gl/gpu_switching_manager.h new file mode 100644 index 0000000..a5b37df --- /dev/null +++ b/ui/gl/gpu_switching_manager.h @@ -0,0 +1,44 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef UI_GL_GPU_SWITCHING_MANAGER_H_ +#define UI_GL_GPU_SWITCHING_MANAGER_H_ + +#include <vector> + +#include "base/memory/singleton.h" +#include "ui/gl/gl_export.h" +#include "ui/gl/gpu_preference.h" + +namespace gfx { + +class GL_EXPORT GpuSwitchingManager { + public: + // Getter for the singleton. This will return NULL on failure. + static GpuSwitchingManager* GetInstance(); + + // Set the switching option, but don't take any actions until later + // we access GPU. + void ForceUseOfIntegratedGpu(); + void ForceUseOfDiscreteGpu(); + + // Adjust GpuPreference based on the current switching option. + // If none is set, return the original GpuPreference. + GpuPreference AdjustGpuPreference(GpuPreference gpu_preference); + + private: + friend struct DefaultSingletonTraits<GpuSwitchingManager>; + + GpuSwitchingManager(); + virtual ~GpuSwitchingManager(); + + std::vector<GpuPreference> gpu_switching_option_; + + DISALLOW_COPY_AND_ASSIGN(GpuSwitchingManager); +}; + +} // namespace gfx + +#endif // UI_GL_GPU_SWITCHING_MANAGER_H_ + |