diff --git a/components/viz/client/frame_eviction_manager.cc b/components/viz/client/frame_eviction_manager.cc index bc70b77c6603cf0c376346b18f26a51cf85da2f5..8a722b997be8ca21467db9ea5856b945d766631b 100644 --- a/components/viz/client/frame_eviction_manager.cc +++ b/components/viz/client/frame_eviction_manager.cc @@ -105,7 +105,7 @@ void FrameEvictionManager::RegisterUnlockedFrame( // Unretained: `idle_frames_culling_timer_` is a member of `this`, doesn't // outlive it, and cancels the task in its destructor. idle_frames_culling_timer_.Start( - FROM_HERE, kPeriodicCullingDelay, + FROM_HERE, features::kAggressiveFrameCullingDelay.Get(), base::BindRepeating(&FrameEvictionManager::CullOldUnlockedFrames, base::Unretained(this))); } @@ -161,7 +161,13 @@ FrameEvictionManager::FrameEvictionManager() switches::kMaxNumberOfSavedFrames)) { max_number_of_saved_frames_ = kMaxNumberOfSavedFrames; } +#endif +#if BUILDFLAG(IS_OHOS) + if (base::FeatureList::IsEnabled(features::kExplicitFrameCullingLimit)) { + max_number_of_saved_frames_ = + std::max(1, features::kExplicitFrameCullingLimitMaxCount.Get()); + } #endif } @@ -193,7 +199,8 @@ void FrameEvictionManager::CullOldUnlockedFrames() { auto now = clock_->NowTicks(); while (!unlocked_frames_.empty() && - now - unlocked_frames_.back().second >= kPeriodicCullingDelay) { + now - unlocked_frames_.back().second >= + features::kAggressiveFrameCullingDelay.Get()) { size_t old_size = unlocked_frames_.size(); auto* frame = unlocked_frames_.back().first; frame->EvictCurrentFrame(); diff --git a/components/viz/common/features.cc b/components/viz/common/features.cc index ebc18015f28128d32566c0486a3343edc42c66fc..8b1908aab7a7dd48e41ca3d62c4790b85bba9665 100644 --- a/components/viz/common/features.cc +++ b/components/viz/common/features.cc @@ -197,6 +197,8 @@ BASE_FEATURE(kAllowUndamagedNonrootRenderPassToSkip, BASE_FEATURE(kAggressiveFrameCulling, "AggressiveFrameCulling", base::FEATURE_ENABLED_BY_DEFAULT); +const base::FeatureParam kAggressiveFrameCullingDelay{ + &kAggressiveFrameCulling, "delay", base::Minutes(5)}; // If enabled, do not rely on surface garbage collection to happen // periodically, but trigger it eagerly, to avoid missing calls. @@ -259,6 +261,23 @@ BASE_FEATURE(kOnBeginFrameAllowLateAcks, "OnBeginFrameAllowLateAcks", base::FEATURE_DISABLED_BY_DEFAULT); +#if BUILDFLAG(IS_OHOS) +// If enabled, define explicit culling limit for *all* frames. +BASE_FEATURE(kExplicitFrameCullingLimit, + "ExplicitFrameCullingLimit", + base::FEATURE_DISABLED_BY_DEFAULT); +const base::FeatureParam kExplicitFrameCullingLimitMaxCount{ + &kExplicitFrameCullingLimit, "max-count", 10}; + +// If enabled, wait to activate a surface with dependencies on the first frame +// drawing with specified deadline. +BASE_FEATURE(kFirstFrameActivationDeadline, + "FirstFrameActivationDeadline", + base::FEATURE_ENABLED_BY_DEFAULT); +const base::FeatureParam kFirstFrameActivationDeadlineTimeout{ + &kFirstFrameActivationDeadline, "timeout", base::Seconds(5)}; +#endif + bool IsDelegatedCompositingEnabled() { return base::FeatureList::IsEnabled(kDelegatedCompositing); } diff --git a/components/viz/common/features.h b/components/viz/common/features.h index 2fc330a4412b1f9044bdd6d65b5d054daa760630..15b6f52c1a735f0c3b72d4f4c4980f16aaf781ef 100644 --- a/components/viz/common/features.h +++ b/components/viz/common/features.h @@ -59,6 +59,8 @@ VIZ_COMMON_EXPORT BASE_DECLARE_FEATURE(kDrawPredictedInkPoint); VIZ_COMMON_EXPORT BASE_DECLARE_FEATURE(kAllowBypassRenderPassQuads); VIZ_COMMON_EXPORT BASE_DECLARE_FEATURE(kAllowUndamagedNonrootRenderPassToSkip); VIZ_COMMON_EXPORT BASE_DECLARE_FEATURE(kAggressiveFrameCulling); +VIZ_COMMON_EXPORT extern const base::FeatureParam + kAggressiveFrameCullingDelay; VIZ_COMMON_EXPORT BASE_DECLARE_FEATURE(kEagerSurfaceGarbageCollection); VIZ_COMMON_EXPORT BASE_DECLARE_FEATURE(kOverrideThrottledFrameRateParams); VIZ_COMMON_EXPORT BASE_DECLARE_FEATURE(kRendererAllocatesImages); @@ -67,6 +69,15 @@ VIZ_COMMON_EXPORT BASE_DECLARE_FEATURE(kEvictSubtree); VIZ_COMMON_EXPORT BASE_DECLARE_FEATURE(kOnBeginFrameAcks); VIZ_COMMON_EXPORT BASE_DECLARE_FEATURE(kOnBeginFrameAllowLateAcks); +#if BUILDFLAG(IS_OHOS) +VIZ_COMMON_EXPORT BASE_DECLARE_FEATURE(kExplicitFrameCullingLimit); +VIZ_COMMON_EXPORT extern const base::FeatureParam + kExplicitFrameCullingLimitMaxCount; +VIZ_COMMON_EXPORT BASE_DECLARE_FEATURE(kFirstFrameActivationDeadline); +VIZ_COMMON_EXPORT extern const base::FeatureParam + kFirstFrameActivationDeadlineTimeout; +#endif + VIZ_COMMON_EXPORT extern const char kDraw1Point12Ms[]; VIZ_COMMON_EXPORT extern const char kDraw2Points6Ms[]; VIZ_COMMON_EXPORT extern const char kDraw1Point6Ms[]; diff --git a/components/viz/common/frame_sinks/begin_frame_source.cc b/components/viz/common/frame_sinks/begin_frame_source.cc index 2a33b47794ae90c09c728bf8cfde3e83ba725946..ac92c8bbcc7fe66c78f941fdd51805b617d2cdc7 100644 --- a/components/viz/common/frame_sinks/begin_frame_source.cc +++ b/components/viz/common/frame_sinks/begin_frame_source.cc @@ -491,10 +491,9 @@ void ExternalBeginFrameSource::OnBeginFrame(const BeginFrameArgs& args) { return; } - TRACE_EVENT2( - "viz", "ExternalBeginFrameSource::OnBeginFrame", "frame_time", - last_begin_frame_args_.frame_time.since_origin().InMicroseconds(), - "interval", last_begin_frame_args_.interval.InMicroseconds()); + TRACE_EVENT2("viz", "ExternalBeginFrameSource::OnBeginFrame", "frame_time", + args.frame_time.since_origin().InMicroseconds(), "interval", + args.interval.InMicroseconds()); last_begin_frame_args_ = args; base::flat_set observers(observers_); diff --git a/components/viz/service/frame_sinks/external_begin_frame_source_ohos.cc b/components/viz/service/frame_sinks/external_begin_frame_source_ohos.cc index d37717a485f144c5cae2ac0a4554e73cee6c86b0..3ce2f59504f18556a8d473e1728115c741c47988 100644 --- a/components/viz/service/frame_sinks/external_begin_frame_source_ohos.cc +++ b/components/viz/service/frame_sinks/external_begin_frame_source_ohos.cc @@ -229,6 +229,30 @@ ReportLossFrame::GetInstance()->SetVsyncPeriod(vsync_period_); } } +BeginFrameArgs ExternalBeginFrameSourceOHOS::GetMissedBeginFrameArgs( + BeginFrameObserver* obs) { + auto frame_time = last_begin_frame_args_.frame_time; + auto interval = last_begin_frame_args_.interval; + auto now = base::TimeTicks::Now(); + + if (last_begin_frame_args_.IsValid()) { + frame_time = now.SnappedToNextTick(frame_time, interval) - interval; + } else { + // Create BeginFrameArgs for now so that we don't have to wait until vsync. + frame_time = now; + interval = BeginFrameArgs::DefaultInterval(); + } + + // Don't create new args unless we've actually moved past the previous frame. + if (!last_begin_frame_args_.IsValid() || + frame_time > last_begin_frame_args_.frame_time) { + last_begin_frame_args_ = begin_frame_args_generator_.GenerateBeginFrameArgs( + source_id(), frame_time, frame_time + interval, interval); + } + + return ExternalBeginFrameSource::GetMissedBeginFrameArgs(obs); +} + void ExternalBeginFrameSourceOHOS::OnNeedsBeginFrames(bool needs_begin_frames) { SetEnabled(needs_begin_frames); } diff --git a/components/viz/service/frame_sinks/external_begin_frame_source_ohos.h b/components/viz/service/frame_sinks/external_begin_frame_source_ohos.h index e56bf67ed6ac4642af5f78874c50a93f7d0429b7..7cb13046345f933bf01c53eeb632132a960717c1 100644 --- a/components/viz/service/frame_sinks/external_begin_frame_source_ohos.h +++ b/components/viz/service/frame_sinks/external_begin_frame_source_ohos.h @@ -63,6 +63,9 @@ class VIZ_SERVICE_EXPORT ExternalBeginFrameSourceOHOS void ResetVSyncFrequency() override; private: + // ExternalBeginFrameSource overrides. + BeginFrameArgs GetMissedBeginFrameArgs(BeginFrameObserver* obs) override; + // ExternalBeginFrameSourceClient implementation. void OnNeedsBeginFrames(bool needs_begin_frames) override; diff --git a/components/viz/service/surfaces/surface.cc b/components/viz/service/surfaces/surface.cc index 499c90315501dbf83792a8464441a422bf4e02f3..e7282a7b0e6624f4d16da11ecd041e00b4a9d7c5 100644 --- a/components/viz/service/surfaces/surface.cc +++ b/components/viz/service/surfaces/surface.cc @@ -354,6 +354,10 @@ void Surface::OnActivationDependencyResolved( blocking_allocation_groups_.erase(group); if (!activation_dependencies_.empty()) return; + + TRACE_EVENT_NESTABLE_ASYNC_END0("viz", "SurfaceQueuedPending", + TRACE_ID_LOCAL(this)); + // All blockers have been cleared. The surface can be activated now. ActivatePendingFrame(); } diff --git a/content/browser/renderer_host/delegated_frame_host.cc b/content/browser/renderer_host/delegated_frame_host.cc index 65766e9570eaf235d49137e4436f6b58c332676c..7b5062a2839c558f654bdeaba9f9a309dfa10d9f 100644 --- a/content/browser/renderer_host/delegated_frame_host.cc +++ b/content/browser/renderer_host/delegated_frame_host.cc @@ -39,6 +39,21 @@ namespace { // factor. constexpr float kFrameContentCaptureQuality = 0.4f; +#if BUILDFLAG(IS_OHOS) +cc::DeadlinePolicy FirstFrameDeadlinePolicy() { + if (base::FeatureList::IsEnabled( + features::kFirstFrameActivationDeadline)) { + // Wait up to deadline timeout for the first frame to be produced. + int64_t deadline_in_frames = base::ClampRound( + features::kFirstFrameActivationDeadlineTimeout.Get() / + viz::BeginFrameArgs::DefaultInterval()); + return cc::DeadlinePolicy::UseSpecifiedDeadline(deadline_in_frames); + } + + return cc::DeadlinePolicy::UseDefaultDeadline(); +} +#endif + } // namespace //////////////////////////////////////////////////////////////////////////////// @@ -96,10 +111,16 @@ void DelegatedFrameHost::WasShown( std::move(record_tab_switch_time_request))); } +#if BUILDFLAG(IS_OHOS) + // Use the specified deadline to synchronize web content with browser UI. + EmbedSurface( + new_local_surface_id, new_dip_size, FirstFrameDeadlinePolicy()); +#else // Use the default deadline to synchronize web content with browser UI. // TODO(fsamuel): Investigate if there is a better deadline to use here. EmbedSurface(new_local_surface_id, new_dip_size, cc::DeadlinePolicy::UseDefaultDeadline()); +#endif // Remove stale content that might be displayed. if (stale_content_layer_->has_external_content()) {