0

Revert 158211 - Revert 158076 - 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

TBR=zmo@chromium.org
Review URL: https://codereview.chromium.org/10959061

TBR=tzik@chromium.org

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@158213 0039d316-1c4b-4281-b951-d872f2087c98
This commit is contained in:
tzik@chromium.org
2012-09-23 19:37:24 +00:00
parent 6408589274
commit 1bb06b0fea
20 changed files with 150 additions and 57 deletions

@ -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:

@ -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]);

@ -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) {
}
};

@ -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);

@ -71,7 +71,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),
@ -83,6 +83,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() {
@ -177,7 +185,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;
}
{
@ -339,6 +348,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,

@ -834,6 +834,7 @@ bool GpuProcessHost::LaunchGpuProcess(const std::string& channel_id) {
#endif
switches::kGpuNoContextLost,
switches::kGpuStartupDialog,
switches::kGpuSwitching,
switches::kLoggingLevel,
switches::kNoSandbox,
switches::kTestGLLib,

@ -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,

@ -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);

@ -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);
}

@ -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',

@ -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

@ -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;

@ -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_

@ -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_

@ -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',

@ -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);
}

@ -38,15 +38,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_;

@ -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() {
!CommandLine::ForCurrentProcess()->HasSwitch(switches::kGpuSwitching);
if (forcibly_disable) {
GLContextCGL::ForceUseOfDiscreteGPU();
GpuSwitchingManager::GetInstance()->ForceUseOfDiscreteGpu();
return false;
}

@ -43,8 +43,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

@ -28,6 +28,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[];