// 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.

#ifndef COMPONENTS_VIZ_COMMON_FEATURES_H_
#define COMPONENTS_VIZ_COMMON_FEATURES_H_

#include <optional>
#include <string>

#include "base/feature_list.h"
#include "base/metrics/field_trial_params.h"
#include "base/time/time.h"
#include "build/build_config.h"
#include "components/viz/common/viz_common_export.h"

// See the following for guidance on adding new viz feature flags:
// https://cs.chromium.org/chromium/src/components/viz/README.md#runtime-features

namespace features {

#if BUILDFLAG(IS_ANDROID)
VIZ_COMMON_EXPORT BASE_DECLARE_FEATURE(kAndroidDumpForBadCompositedUiState);
#endif  // BUILDFLAG(IS_ANDROID)
VIZ_COMMON_EXPORT BASE_DECLARE_FEATURE(kBufferQueuePerRenderPass);

// On Windows, this may interact badly with partial delegation and kBufferQueue,
// causing issues in (at least) tests. Disabled for now on this platform, while
// the underlying issue is investigated (whether it's test-only or not). Using a
// constexpr rather than a feature to prevent accidental enablement on Windows.
inline constexpr bool kAllowVizBufferQueueDiscardOnVisibilityChange =
#if BUILDFLAG(IS_WIN)
    false;
#else
    true;
#endif
VIZ_COMMON_EXPORT BASE_DECLARE_FEATURE(
    kVizBufferQueueDiscardOnVisibilityChange);

VIZ_COMMON_EXPORT bool ShouldDiscardVizBufferQueueOnVisibilityChange();

VIZ_COMMON_EXPORT BASE_DECLARE_FEATURE(kDelegatedCompositing);

#if BUILDFLAG(IS_CHROMEOS)
VIZ_COMMON_EXPORT extern const char kDrawQuadSplit[];
#endif  // BUILDFLAG(IS_CHROMEOS)

VIZ_COMMON_EXPORT BASE_DECLARE_FEATURE(kDrawQuadSplitLimit);

enum class DelegatedCompositingMode {
  // Enable delegated compositing.
  kFull,
#if BUILDFLAG(IS_WIN)
  // Enable partially delegated compositing. In this mode, the web contents will
  // be forced into its own render pass instead of merging into the root pass.
  // This effectively makes it so only the browser UI quads get delegated
  // compositing.
  kLimitToUi,
#endif
};
extern const VIZ_COMMON_EXPORT base::FeatureParam<DelegatedCompositingMode>
    kDelegatedCompositingModeParam;

#if BUILDFLAG(IS_WIN)
VIZ_COMMON_EXPORT BASE_DECLARE_FEATURE(kDCompSurfacesForDelegatedInk);
VIZ_COMMON_EXPORT BASE_DECLARE_FEATURE(kRemoveRedirectionBitmap);
VIZ_COMMON_EXPORT BASE_DECLARE_FEATURE(kBufferQueue);
#endif
VIZ_COMMON_EXPORT BASE_DECLARE_FEATURE(kUseDrmBlackFullscreenOptimization);
#if BUILDFLAG(IS_ANDROID)
VIZ_COMMON_EXPORT BASE_DECLARE_FEATURE(
    kUseFrameIntervalDeciderAdaptiveFrameRate);
VIZ_COMMON_EXPORT BASE_DECLARE_FEATURE(kCalculateDeadlineDerivedInterval);
VIZ_COMMON_EXPORT extern const base::FeatureParam<double>
    kCalculateDeadlineDerivedIntervalSnapToleranceParam;
#endif
VIZ_COMMON_EXPORT BASE_DECLARE_FEATURE(kUseMultipleOverlays);
VIZ_COMMON_EXPORT extern const char kMaxOverlaysParam[];
VIZ_COMMON_EXPORT BASE_DECLARE_FEATURE(kVizFrameSubmissionForWebView);
#if BUILDFLAG(IS_FUCHSIA)
VIZ_COMMON_EXPORT BASE_DECLARE_FEATURE(kUseSkiaOutputDeviceBufferQueue);
#endif
VIZ_COMMON_EXPORT BASE_DECLARE_FEATURE(kWebRtcLogCapturePipeline);
VIZ_COMMON_EXPORT BASE_DECLARE_FEATURE(kWebViewVulkanIntermediateBuffer);
#if BUILDFLAG(IS_ANDROID)
VIZ_COMMON_EXPORT BASE_DECLARE_FEATURE(kWebViewEnableADPF);
VIZ_COMMON_EXPORT extern const base::FeatureParam<std::string>
    kWebViewADPFSocManufacturerAllowlist;
#endif
#if BUILDFLAG(IS_APPLE)
VIZ_COMMON_EXPORT BASE_DECLARE_FEATURE(kCALayerNewLimit);
VIZ_COMMON_EXPORT extern const base::FeatureParam<int> kCALayerNewLimitDefault;
VIZ_COMMON_EXPORT extern const base::FeatureParam<int>
    kCALayerNewLimitManyVideos;
#endif

#if BUILDFLAG(IS_MAC)
VIZ_COMMON_EXPORT BASE_DECLARE_FEATURE(kVSyncAlignedPresentationForScrolling);
VIZ_COMMON_EXPORT BASE_DECLARE_FEATURE(kVSyncAlignedPresentation);
VIZ_COMMON_EXPORT BASE_DECLARE_FEATURE(kUseDisplayRefreshRateForTimer);
VIZ_COMMON_EXPORT extern const base::FeatureParam<std::string> kTargetForVSync;
VIZ_COMMON_EXPORT extern const char kTargetForVSyncAllFrames[];
VIZ_COMMON_EXPORT extern const char kTargetForVSyncAnimation[];
VIZ_COMMON_EXPORT extern const char kTargetForVSyncInteraction[];
#endif

VIZ_COMMON_EXPORT BASE_DECLARE_FEATURE(kAllowUndamagedNonrootRenderPassToSkip);

VIZ_COMMON_EXPORT BASE_DECLARE_FEATURE(kOnBeginFrameThrottleVideo);
VIZ_COMMON_EXPORT BASE_DECLARE_FEATURE(kAdpf);
VIZ_COMMON_EXPORT extern const base::FeatureParam<std::string>
    kADPFSocManufacturerAllowlist;
VIZ_COMMON_EXPORT BASE_DECLARE_FEATURE(kEnableADPFRendererMain);
VIZ_COMMON_EXPORT BASE_DECLARE_FEATURE(kEnableADPFSeparateRendererMainSession);
VIZ_COMMON_EXPORT BASE_DECLARE_FEATURE(kEnableADPFWorkloadReset);
VIZ_COMMON_EXPORT BASE_DECLARE_FEATURE(kEnableADPFScrollNoRendererMain);
VIZ_COMMON_EXPORT BASE_DECLARE_FEATURE(kEnableADPFAsyncSetThreads);
VIZ_COMMON_EXPORT BASE_DECLARE_FEATURE(kSelectFutureFrameDeadline);
VIZ_COMMON_EXPORT BASE_DECLARE_FEATURE(kAllowMultipleSwapsPerVsync);

enum class FrameDeadlineDeciderSequenceStrategy {
  kPresentationDeltaLocking = 0,
  kOsPreferredDeltaLocking = 1,
  kMaxValue = kOsPreferredDeltaLocking,
};

#if BUILDFLAG(IS_ANDROID)
VIZ_COMMON_EXPORT BASE_DECLARE_FEATURE(kUseAndroidCustomFrameDeadlines);
VIZ_COMMON_EXPORT extern const base::FeatureParam<
    FrameDeadlineDeciderSequenceStrategy>
    kAndroidCustomFrameDeadlineSequenceStrategy;
VIZ_COMMON_EXPORT extern const base::FeatureParam<int>
    kAndroidCustomFrameDeadlinePresentationOffset;
VIZ_COMMON_EXPORT extern const base::FeatureParam<base::TimeDelta>
    kAndroidCustomFrameDeadlineMaxNonInteractiveIdleDuration;
VIZ_COMMON_EXPORT extern const base::FeatureParam<base::TimeDelta>
    kAndroidCustomFrameDeadlineMaxInteractionIdleDuration;
#endif
VIZ_COMMON_EXPORT BASE_DECLARE_FEATURE(kUseDisplaySDRMaxLuminanceNits);
VIZ_COMMON_EXPORT BASE_DECLARE_FEATURE(kHideDelegatedFrameHostMac);
VIZ_COMMON_EXPORT BASE_DECLARE_FEATURE(kEvictionUnlocksResources);
VIZ_COMMON_EXPORT BASE_DECLARE_FEATURE(kSingleVideoFrameRateThrottling);
VIZ_COMMON_EXPORT BASE_DECLARE_FEATURE(kMixedFixedIntervalMatcher);

// If enabled, the FrameEvictionManager scales its limit of max number of saved
// frames dynamically based on available memory.
VIZ_COMMON_EXPORT BASE_DECLARE_FEATURE(kScalableFrameEviction);

VIZ_COMMON_EXPORT BASE_DECLARE_FEATURE(kVizDirectCompositorThreadIpcNonRoot);
VIZ_COMMON_EXPORT BASE_DECLARE_FEATURE(
    kVizDirectCompositorThreadIpcFrameSinkManager);
VIZ_COMMON_EXPORT BASE_DECLARE_FEATURE(kVizWithIoMessagePump);
VIZ_COMMON_EXPORT BASE_DECLARE_FEATURE(kVizNullHypothesis);
#if BUILDFLAG(IS_CHROMEOS)
VIZ_COMMON_EXPORT BASE_DECLARE_FEATURE(kCrosContentAdjustedRefreshRate);
#endif  // BUILDFLAG(IS_CHROMEOS)

VIZ_COMMON_EXPORT extern const char kDraw1Point12Ms[];
VIZ_COMMON_EXPORT extern const char kDraw2Points6Ms[];
VIZ_COMMON_EXPORT extern const char kDraw1Point6Ms[];
VIZ_COMMON_EXPORT extern const char kDraw2Points3Ms[];
VIZ_COMMON_EXPORT extern const char kPredictorKalman[];
VIZ_COMMON_EXPORT extern const char kPredictorLinearResampling[];
VIZ_COMMON_EXPORT extern const char kPredictorLinear1[];
VIZ_COMMON_EXPORT extern const char kPredictorLinear2[];
VIZ_COMMON_EXPORT extern const char kPredictorLsq[];

VIZ_COMMON_EXPORT BASE_DECLARE_FEATURE(kAckOnSurfaceActivationWhenInteractive);

VIZ_COMMON_EXPORT BASE_DECLARE_FEATURE(kShutdownForFailedChannelCreation);
VIZ_COMMON_EXPORT BASE_DECLARE_FEATURE(kBatchResourceRelease);
VIZ_COMMON_EXPORT BASE_DECLARE_FEATURE(kNoLateBeginFrames);
VIZ_COMMON_EXPORT BASE_DECLARE_FEATURE(kNoCompositorFrameAcks);
VIZ_COMMON_EXPORT extern const base::FeatureParam<int>
    kNumberPendingFramesUntilThrottle;
VIZ_COMMON_EXPORT BASE_DECLARE_FEATURE(kDisplaySchedulerAsClient);

VIZ_COMMON_EXPORT BASE_DECLARE_FEATURE(kRpdqFilterLookupOptimizations);

VIZ_COMMON_EXPORT BASE_DECLARE_FEATURE(kBypassOutdatedSurfaceActivation);

VIZ_COMMON_EXPORT int DrawQuadSplitLimit();
VIZ_COMMON_EXPORT bool IsRenderPassDrawQuadCullingOptimizationEnabled();
VIZ_COMMON_EXPORT bool IsDelegatedCompositingEnabled();
VIZ_COMMON_EXPORT bool IsVizDirectCompositorThreadIpcNonRootEnabled();
VIZ_COMMON_EXPORT bool IsVizDirectCompositorThreadIpcFrameSinkManagerEnabled();
VIZ_COMMON_EXPORT bool IsVizWithIoMessagePumpEnabled();
#if BUILDFLAG(IS_WIN)
VIZ_COMMON_EXPORT bool ShouldRemoveRedirectionBitmap();
#endif
VIZ_COMMON_EXPORT bool IsUsingVizFrameSubmissionForWebView();
VIZ_COMMON_EXPORT bool IsUsingPreferredIntervalForVideo();
VIZ_COMMON_EXPORT bool IsMixedFixedIntervalMatcherEnabled();
VIZ_COMMON_EXPORT bool ShouldWebRtcLogCapturePipeline();
VIZ_COMMON_EXPORT int MaxOverlaysConsidered();
VIZ_COMMON_EXPORT bool ShouldOnBeginFrameThrottleVideo();
VIZ_COMMON_EXPORT bool IsVSyncAlignedForScrolling();
VIZ_COMMON_EXPORT bool IsVSyncAligned();
VIZ_COMMON_EXPORT std::optional<uint64_t>
NumCooldownFramesForAckOnSurfaceActivationDuringInteraction();
VIZ_COMMON_EXPORT extern const base::FeatureParam<int>
    kNumCooldownFramesForAckOnSurfaceActivationDuringInteraction;
VIZ_COMMON_EXPORT bool ShouldAckOnSurfaceActivationWhenInteractive();
#if BUILDFLAG(IS_CHROMEOS)
VIZ_COMMON_EXPORT bool IsCrosContentAdjustedRefreshRateEnabled();
#endif  // BUILDFLAG(IS_CHROMEOS)
#if BUILDFLAG(IS_ANDROID)
VIZ_COMMON_EXPORT bool IsBrowserControlsInVizEnabled();

// If the allowlist is non-empty, the soc must be in the allowlist. Blocklist
// is ignored in this case.
// If the allowlist is empty, soc must be absent from the blocklist.
VIZ_COMMON_EXPORT bool ShouldUseAdpfForSoc(std::string_view soc_allowlist,
                                           std::string_view soc);

#endif  // BUILDFLAG(IS_ANDROID)

}  // namespace features

#endif  // COMPONENTS_VIZ_COMMON_FEATURES_H_
