| // Copyright 2017 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "components/viz/common/features.h" |
| |
| #include <string> |
| |
| #include "base/command_line.h" |
| #include "base/feature_list.h" |
| #include "base/metrics/field_trial_params.h" |
| #include "base/system/sys_info.h" |
| #include "build/build_config.h" |
| #include "build/chromeos_buildflags.h" |
| #include "components/viz/common/delegated_ink_prediction_configuration.h" |
| #include "components/viz/common/switches.h" |
| #include "components/viz/common/viz_utils.h" |
| #include "gpu/config/gpu_finch_features.h" |
| #include "gpu/config/gpu_switches.h" |
| #include "media/media_buildflags.h" |
| |
| #if BUILDFLAG(IS_ANDROID) |
| #include "base/android/build_info.h" |
| #endif |
| |
| namespace { |
| |
| // FieldTrialParams for `DynamicSchedulerForDraw` and |
| // `kDynamicSchedulerForClients`. |
| const char kDynamicSchedulerPercentile[] = "percentile"; |
| |
| } // namespace |
| |
| namespace features { |
| |
| BASE_FEATURE(kUseMultipleOverlays, |
| "UseMultipleOverlays", |
| #if BUILDFLAG(IS_CHROMEOS_ASH) |
| base::FEATURE_ENABLED_BY_DEFAULT |
| #else |
| base::FEATURE_DISABLED_BY_DEFAULT |
| #endif |
| ); |
| const char kMaxOverlaysParam[] = "max_overlays"; |
| |
| BASE_FEATURE(kDelegatedCompositing, |
| "DelegatedCompositing", |
| #if BUILDFLAG(IS_CHROMEOS_LACROS) |
| base::FEATURE_ENABLED_BY_DEFAULT |
| #else |
| base::FEATURE_DISABLED_BY_DEFAULT |
| #endif |
| ); |
| |
| BASE_FEATURE(kVideoDetectorIgnoreNonVideos, |
| "VideoDetectorIgnoreNonVideos", |
| base::FEATURE_ENABLED_BY_DEFAULT); |
| |
| BASE_FEATURE(kSimpleFrameRateThrottling, |
| "SimpleFrameRateThrottling", |
| base::FEATURE_DISABLED_BY_DEFAULT); |
| |
| #if BUILDFLAG(IS_ANDROID) |
| // When wide color gamut content from the web is encountered, promote our |
| // display to wide color gamut if supported. |
| BASE_FEATURE(kDynamicColorGamut, |
| "DynamicColorGamut", |
| base::FEATURE_DISABLED_BY_DEFAULT); |
| #endif |
| |
| // Submit CompositorFrame from SynchronousLayerTreeFrameSink directly to viz in |
| // WebView. |
| BASE_FEATURE(kVizFrameSubmissionForWebView, |
| "VizFrameSubmissionForWebView", |
| base::FEATURE_DISABLED_BY_DEFAULT); |
| |
| // Whether we should use the real buffers corresponding to overlay candidates in |
| // order to do a pageflip test rather than allocating test buffers. |
| BASE_FEATURE(kUseRealBuffersForPageFlipTest, |
| "UseRealBuffersForPageFlipTest", |
| base::FEATURE_ENABLED_BY_DEFAULT); |
| |
| #if BUILDFLAG(IS_FUCHSIA) |
| // Enables SkiaOutputDeviceBufferQueue instead of Vulkan swapchain on Fuchsia. |
| BASE_FEATURE(kUseSkiaOutputDeviceBufferQueue, |
| "UseSkiaOutputDeviceBufferQueue", |
| base::FEATURE_ENABLED_BY_DEFAULT); |
| #endif |
| |
| // Whether we should log extra debug information to webrtc native log. |
| BASE_FEATURE(kWebRtcLogCapturePipeline, |
| "WebRtcLogCapturePipeline", |
| base::FEATURE_DISABLED_BY_DEFAULT); |
| |
| #if BUILDFLAG(IS_WIN) |
| // Enables swap chains to call SetPresentDuration to request DWM/OS to reduce |
| // vsync. |
| BASE_FEATURE(kUseSetPresentDuration, |
| "UseSetPresentDuration", |
| base::FEATURE_DISABLED_BY_DEFAULT); |
| #endif // BUILDFLAG(IS_WIN) |
| |
| // Enables platform supported delegated ink trails instead of Skia backed |
| // delegated ink trails. |
| BASE_FEATURE(kUsePlatformDelegatedInk, |
| "UsePlatformDelegatedInk", |
| base::FEATURE_ENABLED_BY_DEFAULT); |
| |
| // Used to debug Android WebView Vulkan composite. Composite to an intermediate |
| // buffer and draw the intermediate buffer to the secondary command buffer. |
| BASE_FEATURE(kWebViewVulkanIntermediateBuffer, |
| "WebViewVulkanIntermediateBuffer", |
| base::FEATURE_DISABLED_BY_DEFAULT); |
| |
| #if BUILDFLAG(IS_ANDROID) |
| // Hardcoded as disabled for WebView to have a different default for |
| // UseSurfaceLayerForVideo from chrome. |
| BASE_FEATURE(kUseSurfaceLayerForVideoDefault, |
| "UseSurfaceLayerForVideoDefault", |
| base::FEATURE_ENABLED_BY_DEFAULT); |
| |
| BASE_FEATURE(kWebViewNewInvalidateHeuristic, |
| "WebViewNewInvalidateHeuristic", |
| base::FEATURE_DISABLED_BY_DEFAULT); |
| #endif |
| |
| BASE_FEATURE(kDrawPredictedInkPoint, |
| "DrawPredictedInkPoint", |
| base::FEATURE_DISABLED_BY_DEFAULT); |
| const char kDraw1Point12Ms[] = "1-pt-12ms"; |
| const char kDraw2Points6Ms[] = "2-pt-6ms"; |
| const char kDraw1Point6Ms[] = "1-pt-6ms"; |
| const char kDraw2Points3Ms[] = "2-pt-3ms"; |
| const char kPredictorKalman[] = "kalman"; |
| const char kPredictorLinearResampling[] = "linear-resampling"; |
| const char kPredictorLinear1[] = "linear-1"; |
| const char kPredictorLinear2[] = "linear-2"; |
| const char kPredictorLsq[] = "lsq"; |
| |
| // Used by Viz to parameterize adjustments to scheduler deadlines. |
| BASE_FEATURE(kDynamicSchedulerForDraw, |
| "DynamicSchedulerForDraw", |
| base::FEATURE_DISABLED_BY_DEFAULT); |
| // User to parameterize adjustments to clients' deadlines. |
| BASE_FEATURE(kDynamicSchedulerForClients, |
| "DynamicSchedulerForClients", |
| base::FEATURE_DISABLED_BY_DEFAULT); |
| |
| #if BUILDFLAG(IS_APPLE) |
| // Increase the max CALayer number allowed for CoreAnimation. |
| // * If this feature is disabled, then the default limit is 128 quads, |
| // unless there are 5 or more video elements present, in which case |
| // the limit is 300. |
| // * If this feature is enabled, then these limits are 512, and can be |
| // overridden by the "default" and "many-videos" |
| // feature parameters. |
| BASE_FEATURE(kCALayerNewLimit, |
| "CALayerNewLimit", |
| base::FEATURE_ENABLED_BY_DEFAULT); |
| // Set FeatureParam default to -1. CALayerOverlayProcessor choose the default in |
| // ca_layer_overlay.cc When it's < 0. |
| const base::FeatureParam<int> kCALayerNewLimitDefault{&kCALayerNewLimit, |
| "default", -1}; |
| const base::FeatureParam<int> kCALayerNewLimitManyVideos{&kCALayerNewLimit, |
| "many-videos", -1}; |
| #endif |
| |
| #if BUILDFLAG(IS_APPLE) || BUILDFLAG(IS_OZONE) |
| BASE_FEATURE(kCanSkipRenderPassOverlay, |
| "CanSkipRenderPassOverlay", |
| base::FEATURE_ENABLED_BY_DEFAULT); |
| #endif |
| |
| // Allow SkiaRenderer to skip drawing render passes that contain a single |
| // RenderPassDrawQuad. |
| BASE_FEATURE(kAllowBypassRenderPassQuads, |
| "AllowBypassRenderPassQuads", |
| base::FEATURE_DISABLED_BY_DEFAULT); |
| |
| BASE_FEATURE(kAllowUndamagedNonrootRenderPassToSkip, |
| "AllowUndamagedNonrootRenderPassToSkip", |
| base::FEATURE_DISABLED_BY_DEFAULT); |
| |
| // Whether to: |
| // - Perform periodic inactive frame culling. |
| // - Cull *all* frames in case of critical memory pressure, rather than keeping |
| // one. |
| BASE_FEATURE(kAggressiveFrameCulling, |
| "AggressiveFrameCulling", |
| base::FEATURE_ENABLED_BY_DEFAULT); |
| |
| // If enabled, do not rely on surface garbage collection to happen |
| // periodically, but trigger it eagerly, to avoid missing calls. |
| BASE_FEATURE(kEagerSurfaceGarbageCollection, |
| "EagerSurfaceGarbageCollection", |
| base::FEATURE_ENABLED_BY_DEFAULT); |
| |
| // Only applies when a caller has requested a custom BeginFrame rate via the |
| // Throttle() API in frame_sink_manager.mojom. If enabled, parameters related |
| // to the BeginFrame rate are overridden in viz to reflect the throttled rate |
| // before being circulated in the system. The most notable are the interval and |
| // deadline in BeginFrameArgs. If disabled, these parameters reflect the default |
| // vsync rate (the behavior at the time this feature was created.) |
| BASE_FEATURE(kOverrideThrottledFrameRateParams, |
| "OverrideThrottledFrameRateParams", |
| base::FEATURE_DISABLED_BY_DEFAULT); |
| |
| // Used to gate calling SetPurgeable on OutputPresenter::Image from |
| // SkiaOutputDeviceBufferQueue. |
| BASE_FEATURE(kBufferQueueImageSetPurgeable, |
| "BufferQueueImageSetPurgeable", |
| base::FEATURE_ENABLED_BY_DEFAULT); |
| |
| // On platforms using SkiaOutputDeviceBufferQueue, when this is true |
| // SkiaRenderer will allocate and maintain a buffer queue of images for the root |
| // render pass, instead of SkiaOutputDeviceBufferQueue itself. |
| BASE_FEATURE(kRendererAllocatesImages, |
| "RendererAllocatesImages", |
| #if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_FUCHSIA) || BUILDFLAG(IS_CHROMEOS) |
| base::FEATURE_ENABLED_BY_DEFAULT |
| #else |
| base::FEATURE_DISABLED_BY_DEFAULT |
| #endif |
| ); |
| |
| // On all platforms when attempting to evict a FrameTree, the active |
| // viz::Surface can be not included. This feature ensures that the we always add |
| // the active viz::Surface to the eviction list. |
| // |
| // Furthermore, by default on Android, when a client is being evicted, it only |
| // evicts itself. This differs from Destkop platforms which evict the entire |
| // FrameTree along with the topmost viz::Surface. When this feature is enabled, |
| // Android will begin also evicting the entire FrameTree. |
| BASE_FEATURE(kEvictSubtree, "EvictSubtree", base::FEATURE_DISABLED_BY_DEFAULT); |
| |
| // If enabled, CompositorFrameSinkClient::OnBeginFrame is also treated as the |
| // DidReceiveCompositorFrameAck. Both in providing the Ack for the previous |
| // frame, and in returning resources. While enabled the separate Ack and |
| // ReclaimResources signals will not be sent. |
| BASE_FEATURE(kOnBeginFrameAcks, |
| "OnBeginFrameAcks", |
| base::FEATURE_DISABLED_BY_DEFAULT); |
| |
| // If enabled, and kOnBeginFrameAcks is also enabled, then if we issue an |
| // CompositorFrameSinkClient::OnBeginFrame, while we are pending an Ack. If the |
| // Ack arrives before the next OnBeginFrame we will send it immediately, instead |
| // of batching it. This is to support a frame submission/draw that occurs right |
| // near the OnBeginFrame boundary. |
| BASE_FEATURE(kOnBeginFrameAllowLateAcks, |
| "OnBeginFrameAllowLateAcks", |
| base::FEATURE_DISABLED_BY_DEFAULT); |
| |
| // if enabled, Any CompositorFrameSink of type video that defines a preferred |
| // framerate that is below the display framerate will throttle OnBeginFrame |
| // callbacks to match the preferred framerate. |
| BASE_FEATURE(kOnBeginFrameThrottleVideo, |
| "OnBeginFrameThrottleVideo", |
| base::FEATURE_DISABLED_BY_DEFAULT); |
| |
| BASE_FEATURE(kSharedBitmapToSharedImage, |
| "SharedBitmapToSharedImage", |
| base::FEATURE_DISABLED_BY_DEFAULT); |
| // Used to enable the HintSession::Mode::BOOST mode. BOOST mode try to force |
| // the ADPF(Android Dynamic Performance Framework) to give Chrome more CPU |
| // resources during a scroll. |
| BASE_FEATURE(kEnableADPFScrollBoost, |
| "EnableADPFScrollBoost", |
| base::FEATURE_DISABLED_BY_DEFAULT); |
| |
| // Specifies how long after the boost mode is set, it will expire. |
| const base::FeatureParam<base::TimeDelta> kADPFBoostTimeout{ |
| &kEnableADPFScrollBoost, "adpf_boost_mode_timeout", |
| base::Milliseconds(200)}; |
| |
| // If enabled, Chrome uses ADPF(Android Dynamic Performance Framework) to |
| // request more CPU resources in the middle of a frame production if the frame |
| // is taking longer than expected. |
| BASE_FEATURE(kEnableADPFMidFrameBoost, |
| "EnableADPFMidFrameBoost", |
| base::FEATURE_DISABLED_BY_DEFAULT); |
| |
| // The deadline for requesting a boost in the middle of a frame production is |
| // this multiplier * ADPF target_duration. |
| const base::FeatureParam<double> kADPFMidFrameBoostDurationMultiplier{ |
| &kEnableADPFMidFrameBoost, "adpf_mid_frame_boost_multiplier", 1.0}; |
| |
| // If enabled, Chrome includes the Renderer Main thread(s) into the |
| // ADPF(Android Dynamic Performance Framework) hint session. |
| BASE_FEATURE(kEnableADPFRendererMain, |
| "EnableADPFRendererMain", |
| base::FEATURE_DISABLED_BY_DEFAULT); |
| |
| bool IsDelegatedCompositingEnabled() { |
| return base::FeatureList::IsEnabled(kDelegatedCompositing); |
| } |
| |
| bool IsSimpleFrameRateThrottlingEnabled() { |
| return base::FeatureList::IsEnabled(kSimpleFrameRateThrottling); |
| } |
| |
| #if BUILDFLAG(IS_ANDROID) |
| bool IsDynamicColorGamutEnabled() { |
| if (viz::AlwaysUseWideColorGamut()) |
| return false; |
| auto* build_info = base::android::BuildInfo::GetInstance(); |
| if (build_info->sdk_int() < base::android::SDK_VERSION_Q) |
| return false; |
| return base::FeatureList::IsEnabled(kDynamicColorGamut); |
| } |
| #endif |
| |
| bool IsUsingVizFrameSubmissionForWebView() { |
| return base::FeatureList::IsEnabled(kVizFrameSubmissionForWebView); |
| } |
| |
| bool ShouldUseRealBuffersForPageFlipTest() { |
| return base::FeatureList::IsEnabled(kUseRealBuffersForPageFlipTest); |
| } |
| |
| bool ShouldWebRtcLogCapturePipeline() { |
| return base::FeatureList::IsEnabled(kWebRtcLogCapturePipeline); |
| } |
| |
| #if BUILDFLAG(IS_WIN) |
| bool ShouldUseSetPresentDuration() { |
| return base::FeatureList::IsEnabled(kUseSetPresentDuration); |
| } |
| #endif // BUILDFLAG(IS_WIN) |
| |
| absl::optional<int> ShouldDrawPredictedInkPoints() { |
| if (!base::FeatureList::IsEnabled(kDrawPredictedInkPoint)) |
| return absl::nullopt; |
| |
| std::string predicted_points = GetFieldTrialParamValueByFeature( |
| kDrawPredictedInkPoint, "predicted_points"); |
| if (predicted_points == kDraw1Point12Ms) |
| return viz::PredictionConfig::k1Point12Ms; |
| else if (predicted_points == kDraw2Points6Ms) |
| return viz::PredictionConfig::k2Points6Ms; |
| else if (predicted_points == kDraw1Point6Ms) |
| return viz::PredictionConfig::k1Point6Ms; |
| else if (predicted_points == kDraw2Points3Ms) |
| return viz::PredictionConfig::k2Points3Ms; |
| |
| NOTREACHED(); |
| return absl::nullopt; |
| } |
| |
| std::string InkPredictor() { |
| if (!base::FeatureList::IsEnabled(kDrawPredictedInkPoint)) |
| return ""; |
| |
| return GetFieldTrialParamValueByFeature(kDrawPredictedInkPoint, "predictor"); |
| } |
| |
| bool ShouldUsePlatformDelegatedInk() { |
| return base::FeatureList::IsEnabled(kUsePlatformDelegatedInk); |
| } |
| |
| bool UseSurfaceLayerForVideo() { |
| #if BUILDFLAG(IS_ANDROID) |
| // SurfaceLayer video should work fine with new heuristic. |
| if (base::FeatureList::IsEnabled(kWebViewNewInvalidateHeuristic)) |
| return true; |
| |
| // Allow enabling UseSurfaceLayerForVideo if webview is using surface control. |
| if (::features::IsAndroidSurfaceControlEnabled()) { |
| return true; |
| } |
| return base::FeatureList::IsEnabled(kUseSurfaceLayerForVideoDefault); |
| #else |
| return true; |
| #endif |
| } |
| |
| // Used by Viz to determine if viz::DisplayScheduler should dynamically adjust |
| // its frame deadline. Returns the percentile of historic draw times to base the |
| // deadline on. Or absl::nullopt if the feature is disabled. |
| absl::optional<double> IsDynamicSchedulerEnabledForDraw() { |
| if (!base::FeatureList::IsEnabled(kDynamicSchedulerForDraw)) |
| return absl::nullopt; |
| double result = base::GetFieldTrialParamByFeatureAsDouble( |
| kDynamicSchedulerForDraw, kDynamicSchedulerPercentile, -1.0); |
| if (result < 0.0) |
| return absl::nullopt; |
| return result; |
| } |
| |
| // Used by Viz to determine if the frame deadlines provided to CC should be |
| // dynamically adjusted. Returns the percentile of historic draw times to base |
| // the deadline on. Or absl::nullopt if the feature is disabled. |
| absl::optional<double> IsDynamicSchedulerEnabledForClients() { |
| if (!base::FeatureList::IsEnabled(kDynamicSchedulerForClients)) |
| return absl::nullopt; |
| double result = base::GetFieldTrialParamByFeatureAsDouble( |
| kDynamicSchedulerForClients, kDynamicSchedulerPercentile, -1.0); |
| if (result < 0.0) |
| return absl::nullopt; |
| return result; |
| } |
| |
| int MaxOverlaysConsidered() { |
| if (!base::FeatureList::IsEnabled(kUseMultipleOverlays)) { |
| return 1; |
| } |
| |
| return base::GetFieldTrialParamByFeatureAsInt(kUseMultipleOverlays, |
| kMaxOverlaysParam, 8); |
| } |
| |
| bool ShouldVideoDetectorIgnoreNonVideoFrames() { |
| return base::FeatureList::IsEnabled(kVideoDetectorIgnoreNonVideos); |
| } |
| |
| bool ShouldOverrideThrottledFrameRateParams() { |
| return base::FeatureList::IsEnabled(kOverrideThrottledFrameRateParams); |
| } |
| |
| bool ShouldOnBeginFrameThrottleVideo() { |
| return base::FeatureList::IsEnabled(features::kOnBeginFrameThrottleVideo); |
| } |
| |
| bool ShouldRendererAllocateImages() { |
| return base::FeatureList::IsEnabled(kRendererAllocatesImages); |
| } |
| |
| bool IsOnBeginFrameAcksEnabled() { |
| return base::FeatureList::IsEnabled(features::kOnBeginFrameAcks); |
| } |
| |
| } // namespace features |