blob: e682928b7752a9c08fec9f3be469eacb72dbb6f0 [file] [log] [blame]
// Copyright 2019 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "ui/gl/gl_features.h"
#include "base/command_line.h"
#include "base/feature_list.h"
#include "base/strings/string_split.h"
#include "build/build_config.h"
#include "ui/gl/gl_switches.h"
#if BUILDFLAG(IS_MAC)
#include "base/mac/mac_util.h"
#endif
#if BUILDFLAG(IS_ANDROID)
#include "base/android/build_info.h"
#include "base/metrics/field_trial_params.h"
#include "base/strings/pattern.h"
#include "base/strings/string_split.h"
#include "ui/gfx/android/achoreographer_compat.h"
#include "ui/gfx/android/android_surface_control_compat.h"
#endif
namespace features {
namespace {
#if BUILDFLAG(IS_APPLE)
BASE_FEATURE(kGpuVsync, "GpuVsync", base::FEATURE_DISABLED_BY_DEFAULT);
#else
BASE_FEATURE(kGpuVsync, "GpuVsync", base::FEATURE_ENABLED_BY_DEFAULT);
#endif
#if BUILDFLAG(IS_ANDROID)
const base::FeatureParam<std::string>
kPassthroughCommandDecoderBlockListByBrand{
&kDefaultPassthroughCommandDecoder, "BlockListByBrand", ""};
const base::FeatureParam<std::string>
kPassthroughCommandDecoderBlockListByDevice{
&kDefaultPassthroughCommandDecoder, "BlockListByDevice", ""};
const base::FeatureParam<std::string>
kPassthroughCommandDecoderBlockListByAndroidBuildId{
&kDefaultPassthroughCommandDecoder, "BlockListByAndroidBuildId", ""};
const base::FeatureParam<std::string>
kPassthroughCommandDecoderBlockListByManufacturer{
&kDefaultPassthroughCommandDecoder, "BlockListByManufacturer", ""};
const base::FeatureParam<std::string>
kPassthroughCommandDecoderBlockListByModel{
&kDefaultPassthroughCommandDecoder, "BlockListByModel", ""};
const base::FeatureParam<std::string>
kPassthroughCommandDecoderBlockListByBoard{
&kDefaultPassthroughCommandDecoder, "BlockListByBoard", ""};
const base::FeatureParam<std::string>
kPassthroughCommandDecoderBlockListByAndroidBuildFP{
&kDefaultPassthroughCommandDecoder, "BlockListByAndroidBuildFP", ""};
bool IsDeviceBlocked(const char* field, const std::string& block_list) {
auto disable_patterns = base::SplitString(
block_list, "|", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
for (const auto& disable_pattern : disable_patterns) {
if (base::MatchPattern(field, disable_pattern))
return true;
}
return false;
}
#endif
BASE_FEATURE(kForceANGLEFeatures,
"ForceANGLEFeatures",
base::FEATURE_DISABLED_BY_DEFAULT);
const base::FeatureParam<std::string> kForcedANGLEEnabledFeaturesFP{
&kForceANGLEFeatures, "EnabledFeatures", ""};
const base::FeatureParam<std::string> kForcedANGLEDisabledFeaturesFP{
&kForceANGLEFeatures, "DisabledFeatures", ""};
void SplitAndAppendANGLEFeatureList(const std::string& list,
std::vector<std::string>& out_features) {
for (std::string& feature_name : base::SplitString(
list, ", ;", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY)) {
out_features.push_back(std::move(feature_name));
}
}
} // namespace
#if BUILDFLAG(ENABLE_VALIDATING_COMMAND_DECODER)
// Use the passthrough command decoder by default. This can be overridden with
// the --use-cmd-decoder=passthrough or --use-cmd-decoder=validating flags.
// Feature lives in ui/gl because it affects the GL binding initialization on
// platforms that would otherwise not default to using EGL bindings.
BASE_FEATURE(kDefaultPassthroughCommandDecoder,
"DefaultPassthroughCommandDecoder",
base::FEATURE_ENABLED_BY_DEFAULT
);
#endif // !defined(PASSTHROUGH_COMMAND_DECODER_LAUNCHED)
#if BUILDFLAG(IS_MAC)
// If true, metal shader programs are written to disk.
//
// As the gpu process writes to disk when this is set, you must also disable
// the sandbox.
//
// The path the shaders are written to is controlled via the command line switch
// --shader-cache-path (default is /tmp/shaders).
BASE_FEATURE(kWriteMetalShaderCacheToDisk,
"WriteMetalShaderCacheToDisk",
base::FEATURE_DISABLED_BY_DEFAULT);
// If true, the metal shader cache is read from a file and put into BlobCache
// during startup.
BASE_FEATURE(kUseBuiltInMetalShaderCache,
"UseBuiltInMetalShaderCache",
base::FEATURE_DISABLED_BY_DEFAULT);
#endif
#if BUILDFLAG(IS_WIN)
// If true, VSyncThreadWin will use the primary monitor's
// refresh rate as the vsync interval.
BASE_FEATURE(kUsePrimaryMonitorVSyncIntervalOnSV3,
"UsePrimaryMonitorVSyncIntervalOnSV3",
base::FEATURE_ENABLED_BY_DEFAULT);
#endif // BUILDFLAG(IS_WIN)
bool UseGpuVsync() {
return !base::CommandLine::ForCurrentProcess()->HasSwitch(
switches::kDisableGpuVsync) &&
base::FeatureList::IsEnabled(kGpuVsync);
}
bool IsAndroidFrameDeadlineEnabled() {
#if BUILDFLAG(IS_ANDROID)
static bool enabled =
base::android::BuildInfo::GetInstance()->is_at_least_t() &&
gfx::AChoreographerCompat33::Get().supported &&
gfx::SurfaceControl::SupportsSetFrameTimeline() &&
gfx::SurfaceControl::SupportsSetEnableBackPressure();
return enabled;
#else
return false;
#endif
}
bool UsePassthroughCommandDecoder() {
#if !BUILDFLAG(ENABLE_VALIDATING_COMMAND_DECODER)
return true;
#else
if (!base::FeatureList::IsEnabled(kDefaultPassthroughCommandDecoder))
return false;
#if BUILDFLAG(IS_ANDROID)
// Check block list against build info.
const auto* build_info = base::android::BuildInfo::GetInstance();
if (IsDeviceBlocked(build_info->brand(),
kPassthroughCommandDecoderBlockListByBrand.Get()))
return false;
if (IsDeviceBlocked(build_info->device(),
kPassthroughCommandDecoderBlockListByDevice.Get()))
return false;
if (IsDeviceBlocked(
build_info->android_build_id(),
kPassthroughCommandDecoderBlockListByAndroidBuildId.Get()))
return false;
if (IsDeviceBlocked(build_info->manufacturer(),
kPassthroughCommandDecoderBlockListByManufacturer.Get()))
return false;
if (IsDeviceBlocked(build_info->model(),
kPassthroughCommandDecoderBlockListByModel.Get()))
return false;
if (IsDeviceBlocked(build_info->board(),
kPassthroughCommandDecoderBlockListByBoard.Get()))
return false;
if (IsDeviceBlocked(
build_info->android_build_fp(),
kPassthroughCommandDecoderBlockListByAndroidBuildFP.Get()))
return false;
#endif // BUILDFLAG(IS_ANDROID)
return true;
#endif // defined(PASSTHROUGH_COMMAND_DECODER_LAUNCHED)
}
void GetANGLEFeaturesFromCommandLineAndFinch(
const base::CommandLine* command_line,
std::vector<std::string>& enabled_angle_features,
std::vector<std::string>& disabled_angle_features) {
SplitAndAppendANGLEFeatureList(
command_line->GetSwitchValueASCII(switches::kEnableANGLEFeatures),
enabled_angle_features);
SplitAndAppendANGLEFeatureList(
command_line->GetSwitchValueASCII(switches::kDisableANGLEFeatures),
disabled_angle_features);
if (base::FeatureList::IsEnabled(kForceANGLEFeatures)) {
SplitAndAppendANGLEFeatureList(kForcedANGLEEnabledFeaturesFP.Get(),
enabled_angle_features);
SplitAndAppendANGLEFeatureList(kForcedANGLEDisabledFeaturesFP.Get(),
disabled_angle_features);
}
#if BUILDFLAG(IS_MAC)
if (base::FeatureList::IsEnabled(features::kWriteMetalShaderCacheToDisk)) {
disabled_angle_features.push_back("enableParallelMtlLibraryCompilation");
enabled_angle_features.push_back("compileMetalShaders");
enabled_angle_features.push_back("disableProgramCaching");
}
if (base::FeatureList::IsEnabled(features::kUseBuiltInMetalShaderCache)) {
enabled_angle_features.push_back("loadMetalShadersFromBlobCache");
}
#endif
}
} // namespace features