diff options
Diffstat (limited to 'chromium/third_party/blink/renderer/platform/scheduler/main_thread')
29 files changed, 1045 insertions, 964 deletions
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/compositor_priority_experiments.cc b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/compositor_priority_experiments.cc index 8564cbca5b1..f755622d8dc 100644 --- a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/compositor_priority_experiments.cc +++ b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/compositor_priority_experiments.cc @@ -15,17 +15,14 @@ CompositorPriorityExperiments::CompositorPriorityExperiments( MainThreadSchedulerImpl* scheduler) : scheduler_(scheduler), experiment_(GetExperimentFromFeatureList()), + last_compositor_task_time_(scheduler_->GetTickClock()->NowTicks()), prioritize_compositing_after_delay_length_( base::TimeDelta::FromMilliseconds(kCompositingDelayLength.Get())), stop_signal_(base::FeatureList::IsEnabled( kPrioritizeCompositingUntilBeginMainFrame) ? StopSignalType::kBeginMainFrameTask - : StopSignalType::kAnyCompositorTask) { - do_prioritize_compositing_after_delay_callback_.Reset(base::BindRepeating( - &CompositorPriorityExperiments::DoPrioritizeCompositingAfterDelay, - base::Unretained(this))); -} -CompositorPriorityExperiments::~CompositorPriorityExperiments() {} + : StopSignalType::kAnyCompositorTask) {} +CompositorPriorityExperiments::~CompositorPriorityExperiments() = default; CompositorPriorityExperiments::Experiment CompositorPriorityExperiments::GetExperimentFromFeatureList() { @@ -38,11 +35,11 @@ CompositorPriorityExperiments::GetExperimentFromFeatureList() { kVeryHighPriorityForCompositingAlternating)) { return Experiment::kVeryHighPriorityForCompositingAlternating; } else if (base::FeatureList::IsEnabled( - kVeryHighPriorityForCompositingAfterDelay)) { - return Experiment::kVeryHighPriorityForCompositingAfterDelay; - } else if (base::FeatureList::IsEnabled( kVeryHighPriorityForCompositingBudget)) { return Experiment::kVeryHighPriorityForCompositingBudget; + } else if (base::FeatureList::IsEnabled( + kVeryHighPriorityForCompositingAfterDelay)) { + return Experiment::kVeryHighPriorityForCompositingAfterDelay; } else { return Experiment::kNone; } @@ -75,15 +72,7 @@ QueuePriority CompositorPriorityExperiments::GetCompositorPriority() const { } } -void CompositorPriorityExperiments::DoPrioritizeCompositingAfterDelay() { - delay_compositor_priority_ = QueuePriority::kVeryHighPriority; - scheduler_->OnCompositorPriorityExperimentUpdateCompositorPriority(); -} - void CompositorPriorityExperiments::OnMainThreadSchedulerInitialized() { - if (experiment_ == Experiment::kVeryHighPriorityForCompositingAfterDelay) { - PostPrioritizeCompositingAfterDelayTask(); - } if (experiment_ == Experiment::kVeryHighPriorityForCompositingBudget) { budget_pool_controller_.reset(new CompositorBudgetPoolController( this, scheduler_, scheduler_->CompositorTaskQueue().get(), @@ -102,14 +91,6 @@ void CompositorPriorityExperiments::OnWillBeginMainFrame() { will_begin_main_frame_ = true; } -void CompositorPriorityExperiments::PostPrioritizeCompositingAfterDelayTask() { - DCHECK_EQ(experiment_, Experiment::kVeryHighPriorityForCompositingAfterDelay); - - scheduler_->ControlTaskRunner()->PostDelayedTask( - FROM_HERE, do_prioritize_compositing_after_delay_callback_.GetCallback(), - prioritize_compositing_after_delay_length_); -} - void CompositorPriorityExperiments::OnTaskCompleted( MainThreadTaskQueue* queue, QueuePriority current_compositor_priority, @@ -150,12 +131,15 @@ void CompositorPriorityExperiments::OnTaskCompleted( case Experiment::kVeryHighPriorityForCompositingAfterDelay: if (have_seen_stop_signal) { delay_compositor_priority_ = QueuePriority::kNormalPriority; - do_prioritize_compositing_after_delay_callback_.Cancel(); - PostPrioritizeCompositingAfterDelayTask(); - - if (current_compositor_priority != delay_compositor_priority_) - scheduler_->OnCompositorPriorityExperimentUpdateCompositorPriority(); + last_compositor_task_time_ = task_timing->end_time(); + } else { + if (task_timing->end_time() - last_compositor_task_time_ >= + prioritize_compositing_after_delay_length_) { + delay_compositor_priority_ = QueuePriority::kVeryHighPriority; + } } + if (current_compositor_priority != delay_compositor_priority_) + scheduler_->OnCompositorPriorityExperimentUpdateCompositorPriority(); return; case Experiment::kVeryHighPriorityForCompositingBudget: budget_pool_controller_->OnTaskCompleted(queue, task_timing, @@ -188,7 +172,7 @@ CompositorPriorityExperiments::CompositorBudgetPoolController:: TraceableVariableController* tracing_controller, base::TimeDelta min_budget, double budget_recovery_rate) - : experiment_(experiment), tick_clock_(scheduler->GetTickClock()) { + : experiment_(experiment) { DCHECK_EQ(compositor_queue->queue_type(), MainThreadTaskQueue::QueueType::kCompositor); base::TimeTicks now = scheduler->GetTickClock()->NowTicks(); diff --git a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/compositor_priority_experiments.h b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/compositor_priority_experiments.h index bb034bf4713..725d31d8f3f 100644 --- a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/compositor_priority_experiments.h +++ b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/compositor_priority_experiments.h @@ -93,16 +93,10 @@ class PLATFORM_EXPORT CompositorPriorityExperiments { CompositorPriorityExperiments* experiment_; std::unique_ptr<CPUTimeBudgetPool> compositor_budget_pool_; bool is_exhausted_ = false; - - const base::TickClock* tick_clock_; // Not owned. }; static Experiment GetExperimentFromFeatureList(); - void DoPrioritizeCompositingAfterDelay(); - - void PostPrioritizeCompositingAfterDelayTask(); - enum class StopSignalType { kAnyCompositorTask, kBeginMainFrameTask }; MainThreadSchedulerImpl* scheduler_; // Not owned. @@ -113,7 +107,7 @@ class PLATFORM_EXPORT CompositorPriorityExperiments { QueuePriority::kVeryHighPriority; QueuePriority delay_compositor_priority_ = QueuePriority::kNormalPriority; - CancelableClosureHolder do_prioritize_compositing_after_delay_callback_; + base::TimeTicks last_compositor_task_time_; base::TimeDelta prioritize_compositing_after_delay_length_; QueuePriority budget_compositor_priority_ = QueuePriority::kVeryHighPriority; diff --git a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/find_in_page_budget_pool_controller.cc b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/find_in_page_budget_pool_controller.cc new file mode 100644 index 00000000000..3fc1cfd2f2b --- /dev/null +++ b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/find_in_page_budget_pool_controller.cc @@ -0,0 +1,87 @@ +// Copyright 2020 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. + +#include "third_party/blink/renderer/platform/scheduler/main_thread/find_in_page_budget_pool_controller.h" + +#include "third_party/blink/renderer/platform/scheduler/common/features.h" +#include "third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.h" +#include "third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.h" + +namespace blink { +namespace scheduler { + +namespace { +// We will accumulate at most 1000ms for find-in-page budget. +constexpr base::TimeDelta kFindInPageMaxBudget = + base::TimeDelta::FromSeconds(1); +// At least 25% of the total CPU time will go to find-in-page tasks. +// TODO(rakina): Experiment with this number to figure out the right percentage +// for find-in-page. Currently this is following CompositorPriorityExperiments. +const double kFindInPageBudgetRecoveryRate = 0.25; +} // namespace + +const QueuePriority + FindInPageBudgetPoolController::kFindInPageBudgetNotExhaustedPriority; +const QueuePriority + FindInPageBudgetPoolController::kFindInPageBudgetExhaustedPriority; + +FindInPageBudgetPoolController::FindInPageBudgetPoolController( + MainThreadSchedulerImpl* scheduler) + : scheduler_(scheduler), + best_effort_budget_experiment_enabled_( + base::FeatureList::IsEnabled(kBestEffortPriorityForFindInPage)) { + if (best_effort_budget_experiment_enabled_) { + task_priority_ = QueuePriority::kBestEffortPriority; + } else { + task_priority_ = kFindInPageBudgetNotExhaustedPriority; + } +} + +FindInPageBudgetPoolController::~FindInPageBudgetPoolController() = default; + +void FindInPageBudgetPoolController::EnsureBudgetPoolInitialized() { + DCHECK(!best_effort_budget_experiment_enabled_); + if (find_in_page_budget_pool_) + return; + base::TimeTicks now = scheduler_->GetTickClock()->NowTicks(); + find_in_page_budget_pool_.reset(new CPUTimeBudgetPool( + "FindInPageBudgetPool", this, &scheduler_->tracing_controller_, now)); + // Set no minimum budget for find-in-page, so that we won't delay running + // find-in-page tasks when budget is available. + find_in_page_budget_pool_->SetMinBudgetLevelToRun(now, base::TimeDelta()); + find_in_page_budget_pool_->SetMaxBudgetLevel(now, kFindInPageMaxBudget); + find_in_page_budget_pool_->SetTimeBudgetRecoveryRate( + now, kFindInPageBudgetRecoveryRate); +} + +void FindInPageBudgetPoolController::OnTaskCompleted( + MainThreadTaskQueue* queue, + TaskQueue::TaskTiming* task_timing) { + if (!queue || best_effort_budget_experiment_enabled_) + return; + EnsureBudgetPoolInitialized(); + if (queue->GetPrioritisationType() == + MainThreadTaskQueue::QueueTraits::PrioritisationType::kFindInPage) { + find_in_page_budget_pool_->RecordTaskRunTime( + queue, task_timing->start_time(), task_timing->end_time()); + } + + bool is_exhausted = !find_in_page_budget_pool_->CanRunTasksAt( + task_timing->end_time(), false /* is_wake_up */); + QueuePriority task_priority = is_exhausted + ? kFindInPageBudgetExhaustedPriority + : kFindInPageBudgetNotExhaustedPriority; + + if (task_priority != task_priority_) { + task_priority_ = task_priority; + // If the priority changed, we need to make sure all find-in-page task + // queues across all frames get updated. Note that UpdatePolicy will + // update all task queues for all frames, which is a bit overkill - this + // should probably be optimized in the future. + scheduler_->UpdatePolicy(); + } +} + +} // namespace scheduler +} // namespace blink diff --git a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/find_in_page_budget_pool_controller.h b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/find_in_page_budget_pool_controller.h new file mode 100644 index 00000000000..5fd8f296d48 --- /dev/null +++ b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/find_in_page_budget_pool_controller.h @@ -0,0 +1,67 @@ +// Copyright 2020 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 THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_MAIN_THREAD_FIND_IN_PAGE_BUDGET_POOL_CONTROLLER_H_ +#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_MAIN_THREAD_FIND_IN_PAGE_BUDGET_POOL_CONTROLLER_H_ + +#include "base/task/sequence_manager/task_queue.h" +#include "third_party/blink/renderer/platform/platform_export.h" +#include "third_party/blink/renderer/platform/scheduler/common/throttling/budget_pool_controller.h" +#include "third_party/blink/renderer/platform/scheduler/common/throttling/cpu_time_budget_pool.h" +#include "third_party/blink/renderer/platform/scheduler/main_thread/main_thread_task_queue.h" + +namespace blink { +namespace scheduler { + +using TaskQueue = base::sequence_manager::TaskQueue; +using QueuePriority = base::sequence_manager::TaskQueue::QueuePriority; + +class CPUTimeBudgetPool; +class MainThreadSchedulerImpl; + +class PLATFORM_EXPORT FindInPageBudgetPoolController + : public BudgetPoolController { + public: + static constexpr auto kFindInPageBudgetNotExhaustedPriority = + QueuePriority::kVeryHighPriority; + static constexpr auto kFindInPageBudgetExhaustedPriority = + QueuePriority::kNormalPriority; + + explicit FindInPageBudgetPoolController(MainThreadSchedulerImpl* scheduler); + ~FindInPageBudgetPoolController() override; + + void OnTaskCompleted(MainThreadTaskQueue* queue, + MainThreadTaskQueue::TaskTiming* task_timing); + + QueuePriority CurrentTaskPriority() { return task_priority_; } + + // Unimplemented methods. + // TODO(crbug.com/1056512): Remove these functions once we factor out the + // budget calculating logic from BudgetPoolController. + void UpdateQueueSchedulingLifecycleState(base::TimeTicks now, + TaskQueue* queue) override {} + void AddQueueToBudgetPool(TaskQueue* queue, + BudgetPool* budget_pool) override {} + void RemoveQueueFromBudgetPool(TaskQueue* queue, + BudgetPool* budget_pool) override {} + void UnregisterBudgetPool(BudgetPool* budget_pool) override {} + bool IsThrottled(TaskQueue* queue) const override { return false; } + + private: + // We need to call this from OnTaskCompleted, because PartitionAlloc might not + // be initialized yet when we got constructed. + // TODO(crbug.com/1058645): Initialize |find_in_page_budget_pool_| from the + // constructor and remove this function. + void EnsureBudgetPoolInitialized(); + + MainThreadSchedulerImpl* scheduler_; // Not owned. + std::unique_ptr<CPUTimeBudgetPool> find_in_page_budget_pool_; + QueuePriority task_priority_; + const bool best_effort_budget_experiment_enabled_; +}; + +} // namespace scheduler +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_MAIN_THREAD_FIND_IN_PAGE_BUDGET_POOL_CONTROLLER_H_ diff --git a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/frame_origin_type.cc b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/frame_origin_type.cc index fa4f2fc7761..631724eda29 100644 --- a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/frame_origin_type.cc +++ b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/frame_origin_type.cc @@ -16,10 +16,10 @@ FrameOriginType GetFrameOriginType(FrameScheduler* scheduler) { if (scheduler->GetFrameType() == FrameScheduler::FrameType::kMainFrame) return FrameOriginType::kMainFrame; - if (scheduler->IsCrossOrigin()) { - return FrameOriginType::kCrossOriginFrame; + if (scheduler->IsCrossOriginToMainFrame()) { + return FrameOriginType::kCrossOriginToMainFrame; } else { - return FrameOriginType::kSameOriginFrame; + return FrameOriginType::kSameOriginToMainFrame; } } @@ -27,10 +27,10 @@ const char* FrameOriginTypeToString(FrameOriginType origin) { switch (origin) { case FrameOriginType::kMainFrame: return "main-frame"; - case FrameOriginType::kSameOriginFrame: - return "same-origin"; - case FrameOriginType::kCrossOriginFrame: - return "cross-origin"; + case FrameOriginType::kSameOriginToMainFrame: + return "same-origin-to-main-frame"; + case FrameOriginType::kCrossOriginToMainFrame: + return "cross-origin-to-main-frame"; case FrameOriginType::kCount: NOTREACHED(); } diff --git a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/frame_origin_type.h b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/frame_origin_type.h index 4739e0e0fac..573ba2f4afd 100644 --- a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/frame_origin_type.h +++ b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/frame_origin_type.h @@ -14,9 +14,10 @@ namespace scheduler { // and should not be renumbered. enum class FrameOriginType { kMainFrame = 0, - kSameOriginFrame = 1, - kCrossOriginFrame = 2, - kCount = 3 + kSameOriginToMainFrame = 1, + kCrossOriginToMainFrame = 2, + // TODO(dcheng): Get rid of this and use the kMaxValue idiom. + kCount = 3, }; FrameOriginType GetFrameOriginType(FrameScheduler* frame_scheduler); diff --git a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.cc b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.cc index 0e52953485d..2f15127c778 100644 --- a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.cc +++ b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.cc @@ -10,6 +10,7 @@ #include "base/metrics/histogram_macros.h" #include "base/trace_event/blame_context.h" #include "third_party/blink/public/common/features.h" +#include "third_party/blink/public/common/scheduler/web_scheduler_tracked_feature.h" #include "third_party/blink/public/platform/blame_context.h" #include "third_party/blink/public/platform/web_string.h" #include "third_party/blink/renderer/platform/runtime_enabled_features.h" @@ -17,6 +18,7 @@ #include "third_party/blink/renderer/platform/scheduler/common/throttling/budget_pool.h" #include "third_party/blink/renderer/platform/scheduler/common/tracing_helper.h" #include "third_party/blink/renderer/platform/scheduler/main_thread/auto_advancing_virtual_time_domain.h" +#include "third_party/blink/renderer/platform/scheduler/main_thread/find_in_page_budget_pool_controller.h" #include "third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.h" #include "third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl.h" #include "third_party/blink/renderer/platform/scheduler/main_thread/page_visibility_state.h" @@ -77,45 +79,6 @@ void UpdatePriority(MainThreadTaskQueue* task_queue) { task_queue->SetQueuePriority(frame_scheduler->ComputePriority(task_queue)); } -// Extract a substring from |source| from [start to end), trimming leading -// whitespace. -String ExtractAndTrimString(String source, size_t start, size_t end) { - DCHECK(start < source.length()); - DCHECK(end <= source.length()); - DCHECK(start <= end); - // Trim whitespace - while (start < end && source[start] == ' ') - ++start; - if (start < end) - return source.Substring(start, end - start); - return ""; -} - -HashSet<String> TaskTypesFromFieldTrialParam(const char* param) { - HashSet<String> result; - String task_type_list = - String::FromUTF8(base::GetFieldTrialParamValueByFeature( - kThrottleAndFreezeTaskTypes, param)); - if (!task_type_list.length()) - return result; - // Extract the individual names, separated by ",". - size_t pos = 0, start = 0; - while ((pos = task_type_list.find(',', start)) != kNotFound) { - String task_type = ExtractAndTrimString(task_type_list, start, pos); - // Not valid to start with "," or have ",," in the list. - DCHECK(task_type.length()); - result.insert(task_type); - start = pos + 1; - } - // Handle the last or only task type name. - String task_type = - ExtractAndTrimString(task_type_list, start, task_type_list.length()); - DCHECK(task_type.length()); - result.insert(task_type); - - return result; -} - } // namespace FrameSchedulerImpl::PauseSubresourceLoadingHandleImpl:: @@ -169,7 +132,7 @@ FrameSchedulerImpl::FrameSchedulerImpl( PausedStateToString), frame_origin_type_(frame_type == FrameType::kMainFrame ? FrameOriginType::kMainFrame - : FrameOriginType::kSameOriginFrame, + : FrameOriginType::kSameOriginToMainFrame, "FrameScheduler.Origin", this, &tracing_controller_, @@ -321,16 +284,16 @@ bool FrameSchedulerImpl::IsFrameVisible() const { return frame_visible_; } -void FrameSchedulerImpl::SetCrossOrigin(bool cross_origin) { +void FrameSchedulerImpl::SetCrossOriginToMainFrame(bool cross_origin) { DCHECK(parent_page_scheduler_); if (frame_origin_type_ == FrameOriginType::kMainFrame) { DCHECK(!cross_origin); return; } if (cross_origin) { - frame_origin_type_ = FrameOriginType::kCrossOriginFrame; + frame_origin_type_ = FrameOriginType::kCrossOriginToMainFrame; } else { - frame_origin_type_ = FrameOriginType::kSameOriginFrame; + frame_origin_type_ = FrameOriginType::kSameOriginToMainFrame; } UpdatePolicy(); } @@ -344,8 +307,8 @@ bool FrameSchedulerImpl::IsAdFrame() const { return is_ad_frame_; } -bool FrameSchedulerImpl::IsCrossOrigin() const { - return frame_origin_type_ == FrameOriginType::kCrossOriginFrame; +bool FrameSchedulerImpl::IsCrossOriginToMainFrame() const { + return frame_origin_type_ == FrameOriginType::kCrossOriginToMainFrame; } void FrameSchedulerImpl::TraceUrlChange(const String& url) { @@ -370,42 +333,8 @@ FrameScheduler::FrameType FrameSchedulerImpl::GetFrameType() const { return frame_type_; } -void FrameSchedulerImpl::InitializeTaskTypeQueueTraitsMap( - FrameTaskTypeToQueueTraitsArray& frame_task_types_to_queue_traits) { - DCHECK_EQ(frame_task_types_to_queue_traits.size(), - static_cast<size_t>(TaskType::kCount)); - // Using std set and strings here because field trial parameters are std - // strings, and we cannot use WTF strings as Blink is not yet initialized. - HashSet<String> throttleable_task_type_names; - HashSet<String> freezable_task_type_names; - if (base::FeatureList::IsEnabled(kThrottleAndFreezeTaskTypes)) { - throttleable_task_type_names = - TaskTypesFromFieldTrialParam(kThrottleableTaskTypesListParam); - freezable_task_type_names = - TaskTypesFromFieldTrialParam(kFreezableTaskTypesListParam); - } - for (size_t i = 0; i < static_cast<size_t>(TaskType::kCount); i++) { - TaskType type = static_cast<TaskType>(i); - base::Optional<QueueTraits> queue_traits = - CreateQueueTraitsForTaskType(type); - if (queue_traits && (!throttleable_task_type_names.IsEmpty() || - !freezable_task_type_names.IsEmpty())) { - const char* task_type_name = TaskTypeNames::TaskTypeToString(type); - if (!throttleable_task_type_names.Take(task_type_name).IsEmpty()) - queue_traits->SetCanBeThrottled(true); - if (freezable_task_type_names.Take(task_type_name).IsEmpty()) - queue_traits->SetCanBeFrozen(true); - } - frame_task_types_to_queue_traits[i] = queue_traits; - } - // Protect against configuration errors. - DCHECK(throttleable_task_type_names.IsEmpty()); - DCHECK(freezable_task_type_names.IsEmpty()); -} - // static -base::Optional<QueueTraits> FrameSchedulerImpl::CreateQueueTraitsForTaskType( - TaskType type) { +QueueTraits FrameSchedulerImpl::CreateQueueTraitsForTaskType(TaskType type) { // TODO(haraken): Optimize the mapping from TaskTypes to task runners. // TODO(sreejakshetty): Clean up the PrioritisationType QueueTrait and // QueueType for kInternalContinueScriptLoading and kInternalContentCapture. @@ -464,13 +393,15 @@ base::Optional<QueueTraits> FrameSchedulerImpl::CreateQueueTraitsForTaskType( case TaskType::kInternalUserInteraction: case TaskType::kInternalIntersectionObserver: return PausableTaskQueueTraits(); + case TaskType::kInternalFindInPage: + return FindInPageTaskQueueTraits(); case TaskType::kInternalContinueScriptLoading: return PausableTaskQueueTraits().SetPrioritisationType( QueueTraits::PrioritisationType::kVeryHigh); case TaskType::kDatabaseAccess: if (base::FeatureList::IsEnabled(kHighPriorityDatabaseTaskType)) { return PausableTaskQueueTraits().SetPrioritisationType( - QueueTraits::PrioritisationType::kHigh); + QueueTraits::PrioritisationType::kExperimentalDatabase); } else { return PausableTaskQueueTraits(); } @@ -508,19 +439,22 @@ base::Optional<QueueTraits> FrameSchedulerImpl::CreateQueueTraitsForTaskType( case TaskType::kWorkerThreadTaskQueueDefault: case TaskType::kWorkerThreadTaskQueueV8: case TaskType::kWorkerThreadTaskQueueCompositor: + case TaskType::kMainThreadTaskQueueNonWaking: // The web scheduling API task types are used by WebSchedulingTaskQueues. // The associated TaskRunner should be obtained by creating a // WebSchedulingTaskQueue with CreateWebSchedulingTaskQueue(). case TaskType::kExperimentalWebScheduling: case TaskType::kCount: // Not a valid frame-level TaskType. - return base::nullopt; + NOTREACHED(); + return QueueTraits(); } // This method is called for all values between 0 and kCount. TaskType, // however, has numbering gaps, so even though all enumerated TaskTypes are // handled in the switch and return a value, we fall through for some values // of |type|. - return base::nullopt; + NOTREACHED(); + return QueueTraits(); } scoped_refptr<base::SingleThreadTaskRunner> FrameSchedulerImpl::GetTaskRunner( @@ -532,17 +466,8 @@ scoped_refptr<base::SingleThreadTaskRunner> FrameSchedulerImpl::GetTaskRunner( scoped_refptr<MainThreadTaskQueue> FrameSchedulerImpl::GetTaskQueue( TaskType type) { - DCHECK_LT(static_cast<size_t>(type), - main_thread_scheduler_->scheduling_settings() - .frame_task_types_to_queue_traits.size()); - base::Optional<QueueTraits> queue_traits = - main_thread_scheduler_->scheduling_settings() - .frame_task_types_to_queue_traits[static_cast<size_t>(type)]; - // We don't have a QueueTraits mapping for |task_type| if it is not a - // frame-level task type. - DCHECK(queue_traits); - return frame_task_queue_controller_->GetTaskQueue( - queue_traits.value()); + QueueTraits queue_traits = CreateQueueTraitsForTaskType(type); + return frame_task_queue_controller_->GetTaskQueue(queue_traits); } std::unique_ptr<WebResourceLoadingTaskRunnerHandle> @@ -638,6 +563,13 @@ WebScopedVirtualTimePauser FrameSchedulerImpl::CreateWebScopedVirtualTimePauser( void FrameSchedulerImpl::ResetForNavigation() { document_bound_weak_factory_.InvalidateWeakPtrs(); + for (const auto& it : back_forward_cache_opt_out_counts_) { + TRACE_EVENT_NESTABLE_ASYNC_END0( + "renderer.scheduler", "ActiveSchedulerTrackedFeature", + TRACE_ID_LOCAL(reinterpret_cast<intptr_t>(this) ^ + static_cast<int>(it.first))); + } + back_forward_cache_opt_out_counts_.clear(); back_forward_cache_opt_outs_.reset(); last_uploaded_active_features_ = 0; @@ -650,13 +582,20 @@ void FrameSchedulerImpl::OnStartedUsingFeature( if (policy.disable_aggressive_throttling) OnAddedAggressiveThrottlingOptOut(); - if (policy.disable_back_forward_cache) + if (policy.disable_back_forward_cache) { OnAddedBackForwardCacheOptOut(feature); + } uint64_t new_mask = GetActiveFeaturesTrackedForBackForwardCacheMetricsMask(); - if (old_mask != new_mask) + if (old_mask != new_mask) { NotifyDelegateAboutFeaturesAfterCurrentTask(); + TRACE_EVENT_NESTABLE_ASYNC_BEGIN1( + "renderer.scheduler", "ActiveSchedulerTrackedFeature", + TRACE_ID_LOCAL(reinterpret_cast<intptr_t>(this) ^ + static_cast<int>(feature)), + "feature", FeatureToString(feature)); + } } void FrameSchedulerImpl::OnStoppedUsingFeature( @@ -671,8 +610,13 @@ void FrameSchedulerImpl::OnStoppedUsingFeature( uint64_t new_mask = GetActiveFeaturesTrackedForBackForwardCacheMetricsMask(); - if (old_mask != new_mask) + if (old_mask != new_mask) { NotifyDelegateAboutFeaturesAfterCurrentTask(); + TRACE_EVENT_NESTABLE_ASYNC_END0( + "renderer.scheduler", "ActiveSchedulerTrackedFeature", + TRACE_ID_LOCAL(reinterpret_cast<intptr_t>(this) ^ + static_cast<int>(feature))); + } } void FrameSchedulerImpl::NotifyDelegateAboutFeaturesAfterCurrentTask() { @@ -743,7 +687,7 @@ void FrameSchedulerImpl::AsValueInto( base::trace_event::TracedValue* state) const { state->SetBoolean("frame_visible", frame_visible_); state->SetBoolean("page_visible", parent_page_scheduler_->IsPageVisible()); - state->SetBoolean("cross_origin", IsCrossOrigin()); + state->SetBoolean("cross_origin_to_main_frame", IsCrossOriginToMainFrame()); state->SetString("frame_type", frame_type_ == FrameScheduler::FrameType::kMainFrame ? "MainFrame" @@ -892,7 +836,7 @@ bool FrameSchedulerImpl::ShouldThrottleTaskQueues() const { if (!parent_page_scheduler_->IsPageVisible()) return true; return RuntimeEnabledFeatures::TimerThrottlingForHiddenFramesEnabled() && - !frame_visible_ && IsCrossOrigin(); + !frame_visible_ && IsCrossOriginToMainFrame(); } void FrameSchedulerImpl::UpdateTaskQueueThrottling( @@ -938,16 +882,12 @@ TaskQueue::QueuePriority FrameSchedulerImpl::ComputePriority( // and add a range of new priorities less than low. if (task_queue->web_scheduling_priority()) { switch (task_queue->web_scheduling_priority().value()) { - case WebSchedulingPriority::kImmediatePriority: - return TaskQueue::QueuePriority::kHighestPriority; - case WebSchedulingPriority::kHighPriority: + case WebSchedulingPriority::kUserBlockingPriority: return TaskQueue::QueuePriority::kHighPriority; - case WebSchedulingPriority::kDefaultPriority: + case WebSchedulingPriority::kUserVisiblePriority: return TaskQueue::QueuePriority::kNormalPriority; - case WebSchedulingPriority::kLowPriority: + case WebSchedulingPriority::kBackgroundPriority: return TaskQueue::QueuePriority::kLowPriority; - case WebSchedulingPriority::kIdlePriority: - return TaskQueue::QueuePriority::kBestEffortPriority; } } @@ -1022,7 +962,7 @@ TaskQueue::QueuePriority FrameSchedulerImpl::ComputePriority( } // Frame origin type experiment. - if (IsCrossOrigin()) { + if (IsCrossOriginToMainFrame()) { if (main_thread_scheduler_->scheduling_settings() .low_priority_cross_origin || (main_thread_scheduler_->scheduling_settings() @@ -1046,6 +986,21 @@ TaskQueue::QueuePriority FrameSchedulerImpl::ComputePriority( return main_thread_scheduler_->compositor_priority(); } + if (task_queue->GetPrioritisationType() == + MainThreadTaskQueue::QueueTraits::PrioritisationType::kFindInPage) { + return main_thread_scheduler_->find_in_page_priority(); + } + + if (task_queue->GetPrioritisationType() == + MainThreadTaskQueue::QueueTraits::PrioritisationType:: + kExperimentalDatabase) { + // TODO(shaseley): This decision should probably be based on Agent + // visibility. Consider changing this before shipping anything. + return parent_page_scheduler_->IsPageVisible() + ? TaskQueue::QueuePriority::kHighPriority + : TaskQueue::QueuePriority::kNormalPriority; + } + return TaskQueue::QueuePriority::kNormalPriority; } @@ -1242,5 +1197,10 @@ FrameSchedulerImpl::LoadingControlTaskQueueTraits() { QueueTraits::PrioritisationType::kLoadingControl); } +MainThreadTaskQueue::QueueTraits +FrameSchedulerImpl::FindInPageTaskQueueTraits() { + return PausableTaskQueueTraits().SetPrioritisationType( + QueueTraits::PrioritisationType::kFindInPage); +} } // namespace scheduler } // namespace blink diff --git a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.h b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.h index 860cd684172..cb6d72cf306 100644 --- a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.h +++ b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.h @@ -93,8 +93,8 @@ class PLATFORM_EXPORT FrameSchedulerImpl : public FrameScheduler, void SetPaused(bool frame_paused) override; void SetShouldReportPostedTasksWhenDisabled(bool should_report) override; - void SetCrossOrigin(bool cross_origin) override; - bool IsCrossOrigin() const override; + void SetCrossOriginToMainFrame(bool cross_origin) override; + bool IsCrossOriginToMainFrame() const override; void SetIsAdFrame() override; bool IsAdFrame() const override; @@ -160,16 +160,6 @@ class PLATFORM_EXPORT FrameSchedulerImpl : public FrameScheduler, MainThreadTaskQueue*, base::sequence_manager::TaskQueue::QueueEnabledVoter*) override; - using FrameTaskTypeToQueueTraitsArray = - std::array<base::Optional<MainThreadTaskQueue::QueueTraits>, - static_cast<size_t>(TaskType::kCount)>; - - // Initializes the mapping from TaskType to QueueTraits for frame-level tasks. - // We control the policy and initialize this, but the map is stored with main - // thread scheduling settings to avoid redundancy. - static void InitializeTaskTypeQueueTraitsMap( - FrameTaskTypeToQueueTraitsArray&); - // Returns the list of active features which currently tracked by the // scheduler for back-forward cache metrics. WTF::HashSet<SchedulingPolicy::Feature> @@ -269,8 +259,8 @@ class PLATFORM_EXPORT FrameSchedulerImpl : public FrameScheduler, // Create the QueueTraits for a specific TaskType. This returns base::nullopt // for loading tasks and non-frame-level tasks. - static base::Optional<MainThreadTaskQueue::QueueTraits> - CreateQueueTraitsForTaskType(TaskType); + static MainThreadTaskQueue::QueueTraits CreateQueueTraitsForTaskType( + TaskType); // Reset the state which should not persist across navigations. void ResetForNavigation(); @@ -294,6 +284,7 @@ class PLATFORM_EXPORT FrameSchedulerImpl : public FrameScheduler, DoesNotUseVirtualTimeTaskQueueTraits(); static MainThreadTaskQueue::QueueTraits LoadingTaskQueueTraits(); static MainThreadTaskQueue::QueueTraits LoadingControlTaskQueueTraits(); + static MainThreadTaskQueue::QueueTraits FindInPageTaskQueueTraits(); const FrameScheduler::FrameType frame_type_; diff --git a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl_unittest.cc b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl_unittest.cc index 43efd83327e..6411d32f558 100644 --- a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl_unittest.cc +++ b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl_unittest.cc @@ -40,6 +40,11 @@ namespace scheduler { namespace frame_scheduler_impl_unittest { using FeatureHandle = FrameOrWorkerScheduler::SchedulingAffectingFeatureHandle; +using PrioritisationType = MainThreadTaskQueue::QueueTraits::PrioritisationType; + +void AppendToVectorTestTask(Vector<String>* vector, String value) { + vector->push_back(std::move(value)); +} class FrameSchedulerDelegateForTesting : public FrameScheduler::Delegate { public: @@ -126,6 +131,49 @@ class FrameSchedulerImplTest : public testing::Test { UseCase::kLoading); } + // Helper for posting several tasks of specific prioritisation types for + // testing the relative order of tasks. |task_descriptor| is a string with + // space delimited task identifiers. The first letter of each task identifier + // specifies the prioritisation type: + // - 'R': Regular (normal priority) + // - 'V': Very high + // - 'B': Best-effort + // - 'D': Database + void PostTestTasksForPrioritisationType(Vector<String>* run_order, + const String& task_descriptor) { + std::istringstream stream(task_descriptor.Utf8()); + PrioritisationType prioritisation_type; + while (!stream.eof()) { + std::string task; + stream >> task; + switch (task[0]) { + case 'R': + prioritisation_type = PrioritisationType::kRegular; + break; + case 'V': + prioritisation_type = PrioritisationType::kVeryHigh; + break; + case 'B': + prioritisation_type = PrioritisationType::kBestEffort; + break; + case 'D': + prioritisation_type = PrioritisationType::kExperimentalDatabase; + break; + default: + EXPECT_FALSE(true); + return; + } + auto queue_traits = + FrameSchedulerImpl::PausableTaskQueueTraits().SetPrioritisationType( + prioritisation_type); + GetTaskQueue(queue_traits) + ->task_runner() + ->PostTask(FROM_HERE, + base::BindOnce(&AppendToVectorTestTask, run_order, + String::FromUTF8(task))); + } + } + static void ResetForNavigation(FrameSchedulerImpl* frame_scheduler) { frame_scheduler->ResetForNavigation(); } @@ -306,19 +354,10 @@ void IncrementCounter(int* counter) { ++*counter; } -void ExpectAndIncrementCounter(int expected, int* actual) { - EXPECT_EQ(expected, *actual); - IncrementCounter(actual); -} - void RecordQueueName(String name, Vector<String>* tasks) { tasks->push_back(std::move(name)); } -void AppendToVectorTestTask(Vector<String>* vector, String value) { - vector->push_back(std::move(value)); -} - // Simulate running a task of a particular length by fast forwarding the task // environment clock, which is used to determine the wall time of a task. void RunTaskOfLength(base::test::TaskEnvironment* task_environment, @@ -374,10 +413,10 @@ TEST_F(FrameSchedulerImplTest, LazyInitThrottleableTaskQueue(); EXPECT_FALSE(IsThrottled()); frame_scheduler_->SetFrameVisible(false); - frame_scheduler_->SetCrossOrigin(true); - frame_scheduler_->SetCrossOrigin(false); + frame_scheduler_->SetCrossOriginToMainFrame(true); + frame_scheduler_->SetCrossOriginToMainFrame(false); EXPECT_FALSE(IsThrottled()); - frame_scheduler_->SetCrossOrigin(true); + frame_scheduler_->SetCrossOriginToMainFrame(true); EXPECT_TRUE(IsThrottled()); frame_scheduler_->SetFrameVisible(true); EXPECT_FALSE(IsThrottled()); @@ -388,7 +427,7 @@ TEST_F(FrameSchedulerImplTest, TEST_F(FrameSchedulerImplTest, FrameHidden_CrossOrigin_LazyInit) { ScopedTimerThrottlingForHiddenFramesForTest throttle_hidden_frames(true); frame_scheduler_->SetFrameVisible(false); - frame_scheduler_->SetCrossOrigin(true); + frame_scheduler_->SetCrossOriginToMainFrame(true); LazyInitThrottleableTaskQueue(); EXPECT_TRUE(IsThrottled()); } @@ -399,14 +438,14 @@ TEST_F(FrameSchedulerImplTest, LazyInitThrottleableTaskQueue(); EXPECT_FALSE(IsThrottled()); frame_scheduler_->SetFrameVisible(false); - frame_scheduler_->SetCrossOrigin(true); + frame_scheduler_->SetCrossOriginToMainFrame(true); EXPECT_FALSE(IsThrottled()); } TEST_F(FrameSchedulerImplTest, FrameHidden_CrossOrigin_NoThrottling_LazyInit) { ScopedTimerThrottlingForHiddenFramesForTest throttle_hidden_frames(false); frame_scheduler_->SetFrameVisible(false); - frame_scheduler_->SetCrossOrigin(true); + frame_scheduler_->SetCrossOriginToMainFrame(true); LazyInitThrottleableTaskQueue(); EXPECT_FALSE(IsThrottled()); } @@ -433,14 +472,14 @@ TEST_F(FrameSchedulerImplTest, FrameVisible_CrossOrigin_ExplicitInit) { EXPECT_TRUE(throttleable_task_queue()); frame_scheduler_->SetFrameVisible(true); EXPECT_FALSE(IsThrottled()); - frame_scheduler_->SetCrossOrigin(true); + frame_scheduler_->SetCrossOriginToMainFrame(true); EXPECT_FALSE(IsThrottled()); } TEST_F(FrameSchedulerImplTest, FrameVisible_CrossOrigin_LazyInit) { ScopedTimerThrottlingForHiddenFramesForTest throttle_hidden_frames(true); frame_scheduler_->SetFrameVisible(true); - frame_scheduler_->SetCrossOrigin(true); + frame_scheduler_->SetCrossOriginToMainFrame(true); LazyInitThrottleableTaskQueue(); EXPECT_FALSE(IsThrottled()); } @@ -1678,7 +1717,7 @@ class LowPriorityCrossOriginTaskExperimentTest : public FrameSchedulerImplTest { }; TEST_F(LowPriorityCrossOriginTaskExperimentTest, FrameQueuesPriorities) { - EXPECT_FALSE(frame_scheduler_->IsCrossOrigin()); + EXPECT_FALSE(frame_scheduler_->IsCrossOriginToMainFrame()); // Same Origin Task Queues. EXPECT_EQ(LoadingTaskQueue()->GetQueuePriority(), @@ -1694,8 +1733,8 @@ TEST_F(LowPriorityCrossOriginTaskExperimentTest, FrameQueuesPriorities) { EXPECT_EQ(UnpausableTaskQueue()->GetQueuePriority(), TaskQueue::QueuePriority::kNormalPriority); - frame_scheduler_->SetCrossOrigin(true); - EXPECT_TRUE(frame_scheduler_->IsCrossOrigin()); + frame_scheduler_->SetCrossOriginToMainFrame(true); + EXPECT_TRUE(frame_scheduler_->IsCrossOriginToMainFrame()); EXPECT_EQ(LoadingTaskQueue()->GetQueuePriority(), TaskQueue::QueuePriority::kLowPriority); @@ -1737,8 +1776,8 @@ TEST_F(LowPriorityCrossOriginTaskDuringLoadingExperimentTest, EXPECT_EQ(UnpausableTaskQueue()->GetQueuePriority(), TaskQueue::QueuePriority::kNormalPriority); - frame_scheduler_->SetCrossOrigin(true); - EXPECT_TRUE(frame_scheduler_->IsCrossOrigin()); + frame_scheduler_->SetCrossOriginToMainFrame(true); + EXPECT_TRUE(frame_scheduler_->IsCrossOriginToMainFrame()); EXPECT_EQ(LoadingTaskQueue()->GetQueuePriority(), TaskQueue::QueuePriority::kLowPriority); @@ -1787,191 +1826,6 @@ TEST_F(FrameSchedulerImplTest, TaskTypeToTaskQueueMapping) { ForegroundOnlyTaskQueue()); } -class ThrottleAndFreezeTaskTypesExperimentTest : public FrameSchedulerImplTest { - public: - ThrottleAndFreezeTaskTypesExperimentTest(const base::FieldTrialParams& params, - const char* group_name) { - scoped_feature_list().InitAndEnableFeatureWithParameters( - kThrottleAndFreezeTaskTypes, params); - } -}; - -class ThrottleableAndFreezableTaskTypesTest - : public ThrottleAndFreezeTaskTypesExperimentTest { - public: - ThrottleableAndFreezableTaskTypesTest() - : ThrottleAndFreezeTaskTypesExperimentTest( - base::FieldTrialParams{ - // Leading spaces are allowed. - {kThrottleableTaskTypesListParam, "PostedMessage"}, - {kFreezableTaskTypesListParam, - "PostedMessage, MediaElementEvent,DOMManipulation"}}, - "Group1") {} -}; - -TEST_F(ThrottleableAndFreezableTaskTypesTest, QueueTraitsFromFieldTrialParams) { - if (base::FeatureList::IsEnabled(blink::features::kStopNonTimersInBackground)) - return; - // These tests will start to fail if the default task queues or queue traits - // change for these task types. - - // Check that the overrides work. - auto task_queue = GetTaskQueue(TaskType::kPostedMessage); - EXPECT_EQ(task_queue->GetQueueTraits(), - MainThreadTaskQueue::QueueTraits() - .SetCanBeThrottled(true) - .SetCanBeFrozen(true) - .SetCanBePaused(true) - .SetCanRunWhenVirtualTimePaused(false)); - - task_queue = GetTaskQueue(TaskType::kMediaElementEvent); - EXPECT_EQ(task_queue->GetQueueTraits(), - MainThreadTaskQueue::QueueTraits() - .SetCanBeFrozen(true) - .SetCanBePaused(true) - .SetCanRunWhenVirtualTimePaused(false)); - - task_queue = GetTaskQueue(TaskType::kDatabaseAccess); - EXPECT_EQ(task_queue->GetQueueTraits(), - MainThreadTaskQueue::QueueTraits() - .SetCanBePaused(true) - .SetCanRunWhenVirtualTimePaused(false)); - - task_queue = GetTaskQueue(TaskType::kDOMManipulation); - EXPECT_EQ(task_queue->GetQueueTraits(), - MainThreadTaskQueue::QueueTraits() - .SetCanBeFrozen(true) - .SetCanBeDeferred(true) - .SetCanBePaused(true) - .SetCanRunWhenVirtualTimePaused(false)); - - // Test some task types that were not configured through field trial - // parameters. - task_queue = GetTaskQueue(TaskType::kWebLocks); - EXPECT_EQ( - task_queue->GetQueueTraits(), - MainThreadTaskQueue::QueueTraits().SetCanRunWhenVirtualTimePaused(false)); - - task_queue = GetTaskQueue(TaskType::kMiscPlatformAPI); - EXPECT_EQ(task_queue->GetQueueTraits(), - MainThreadTaskQueue::QueueTraits() - .SetCanBeDeferred(true) - .SetCanBePaused(true) - .SetCanRunWhenVirtualTimePaused(false)); -} - - -class FreezableOnlyTaskTypesTest - : public ThrottleAndFreezeTaskTypesExperimentTest { - public: - FreezableOnlyTaskTypesTest() - : ThrottleAndFreezeTaskTypesExperimentTest( - base::FieldTrialParams{ - {kThrottleableTaskTypesListParam, ""}, - {kFreezableTaskTypesListParam, - "PostedMessage,MediaElementEvent,DOMManipulation"}}, - "Group2") {} -}; - -TEST_F(FreezableOnlyTaskTypesTest, QueueTraitsFromFieldTrialParams) { - if (base::FeatureList::IsEnabled(blink::features::kStopNonTimersInBackground)) - return; - - // These tests will start to fail if the default task queues or queue traits - // change for these task types. - - // Check that the overrides work. - auto task_queue = GetTaskQueue(TaskType::kPostedMessage); - EXPECT_EQ(task_queue->GetQueueTraits(), MainThreadTaskQueue::QueueTraits() - .SetCanBeFrozen(true) - .SetCanBePaused(true)); - - task_queue = GetTaskQueue(TaskType::kMediaElementEvent); - EXPECT_EQ(task_queue->GetQueueTraits(), MainThreadTaskQueue::QueueTraits() - .SetCanBeFrozen(true) - .SetCanBePaused(true)); - - task_queue = GetTaskQueue(TaskType::kDatabaseAccess); - EXPECT_EQ(task_queue->GetQueueTraits(), MainThreadTaskQueue::QueueTraits() - .SetCanBePaused(true)); - - task_queue = GetTaskQueue(TaskType::kDOMManipulation); - EXPECT_EQ(task_queue->GetQueueTraits(), MainThreadTaskQueue::QueueTraits() - .SetCanBeFrozen(true) - .SetCanBeDeferred(true) - .SetCanBePaused(true)); - - // Test some task types that were not configured through field trial - // parameters. - task_queue = GetTaskQueue(TaskType::kWebLocks); - EXPECT_EQ(task_queue->GetQueueTraits(), MainThreadTaskQueue::QueueTraits()); - - task_queue = GetTaskQueue(TaskType::kMiscPlatformAPI); - EXPECT_EQ(task_queue->GetQueueTraits(), MainThreadTaskQueue::QueueTraits() - .SetCanBeDeferred(true) - .SetCanBePaused(true)); -} - -class ThrottleableOnlyTaskTypesTest - : public ThrottleAndFreezeTaskTypesExperimentTest { - public: - ThrottleableOnlyTaskTypesTest() - : ThrottleAndFreezeTaskTypesExperimentTest( - base::FieldTrialParams{ - {kFreezableTaskTypesListParam, ""}, - {kThrottleableTaskTypesListParam, "PostedMessage"}}, - "Group3") {} -}; - -TEST_F(ThrottleableOnlyTaskTypesTest, QueueTraitsFromFieldTrialParams) { - if (base::FeatureList::IsEnabled(blink::features::kStopNonTimersInBackground)) - return; - - // These tests will start to fail if the default task queues or queue traits - // change for these task types. - - // Check that the overrides work. - auto task_queue = GetTaskQueue(TaskType::kPostedMessage); - EXPECT_EQ(task_queue->GetQueueTraits(), - MainThreadTaskQueue::QueueTraits() - .SetCanBeThrottled(true) - .SetCanBePaused(true) - .SetCanRunWhenVirtualTimePaused(false)); - - task_queue = GetTaskQueue(TaskType::kMediaElementEvent); - EXPECT_EQ(task_queue->GetQueueTraits(), - MainThreadTaskQueue::QueueTraits() - .SetCanBePaused(true) - .SetCanRunWhenVirtualTimePaused(false)); - - task_queue = GetTaskQueue(TaskType::kDatabaseAccess); - EXPECT_EQ(task_queue->GetQueueTraits(), - MainThreadTaskQueue::QueueTraits() - .SetCanBePaused(true) - .SetCanRunWhenVirtualTimePaused(false)); - - task_queue = GetTaskQueue(TaskType::kDOMManipulation); - EXPECT_EQ(task_queue->GetQueueTraits(), - MainThreadTaskQueue::QueueTraits() - .SetCanBeDeferred(true) - .SetCanBePaused(true) - .SetCanRunWhenVirtualTimePaused(false)); - - // Test some task types that were not configured through field trial - // parameters. - task_queue = GetTaskQueue(TaskType::kWebLocks); - EXPECT_EQ( - task_queue->GetQueueTraits(), - MainThreadTaskQueue::QueueTraits().SetCanRunWhenVirtualTimePaused(false)); - - task_queue = GetTaskQueue(TaskType::kMiscPlatformAPI); - EXPECT_EQ(task_queue->GetQueueTraits(), - MainThreadTaskQueue::QueueTraits() - .SetCanBeDeferred(true) - .SetCanBePaused(true) - .SetCanRunWhenVirtualTimePaused(false)); -} - class FrameSchedulerImplDatabaseAccessWithoutHighPriority : public FrameSchedulerImplTest { public: @@ -1980,37 +1834,11 @@ class FrameSchedulerImplDatabaseAccessWithoutHighPriority }; TEST_F(FrameSchedulerImplDatabaseAccessWithoutHighPriority, QueueTraits) { - // These tests will start to fail if the default task queues or queue traits - // change for these task types. - - int counter = 0; - - auto loading_queue = GetTaskQueue(TaskType::kInternalContinueScriptLoading); - EXPECT_EQ(loading_queue->GetQueuePriority(), - TaskQueue::QueuePriority::kVeryHighPriority); - loading_queue->task_runner()->PostTask( - FROM_HERE, base::BindOnce(&ExpectAndIncrementCounter, 0, - base::Unretained(&counter))); - auto da_queue = GetTaskQueue(TaskType::kDatabaseAccess); EXPECT_EQ(da_queue->GetQueueTraits().prioritisation_type, MainThreadTaskQueue::QueueTraits::PrioritisationType::kRegular); EXPECT_EQ(da_queue->GetQueuePriority(), TaskQueue::QueuePriority::kNormalPriority); - da_queue->task_runner()->PostTask( - FROM_HERE, base::BindOnce(&ExpectAndIncrementCounter, 1, - base::Unretained(&counter))); - - auto content_queue = GetTaskQueue(TaskType::kInternalContentCapture); - EXPECT_EQ(content_queue->GetQueuePriority(), - TaskQueue::QueuePriority::kBestEffortPriority); - content_queue->task_runner()->PostTask( - FROM_HERE, base::BindOnce(&ExpectAndIncrementCounter, 2, - base::Unretained(&counter))); - - EXPECT_EQ(0, counter); - base::RunLoop().RunUntilIdle(); - EXPECT_EQ(3, counter); } class FrameSchedulerImplDatabaseAccessWithHighPriority @@ -2021,37 +1849,31 @@ class FrameSchedulerImplDatabaseAccessWithHighPriority }; TEST_F(FrameSchedulerImplDatabaseAccessWithHighPriority, QueueTraits) { - // These tests will start to fail if the default task queues or queue traits - // change for these task types. - - int counter = 0; - - auto loading_queue = GetTaskQueue(TaskType::kInternalContinueScriptLoading); - EXPECT_EQ(loading_queue->GetQueuePriority(), - TaskQueue::QueuePriority::kVeryHighPriority); - loading_queue->task_runner()->PostTask( - FROM_HERE, base::BindOnce(&ExpectAndIncrementCounter, 0, - base::Unretained(&counter))); - auto da_queue = GetTaskQueue(TaskType::kDatabaseAccess); EXPECT_EQ(da_queue->GetQueueTraits().prioritisation_type, - MainThreadTaskQueue::QueueTraits::PrioritisationType::kHigh); + MainThreadTaskQueue::QueueTraits::PrioritisationType:: + kExperimentalDatabase); EXPECT_EQ(da_queue->GetQueuePriority(), TaskQueue::QueuePriority::kHighPriority); - da_queue->task_runner()->PostTask( - FROM_HERE, base::BindOnce(&ExpectAndIncrementCounter, 1, - base::Unretained(&counter))); +} - auto pausable_queue = PausableTaskQueue(); - EXPECT_EQ(pausable_queue->GetQueuePriority(), - TaskQueue::QueuePriority::kNormalPriority); - pausable_queue->task_runner()->PostTask( - FROM_HERE, base::BindOnce(&ExpectAndIncrementCounter, 2, - base::Unretained(&counter))); +TEST_F(FrameSchedulerImplDatabaseAccessWithHighPriority, RunOrder) { + Vector<String> run_order; + PostTestTasksForPrioritisationType(&run_order, "D1 R1 D2 V1 B1"); - EXPECT_EQ(0, counter); base::RunLoop().RunUntilIdle(); - EXPECT_EQ(3, counter); + EXPECT_THAT(run_order, testing::ElementsAre("V1", "D1", "D2", "R1", "B1")); +} + +TEST_F(FrameSchedulerImplDatabaseAccessWithHighPriority, + NormalPriorityInBackground) { + page_scheduler_->SetPageVisible(false); + + Vector<String> run_order; + PostTestTasksForPrioritisationType(&run_order, "D1 R1 D2 V1 B1"); + + base::RunLoop().RunUntilIdle(); + EXPECT_THAT(run_order, testing::ElementsAre("V1", "D1", "R1", "D2", "B1")); } TEST_F(FrameSchedulerImplTest, ContentCaptureHasIdleTaskQueue) { @@ -2314,11 +2136,9 @@ class WebSchedulingTaskQueueTest : public FrameSchedulerImplTest { // Helper for posting tasks to a WebSchedulingTaskQueue. |task_descriptor| is // a string with space delimited task identifiers. The first letter of each // task identifier specifies the task queue priority: - // - 'I': Immediate - // - 'H': High - // - 'D': Default - // - 'L': Low - // - 'E': Idle + // - 'U': UserBlocking + // - 'V': UserVisible + // - 'B': Background void PostWebSchedulingTestTasks(Vector<String>* run_order, const String& task_descriptor) { std::istringstream stream(task_descriptor.Utf8()); @@ -2327,20 +2147,14 @@ class WebSchedulingTaskQueueTest : public FrameSchedulerImplTest { stream >> task; WebSchedulingPriority priority; switch (task[0]) { - case 'I': - priority = WebSchedulingPriority::kImmediatePriority; - break; - case 'H': - priority = WebSchedulingPriority::kHighPriority; + case 'U': + priority = WebSchedulingPriority::kUserBlockingPriority; break; - case 'D': - priority = WebSchedulingPriority::kDefaultPriority; + case 'V': + priority = WebSchedulingPriority::kUserVisiblePriority; break; - case 'L': - priority = WebSchedulingPriority::kLowPriority; - break; - case 'E': - priority = WebSchedulingPriority::kIdlePriority; + case 'B': + priority = WebSchedulingPriority::kBackgroundPriority; break; default: EXPECT_FALSE(true); @@ -2361,23 +2175,23 @@ class WebSchedulingTaskQueueTest : public FrameSchedulerImplTest { TEST_F(WebSchedulingTaskQueueTest, TasksRunInPriorityOrder) { Vector<String> run_order; - PostWebSchedulingTestTasks(&run_order, "E1 E2 L1 L2 D1 D2 H1 H2 I1 I2"); + PostWebSchedulingTestTasks(&run_order, "B1 B2 V1 V2 U1 U2"); base::RunLoop().RunUntilIdle(); - EXPECT_THAT(run_order, testing::ElementsAre("I1", "I2", "H1", "H2", "D1", - "D2", "L1", "L2", "E1", "E2")); + EXPECT_THAT(run_order, + testing::ElementsAre("U1", "U2", "V1", "V2", "B1", "B2")); } TEST_F(WebSchedulingTaskQueueTest, DynamicTaskPriorityOrder) { Vector<String> run_order; - PostWebSchedulingTestTasks(&run_order, "E1 E2 D1 D2 I1 I2"); - task_queues_[static_cast<int>(WebSchedulingPriority::kImmediatePriority)] - ->SetPriority(WebSchedulingPriority::kLowPriority); + PostWebSchedulingTestTasks(&run_order, "B1 B2 V1 V2 U1 U2"); + task_queues_[static_cast<int>(WebSchedulingPriority::kUserBlockingPriority)] + ->SetPriority(WebSchedulingPriority::kBackgroundPriority); base::RunLoop().RunUntilIdle(); EXPECT_THAT(run_order, - testing::ElementsAre("D1", "D2", "I1", "I2", "E1", "E2")); + testing::ElementsAre("V1", "V2", "B1", "B2", "U1", "U2")); } } // namespace frame_scheduler_impl_unittest diff --git a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/frame_status.cc b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/frame_status.cc index cfda104e005..d8a1c929c2b 100644 --- a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/frame_status.cc +++ b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/frame_status.cc @@ -26,9 +26,10 @@ enum class FrameThrottlingState { enum class FrameOriginState { kMainFrame = 0, - kSameOrigin = 1, - kCrossOrigin = 2, + kSameOriginToMainFrame = 1, + kCrossOriginToMainFrame = 2, + // TODO(dcheng): get rid of kCount here. kCount = 3 }; @@ -60,9 +61,9 @@ FrameOriginState GetFrameOriginState(const FrameScheduler& frame_scheduler) { if (frame_scheduler.GetFrameType() == FrameScheduler::FrameType::kMainFrame) { return FrameOriginState::kMainFrame; } - if (frame_scheduler.IsCrossOrigin()) - return FrameOriginState::kCrossOrigin; - return FrameOriginState::kSameOrigin; + if (frame_scheduler.IsCrossOriginToMainFrame()) + return FrameOriginState::kCrossOriginToMainFrame; + return FrameOriginState::kSameOriginToMainFrame; } } // namespace diff --git a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/frame_task_queue_controller.cc b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/frame_task_queue_controller.cc index 710f3d595b9..362b0e1b5f1 100644 --- a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/frame_task_queue_controller.cc +++ b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/frame_task_queue_controller.cc @@ -107,10 +107,6 @@ void FrameTaskQueueController::CreateTaskQueue( queue_creation_params = queue_creation_params.SetFixedPriority( TaskQueue::QueuePriority::kVeryHighPriority); break; - case QueueTraits::PrioritisationType::kHigh: - queue_creation_params = queue_creation_params.SetFixedPriority( - TaskQueue::QueuePriority::kHighPriority); - break; case QueueTraits::PrioritisationType::kBestEffort: queue_creation_params = queue_creation_params.SetFixedPriority( TaskQueue::QueuePriority::kBestEffortPriority); @@ -179,7 +175,7 @@ bool FrameTaskQueueController::RemoveResourceLoadingTaskQueue( void FrameTaskQueueController::AsValueInto( base::trace_event::TracedValue* state) const { state->BeginArray("task_queues"); - for (const auto it : task_queues_) { + for (const auto& it : task_queues_) { state->AppendString(PointerToString(it.value.get())); } state->EndArray(); diff --git a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/frame_task_queue_controller_unittest.cc b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/frame_task_queue_controller_unittest.cc index 18f4199534c..28f6af4d89a 100644 --- a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/frame_task_queue_controller_unittest.cc +++ b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/frame_task_queue_controller_unittest.cc @@ -260,38 +260,24 @@ TEST_F(FrameTaskQueueControllerTest, TEST_F(FrameTaskQueueControllerTest, AddWebSchedulingTaskQueues) { scoped_refptr<MainThreadTaskQueue> task_queue = frame_task_queue_controller_->NewWebSchedulingTaskQueue( - QueueTraits(), WebSchedulingPriority::kImmediatePriority); + QueueTraits(), WebSchedulingPriority::kUserBlockingPriority); EXPECT_EQ(1u, frame_task_queue_controller_->GetAllTaskQueuesAndVoters().size()); - EXPECT_EQ(WebSchedulingPriority::kImmediatePriority, + EXPECT_EQ(WebSchedulingPriority::kUserBlockingPriority, task_queue->web_scheduling_priority().value()); task_queue = frame_task_queue_controller_->NewWebSchedulingTaskQueue( - QueueTraits(), WebSchedulingPriority::kHighPriority); + QueueTraits(), WebSchedulingPriority::kUserVisiblePriority); EXPECT_EQ(2u, frame_task_queue_controller_->GetAllTaskQueuesAndVoters().size()); - EXPECT_EQ(WebSchedulingPriority::kHighPriority, + EXPECT_EQ(WebSchedulingPriority::kUserVisiblePriority, task_queue->web_scheduling_priority().value()); task_queue = frame_task_queue_controller_->NewWebSchedulingTaskQueue( - QueueTraits(), WebSchedulingPriority::kDefaultPriority); + QueueTraits(), WebSchedulingPriority::kBackgroundPriority); EXPECT_EQ(3u, frame_task_queue_controller_->GetAllTaskQueuesAndVoters().size()); - EXPECT_EQ(WebSchedulingPriority::kDefaultPriority, - task_queue->web_scheduling_priority().value()); - - task_queue = frame_task_queue_controller_->NewWebSchedulingTaskQueue( - QueueTraits(), WebSchedulingPriority::kLowPriority); - EXPECT_EQ(4u, - frame_task_queue_controller_->GetAllTaskQueuesAndVoters().size()); - EXPECT_EQ(WebSchedulingPriority::kLowPriority, - task_queue->web_scheduling_priority().value()); - - task_queue = frame_task_queue_controller_->NewWebSchedulingTaskQueue( - QueueTraits(), WebSchedulingPriority::kIdlePriority); - EXPECT_EQ(5u, - frame_task_queue_controller_->GetAllTaskQueuesAndVoters().size()); - EXPECT_EQ(WebSchedulingPriority::kIdlePriority, + EXPECT_EQ(WebSchedulingPriority::kBackgroundPriority, task_queue->web_scheduling_priority().value()); } @@ -299,18 +285,18 @@ TEST_F(FrameTaskQueueControllerTest, AddMultipleSamePriorityWebSchedulingTaskQueues) { scoped_refptr<MainThreadTaskQueue> task_queue1 = frame_task_queue_controller_->NewWebSchedulingTaskQueue( - QueueTraits(), WebSchedulingPriority::kImmediatePriority); + QueueTraits(), WebSchedulingPriority::kUserBlockingPriority); EXPECT_EQ(1u, frame_task_queue_controller_->GetAllTaskQueuesAndVoters().size()); - EXPECT_EQ(WebSchedulingPriority::kImmediatePriority, + EXPECT_EQ(WebSchedulingPriority::kUserBlockingPriority, task_queue1->web_scheduling_priority().value()); scoped_refptr<MainThreadTaskQueue> task_queue2 = frame_task_queue_controller_->NewWebSchedulingTaskQueue( - QueueTraits(), WebSchedulingPriority::kImmediatePriority); + QueueTraits(), WebSchedulingPriority::kUserBlockingPriority); EXPECT_EQ(2u, frame_task_queue_controller_->GetAllTaskQueuesAndVoters().size()); - EXPECT_EQ(WebSchedulingPriority::kImmediatePriority, + EXPECT_EQ(WebSchedulingPriority::kUserBlockingPriority, task_queue2->web_scheduling_priority().value()); EXPECT_NE(task_queue1.get(), task_queue2.get()); @@ -338,11 +324,12 @@ INSTANTIATE_TEST_SUITE_P( All, TaskQueueCreationFromQueueTraitsTest, ::testing::Values(QueueTraits::PrioritisationType::kVeryHigh, - QueueTraits::PrioritisationType::kHigh, QueueTraits::PrioritisationType::kBestEffort, QueueTraits::PrioritisationType::kRegular, QueueTraits::PrioritisationType::kLoading, - QueueTraits::PrioritisationType::kLoadingControl)); + QueueTraits::PrioritisationType::kLoadingControl, + QueueTraits::PrioritisationType::kFindInPage, + QueueTraits::PrioritisationType::kExperimentalDatabase)); TEST_P(TaskQueueCreationFromQueueTraitsTest, AddAndRetrieveAllTaskQueues) { diff --git a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_metrics_helper_unittest.cc b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_metrics_helper_unittest.cc index 2adac49f386..9b7e85a92b6 100644 --- a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_metrics_helper_unittest.cc +++ b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_metrics_helper_unittest.cc @@ -191,38 +191,38 @@ class MainThreadMetricsHelperTest : public testing::Test { break; case FrameStatus::kCrossOriginVisible: builder.SetFrameType(FrameScheduler::FrameType::kSubframe) - .SetIsCrossOrigin(true) + .SetIsCrossOriginToMainFrame(true) .SetIsPageVisible(true) .SetIsFrameVisible(true); break; case FrameStatus::kCrossOriginVisibleService: builder.SetFrameType(FrameScheduler::FrameType::kSubframe) - .SetIsCrossOrigin(true) + .SetIsCrossOriginToMainFrame(true) .SetPageScheduler(playing_view_.get()) .SetIsFrameVisible(true); break; case FrameStatus::kCrossOriginHidden: builder.SetFrameType(FrameScheduler::FrameType::kSubframe) - .SetIsCrossOrigin(true) + .SetIsCrossOriginToMainFrame(true) .SetIsPageVisible(true); break; case FrameStatus::kCrossOriginHiddenService: builder.SetFrameType(FrameScheduler::FrameType::kSubframe) - .SetIsCrossOrigin(true) + .SetIsCrossOriginToMainFrame(true) .SetPageScheduler(playing_view_.get()); break; case FrameStatus::kCrossOriginBackground: builder.SetFrameType(FrameScheduler::FrameType::kSubframe) - .SetIsCrossOrigin(true); + .SetIsCrossOriginToMainFrame(true); break; case FrameStatus::kCrossOriginBackgroundExemptSelf: builder.SetFrameType(FrameScheduler::FrameType::kSubframe) - .SetIsCrossOrigin(true) + .SetIsCrossOriginToMainFrame(true) .SetIsExemptFromThrottling(true); break; case FrameStatus::kCrossOriginBackgroundExemptOther: builder.SetFrameType(FrameScheduler::FrameType::kSubframe) - .SetIsCrossOrigin(true) + .SetIsCrossOriginToMainFrame(true) .SetPageScheduler(throtting_exempt_view_.get()); break; case FrameStatus::kCount: diff --git a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.cc b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.cc index 1c1a13067ab..9bf6ae8538a 100644 --- a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.cc +++ b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.cc @@ -22,10 +22,11 @@ #include "build/build_config.h" #include "components/viz/common/frame_sinks/begin_frame_args.h" #include "services/metrics/public/cpp/ukm_builders.h" +#include "third_party/blink/public/common/input/web_input_event_attribution.h" +#include "third_party/blink/public/common/input/web_mouse_wheel_event.h" +#include "third_party/blink/public/common/input/web_touch_event.h" #include "third_party/blink/public/common/page/launching_process_state.h" #include "third_party/blink/public/platform/scheduler/web_renderer_process_type.h" -#include "third_party/blink/public/platform/web_mouse_wheel_event.h" -#include "third_party/blink/public/platform/web_touch_event.h" #include "third_party/blink/renderer/platform/bindings/parkable_string_manager.h" #include "third_party/blink/renderer/platform/instrumentation/resource_coordinator/renderer_resource_coordinator.h" #include "third_party/blink/renderer/platform/runtime_enabled_features.h" @@ -37,6 +38,7 @@ #include "third_party/blink/renderer/platform/scheduler/main_thread/main_thread.h" #include "third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl.h" #include "third_party/blink/renderer/platform/scheduler/main_thread/task_type_names.h" +#include "third_party/blink/renderer/platform/scheduler/main_thread/widget_scheduler.h" #include "third_party/blink/renderer/platform/scheduler/public/event_loop.h" #include "v8/include/v8.h" @@ -201,24 +203,15 @@ MainThreadSchedulerImpl::MainThreadSchedulerImpl( .SetFixedPriority( TaskQueue::QueuePriority::kBestEffortPriority))), render_widget_scheduler_signals_(this), + find_in_page_budget_pool_controller_( + new FindInPageBudgetPoolController(this)), control_task_queue_(helper_.ControlMainThreadTaskQueue()), compositor_task_queue_( helper_.NewTaskQueue(MainThreadTaskQueue::QueueCreationParams( MainThreadTaskQueue::QueueType::kCompositor) .SetShouldMonitorQuiescence(true))), - input_task_queue_(helper_.NewTaskQueue( - MainThreadTaskQueue::QueueCreationParams( - MainThreadTaskQueue::QueueType::kInput) - .SetShouldMonitorQuiescence(true) - .SetFixedPriority( - scheduling_settings_.high_priority_input - ? base::make_optional( - TaskQueue::QueuePriority::kHighestPriority) - : base::nullopt))), compositor_task_queue_enabled_voter_( compositor_task_queue_->CreateQueueEnabledVoter()), - input_task_queue_enabled_voter_( - input_task_queue_->CreateQueueEnabledVoter()), memory_purge_task_queue_(helper_.NewTaskQueue( MainThreadTaskQueue::QueueCreationParams( MainThreadTaskQueue::QueueType::kIdle) @@ -226,6 +219,7 @@ MainThreadSchedulerImpl::MainThreadSchedulerImpl( TaskQueue::QueuePriority::kBestEffortPriority))), memory_purge_manager_(memory_purge_task_queue_->CreateTaskRunner( TaskType::kMainThreadTaskQueueMemoryPurge)), + non_waking_time_domain_(tick_clock()), delayed_update_policy_runner_( base::BindRepeating(&MainThreadSchedulerImpl::UpdatePolicy, base::Unretained(this)), @@ -246,8 +240,8 @@ MainThreadSchedulerImpl::MainThreadSchedulerImpl( task_runners_.emplace(helper_.DefaultMainThreadTaskQueue(), nullptr); task_runners_.emplace(compositor_task_queue_, compositor_task_queue_->CreateQueueEnabledVoter()); - task_runners_.emplace(input_task_queue_, - input_task_queue_->CreateQueueEnabledVoter()); + + RegisterTimeDomain(&non_waking_time_domain_); v8_task_queue_ = NewTaskQueue(MainThreadTaskQueue::QueueCreationParams( MainThreadTaskQueue::QueueType::kV8)); @@ -255,6 +249,10 @@ MainThreadSchedulerImpl::MainThreadSchedulerImpl( MainThreadTaskQueue::QueueType::kIPC)); cleanup_task_queue_ = NewTaskQueue(MainThreadTaskQueue::QueueCreationParams( MainThreadTaskQueue::QueueType::kCleanup)); + non_waking_task_queue_ = + NewTaskQueue(MainThreadTaskQueue::QueueCreationParams( + MainThreadTaskQueue::QueueType::kNonWaking) + .SetTimeDomain(&non_waking_time_domain_)); v8_task_runner_ = v8_task_queue_->CreateTaskRunner(TaskType::kMainThreadTaskQueueV8); @@ -262,12 +260,12 @@ MainThreadSchedulerImpl::MainThreadSchedulerImpl( TaskType::kMainThreadTaskQueueCompositor); control_task_runner_ = helper_.ControlMainThreadTaskQueue()->CreateTaskRunner( TaskType::kMainThreadTaskQueueControl); - input_task_runner_ = - input_task_queue_->CreateTaskRunner(TaskType::kMainThreadTaskQueueInput); ipc_task_runner_ = ipc_task_queue_->CreateTaskRunner(TaskType::kMainThreadTaskQueueIPC); cleanup_task_runner_ = cleanup_task_queue_->CreateTaskRunner( TaskType::kMainThreadTaskQueueCleanup); + non_waking_task_runner_ = non_waking_task_queue_->CreateTaskRunner( + TaskType::kMainThreadTaskQueueNonWaking); // TaskQueueThrottler requires some task runners, then initialize // TaskQueueThrottler after task queues/runners are initialized. @@ -307,6 +305,9 @@ MainThreadSchedulerImpl::MainThreadSchedulerImpl( main_thread_only() .compositor_priority_experiments.OnMainThreadSchedulerInitialized(); + main_thread_only().current_policy.find_in_page_priority() = + find_in_page_budget_pool_controller_->CurrentTaskPriority(); + g_main_thread_scheduler = this; } @@ -319,6 +320,8 @@ MainThreadSchedulerImpl::~MainThreadSchedulerImpl() { pair.first->ShutdownTaskQueue(); } + UnregisterTimeDomain(&non_waking_time_domain_); + if (virtual_time_domain_) UnregisterTimeDomain(virtual_time_domain_.get()); @@ -552,9 +555,6 @@ MainThreadSchedulerImpl::AnyThread::AnyThread( &main_thread_scheduler_impl->tracing_controller_) {} MainThreadSchedulerImpl::SchedulingSettings::SchedulingSettings() { - high_priority_input = - base::FeatureList::IsEnabled(kHighPriorityInputOnMainThread); - low_priority_background_page = base::FeatureList::IsEnabled(kLowPriorityForBackgroundPages); best_effort_background_page = @@ -607,9 +607,6 @@ MainThreadSchedulerImpl::SchedulingSettings::SchedulingSettings() { } } } - - FrameSchedulerImpl::InitializeTaskTypeQueueTraitsMap( - frame_task_types_to_queue_traits); } MainThreadSchedulerImpl::AnyThread::~AnyThread() = default; @@ -662,6 +659,11 @@ std::unique_ptr<Thread> MainThreadSchedulerImpl::CreateMainThread() { return std::make_unique<MainThread>(this); } +std::unique_ptr<WebWidgetScheduler> +MainThreadSchedulerImpl::CreateWidgetScheduler() { + return std::make_unique<WidgetScheduler>(this); +} + scoped_refptr<base::SingleThreadTaskRunner> MainThreadSchedulerImpl::ControlTaskRunner() { return control_task_runner_; @@ -672,12 +674,6 @@ MainThreadSchedulerImpl::DefaultTaskRunner() { return helper_.DefaultTaskRunner(); } -scoped_refptr<base::SingleThreadTaskRunner> -MainThreadSchedulerImpl::InputTaskRunner() { - helper_.CheckOnValidThread(); - return input_task_runner_; -} - scoped_refptr<SingleThreadIdleTaskRunner> MainThreadSchedulerImpl::IdleTaskRunner() { return idle_helper_.IdleTaskRunner(); @@ -709,11 +705,6 @@ MainThreadSchedulerImpl::CompositorTaskQueue() { return compositor_task_queue_; } -scoped_refptr<MainThreadTaskQueue> MainThreadSchedulerImpl::InputTaskQueue() { - helper_.CheckOnValidThread(); - return input_task_queue_; -} - scoped_refptr<MainThreadTaskQueue> MainThreadSchedulerImpl::V8TaskQueue() { helper_.CheckOnValidThread(); return v8_task_queue_; @@ -1269,13 +1260,15 @@ void MainThreadSchedulerImpl::UpdateForInputEventOnCompositorThread( } void MainThreadSchedulerImpl::WillPostInputEventToMainThread( - WebInputEvent::Type web_input_event_type) { + WebInputEvent::Type web_input_event_type, + const WebInputEventAttribution& web_input_event_attribution) { base::AutoLock lock(any_thread_lock_); any_thread().pending_input_monitor.OnEnqueue(web_input_event_type); } void MainThreadSchedulerImpl::WillHandleInputEventOnMainThread( - WebInputEvent::Type web_input_event_type) { + WebInputEvent::Type web_input_event_type, + const WebInputEventAttribution& web_input_event_attribution) { helper_.CheckOnValidThread(); base::AutoLock lock(any_thread_lock_); @@ -1484,7 +1477,7 @@ void MainThreadSchedulerImpl::UpdatePolicyLocked(UpdateType update_type) { break; case UseCase::kNone: - // It's only safe to block tasks that if we are expecting a compositor + // It's only safe to block tasks if we are expecting a compositor // driven gesture. if (main_thread_only().blocking_input_expected_soon && any_thread().last_gesture_was_compositor_driven) { @@ -1549,6 +1542,9 @@ void MainThreadSchedulerImpl::UpdatePolicyLocked(UpdateType update_type) { new_policy.should_disable_throttling() = main_thread_only().use_virtual_time; + new_policy.find_in_page_priority() = + find_in_page_budget_pool_controller_->CurrentTaskPriority(); + // Tracing is done before the early out check, because it's quite possible we // will otherwise miss this information in traces. CreateTraceEventObjectSnapshotLocked(); @@ -1810,6 +1806,9 @@ void MainThreadSchedulerImpl::DisableVirtualTimeForTesting() { virtual_time_control_task_queue_ = nullptr; ApplyVirtualTimePolicy(); + main_thread_only().initial_virtual_time = base::Time(); + main_thread_only().initial_virtual_time_ticks = base::TimeTicks(); + // Reset the MetricsHelper because it gets confused by time going backwards. base::TimeTicks now = tick_clock()->NowTicks(); main_thread_only().metrics_helper.ResetForTest(now); @@ -1954,13 +1953,26 @@ void MainThreadSchedulerImpl::CreateTraceEventObjectSnapshotLocked() const { std::unique_ptr<base::trace_event::ConvertableToTraceFormat> MainThreadSchedulerImpl::AsValueLocked(base::TimeTicks optional_now) const { + auto state = std::make_unique<base::trace_event::TracedValue>(); + AsValueIntoLocked(state.get(), optional_now); + return std::move(state); +} + +std::string MainThreadSchedulerImpl::ToString() const { + base::AutoLock lock(any_thread_lock_); + base::trace_event::TracedValueJSON value; + AsValueIntoLocked(&value, base::TimeTicks()); + return value.ToJSON(); +} + +void MainThreadSchedulerImpl::AsValueIntoLocked( + base::trace_event::TracedValue* state, + base::TimeTicks optional_now) const { helper_.CheckOnValidThread(); any_thread_lock_.AssertAcquired(); if (optional_now.is_null()) optional_now = helper_.NowTicks(); - std::unique_ptr<base::trace_event::TracedValue> state( - new base::trace_event::TracedValue()); state->SetBoolean( "has_visible_render_widget_with_touch_handler", main_thread_only().has_visible_render_widget_with_touch_handler); @@ -2024,13 +2036,13 @@ MainThreadSchedulerImpl::AsValueLocked(base::TimeTicks optional_now) const { state->BeginDictionary("page_schedulers"); for (PageSchedulerImpl* page_scheduler : main_thread_only().page_schedulers) { state->BeginDictionaryWithCopiedName(PointerToString(page_scheduler)); - page_scheduler->AsValueInto(state.get()); + page_scheduler->AsValueInto(state); state->EndDictionary(); } state->EndDictionary(); state->BeginDictionary("policy"); - main_thread_only().current_policy.AsValueInto(state.get()); + main_thread_only().current_policy.AsValueInto(state); state->EndDictionary(); // TODO(skyostil): Can we somehow trace how accurate these estimates were? @@ -2046,14 +2058,12 @@ MainThreadSchedulerImpl::AsValueLocked(base::TimeTicks optional_now) const { .InMillisecondsF()); state->SetBoolean("in_idle_period", any_thread().in_idle_period); - any_thread().user_model.AsValueInto(state.get()); - render_widget_scheduler_signals_.AsValueInto(state.get()); + any_thread().user_model.AsValueInto(state); + render_widget_scheduler_signals_.AsValueInto(state); state->BeginDictionary("task_queue_throttler"); - task_queue_throttler_->AsValueInto(state.get(), optional_now); + task_queue_throttler_->AsValueInto(state, optional_now); state->EndDictionary(); - - return std::move(state); } bool MainThreadSchedulerImpl::TaskQueuePolicy::IsQueueEnabled( @@ -2090,6 +2100,8 @@ MainThreadSchedulerImpl::Policy::Policy() should_prioritize_loading_with_compositing_(false), compositor_priority_( base::sequence_manager::TaskQueue::QueuePriority::kNormalPriority), + find_in_page_priority_(FindInPageBudgetPoolController:: + kFindInPageBudgetNotExhaustedPriority), use_case_(UseCase::kNone) {} void MainThreadSchedulerImpl::Policy::AsValueInto( @@ -2336,6 +2348,11 @@ MainThreadSchedulerImpl::CompositorTaskRunner() { return compositor_task_runner_; } +scoped_refptr<base::SingleThreadTaskRunner> +MainThreadSchedulerImpl::NonWakingTaskRunner() { + return non_waking_task_runner_; +} + std::unique_ptr<PageScheduler> MainThreadSchedulerImpl::CreatePageScheduler( PageScheduler::Delegate* delegate) { return std::make_unique<PageSchedulerImpl>(delegate, this); @@ -2482,6 +2499,9 @@ void MainThreadSchedulerImpl::OnTaskCompleted( main_thread_only().compositor_priority_experiments.OnTaskCompleted( queue.get(), main_thread_only().current_policy.compositor_priority(), task_timing); + + find_in_page_budget_pool_controller_->OnTaskCompleted(queue.get(), + task_timing); } void MainThreadSchedulerImpl::RecordTaskUkm( @@ -2577,7 +2597,7 @@ TaskQueue::QueuePriority MainThreadSchedulerImpl::ComputePriority( MainThreadTaskQueue* task_queue) const { DCHECK(task_queue); - // If |task_queue| is associated to a frame, the the frame scheduler computes + // If |task_queue| is associated to a frame, then the frame scheduler computes // the priority. FrameSchedulerImpl* frame_scheduler = task_queue->GetFrameScheduler(); @@ -2735,7 +2755,9 @@ bool MainThreadSchedulerImpl::ShouldUpdateTaskQueuePriorities( return old_policy.use_case() != main_thread_only().current_policy.use_case() || old_policy.compositor_priority() != - main_thread_only().current_policy.compositor_priority(); + main_thread_only().current_policy.compositor_priority() || + old_policy.find_in_page_priority() != + main_thread_only().current_policy.find_in_page_priority(); } UseCase MainThreadSchedulerImpl::current_use_case() const { diff --git a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.h b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.h index 612cd8ea852..5914b7f7175 100644 --- a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.h +++ b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.h @@ -32,11 +32,13 @@ #include "third_party/blink/renderer/platform/scheduler/main_thread/auto_advancing_virtual_time_domain.h" #include "third_party/blink/renderer/platform/scheduler/main_thread/compositor_priority_experiments.h" #include "third_party/blink/renderer/platform/scheduler/main_thread/deadline_task_runner.h" +#include "third_party/blink/renderer/platform/scheduler/main_thread/find_in_page_budget_pool_controller.h" #include "third_party/blink/renderer/platform/scheduler/main_thread/idle_time_estimator.h" #include "third_party/blink/renderer/platform/scheduler/main_thread/main_thread_metrics_helper.h" #include "third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_helper.h" #include "third_party/blink/renderer/platform/scheduler/main_thread/main_thread_task_queue.h" #include "third_party/blink/renderer/platform/scheduler/main_thread/memory_purge_manager.h" +#include "third_party/blink/renderer/platform/scheduler/main_thread/non_waking_time_domain.h" #include "third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl.h" #include "third_party/blink/renderer/platform/scheduler/main_thread/pending_user_input.h" #include "third_party/blink/renderer/platform/scheduler/main_thread/prioritize_compositing_after_input_experiment.h" @@ -96,9 +98,6 @@ class PLATFORM_EXPORT MainThreadSchedulerImpl struct SchedulingSettings { SchedulingSettings(); - // High priority input experiment. - bool high_priority_input; - // Background page priority experiment (crbug.com/848835). bool low_priority_background_page; bool best_effort_background_page; @@ -137,14 +136,6 @@ class PLATFORM_EXPORT MainThreadSchedulerImpl std::array<base::sequence_manager::TaskQueue::QueuePriority, net::RequestPrioritySize::NUM_PRIORITIES> net_to_blink_priority; - - using FrameTaskTypeToQueueTraitsArray = - std::array<base::Optional<MainThreadTaskQueue::QueueTraits>, - static_cast<size_t>(TaskType::kCount)>; - // Array of QueueTraits indexed by TaskType, containing TaskType::kCount - // entries. This is initialized early with all valid entries. Entries that - // aren't valid task types, i.e. non-frame level, are base::nullopt. - FrameTaskTypeToQueueTraitsArray frame_task_types_to_queue_traits; }; static const char* UseCaseToString(UseCase use_case); @@ -170,9 +161,11 @@ class PLATFORM_EXPORT MainThreadSchedulerImpl // WebThreadScheduler implementation: std::unique_ptr<Thread> CreateMainThread() override; + std::unique_ptr<WebWidgetScheduler> CreateWidgetScheduler() override; // Note: this is also shared by the ThreadScheduler interface. scoped_refptr<base::SingleThreadTaskRunner> IPCTaskRunner() override; scoped_refptr<base::SingleThreadTaskRunner> CleanupTaskRunner() override; + scoped_refptr<base::SingleThreadTaskRunner> NonWakingTaskRunner() override; scoped_refptr<base::SingleThreadTaskRunner> DeprecatedDefaultTaskRunner() override; std::unique_ptr<WebRenderWidgetSchedulingState> @@ -185,9 +178,11 @@ class PLATFORM_EXPORT MainThreadSchedulerImpl const WebInputEvent& web_input_event, InputEventState event_state) override; void WillPostInputEventToMainThread( - WebInputEvent::Type web_input_event_type) override; + WebInputEvent::Type web_input_event_type, + const WebInputEventAttribution& web_input_event_attribution) override; void WillHandleInputEventOnMainThread( - WebInputEvent::Type web_input_event_type) override; + WebInputEvent::Type web_input_event_type, + const WebInputEventAttribution& web_input_event_attribution) override; void DidHandleInputEventOnMainThread(const WebInputEvent& web_input_event, WebInputEventResult result) override; void DidAnimateForInputOnCompositorThread() override; @@ -240,7 +235,6 @@ class PLATFORM_EXPORT MainThreadSchedulerImpl // WebThreadScheduler implementation: scoped_refptr<base::SingleThreadTaskRunner> DefaultTaskRunner() override; - scoped_refptr<base::SingleThreadTaskRunner> InputTaskRunner() override; // The following functions are defined in both WebThreadScheduler and // ThreadScheduler, and have the same function signatures -- see above. @@ -428,11 +422,14 @@ class PLATFORM_EXPORT MainThreadSchedulerImpl return main_thread_only().main_thread_compositing_is_fast; } + QueuePriority find_in_page_priority() const { + return main_thread_only().current_policy.find_in_page_priority(); + } + protected: scoped_refptr<MainThreadTaskQueue> ControlTaskQueue(); scoped_refptr<MainThreadTaskQueue> DefaultTaskQueue(); scoped_refptr<MainThreadTaskQueue> CompositorTaskQueue(); - scoped_refptr<MainThreadTaskQueue> InputTaskQueue(); scoped_refptr<MainThreadTaskQueue> V8TaskQueue(); // A control task queue which also respects virtual time. Only available if // virtual time has been enabled. @@ -459,6 +456,7 @@ class PLATFORM_EXPORT MainThreadSchedulerImpl friend class main_thread_scheduler_impl_unittest::MainThreadSchedulerImplTest; friend class CompositorPriorityExperiments; + friend class FindInPageBudgetPoolController; FRIEND_TEST_ALL_PREFIXES( main_thread_scheduler_impl_unittest::MainThreadSchedulerImplTest, @@ -577,6 +575,14 @@ class PLATFORM_EXPORT MainThreadSchedulerImpl return compositor_priority_; } + base::sequence_manager::TaskQueue::QueuePriority& find_in_page_priority() { + return find_in_page_priority_; + } + base::sequence_manager::TaskQueue::QueuePriority find_in_page_priority() + const { + return find_in_page_priority_; + } + UseCase& use_case() { return use_case_; } UseCase use_case() const { return use_case_; } @@ -587,6 +593,7 @@ class PLATFORM_EXPORT MainThreadSchedulerImpl should_prioritize_loading_with_compositing_ == other.should_prioritize_loading_with_compositing_ && compositor_priority_ == other.compositor_priority_ && + find_in_page_priority_ == other.find_in_page_priority_ && use_case_ == other.use_case_; } @@ -602,6 +609,8 @@ class PLATFORM_EXPORT MainThreadSchedulerImpl // MainThread::QueueClass). base::sequence_manager::TaskQueue::QueuePriority compositor_priority_; + base::sequence_manager::TaskQueue::QueuePriority find_in_page_priority_; + UseCase use_case_; std::array<TaskQueuePolicy, @@ -647,6 +656,8 @@ class PLATFORM_EXPORT MainThreadSchedulerImpl base::TimeTicks optional_now) const; void CreateTraceEventObjectSnapshotLocked() const; + std::string ToString() const; + static bool ShouldPrioritizeInputEvent(const WebInputEvent& web_input_event); // The amount of time which idle periods can continue being scheduled when the @@ -775,6 +786,9 @@ class PLATFORM_EXPORT MainThreadSchedulerImpl // task. void DispatchOnTaskCompletionCallbacks(); + void AsValueIntoLocked(base::trace_event::TracedValue*, + base::TimeTicks optional_now) const; + // Indicates that scheduler has been shutdown. // It should be accessed only on the main thread, but couldn't be a member // of MainThreadOnly struct because last might be destructed before we @@ -799,14 +813,14 @@ class PLATFORM_EXPORT MainThreadSchedulerImpl std::unique_ptr<TaskQueueThrottler> task_queue_throttler_; RenderWidgetSignals render_widget_scheduler_signals_; + std::unique_ptr<FindInPageBudgetPoolController> + find_in_page_budget_pool_controller_; + const scoped_refptr<MainThreadTaskQueue> control_task_queue_; const scoped_refptr<MainThreadTaskQueue> compositor_task_queue_; - const scoped_refptr<MainThreadTaskQueue> input_task_queue_; scoped_refptr<MainThreadTaskQueue> virtual_time_control_task_queue_; std::unique_ptr<base::sequence_manager::TaskQueue::QueueEnabledVoter> compositor_task_queue_enabled_voter_; - std::unique_ptr<base::sequence_manager::TaskQueue::QueueEnabledVoter> - input_task_queue_enabled_voter_; using TaskQueueVoterMap = std::map< scoped_refptr<MainThreadTaskQueue>, @@ -818,20 +832,22 @@ class PLATFORM_EXPORT MainThreadSchedulerImpl scoped_refptr<MainThreadTaskQueue> ipc_task_queue_; scoped_refptr<MainThreadTaskQueue> cleanup_task_queue_; scoped_refptr<MainThreadTaskQueue> memory_purge_task_queue_; + scoped_refptr<MainThreadTaskQueue> non_waking_task_queue_; scoped_refptr<base::SingleThreadTaskRunner> v8_task_runner_; scoped_refptr<base::SingleThreadTaskRunner> compositor_task_runner_; scoped_refptr<base::SingleThreadTaskRunner> control_task_runner_; - scoped_refptr<base::SingleThreadTaskRunner> input_task_runner_; scoped_refptr<base::SingleThreadTaskRunner> ipc_task_runner_; scoped_refptr<base::SingleThreadTaskRunner> cleanup_task_runner_; + scoped_refptr<base::SingleThreadTaskRunner> non_waking_task_runner_; MemoryPurgeManager memory_purge_manager_; // Note |virtual_time_domain_| is lazily created. std::unique_ptr<AutoAdvancingVirtualTimeDomain> virtual_time_domain_; + NonWakingTimeDomain non_waking_time_domain_; - base::Closure update_policy_closure_; + base::RepeatingClosure update_policy_closure_; DeadlineTaskRunner delayed_update_policy_runner_; CancelableClosureHolder end_renderer_hidden_idle_period_closure_; diff --git a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl_unittest.cc b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl_unittest.cc index 807506d92e1..1f4d240aa79 100644 --- a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl_unittest.cc +++ b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl_unittest.cc @@ -11,6 +11,7 @@ #include "base/bind.h" #include "base/callback.h" #include "base/macros.h" +#include "base/memory/ptr_util.h" #include "base/run_loop.h" #include "base/single_thread_task_runner.h" #include "base/task/post_task.h" @@ -18,7 +19,6 @@ #include "base/task/sequence_manager/test/sequence_manager_for_test.h" #include "base/task/task_executor.h" #include "base/test/bind_test_util.h" -#include "base/test/gtest_util.h" #include "base/test/metrics/histogram_tester.h" #include "base/test/scoped_feature_list.h" #include "base/test/simple_test_tick_clock.h" @@ -27,12 +27,14 @@ #include "components/viz/common/frame_sinks/begin_frame_args.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" +#include "third_party/blink/public/common/input/web_mouse_wheel_event.h" +#include "third_party/blink/public/common/input/web_touch_event.h" #include "third_party/blink/public/common/page/launching_process_state.h" -#include "third_party/blink/public/platform/web_mouse_wheel_event.h" -#include "third_party/blink/public/platform/web_touch_event.h" +#include "third_party/blink/public/platform/scheduler/web_widget_scheduler.h" #include "third_party/blink/renderer/platform/scheduler/common/features.h" #include "third_party/blink/renderer/platform/scheduler/common/throttling/budget_pool.h" #include "third_party/blink/renderer/platform/scheduler/main_thread/auto_advancing_virtual_time_domain.h" +#include "third_party/blink/renderer/platform/scheduler/main_thread/find_in_page_budget_pool_controller.h" #include "third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.h" #include "third_party/blink/renderer/platform/scheduler/main_thread/frame_task_queue_controller.h" #include "third_party/blink/renderer/platform/scheduler/test/recording_task_time_observer.h" @@ -46,40 +48,23 @@ namespace scheduler { // To avoid symbol collisions in jumbo builds. namespace main_thread_scheduler_impl_unittest { -using testing::IsNull; using testing::Mock; using testing::NotNull; using InputEventState = WebThreadScheduler::InputEventState; using base::sequence_manager::FakeTask; using base::sequence_manager::FakeTaskTiming; -enum class AntiStarvationLogic { - kEnabled, - kDisabled, -}; - -std::string ToString(AntiStarvationLogic type) { - switch (type) { - case AntiStarvationLogic::kEnabled: - return "AntiStarvationLogicEnabled"; - case AntiStarvationLogic::kDisabled: - return "AntiStarvationLogicDisabled"; - } -} - -std::string GetTestNameSuffix( - const testing::TestParamInfo<AntiStarvationLogic>& info) { - return "With" + ToString(info.param); -} - class FakeInputEvent : public blink::WebInputEvent { public: explicit FakeInputEvent(blink::WebInputEvent::Type event_type, int modifiers = WebInputEvent::kNoModifiers) - : WebInputEvent(sizeof(FakeInputEvent), - event_type, + : WebInputEvent(event_type, modifiers, WebInputEvent::GetStaticTimeStampForTests()) {} + + std::unique_ptr<WebInputEvent> Clone() const override { + return std::make_unique<FakeInputEvent>(*this); + } }; class FakeTouchEvent : public blink::WebTouchEvent { @@ -254,7 +239,6 @@ class MainThreadSchedulerImplForTest : public MainThreadSchedulerImpl { using MainThreadSchedulerImpl::ControlTaskQueue; using MainThreadSchedulerImpl::DefaultTaskQueue; using MainThreadSchedulerImpl::EstimateLongestJankFreeTaskDuration; - using MainThreadSchedulerImpl::InputTaskQueue; using MainThreadSchedulerImpl::OnIdlePeriodEnded; using MainThreadSchedulerImpl::OnIdlePeriodStarted; using MainThreadSchedulerImpl::OnPendingTasksChanged; @@ -332,8 +316,7 @@ class MainThreadSchedulerImplForTest : public MainThreadSchedulerImpl { return os << MainThreadSchedulerImpl::UseCaseToString(use_case); } -class MainThreadSchedulerImplTest - : public testing::TestWithParam<AntiStarvationLogic> { +class MainThreadSchedulerImplTest : public testing::Test { public: MainThreadSchedulerImplTest(std::vector<base::Feature> features_to_enable, std::vector<base::Feature> features_to_disable) { @@ -341,8 +324,7 @@ class MainThreadSchedulerImplTest } MainThreadSchedulerImplTest() - : MainThreadSchedulerImplTest({kHighPriorityInputOnMainThread}, - {kPrioritizeCompositingAfterInput}) {} + : MainThreadSchedulerImplTest({}, {kPrioritizeCompositingAfterInput}) {} ~MainThreadSchedulerImplTest() override = default; @@ -353,8 +335,6 @@ class MainThreadSchedulerImplTest nullptr, test_task_runner_, test_task_runner_->GetMockTickClock(), base::sequence_manager::SequenceManager::Settings::Builder() .SetRandomisedSamplingEnabled(true) - .SetAntiStarvationLogicForPrioritiesDisabled( - GetParam() == AntiStarvationLogic::kDisabled) .Build()), base::nullopt)); if (initially_ensure_usecase_none_) @@ -381,7 +361,6 @@ class MainThreadSchedulerImplTest default_task_runner_ = scheduler_->DefaultTaskQueue()->task_runner(); compositor_task_runner_ = scheduler_->CompositorTaskQueue()->task_runner(); - input_task_runner_ = scheduler_->InputTaskQueue()->task_runner(); idle_task_runner_ = scheduler_->IdleTaskRunner(); v8_task_runner_ = scheduler_->V8TaskQueue()->task_runner(); @@ -391,12 +370,17 @@ class MainThreadSchedulerImplTest FrameSchedulerImpl::Create(page_scheduler_.get(), nullptr, nullptr, FrameScheduler::FrameType::kMainFrame); + widget_scheduler_ = scheduler_->CreateWidgetScheduler(); + input_task_runner_ = widget_scheduler_->InputTaskRunner(); + loading_control_task_runner_ = main_frame_scheduler_->FrameTaskQueueControllerForTest() ->GetTaskQueue( main_frame_scheduler_->LoadingControlTaskQueueTraits()) ->task_runner(); timer_task_runner_ = timer_task_queue()->task_runner(); + find_in_page_task_runner_ = main_frame_scheduler_->GetTaskRunner( + blink::TaskType::kInternalFindInPage); } TaskQueue* loading_task_queue() { @@ -414,7 +398,17 @@ class MainThreadSchedulerImplTest .get(); } + MainThreadTaskQueue* find_in_page_task_queue() { + auto* frame_task_queue_controller = + main_frame_scheduler_->FrameTaskQueueControllerForTest(); + + return frame_task_queue_controller + ->GetTaskQueue(main_frame_scheduler_->FindInPageTaskQueueTraits()) + .get(); + } + void TearDown() override { + widget_scheduler_.reset(); main_frame_scheduler_.reset(); page_scheduler_.reset(); scheduler_->Shutdown(); @@ -768,6 +762,11 @@ class MainThreadSchedulerImplTest FROM_HERE, base::BindOnce(&AppendToVectorTestTask, run_order, String::FromUTF8(task))); break; + case 'F': + find_in_page_task_runner_->PostTask( + FROM_HERE, base::BindOnce(&AppendToVectorTestTask, run_order, + String::FromUTF8(task))); + break; default: NOTREACHED(); } @@ -846,6 +845,7 @@ class MainThreadSchedulerImplTest std::unique_ptr<MainThreadSchedulerImplForTest> scheduler_; std::unique_ptr<PageSchedulerImpl> page_scheduler_; std::unique_ptr<FrameSchedulerImpl> main_frame_scheduler_; + std::unique_ptr<WebWidgetScheduler> widget_scheduler_; scoped_refptr<base::SingleThreadTaskRunner> default_task_runner_; scoped_refptr<base::SingleThreadTaskRunner> compositor_task_runner_; @@ -854,6 +854,7 @@ class MainThreadSchedulerImplTest scoped_refptr<SingleThreadIdleTaskRunner> idle_task_runner_; scoped_refptr<base::SingleThreadTaskRunner> timer_task_runner_; scoped_refptr<base::SingleThreadTaskRunner> v8_task_runner_; + scoped_refptr<base::SingleThreadTaskRunner> find_in_page_task_runner_; bool simulate_timer_task_ran_; bool initially_ensure_usecase_none_ = true; uint64_t next_begin_frame_number_ = viz::BeginFrameArgs::kStartingFrameNumber; @@ -861,13 +862,7 @@ class MainThreadSchedulerImplTest DISALLOW_COPY_AND_ASSIGN(MainThreadSchedulerImplTest); }; -INSTANTIATE_TEST_SUITE_P(All, - MainThreadSchedulerImplTest, - testing::Values(AntiStarvationLogic::kEnabled, - AntiStarvationLogic::kDisabled), - GetTestNameSuffix); - -TEST_P(MainThreadSchedulerImplTest, TestPostDefaultTask) { +TEST_F(MainThreadSchedulerImplTest, TestPostDefaultTask) { Vector<String> run_order; PostTestTasks(&run_order, "D1 D2 D3 D4"); @@ -875,7 +870,7 @@ TEST_P(MainThreadSchedulerImplTest, TestPostDefaultTask) { EXPECT_THAT(run_order, testing::ElementsAre("D1", "D2", "D3", "D4")); } -TEST_P(MainThreadSchedulerImplTest, TestPostDefaultAndCompositor) { +TEST_F(MainThreadSchedulerImplTest, TestPostDefaultAndCompositor) { Vector<String> run_order; PostTestTasks(&run_order, "D1 C1 P1"); base::RunLoop().RunUntilIdle(); @@ -884,7 +879,7 @@ TEST_P(MainThreadSchedulerImplTest, TestPostDefaultAndCompositor) { EXPECT_THAT(run_order, testing::Contains("P1")); } -TEST_P(MainThreadSchedulerImplTest, TestRentrantTask) { +TEST_F(MainThreadSchedulerImplTest, TestRentrantTask) { int count = 0; Vector<int> run_order; default_task_runner_->PostTask( @@ -896,7 +891,7 @@ TEST_P(MainThreadSchedulerImplTest, TestRentrantTask) { EXPECT_THAT(run_order, testing::ElementsAre(0, 1, 2, 3, 4)); } -TEST_P(MainThreadSchedulerImplTest, TestPostIdleTask) { +TEST_F(MainThreadSchedulerImplTest, TestPostIdleTask) { int run_count = 0; base::TimeTicks expected_deadline = Now() + base::TimeDelta::FromMilliseconds(2300); @@ -935,7 +930,7 @@ TEST_P(MainThreadSchedulerImplTest, TestPostIdleTask) { EXPECT_EQ(expected_deadline, deadline_in_task); } -TEST_P(MainThreadSchedulerImplTest, TestRepostingIdleTask) { +TEST_F(MainThreadSchedulerImplTest, TestRepostingIdleTask) { int run_count = 0; g_max_idle_task_reposts = 2; @@ -956,7 +951,7 @@ TEST_P(MainThreadSchedulerImplTest, TestRepostingIdleTask) { EXPECT_EQ(2, run_count); } -TEST_P(MainThreadSchedulerImplTest, TestIdleTaskExceedsDeadline) { +TEST_F(MainThreadSchedulerImplTest, TestIdleTaskExceedsDeadline) { int run_count = 0; // Post two UpdateClockToDeadlineIdleTestTask tasks. @@ -978,7 +973,7 @@ TEST_P(MainThreadSchedulerImplTest, TestIdleTaskExceedsDeadline) { EXPECT_EQ(2, run_count); } -TEST_P(MainThreadSchedulerImplTest, TestDelayedEndIdlePeriodCanceled) { +TEST_F(MainThreadSchedulerImplTest, TestDelayedEndIdlePeriodCanceled) { int run_count = 0; base::TimeTicks deadline_in_task; @@ -1018,7 +1013,7 @@ TEST_P(MainThreadSchedulerImplTest, TestDelayedEndIdlePeriodCanceled) { EXPECT_EQ(1, run_count); // We should still be in the new idle period. } -TEST_P(MainThreadSchedulerImplTest, TestDefaultPolicy) { +TEST_F(MainThreadSchedulerImplTest, TestDefaultPolicy) { EnsureUseCaseNone(); Vector<String> run_order; @@ -1034,7 +1029,7 @@ TEST_P(MainThreadSchedulerImplTest, TestDefaultPolicy) { EXPECT_EQ(UseCase::kNone, CurrentUseCase()); } -TEST_P(MainThreadSchedulerImplTest, TestDefaultPolicyWithSlowCompositor) { +TEST_F(MainThreadSchedulerImplTest, TestDefaultPolicyWithSlowCompositor) { RunSlowCompositorTask(); Vector<String> run_order; @@ -1048,7 +1043,7 @@ TEST_P(MainThreadSchedulerImplTest, TestDefaultPolicyWithSlowCompositor) { EXPECT_EQ(UseCase::kNone, CurrentUseCase()); } -TEST_P(MainThreadSchedulerImplTest, +TEST_F(MainThreadSchedulerImplTest, TestCompositorPolicy_CompositorHandlesInput_WithTouchHandler) { Vector<String> run_order; PostTestTasks(&run_order, "L1 I1 D1 C1 D2 C2"); @@ -1062,7 +1057,7 @@ TEST_P(MainThreadSchedulerImplTest, EXPECT_EQ(UseCase::kCompositorGesture, CurrentUseCase()); } -TEST_P(MainThreadSchedulerImplTest, +TEST_F(MainThreadSchedulerImplTest, TestCompositorPolicy_MainThreadHandlesInput_WithoutScrollUpdates) { Vector<String> run_order; PostTestTasks(&run_order, "L1 I1 D1 C1 D2 C2"); @@ -1076,7 +1071,7 @@ TEST_P(MainThreadSchedulerImplTest, EXPECT_EQ(UseCase::kMainThreadCustomInputHandling, CurrentUseCase()); } -TEST_P(MainThreadSchedulerImplTest, +TEST_F(MainThreadSchedulerImplTest, TestCompositorPolicy_MainThreadHandlesInput_WithoutPreventDefault) { Vector<String> run_order; PostTestTasks(&run_order, "L1 I1 D1 C1 D2 C2"); @@ -1090,7 +1085,7 @@ TEST_P(MainThreadSchedulerImplTest, EXPECT_EQ(UseCase::kCompositorGesture, CurrentUseCase()); } -TEST_P(MainThreadSchedulerImplTest, +TEST_F(MainThreadSchedulerImplTest, TestCompositorPolicy_CompositorHandlesInput_LongGestureDuration) { EnableIdleTasks(); SimulateCompositorGestureStart(TouchEventPolicy::kSendTouchStart); @@ -1120,7 +1115,7 @@ TEST_P(MainThreadSchedulerImplTest, EXPECT_EQ(UseCase::kCompositorGesture, CurrentUseCase()); } -TEST_P(MainThreadSchedulerImplTest, +TEST_F(MainThreadSchedulerImplTest, TestCompositorPolicy_CompositorHandlesInput_WithoutTouchHandler) { Vector<String> run_order; PostTestTasks(&run_order, "L1 I1 D1 C1 D2 C2"); @@ -1133,7 +1128,7 @@ TEST_P(MainThreadSchedulerImplTest, EXPECT_EQ(UseCase::kCompositorGesture, CurrentUseCase()); } -TEST_P(MainThreadSchedulerImplTest, +TEST_F(MainThreadSchedulerImplTest, TestCompositorPolicy_MainThreadHandlesInput_WithTouchHandler) { Vector<String> run_order; PostTestTasks(&run_order, "L1 I1 D1 C1 D2 C2"); @@ -1151,7 +1146,7 @@ TEST_P(MainThreadSchedulerImplTest, WebInputEventResult::kHandledSystem); } -TEST_P(MainThreadSchedulerImplTest, +TEST_F(MainThreadSchedulerImplTest, TestCompositorPolicy_MainThreadHandlesInput_WithoutTouchHandler) { Vector<String> run_order; PostTestTasks(&run_order, "L1 I1 D1 C1 D2 C2"); @@ -1168,7 +1163,7 @@ TEST_P(MainThreadSchedulerImplTest, WebInputEventResult::kHandledSystem); } -TEST_P(MainThreadSchedulerImplTest, +TEST_F(MainThreadSchedulerImplTest, TestCompositorPolicy_MainThreadHandlesInput_SingleEvent_PreventDefault) { Vector<String> run_order; PostTestTasks(&run_order, "L1 I1 D1 C1 D2 C2"); @@ -1189,7 +1184,7 @@ TEST_P(MainThreadSchedulerImplTest, EXPECT_EQ(UseCase::kMainThreadCustomInputHandling, CurrentUseCase()); } -TEST_P( +TEST_F( MainThreadSchedulerImplTest, TestCompositorPolicy_MainThreadHandlesInput_SingleEvent_NoPreventDefault) { Vector<String> run_order; @@ -1210,7 +1205,7 @@ TEST_P( EXPECT_EQ(UseCase::kTouchstart, CurrentUseCase()); } -TEST_P(MainThreadSchedulerImplTest, TestCompositorPolicy_DidAnimateForInput) { +TEST_F(MainThreadSchedulerImplTest, TestCompositorPolicy_DidAnimateForInput) { Vector<String> run_order; PostTestTasks(&run_order, "I1 D1 C1 D2 C2"); @@ -1226,7 +1221,7 @@ TEST_P(MainThreadSchedulerImplTest, TestCompositorPolicy_DidAnimateForInput) { EXPECT_EQ(UseCase::kCompositorGesture, CurrentUseCase()); } -TEST_P(MainThreadSchedulerImplTest, Navigation_ResetsTaskCostEstimations) { +TEST_F(MainThreadSchedulerImplTest, Navigation_ResetsTaskCostEstimations) { Vector<String> run_order; scheduler_->SetHasVisibleRenderWidgetWithTouchHandler(true); @@ -1245,7 +1240,7 @@ TEST_P(MainThreadSchedulerImplTest, Navigation_ResetsTaskCostEstimations) { EXPECT_THAT(run_order, testing::ElementsAre("C1", "T1")); } -TEST_P(MainThreadSchedulerImplTest, TestTouchstartPolicy_Compositor) { +TEST_F(MainThreadSchedulerImplTest, TestTouchstartPolicy_Compositor) { Vector<String> run_order; PostTestTasks(&run_order, "L1 D1 C1 D2 C2 T1 T2"); @@ -1282,7 +1277,7 @@ TEST_P(MainThreadSchedulerImplTest, TestTouchstartPolicy_Compositor) { EXPECT_THAT(run_order, testing::ElementsAre("L1", "T1", "T2")); } -TEST_P(MainThreadSchedulerImplTest, TestTouchstartPolicy_MainThread) { +TEST_F(MainThreadSchedulerImplTest, TestTouchstartPolicy_MainThread) { Vector<String> run_order; PostTestTasks(&run_order, "L1 D1 C1 D2 C2 T1 T2"); @@ -1336,13 +1331,7 @@ class DefaultUseCaseTest : public MainThreadSchedulerImplTest { } }; -INSTANTIATE_TEST_SUITE_P(All, - DefaultUseCaseTest, - testing::Values(AntiStarvationLogic::kEnabled, - AntiStarvationLogic::kDisabled), - GetTestNameSuffix); - -TEST_P(DefaultUseCaseTest, InitiallyInEarlyLoadingUseCase) { +TEST_F(DefaultUseCaseTest, InitiallyInEarlyLoadingUseCase) { // Should be early loading by default. EXPECT_EQ(UseCase::kEarlyLoading, ForceUpdatePolicyAndGetCurrentUseCase()); @@ -1362,7 +1351,7 @@ class PrioritizeCompositingAndLoadingInUseCaseLoadingTest {}) {} }; -TEST_P(PrioritizeCompositingAndLoadingInUseCaseLoadingTest, LoadingUseCase) { +TEST_F(PrioritizeCompositingAndLoadingInUseCaseLoadingTest, LoadingUseCase) { Vector<String> run_order; PostTestTasks(&run_order, "I1 D1 C1 T1 L1 D2 C2 T2 L2"); @@ -1386,15 +1375,8 @@ TEST_P(PrioritizeCompositingAndLoadingInUseCaseLoadingTest, LoadingUseCase) { EnableIdleTasks(); base::RunLoop().RunUntilIdle(); - String default_order_expected[] = {"D1", - "C1" - "T1", - "L1", - "D2", - "C2", - "T2", - "L2", - "I1"}; + String default_order_expected[] = {"D1", "C1", "T1", "L1", "D2", + "C2", "T2", "L2", "I1"}; EXPECT_THAT(run_order, testing::ElementsAreArray(default_order_expected)); EXPECT_EQ(UseCase::kLoading, CurrentUseCase()); @@ -1413,7 +1395,7 @@ TEST_P(PrioritizeCompositingAndLoadingInUseCaseLoadingTest, LoadingUseCase) { EXPECT_EQ(UseCase::kNone, CurrentUseCase()); } -TEST_P(MainThreadSchedulerImplTest, +TEST_F(MainThreadSchedulerImplTest, EventConsumedOnCompositorThread_IgnoresMouseMove_WhenMouseUp) { RunSlowCompositorTask(); @@ -1430,7 +1412,7 @@ TEST_P(MainThreadSchedulerImplTest, EXPECT_THAT(run_order, testing::ElementsAre("D1", "C1", "D2", "C2", "I1")); } -TEST_P(MainThreadSchedulerImplTest, +TEST_F(MainThreadSchedulerImplTest, EventForwardedToMainThread_IgnoresMouseMove_WhenMouseUp) { RunSlowCompositorTask(); @@ -1447,7 +1429,7 @@ TEST_P(MainThreadSchedulerImplTest, EXPECT_THAT(run_order, testing::ElementsAre("D1", "C1", "D2", "C2", "I1")); } -TEST_P(MainThreadSchedulerImplTest, +TEST_F(MainThreadSchedulerImplTest, EventConsumedOnCompositorThread_MouseMove_WhenMouseDown) { Vector<String> run_order; PostTestTasks(&run_order, "I1 D1 C1 D2 C2"); @@ -1465,7 +1447,7 @@ TEST_P(MainThreadSchedulerImplTest, EXPECT_THAT(run_order, testing::ElementsAre("D1", "D2", "C1", "C2", "I1")); } -TEST_P(MainThreadSchedulerImplTest, +TEST_F(MainThreadSchedulerImplTest, EventForwardedToMainThread_MouseMove_WhenMouseDown) { Vector<String> run_order; PostTestTasks(&run_order, "I1 D1 C1 D2 C2"); @@ -1484,7 +1466,7 @@ TEST_P(MainThreadSchedulerImplTest, WebInputEventResult::kHandledSystem); } -TEST_P(MainThreadSchedulerImplTest, +TEST_F(MainThreadSchedulerImplTest, EventForwardedToMainThread_MouseMove_WhenMouseDown_AfterMouseWheel) { // Simulate a main thread driven mouse wheel scroll gesture. SimulateMainThreadGestureStart(TouchEventPolicy::kSendTouchStart, @@ -1515,7 +1497,7 @@ TEST_P(MainThreadSchedulerImplTest, EXPECT_THAT(run_order, testing::ElementsAre("C1", "C2", "D1", "D2", "I1")); } -TEST_P(MainThreadSchedulerImplTest, EventForwardedToMainThread_MouseClick) { +TEST_F(MainThreadSchedulerImplTest, EventForwardedToMainThread_MouseClick) { // A mouse click should be detected as main thread input handling, which means // we won't try to defer expensive tasks because of one. We can, however, // prioritize compositing/input handling. @@ -1539,7 +1521,7 @@ TEST_P(MainThreadSchedulerImplTest, EventForwardedToMainThread_MouseClick) { EXPECT_THAT(run_order, testing::ElementsAre("C1", "C2", "D1", "D2", "I1")); } -TEST_P(MainThreadSchedulerImplTest, +TEST_F(MainThreadSchedulerImplTest, EventConsumedOnCompositorThread_MouseWheel) { Vector<String> run_order; PostTestTasks(&run_order, "I1 D1 C1 D2 C2"); @@ -1554,7 +1536,7 @@ TEST_P(MainThreadSchedulerImplTest, EXPECT_EQ(UseCase::kCompositorGesture, CurrentUseCase()); } -TEST_P(MainThreadSchedulerImplTest, +TEST_F(MainThreadSchedulerImplTest, EventForwardedToMainThread_MouseWheel_PreventDefault) { Vector<String> run_order; PostTestTasks(&run_order, "I1 D1 C1 D2 C2"); @@ -1569,7 +1551,7 @@ TEST_P(MainThreadSchedulerImplTest, EXPECT_EQ(UseCase::kMainThreadCustomInputHandling, CurrentUseCase()); } -TEST_P(MainThreadSchedulerImplTest, +TEST_F(MainThreadSchedulerImplTest, EventForwardedToMainThread_NoPreventDefault) { Vector<String> run_order; PostTestTasks(&run_order, "I1 D1 C1 D2 C2"); @@ -1593,7 +1575,7 @@ TEST_P(MainThreadSchedulerImplTest, EXPECT_EQ(UseCase::kMainThreadGesture, CurrentUseCase()); } -TEST_P( +TEST_F( MainThreadSchedulerImplTest, EventForwardedToMainThreadAndBackToCompositor_MouseWheel_NoPreventDefault) { Vector<String> run_order; @@ -1618,7 +1600,7 @@ TEST_P( EXPECT_EQ(UseCase::kCompositorGesture, CurrentUseCase()); } -TEST_P(MainThreadSchedulerImplTest, +TEST_F(MainThreadSchedulerImplTest, EventConsumedOnCompositorThread_IgnoresKeyboardEvents) { RunSlowCompositorTask(); @@ -1635,7 +1617,7 @@ TEST_P(MainThreadSchedulerImplTest, EXPECT_EQ(UseCase::kNone, CurrentUseCase()); } -TEST_P(MainThreadSchedulerImplTest, +TEST_F(MainThreadSchedulerImplTest, EventForwardedToMainThread_IgnoresKeyboardEvents) { RunSlowCompositorTask(); @@ -1656,7 +1638,7 @@ TEST_P(MainThreadSchedulerImplTest, WebInputEventResult::kHandledSystem); } -TEST_P(MainThreadSchedulerImplTest, +TEST_F(MainThreadSchedulerImplTest, TestMainthreadScrollingUseCaseDoesNotStarveDefaultTasks) { SimulateMainThreadGestureStart(TouchEventPolicy::kDontSendTouchStart, blink::WebInputEvent::kGestureScrollBegin); @@ -1675,21 +1657,10 @@ TEST_P(MainThreadSchedulerImplTest, InputEventState::EVENT_CONSUMED_BY_COMPOSITOR); base::RunLoop().RunUntilIdle(); - switch (GetParam()) { - case AntiStarvationLogic::kEnabled: - // Ensure that the default D1 task gets to run at some point before the - // final C2 compositor task. - EXPECT_THAT(run_order, testing::ElementsAre("C1", "D1", "C2")); - break; - case AntiStarvationLogic::kDisabled: - // Without anti-starvation logic, the default D1 task should get stuck at - // the end. - EXPECT_THAT(run_order, testing::ElementsAre("C1", "C2", "D1")); - break; - } + EXPECT_THAT(run_order, testing::ElementsAre("C1", "C2", "D1")); } -TEST_P(MainThreadSchedulerImplTest, +TEST_F(MainThreadSchedulerImplTest, TestCompositorPolicyEnds_CompositorHandlesInput) { SimulateCompositorGestureStart(TouchEventPolicy::kDontSendTouchStart); EXPECT_EQ(UseCase::kCompositorGesture, @@ -1699,7 +1670,7 @@ TEST_P(MainThreadSchedulerImplTest, EXPECT_EQ(UseCase::kNone, ForceUpdatePolicyAndGetCurrentUseCase()); } -TEST_P(MainThreadSchedulerImplTest, +TEST_F(MainThreadSchedulerImplTest, TestCompositorPolicyEnds_MainThreadHandlesInput) { SimulateMainThreadGestureStart(TouchEventPolicy::kDontSendTouchStart, blink::WebInputEvent::kGestureScrollBegin); @@ -1710,7 +1681,7 @@ TEST_P(MainThreadSchedulerImplTest, EXPECT_EQ(UseCase::kNone, ForceUpdatePolicyAndGetCurrentUseCase()); } -TEST_P(MainThreadSchedulerImplTest, TestTouchstartPolicyEndsAfterTimeout) { +TEST_F(MainThreadSchedulerImplTest, TestTouchstartPolicyEndsAfterTimeout) { Vector<String> run_order; PostTestTasks(&run_order, "L1 D1 C1 D2 C2"); @@ -1732,7 +1703,7 @@ TEST_P(MainThreadSchedulerImplTest, TestTouchstartPolicyEndsAfterTimeout) { EXPECT_THAT(run_order, testing::ElementsAre("L1", "D1", "D2")); } -TEST_P(MainThreadSchedulerImplTest, +TEST_F(MainThreadSchedulerImplTest, TestTouchstartPolicyEndsAfterConsecutiveTouchmoves) { Vector<String> run_order; PostTestTasks(&run_order, "L1 D1 C1 D2 C2"); @@ -1761,7 +1732,7 @@ TEST_P(MainThreadSchedulerImplTest, EXPECT_THAT(run_order, testing::ElementsAre("L1")); } -TEST_P(MainThreadSchedulerImplTest, TestIsHighPriorityWorkAnticipated) { +TEST_F(MainThreadSchedulerImplTest, TestIsHighPriorityWorkAnticipated) { bool is_anticipated_before = false; bool is_anticipated_after = false; @@ -1829,7 +1800,7 @@ TEST_P(MainThreadSchedulerImplTest, TestIsHighPriorityWorkAnticipated) { EXPECT_FALSE(is_anticipated_after); } -TEST_P(MainThreadSchedulerImplTest, TestShouldYield) { +TEST_F(MainThreadSchedulerImplTest, TestShouldYield) { bool should_yield_before = false; bool should_yield_after = false; @@ -1863,7 +1834,7 @@ TEST_P(MainThreadSchedulerImplTest, TestShouldYield) { EXPECT_TRUE(should_yield_after); } -TEST_P(MainThreadSchedulerImplTest, TestShouldYield_TouchStart) { +TEST_F(MainThreadSchedulerImplTest, TestShouldYield_TouchStart) { // Receiving a touchstart should immediately trigger yielding, even if // there's no immediately pending work in the compositor queue. EXPECT_FALSE(scheduler_->ShouldYieldForHighPriorityWork()); @@ -1874,7 +1845,7 @@ TEST_P(MainThreadSchedulerImplTest, TestShouldYield_TouchStart) { base::RunLoop().RunUntilIdle(); } -TEST_P(MainThreadSchedulerImplTest, SlowMainThreadInputEvent) { +TEST_F(MainThreadSchedulerImplTest, SlowMainThreadInputEvent) { EXPECT_EQ(UseCase::kNone, CurrentUseCase()); // An input event should bump us into input priority. @@ -1903,7 +1874,7 @@ TEST_P(MainThreadSchedulerImplTest, SlowMainThreadInputEvent) { EXPECT_EQ(UseCase::kNone, CurrentUseCase()); } -TEST_P(MainThreadSchedulerImplTest, OnlyOnePendingUrgentPolicyUpdate) { +TEST_F(MainThreadSchedulerImplTest, OnlyOnePendingUrgentPolicyUpdate) { for (int i = 0; i < 4; i++) { scheduler_->EnsureUrgentPolicyUpdatePostedOnMainThread(); } @@ -1911,7 +1882,7 @@ TEST_P(MainThreadSchedulerImplTest, OnlyOnePendingUrgentPolicyUpdate) { EXPECT_EQ(1, scheduler_->update_policy_count_); } -TEST_P(MainThreadSchedulerImplTest, OnePendingDelayedAndOneUrgentUpdatePolicy) { +TEST_F(MainThreadSchedulerImplTest, OnePendingDelayedAndOneUrgentUpdatePolicy) { scheduler_->ScheduleDelayedPolicyUpdate(Now(), base::TimeDelta::FromMilliseconds(1)); scheduler_->EnsureUrgentPolicyUpdatePostedOnMainThread(); @@ -1921,7 +1892,7 @@ TEST_P(MainThreadSchedulerImplTest, OnePendingDelayedAndOneUrgentUpdatePolicy) { EXPECT_EQ(2, scheduler_->update_policy_count_); } -TEST_P(MainThreadSchedulerImplTest, OneUrgentAndOnePendingDelayedUpdatePolicy) { +TEST_F(MainThreadSchedulerImplTest, OneUrgentAndOnePendingDelayedUpdatePolicy) { scheduler_->EnsureUrgentPolicyUpdatePostedOnMainThread(); scheduler_->ScheduleDelayedPolicyUpdate(Now(), base::TimeDelta::FromMilliseconds(1)); @@ -1931,7 +1902,7 @@ TEST_P(MainThreadSchedulerImplTest, OneUrgentAndOnePendingDelayedUpdatePolicy) { EXPECT_EQ(2, scheduler_->update_policy_count_); } -TEST_P(MainThreadSchedulerImplTest, UpdatePolicyCountTriggeredByOneInputEvent) { +TEST_F(MainThreadSchedulerImplTest, UpdatePolicyCountTriggeredByOneInputEvent) { // We expect DidHandleInputEventOnCompositorThread to post an urgent policy // update. scheduler_->DidHandleInputEventOnCompositorThread( @@ -1952,7 +1923,7 @@ TEST_P(MainThreadSchedulerImplTest, UpdatePolicyCountTriggeredByOneInputEvent) { EXPECT_EQ(2, scheduler_->update_policy_count_); } -TEST_P(MainThreadSchedulerImplTest, +TEST_F(MainThreadSchedulerImplTest, UpdatePolicyCountTriggeredByThreeInputEvents) { // We expect DidHandleInputEventOnCompositorThread to post // an urgent policy update. @@ -2002,7 +1973,7 @@ TEST_P(MainThreadSchedulerImplTest, EXPECT_EQ(3, scheduler_->update_policy_count_); } -TEST_P(MainThreadSchedulerImplTest, +TEST_F(MainThreadSchedulerImplTest, UpdatePolicyCountTriggeredByTwoInputEventsWithALongSeparatingDelay) { // We expect DidHandleInputEventOnCompositorThread to post an urgent policy // update. @@ -2040,7 +2011,7 @@ TEST_P(MainThreadSchedulerImplTest, EXPECT_EQ(4, scheduler_->update_policy_count_); } -TEST_P(MainThreadSchedulerImplTest, EnsureUpdatePolicyNotTriggeredTooOften) { +TEST_F(MainThreadSchedulerImplTest, EnsureUpdatePolicyNotTriggeredTooOften) { EXPECT_EQ(0, scheduler_->update_policy_count_); scheduler_->SetHasVisibleRenderWidgetWithTouchHandler(true); EXPECT_EQ(1, scheduler_->update_policy_count_); @@ -2094,7 +2065,7 @@ TEST_P(MainThreadSchedulerImplTest, EnsureUpdatePolicyNotTriggeredTooOften) { "none blocking input expected", "none")); } -TEST_P(MainThreadSchedulerImplTest, +TEST_F(MainThreadSchedulerImplTest, BlockingInputExpectedSoonWhenBlockInputEventSeen) { SimulateCompositorGestureStart(TouchEventPolicy::kSendTouchStart); EXPECT_TRUE(HaveSeenABlockingGesture()); @@ -2102,7 +2073,7 @@ TEST_P(MainThreadSchedulerImplTest, EXPECT_TRUE(BlockingInputExpectedSoon()); } -TEST_P(MainThreadSchedulerImplTest, +TEST_F(MainThreadSchedulerImplTest, BlockingInputNotExpectedSoonWhenNoBlockInputEventSeen) { SimulateCompositorGestureStart(TouchEventPolicy::kDontSendTouchStart); EXPECT_FALSE(HaveSeenABlockingGesture()); @@ -2110,7 +2081,7 @@ TEST_P(MainThreadSchedulerImplTest, EXPECT_FALSE(BlockingInputExpectedSoon()); } -TEST_P(MainThreadSchedulerImplTest, +TEST_F(MainThreadSchedulerImplTest, GetTaskExecutorForCurrentThreadInPostedTask) { base::TaskExecutor* task_executor = base::GetTaskExecutorForCurrentThread(); EXPECT_THAT(task_executor, NotNull()); @@ -2126,36 +2097,7 @@ TEST_P(MainThreadSchedulerImplTest, run_loop.Run(); } -TEST_P(MainThreadSchedulerImplTest, CurrentThread) { - EXPECT_EQ(scheduler_->DeprecatedDefaultTaskRunner(), - base::CreateSingleThreadTaskRunner({base::CurrentThread()})); - - // base::TaskPriority is currently ignored in blink. - EXPECT_EQ(scheduler_->DeprecatedDefaultTaskRunner(), - base::CreateSingleThreadTaskRunner( - {base::CurrentThread(), base::TaskPriority::BEST_EFFORT})); -} - -TEST_P(MainThreadSchedulerImplTest, GetContinuationTaskRunner) { - scoped_refptr<MainThreadTaskQueue> timer_tq = scheduler_->NewTimerTaskQueue( - MainThreadTaskQueue::QueueType::kFrameThrottleable, nullptr); - auto task_runner = timer_tq->CreateTaskRunner(TaskType::kJavascriptTimer); - - base::RunLoop run_loop; - task_runner->PostTask(FROM_HERE, base::BindLambdaForTesting([&]() { - EXPECT_EQ(task_runner, - base::GetContinuationTaskRunner()); - run_loop.Quit(); - })); - run_loop.Run(); -} - -TEST_P(MainThreadSchedulerImplTest, - GetContinuationTaskRunnerWithNoTaskRunning) { - EXPECT_DCHECK_DEATH(base::GetContinuationTaskRunner()); -} - -TEST_P(MainThreadSchedulerImplTest, TestBeginMainFrameNotExpectedUntil) { +TEST_F(MainThreadSchedulerImplTest, TestBeginMainFrameNotExpectedUntil) { base::TimeDelta ten_millis(base::TimeDelta::FromMilliseconds(10)); base::TimeTicks expected_deadline = Now() + ten_millis; base::TimeTicks deadline_in_task; @@ -2177,7 +2119,7 @@ TEST_P(MainThreadSchedulerImplTest, TestBeginMainFrameNotExpectedUntil) { EXPECT_EQ(expected_deadline, deadline_in_task); } -TEST_P(MainThreadSchedulerImplTest, TestLongIdlePeriod) { +TEST_F(MainThreadSchedulerImplTest, TestLongIdlePeriod) { base::TimeTicks expected_deadline = Now() + maximum_idle_period_duration(); base::TimeTicks deadline_in_task; int run_count = 0; @@ -2194,7 +2136,7 @@ TEST_P(MainThreadSchedulerImplTest, TestLongIdlePeriod) { EXPECT_EQ(expected_deadline, deadline_in_task); } -TEST_P(MainThreadSchedulerImplTest, TestLongIdlePeriodWithPendingDelayedTask) { +TEST_F(MainThreadSchedulerImplTest, TestLongIdlePeriodWithPendingDelayedTask) { base::TimeDelta pending_task_delay = base::TimeDelta::FromMilliseconds(30); base::TimeTicks expected_deadline = Now() + pending_task_delay; base::TimeTicks deadline_in_task; @@ -2211,7 +2153,7 @@ TEST_P(MainThreadSchedulerImplTest, TestLongIdlePeriodWithPendingDelayedTask) { EXPECT_EQ(expected_deadline, deadline_in_task); } -TEST_P(MainThreadSchedulerImplTest, +TEST_F(MainThreadSchedulerImplTest, TestLongIdlePeriodWithLatePendingDelayedTask) { base::TimeDelta pending_task_delay = base::TimeDelta::FromMilliseconds(10); base::TimeTicks deadline_in_task; @@ -2238,7 +2180,7 @@ TEST_P(MainThreadSchedulerImplTest, EXPECT_EQ(1, run_count); } -TEST_P(MainThreadSchedulerImplTest, TestLongIdlePeriodRepeating) { +TEST_F(MainThreadSchedulerImplTest, TestLongIdlePeriodRepeating) { Vector<base::TimeTicks> actual_deadlines; int run_count = 0; @@ -2277,7 +2219,7 @@ TEST_P(MainThreadSchedulerImplTest, TestLongIdlePeriodRepeating) { EXPECT_EQ(4, run_count); } -TEST_P(MainThreadSchedulerImplTest, TestLongIdlePeriodInTouchStartPolicy) { +TEST_F(MainThreadSchedulerImplTest, TestLongIdlePeriodInTouchStartPolicy) { base::TimeTicks deadline_in_task; int run_count = 0; @@ -2305,7 +2247,7 @@ void TestCanExceedIdleDeadlineIfRequiredTask(ThreadScheduler* scheduler, (*run_count)++; } -TEST_P(MainThreadSchedulerImplTest, CanExceedIdleDeadlineIfRequired) { +TEST_F(MainThreadSchedulerImplTest, CanExceedIdleDeadlineIfRequired) { int run_count = 0; bool can_exceed_idle_deadline = false; @@ -2355,7 +2297,7 @@ TEST_P(MainThreadSchedulerImplTest, CanExceedIdleDeadlineIfRequired) { EXPECT_FALSE(scheduler_->CanExceedIdleDeadlineIfRequired()); } -TEST_P(MainThreadSchedulerImplTest, TestRendererHiddenIdlePeriod) { +TEST_F(MainThreadSchedulerImplTest, TestRendererHiddenIdlePeriod) { int run_count = 0; g_max_idle_task_reposts = 2; @@ -2387,14 +2329,14 @@ TEST_P(MainThreadSchedulerImplTest, TestRendererHiddenIdlePeriod) { EXPECT_EQ(2, run_count); } -TEST_P(MainThreadSchedulerImplTest, TimerQueueEnabledByDefault) { +TEST_F(MainThreadSchedulerImplTest, TimerQueueEnabledByDefault) { Vector<String> run_order; PostTestTasks(&run_order, "T1 T2"); base::RunLoop().RunUntilIdle(); EXPECT_THAT(run_order, testing::ElementsAre("T1", "T2")); } -TEST_P(MainThreadSchedulerImplTest, StopAndResumeRenderer) { +TEST_F(MainThreadSchedulerImplTest, StopAndResumeRenderer) { Vector<String> run_order; PostTestTasks(&run_order, "T1 T2"); @@ -2407,7 +2349,7 @@ TEST_P(MainThreadSchedulerImplTest, StopAndResumeRenderer) { EXPECT_THAT(run_order, testing::ElementsAre("T1", "T2")); } -TEST_P(MainThreadSchedulerImplTest, StopAndThrottleTimerQueue) { +TEST_F(MainThreadSchedulerImplTest, StopAndThrottleTimerQueue) { Vector<String> run_order; PostTestTasks(&run_order, "T1 T2"); @@ -2419,7 +2361,7 @@ TEST_P(MainThreadSchedulerImplTest, StopAndThrottleTimerQueue) { EXPECT_THAT(run_order, testing::ElementsAre()); } -TEST_P(MainThreadSchedulerImplTest, ThrottleAndPauseRenderer) { +TEST_F(MainThreadSchedulerImplTest, ThrottleAndPauseRenderer) { Vector<String> run_order; PostTestTasks(&run_order, "T1 T2"); @@ -2431,7 +2373,7 @@ TEST_P(MainThreadSchedulerImplTest, ThrottleAndPauseRenderer) { EXPECT_THAT(run_order, testing::ElementsAre()); } -TEST_P(MainThreadSchedulerImplTest, MultipleStopsNeedMultipleResumes) { +TEST_F(MainThreadSchedulerImplTest, MultipleStopsNeedMultipleResumes) { Vector<String> run_order; PostTestTasks(&run_order, "T1 T2"); @@ -2454,7 +2396,7 @@ TEST_P(MainThreadSchedulerImplTest, MultipleStopsNeedMultipleResumes) { EXPECT_THAT(run_order, testing::ElementsAre("T1", "T2")); } -TEST_P(MainThreadSchedulerImplTest, PauseRenderer) { +TEST_F(MainThreadSchedulerImplTest, PauseRenderer) { // Tasks in some queues don't fire when the renderer is paused. Vector<String> run_order; PostTestTasks(&run_order, "D1 C1 L1 I1 T1"); @@ -2470,11 +2412,11 @@ TEST_P(MainThreadSchedulerImplTest, PauseRenderer) { EXPECT_THAT(run_order, testing::ElementsAre("L1", "T1")); } -TEST_P(MainThreadSchedulerImplTest, UseCaseToString) { +TEST_F(MainThreadSchedulerImplTest, UseCaseToString) { CheckAllUseCaseToString(); } -TEST_P(MainThreadSchedulerImplTest, MismatchedDidHandleInputEventOnMainThread) { +TEST_F(MainThreadSchedulerImplTest, MismatchedDidHandleInputEventOnMainThread) { // This should not DCHECK because there was no corresponding compositor side // call to DidHandleInputEventOnCompositorThread with // INPUT_EVENT_ACK_STATE_NOT_CONSUMED. There are legitimate reasons for the @@ -2484,7 +2426,7 @@ TEST_P(MainThreadSchedulerImplTest, MismatchedDidHandleInputEventOnMainThread) { WebInputEventResult::kHandledSystem); } -TEST_P(MainThreadSchedulerImplTest, BeginMainFrameOnCriticalPath) { +TEST_F(MainThreadSchedulerImplTest, BeginMainFrameOnCriticalPath) { ASSERT_FALSE(scheduler_->BeginMainFrameOnCriticalPath()); viz::BeginFrameArgs begin_frame_args = viz::BeginFrameArgs::Create( @@ -2499,7 +2441,7 @@ TEST_P(MainThreadSchedulerImplTest, BeginMainFrameOnCriticalPath) { ASSERT_FALSE(scheduler_->BeginMainFrameOnCriticalPath()); } -TEST_P(MainThreadSchedulerImplTest, ShutdownPreventsPostingOfNewTasks) { +TEST_F(MainThreadSchedulerImplTest, ShutdownPreventsPostingOfNewTasks) { main_frame_scheduler_.reset(); page_scheduler_.reset(); scheduler_->Shutdown(); @@ -2509,7 +2451,7 @@ TEST_P(MainThreadSchedulerImplTest, ShutdownPreventsPostingOfNewTasks) { EXPECT_THAT(run_order, testing::ElementsAre()); } -TEST_P(MainThreadSchedulerImplTest, +TEST_F(MainThreadSchedulerImplTest, EstimateLongestJankFreeTaskDuration_UseCase_NONE) { EnsureUseCaseNone(); EXPECT_EQ(UseCase::kNone, CurrentUseCase()); @@ -2517,7 +2459,7 @@ TEST_P(MainThreadSchedulerImplTest, scheduler_->EstimateLongestJankFreeTaskDuration()); } -TEST_P(MainThreadSchedulerImplTest, +TEST_F(MainThreadSchedulerImplTest, EstimateLongestJankFreeTaskDuration_UseCase_kCompositorGesture) { SimulateCompositorGestureStart(TouchEventPolicy::kDontSendTouchStart); EXPECT_EQ(UseCase::kCompositorGesture, @@ -2526,7 +2468,7 @@ TEST_P(MainThreadSchedulerImplTest, scheduler_->EstimateLongestJankFreeTaskDuration()); } -TEST_P(MainThreadSchedulerImplTest, +TEST_F(MainThreadSchedulerImplTest, EstimateLongestJankFreeTaskDuration_UseCase_EarlyLoading) { scheduler_->DidStartProvisionalLoad(true); EXPECT_EQ(UseCase::kEarlyLoading, ForceUpdatePolicyAndGetCurrentUseCase()); @@ -2534,7 +2476,7 @@ TEST_P(MainThreadSchedulerImplTest, scheduler_->EstimateLongestJankFreeTaskDuration()); } -TEST_P(MainThreadSchedulerImplTest, +TEST_F(MainThreadSchedulerImplTest, EstimateLongestJankFreeTaskDuration_UseCase_Loading) { scheduler_->DidStartProvisionalLoad(true); scheduler_->OnFirstContentfulPaint(); @@ -2543,7 +2485,7 @@ TEST_P(MainThreadSchedulerImplTest, scheduler_->EstimateLongestJankFreeTaskDuration()); } -TEST_P(MainThreadSchedulerImplTest, +TEST_F(MainThreadSchedulerImplTest, EstimateLongestJankFreeTaskDuration_UseCase_MAIN_THREAD_GESTURE) { SimulateMainThreadGestureStart(TouchEventPolicy::kSendTouchStart, blink::WebInputEvent::kGestureScrollUpdate); @@ -2569,7 +2511,7 @@ TEST_P(MainThreadSchedulerImplTest, scheduler_->EstimateLongestJankFreeTaskDuration()); } -TEST_P( +TEST_F( MainThreadSchedulerImplTest, EstimateLongestJankFreeTaskDuration_UseCase_MAIN_THREAD_CUSTOM_INPUT_HANDLING) { viz::BeginFrameArgs begin_frame_args = viz::BeginFrameArgs::Create( @@ -2594,7 +2536,7 @@ TEST_P( scheduler_->EstimateLongestJankFreeTaskDuration()); } -TEST_P(MainThreadSchedulerImplTest, +TEST_F(MainThreadSchedulerImplTest, EstimateLongestJankFreeTaskDuration_UseCase_SYNCHRONIZED_GESTURE) { SimulateCompositorGestureStart(TouchEventPolicy::kDontSendTouchStart); @@ -2654,7 +2596,7 @@ void SlowCountingTask(size_t* count, } } // namespace -TEST_P(MainThreadSchedulerImplTest, +TEST_F(MainThreadSchedulerImplTest, SYNCHRONIZED_GESTURE_TimerTaskThrottling_TimersStopped) { SimulateCompositorGestureStart(TouchEventPolicy::kSendTouchStart); @@ -2711,7 +2653,7 @@ TEST_P(MainThreadSchedulerImplTest, EXPECT_EQ(2u, count); } -TEST_P(MainThreadSchedulerImplTest, +TEST_F(MainThreadSchedulerImplTest, SYNCHRONIZED_GESTURE_TimerTaskThrottling_task_not_expensive) { SimulateCompositorGestureStart(TouchEventPolicy::kSendTouchStart); @@ -2749,7 +2691,7 @@ TEST_P(MainThreadSchedulerImplTest, EXPECT_EQ(500u, count); } -TEST_P(MainThreadSchedulerImplTest, DenyLongIdleDuringTouchStart) { +TEST_F(MainThreadSchedulerImplTest, DenyLongIdleDuringTouchStart) { scheduler_->DidHandleInputEventOnCompositorThread( FakeTouchEvent(blink::WebInputEvent::kTouchStart), InputEventState::EVENT_CONSUMED_BY_COMPOSITOR); @@ -2769,7 +2711,7 @@ TEST_P(MainThreadSchedulerImplTest, DenyLongIdleDuringTouchStart) { EXPECT_GE(next_time_to_check, base::TimeDelta()); } -TEST_P(MainThreadSchedulerImplTest, +TEST_F(MainThreadSchedulerImplTest, TestCompositorPolicy_TouchStartDuringFling) { scheduler_->SetHasVisibleRenderWidgetWithTouchHandler(true); scheduler_->DidAnimateForInputOnCompositorThread(); @@ -2785,7 +2727,7 @@ TEST_P(MainThreadSchedulerImplTest, EXPECT_EQ(UseCase::kTouchstart, ForceUpdatePolicyAndGetCurrentUseCase()); } -TEST_P(MainThreadSchedulerImplTest, SYNCHRONIZED_GESTURE_CompositingExpensive) { +TEST_F(MainThreadSchedulerImplTest, SYNCHRONIZED_GESTURE_CompositingExpensive) { SimulateCompositorGestureStart(TouchEventPolicy::kSendTouchStart); // With the compositor task taking 20ms, there is not enough time to run @@ -2824,7 +2766,7 @@ TEST_P(MainThreadSchedulerImplTest, SYNCHRONIZED_GESTURE_CompositingExpensive) { EXPECT_EQ(1000u, run_order.size()); } -TEST_P(MainThreadSchedulerImplTest, MAIN_THREAD_CUSTOM_INPUT_HANDLING) { +TEST_F(MainThreadSchedulerImplTest, MAIN_THREAD_CUSTOM_INPUT_HANDLING) { SimulateMainThreadGestureStart(TouchEventPolicy::kSendTouchStart, blink::WebInputEvent::kGestureScrollBegin); @@ -2865,7 +2807,7 @@ TEST_P(MainThreadSchedulerImplTest, MAIN_THREAD_CUSTOM_INPUT_HANDLING) { EXPECT_EQ(1000u, run_order.size()); } -TEST_P(MainThreadSchedulerImplTest, MAIN_THREAD_GESTURE) { +TEST_F(MainThreadSchedulerImplTest, MAIN_THREAD_GESTURE) { SimulateMainThreadGestureStart(TouchEventPolicy::kDontSendTouchStart, blink::WebInputEvent::kGestureScrollBegin); @@ -2909,7 +2851,7 @@ class MockRAILModeObserver : public RAILModeObserver { MOCK_METHOD1(OnRAILModeChanged, void(RAILMode rail_mode)); }; -TEST_P(MainThreadSchedulerImplTest, TestResponseRAILMode) { +TEST_F(MainThreadSchedulerImplTest, TestResponseRAILMode) { MockRAILModeObserver observer; scheduler_->AddRAILModeObserver(&observer); EXPECT_CALL(observer, OnRAILModeChanged(RAILMode::kResponse)); @@ -2921,7 +2863,7 @@ TEST_P(MainThreadSchedulerImplTest, TestResponseRAILMode) { scheduler_->RemoveRAILModeObserver(&observer); } -TEST_P(MainThreadSchedulerImplTest, TestAnimateRAILMode) { +TEST_F(MainThreadSchedulerImplTest, TestAnimateRAILMode) { MockRAILModeObserver observer; scheduler_->AddRAILModeObserver(&observer); EXPECT_CALL(observer, OnRAILModeChanged(RAILMode::kAnimation)).Times(0); @@ -2932,7 +2874,7 @@ TEST_P(MainThreadSchedulerImplTest, TestAnimateRAILMode) { scheduler_->RemoveRAILModeObserver(&observer); } -TEST_P(MainThreadSchedulerImplTest, TestIdleRAILMode) { +TEST_F(MainThreadSchedulerImplTest, TestIdleRAILMode) { MockRAILModeObserver observer; scheduler_->AddRAILModeObserver(&observer); EXPECT_CALL(observer, OnRAILModeChanged(RAILMode::kAnimation)); @@ -2947,7 +2889,7 @@ TEST_P(MainThreadSchedulerImplTest, TestIdleRAILMode) { scheduler_->RemoveRAILModeObserver(&observer); } -TEST_P(MainThreadSchedulerImplTest, TestLoadRAILMode) { +TEST_F(MainThreadSchedulerImplTest, TestLoadRAILMode) { MockRAILModeObserver observer; scheduler_->AddRAILModeObserver(&observer); EXPECT_CALL(observer, OnRAILModeChanged(RAILMode::kAnimation)); @@ -2964,7 +2906,7 @@ TEST_P(MainThreadSchedulerImplTest, TestLoadRAILMode) { scheduler_->RemoveRAILModeObserver(&observer); } -TEST_P(MainThreadSchedulerImplTest, InputTerminatesLoadRAILMode) { +TEST_F(MainThreadSchedulerImplTest, InputTerminatesLoadRAILMode) { MockRAILModeObserver observer; scheduler_->AddRAILModeObserver(&observer); EXPECT_CALL(observer, OnRAILModeChanged(RAILMode::kAnimation)); @@ -2985,7 +2927,7 @@ TEST_P(MainThreadSchedulerImplTest, InputTerminatesLoadRAILMode) { scheduler_->RemoveRAILModeObserver(&observer); } -TEST_P(MainThreadSchedulerImplTest, UnthrottledTaskRunner) { +TEST_F(MainThreadSchedulerImplTest, UnthrottledTaskRunner) { // Ensure neither suspension nor timer task throttling affects an unthrottled // task runner. SimulateCompositorGestureStart(TouchEventPolicy::kSendTouchStart); @@ -3030,7 +2972,7 @@ TEST_P(MainThreadSchedulerImplTest, UnthrottledTaskRunner) { EXPECT_EQ(500u, unthrottled_count); } -TEST_P(MainThreadSchedulerImplTest, +TEST_F(MainThreadSchedulerImplTest, VirtualTimePolicyDoesNotAffectNewTimerTaskQueueIfVirtualTimeNotEnabled) { scheduler_->SetVirtualTimePolicy( PageSchedulerImpl::VirtualTimePolicy::kPause); @@ -3039,7 +2981,7 @@ TEST_P(MainThreadSchedulerImplTest, EXPECT_FALSE(timer_tq->HasActiveFence()); } -TEST_P(MainThreadSchedulerImplTest, EnableVirtualTime) { +TEST_F(MainThreadSchedulerImplTest, EnableVirtualTime) { EXPECT_FALSE(scheduler_->IsVirtualTimeEnabled()); scheduler_->EnableVirtualTime( MainThreadSchedulerImpl::BaseTimeOverridePolicy::DO_NOT_OVERRIDE); @@ -3101,7 +3043,7 @@ TEST_P(MainThreadSchedulerImplTest, EnableVirtualTime) { scheduler_->GetVirtualTimeDomain()); } -TEST_P(MainThreadSchedulerImplTest, EnableVirtualTimeAfterThrottling) { +TEST_F(MainThreadSchedulerImplTest, EnableVirtualTimeAfterThrottling) { std::unique_ptr<PageSchedulerImpl> page_scheduler = base::WrapUnique(new PageSchedulerImpl(nullptr, scheduler_.get())); scheduler_->AddPageScheduler(page_scheduler.get()); @@ -3112,7 +3054,7 @@ TEST_P(MainThreadSchedulerImplTest, EnableVirtualTimeAfterThrottling) { TaskQueue* timer_tq = ThrottleableTaskQueue(frame_scheduler.get()).get(); - frame_scheduler->SetCrossOrigin(true); + frame_scheduler->SetCrossOriginToMainFrame(true); frame_scheduler->SetFrameVisible(false); EXPECT_TRUE(scheduler_->task_queue_throttler()->IsThrottled(timer_tq)); @@ -3122,7 +3064,7 @@ TEST_P(MainThreadSchedulerImplTest, EnableVirtualTimeAfterThrottling) { EXPECT_FALSE(scheduler_->task_queue_throttler()->IsThrottled(timer_tq)); } -TEST_P(MainThreadSchedulerImplTest, DisableVirtualTimeForTesting) { +TEST_F(MainThreadSchedulerImplTest, DisableVirtualTimeForTesting) { scheduler_->EnableVirtualTime( MainThreadSchedulerImpl::BaseTimeOverridePolicy::DO_NOT_OVERRIDE); @@ -3148,7 +3090,7 @@ TEST_P(MainThreadSchedulerImplTest, DisableVirtualTimeForTesting) { EXPECT_FALSE(scheduler_->VirtualTimeControlTaskQueue()); } -TEST_P(MainThreadSchedulerImplTest, VirtualTimePauser) { +TEST_F(MainThreadSchedulerImplTest, VirtualTimePauser) { scheduler_->EnableVirtualTime( MainThreadSchedulerImpl::BaseTimeOverridePolicy::DO_NOT_OVERRIDE); scheduler_->SetVirtualTimePolicy( @@ -3169,7 +3111,7 @@ TEST_P(MainThreadSchedulerImplTest, VirtualTimePauser) { EXPECT_EQ(after, before); } -TEST_P(MainThreadSchedulerImplTest, VirtualTimePauserNonInstantTask) { +TEST_F(MainThreadSchedulerImplTest, VirtualTimePauserNonInstantTask) { scheduler_->EnableVirtualTime( MainThreadSchedulerImpl::BaseTimeOverridePolicy::DO_NOT_OVERRIDE); scheduler_->SetVirtualTimePolicy( @@ -3186,7 +3128,7 @@ TEST_P(MainThreadSchedulerImplTest, VirtualTimePauserNonInstantTask) { EXPECT_GT(after, before); } -TEST_P(MainThreadSchedulerImplTest, VirtualTimeWithOneQueueWithoutVirtualTime) { +TEST_F(MainThreadSchedulerImplTest, VirtualTimeWithOneQueueWithoutVirtualTime) { // This test ensures that we do not do anything strange like stopping // processing task queues after we encountered one task queue with // DoNotUseVirtualTime trait. @@ -3232,7 +3174,7 @@ TEST_P(MainThreadSchedulerImplTest, VirtualTimeWithOneQueueWithoutVirtualTime) { EXPECT_EQ(counter, kTaskQueueCount); } -TEST_P(MainThreadSchedulerImplTest, Tracing) { +TEST_F(MainThreadSchedulerImplTest, Tracing) { // This test sets renderer scheduler to some non-trivial state // (by posting tasks, creating child schedulers, etc) and converts it into a // traced value. This test checks that no internal checks fire during this. @@ -3260,10 +3202,7 @@ TEST_P(MainThreadSchedulerImplTest, Tracing) { FROM_HERE, base::BindOnce(NullTask), base::TimeDelta::FromMilliseconds(10)); - std::unique_ptr<base::trace_event::ConvertableToTraceFormat> value = - scheduler_->AsValue(base::TimeTicks()); - EXPECT_TRUE(value); - EXPECT_FALSE(value->ToString().empty()); + EXPECT_FALSE(scheduler_->ToString().empty()); } void RecordingTimeTestTask( @@ -3285,7 +3224,7 @@ void RecordingTimeTestTask( // // MaxEQT1 = 500ms is recorded and observed in histogram. // MaxEQT2 is recorded but not yet in histogram for not being flushed. -TEST_P(MainThreadSchedulerImplTest, +TEST_F(MainThreadSchedulerImplTest, MaxQueueingTimeMetricRecordedOnlyDuringNavigation) { base::HistogramTester tester; // Start with a long task whose queueing time will be ignored. @@ -3305,7 +3244,7 @@ TEST_P(MainThreadSchedulerImplTest, } // Only the max of all the queueing times is recorded. -TEST_P(MainThreadSchedulerImplTest, MaxQueueingTimeMetricRecordTheMax) { +TEST_F(MainThreadSchedulerImplTest, MaxQueueingTimeMetricRecordTheMax) { base::HistogramTester tester; scheduler_->DidCommitProvisionalLoad(false, false, false); // The smaller queuing time will be ignored. @@ -3318,7 +3257,7 @@ TEST_P(MainThreadSchedulerImplTest, MaxQueueingTimeMetricRecordTheMax) { tester.ExpectUniqueSample("RendererScheduler.MaxQueueingTime", 500, 1); } -TEST_P(MainThreadSchedulerImplTest, DidCommitProvisionalLoad) { +TEST_F(MainThreadSchedulerImplTest, DidCommitProvisionalLoad) { scheduler_->OnFirstMeaningfulPaint(); EXPECT_FALSE(scheduler_->waiting_for_meaningful_paint()); @@ -3372,7 +3311,7 @@ TEST_P(MainThreadSchedulerImplTest, DidCommitProvisionalLoad) { EXPECT_TRUE(scheduler_->waiting_for_meaningful_paint()); // State cleared. } -TEST_P(MainThreadSchedulerImplTest, LoadingControlTasks) { +TEST_F(MainThreadSchedulerImplTest, LoadingControlTasks) { // Expect control loading tasks (M) to jump ahead of any regular loading // tasks (L). Vector<String> run_order; @@ -3382,7 +3321,7 @@ TEST_P(MainThreadSchedulerImplTest, LoadingControlTasks) { "L4", "L5", "L6")); } -TEST_P(MainThreadSchedulerImplTest, RequestBeginMainFrameNotExpected) { +TEST_F(MainThreadSchedulerImplTest, RequestBeginMainFrameNotExpected) { std::unique_ptr<PageSchedulerImplForTest> page_scheduler = std::make_unique<PageSchedulerImplForTest>(scheduler_.get()); scheduler_->AddPageScheduler(page_scheduler.get()); @@ -3404,7 +3343,7 @@ TEST_P(MainThreadSchedulerImplTest, RequestBeginMainFrameNotExpected) { Mock::VerifyAndClearExpectations(page_scheduler.get()); } -TEST_P(MainThreadSchedulerImplTest, +TEST_F(MainThreadSchedulerImplTest, RequestBeginMainFrameNotExpected_MultipleCalls) { std::unique_ptr<PageSchedulerImplForTest> page_scheduler = std::make_unique<PageSchedulerImplForTest>(scheduler_.get()); @@ -3422,7 +3361,7 @@ TEST_P(MainThreadSchedulerImplTest, } #if defined(OS_ANDROID) -TEST_P(MainThreadSchedulerImplTest, PauseTimersForAndroidWebView) { +TEST_F(MainThreadSchedulerImplTest, PauseTimersForAndroidWebView) { // Tasks in some queues don't fire when the timers are paused. Vector<String> run_order; PostTestTasks(&run_order, "D1 C1 L1 I1 T1"); @@ -3448,20 +3387,12 @@ class MainThreadSchedulerImplWithInitalVirtualTimeTest nullptr, test_task_runner_, test_task_runner_->GetMockTickClock(), base::sequence_manager::SequenceManager::Settings::Builder() .SetRandomisedSamplingEnabled(true) - .SetAntiStarvationLogicForPrioritiesDisabled( - GetParam() == AntiStarvationLogic::kDisabled) .Build()), base::Time::FromJsTime(1000000.0))); } }; -INSTANTIATE_TEST_SUITE_P(All, - MainThreadSchedulerImplWithInitalVirtualTimeTest, - testing::Values(AntiStarvationLogic::kEnabled, - AntiStarvationLogic::kDisabled), - GetTestNameSuffix); - -TEST_P(MainThreadSchedulerImplWithInitalVirtualTimeTest, VirtualTimeOverride) { +TEST_F(MainThreadSchedulerImplWithInitalVirtualTimeTest, VirtualTimeOverride) { EXPECT_TRUE(scheduler_->IsVirtualTimeEnabled()); EXPECT_EQ(PageSchedulerImpl::VirtualTimePolicy::kPause, scheduler_->virtual_time_policy()); @@ -3473,19 +3404,13 @@ class CompositingExperimentWithExplicitSignalsTest public: CompositingExperimentWithExplicitSignalsTest() : MainThreadSchedulerImplTest( - {kHighPriorityInputOnMainThread, kPrioritizeCompositingAfterInput, + {kPrioritizeCompositingAfterInput, kUseExplicitSignalForTriggeringCompositingPrioritization, kUseWillBeginMainFrameForCompositingPrioritization}, {}) {} }; -INSTANTIATE_TEST_SUITE_P(All, - CompositingExperimentWithExplicitSignalsTest, - testing::Values(AntiStarvationLogic::kEnabled, - AntiStarvationLogic::kDisabled), - GetTestNameSuffix); - -TEST_P(CompositingExperimentWithExplicitSignalsTest, CompositingAfterInput) { +TEST_F(CompositingExperimentWithExplicitSignalsTest, CompositingAfterInput) { Vector<String> run_order; PostTestTasks(&run_order, "P1 T1 C1"); base::RunLoop().RunUntilIdle(); @@ -3515,19 +3440,13 @@ class CompositingExperimentWithImplicitSignalsTest public: CompositingExperimentWithImplicitSignalsTest() : MainThreadSchedulerImplTest( - {kHighPriorityInputOnMainThread, kPrioritizeCompositingAfterInput}, + {kPrioritizeCompositingAfterInput}, {kHighestPriorityForCompositingAfterInput, kUseExplicitSignalForTriggeringCompositingPrioritization, kUseWillBeginMainFrameForCompositingPrioritization}) {} }; -INSTANTIATE_TEST_SUITE_P(All, - CompositingExperimentWithImplicitSignalsTest, - testing::Values(AntiStarvationLogic::kEnabled, - AntiStarvationLogic::kDisabled), - GetTestNameSuffix); - -TEST_P(CompositingExperimentWithImplicitSignalsTest, CompositingAfterInput) { +TEST_F(CompositingExperimentWithImplicitSignalsTest, CompositingAfterInput) { Vector<String> run_order; PostTestTasks(&run_order, "T1 C1 C2 P1 P2"); base::RunLoop().RunUntilIdle(); @@ -3535,7 +3454,7 @@ TEST_P(CompositingExperimentWithImplicitSignalsTest, CompositingAfterInput) { EXPECT_THAT(run_order, testing::ElementsAre("P1", "P2", "C1", "T1", "C2")); } -TEST_P(MainThreadSchedulerImplTest, EQTWithNestedLoop) { +TEST_F(MainThreadSchedulerImplTest, EQTWithNestedLoop) { AdvanceMockTickClockBy(base::TimeDelta::FromMilliseconds(100)); RunTask(base::BindLambdaForTesting([&] { @@ -3574,7 +3493,7 @@ TEST_P(MainThreadSchedulerImplTest, EQTWithNestedLoop) { base::TimeDelta::FromMicroseconds(400 + 50 + 50 + 1250))); } -TEST_P(MainThreadSchedulerImplTest, TaskQueueReferenceClearedOnShutdown) { +TEST_F(MainThreadSchedulerImplTest, TaskQueueReferenceClearedOnShutdown) { // Ensure that the scheduler clears its references to a task queue after // |shutdown| and doesn't try to update its policies. scoped_refptr<MainThreadTaskQueue> queue1 = scheduler_->NewTimerTaskQueue( @@ -3596,7 +3515,7 @@ TEST_P(MainThreadSchedulerImplTest, TaskQueueReferenceClearedOnShutdown) { EXPECT_EQ(queue2->GetTimeDomain(), scheduler_->GetVirtualTimeDomain()); } -TEST_P(MainThreadSchedulerImplTest, MicrotaskCheckpointTiming) { +TEST_F(MainThreadSchedulerImplTest, MicrotaskCheckpointTiming) { base::RunLoop().RunUntilIdle(); base::TimeTicks start_time = Now(); @@ -3623,7 +3542,7 @@ TEST_P(MainThreadSchedulerImplTest, MicrotaskCheckpointTiming) { observer.result().front().second); } -TEST_P(MainThreadSchedulerImplTest, IsBeginMainFrameScheduled) { +TEST_F(MainThreadSchedulerImplTest, IsBeginMainFrameScheduled) { EXPECT_FALSE(scheduler_->IsBeginMainFrameScheduled()); scheduler_->DidScheduleBeginMainFrame(); EXPECT_TRUE(scheduler_->IsBeginMainFrameScheduled()); @@ -3638,6 +3557,119 @@ TEST_P(MainThreadSchedulerImplTest, IsBeginMainFrameScheduled) { EXPECT_FALSE(scheduler_->IsBeginMainFrameScheduled()); } +TEST_F(MainThreadSchedulerImplTest, NonWakingTaskQueue) { + std::vector<std::pair<std::string, base::TimeTicks>> log; + base::TimeTicks start = scheduler_->GetTickClock()->NowTicks(); + + scheduler_->DefaultTaskQueue()->task_runner()->PostTask( + FROM_HERE, + base::BindOnce( + [](std::vector<std::pair<std::string, base::TimeTicks>>* log, + const base::TickClock* clock) { + log->emplace_back("regular (immediate)", clock->NowTicks()); + }, + &log, scheduler_->GetTickClock())); + scheduler_->NonWakingTaskRunner()->PostDelayedTask( + FROM_HERE, + base::BindOnce( + [](std::vector<std::pair<std::string, base::TimeTicks>>* log, + const base::TickClock* clock) { + log->emplace_back("non-waking", clock->NowTicks()); + }, + &log, scheduler_->GetTickClock()), + base::TimeDelta::FromSeconds(3)); + scheduler_->DefaultTaskQueue()->task_runner()->PostDelayedTask( + FROM_HERE, + base::BindOnce( + [](std::vector<std::pair<std::string, base::TimeTicks>>* log, + const base::TickClock* clock) { + log->emplace_back("regular (delayed)", clock->NowTicks()); + }, + &log, scheduler_->GetTickClock()), + base::TimeDelta::FromSeconds(5)); + + test_task_runner_->FastForwardUntilNoTasksRemain(); + + // Check that the non-waking task runner didn't generate an unnecessary + // wake-up. + // Note: the exact order of these tasks is not fixed and depends on the time + // domain iteration order. + EXPECT_THAT( + log, + testing::UnorderedElementsAre( + std::make_pair("regular (immediate)", start), + std::make_pair("non-waking", start + base::TimeDelta::FromSeconds(5)), + std::make_pair("regular (delayed)", + start + base::TimeDelta::FromSeconds(5)))); +} + +class BestEffortPriorityForFindInPageExperimentTest + : public MainThreadSchedulerImplTest { + public: + BestEffortPriorityForFindInPageExperimentTest() + : MainThreadSchedulerImplTest({kBestEffortPriorityForFindInPage}, {}) {} +}; + +TEST_F(BestEffortPriorityForFindInPageExperimentTest, + FindInPageTasksAreBestEffortPriorityUnderExperiment) { + Vector<String> run_order; + PostTestTasks(&run_order, "F1 D1 F2 D2 F3 D3"); + EnableIdleTasks(); + EXPECT_EQ(scheduler_->find_in_page_priority(), + QueuePriority::kBestEffortPriority); + base::RunLoop().RunUntilIdle(); + // Find-in-page tasks have "best-effort" priority, so they will be done after + // the default tasks (which have normal priority). + EXPECT_THAT(run_order, + testing::ElementsAre("D1", "D2", "D3", "F1", "F2", "F3")); +} + +TEST_F(MainThreadSchedulerImplTest, FindInPageTasksAreVeryHighPriority) { + Vector<String> run_order; + PostTestTasks(&run_order, "D1 D2 D3 F1 F2 F3"); + EnableIdleTasks(); + EXPECT_EQ( + scheduler_->find_in_page_priority(), + FindInPageBudgetPoolController::kFindInPageBudgetNotExhaustedPriority); + base::RunLoop().RunUntilIdle(); + // Find-in-page tasks have very high task priority, so we will do them before + // the default tasks. + EXPECT_THAT(run_order, + testing::ElementsAre("F1", "F2", "F3", "D1", "D2", "D3")); +} + +TEST_F(MainThreadSchedulerImplTest, FindInPageTasksChangeToNormalPriority) { + EXPECT_EQ( + scheduler_->find_in_page_priority(), + FindInPageBudgetPoolController::kFindInPageBudgetNotExhaustedPriority); + EnableIdleTasks(); + // Simulate a really long find-in-page task that takes 30% of CPU time + // (300ms out of 1000 ms). + base::TimeTicks task_start_time = Now(); + base::TimeTicks task_end_time = + task_start_time + base::TimeDelta::FromMilliseconds(300); + FakeTask fake_task; + fake_task.set_enqueue_order( + base::sequence_manager::EnqueueOrder::FromIntForTesting(42)); + FakeTaskTiming task_timing(task_start_time, task_end_time); + scheduler_->OnTaskStarted(find_in_page_task_queue(), fake_task, task_timing); + AdvanceMockTickClockTo(task_start_time + + base::TimeDelta::FromMilliseconds(1000)); + scheduler_->OnTaskCompleted(find_in_page_task_queue()->AsWeakPtr(), fake_task, + &task_timing, nullptr); + + // Now the find-in-page tasks have normal priority (same priority as default + // tasks, so we will do them in order). + EXPECT_EQ(scheduler_->find_in_page_priority(), + FindInPageBudgetPoolController::kFindInPageBudgetExhaustedPriority); + Vector<String> run_order; + PostTestTasks(&run_order, "D1 D2 F1 F2 D3 F3"); + + base::RunLoop().RunUntilIdle(); + EXPECT_THAT(run_order, + testing::ElementsAre("D1", "D2", "F1", "F2", "D3", "F3")); +} + class VeryHighPriorityForCompositingAlwaysExperimentTest : public MainThreadSchedulerImplTest { public: @@ -3646,13 +3678,7 @@ class VeryHighPriorityForCompositingAlwaysExperimentTest {}) {} }; -INSTANTIATE_TEST_SUITE_P(All, - VeryHighPriorityForCompositingAlwaysExperimentTest, - testing::Values(AntiStarvationLogic::kEnabled, - AntiStarvationLogic::kDisabled), - GetTestNameSuffix); - -TEST_P(VeryHighPriorityForCompositingAlwaysExperimentTest, +TEST_F(VeryHighPriorityForCompositingAlwaysExperimentTest, TestCompositorPolicy) { Vector<String> run_order; PostTestTasks(&run_order, "I1 D1 C1 D2 C2 P1"); @@ -3672,13 +3698,7 @@ class VeryHighPriorityForCompositingWhenFastExperimentTest {}) {} }; -INSTANTIATE_TEST_SUITE_P(All, - VeryHighPriorityForCompositingWhenFastExperimentTest, - testing::Values(AntiStarvationLogic::kEnabled, - AntiStarvationLogic::kDisabled), - GetTestNameSuffix); - -TEST_P(VeryHighPriorityForCompositingWhenFastExperimentTest, +TEST_F(VeryHighPriorityForCompositingWhenFastExperimentTest, TestCompositorPolicy_FastCompositing) { Vector<String> run_order; PostTestTasks(&run_order, "I1 D1 C1 D2 C2 P1"); @@ -3690,7 +3710,7 @@ TEST_P(VeryHighPriorityForCompositingWhenFastExperimentTest, EXPECT_EQ(UseCase::kNone, CurrentUseCase()); } -TEST_P(VeryHighPriorityForCompositingWhenFastExperimentTest, +TEST_F(VeryHighPriorityForCompositingWhenFastExperimentTest, TestCompositorPolicy_SlowCompositing) { RunSlowCompositorTask(); Vector<String> run_order; @@ -3703,7 +3723,7 @@ TEST_P(VeryHighPriorityForCompositingWhenFastExperimentTest, EXPECT_EQ(UseCase::kNone, CurrentUseCase()); } -TEST_P(VeryHighPriorityForCompositingWhenFastExperimentTest, +TEST_F(VeryHighPriorityForCompositingWhenFastExperimentTest, TestCompositorPolicy_CompositingStaysAtHighest) { Vector<String> run_order; PostTestTasks(&run_order, "L1 I1 D1 C1 D2 P1 C2"); @@ -3727,14 +3747,7 @@ class VeryHighPriorityForCompositingAlternatingExperimentTest {}) {} }; -INSTANTIATE_TEST_SUITE_P( - All, - VeryHighPriorityForCompositingAlternatingExperimentTest, - testing::Values(AntiStarvationLogic::kEnabled, - AntiStarvationLogic::kDisabled), - GetTestNameSuffix); - -TEST_P(VeryHighPriorityForCompositingAlternatingExperimentTest, +TEST_F(VeryHighPriorityForCompositingAlternatingExperimentTest, TestCompositorPolicy_AlternatingCompositorTasks) { Vector<String> run_order; PostTestTasks(&run_order, "D1 D2 D3 C1 C2 C3"); @@ -3746,7 +3759,7 @@ TEST_P(VeryHighPriorityForCompositingAlternatingExperimentTest, EXPECT_EQ(UseCase::kNone, CurrentUseCase()); } -TEST_P(VeryHighPriorityForCompositingAlternatingExperimentTest, +TEST_F(VeryHighPriorityForCompositingAlternatingExperimentTest, TestCompositorPolicy_AlternatingCompositorStaysAtHighest) { Vector<String> run_order; PostTestTasks(&run_order, "D1 D2 D3 C1 C2 C3"); @@ -3769,13 +3782,7 @@ class VeryHighPriorityForCompositingAfterDelayExperimentTest {}) {} }; -INSTANTIATE_TEST_SUITE_P(All, - VeryHighPriorityForCompositingAfterDelayExperimentTest, - testing::Values(AntiStarvationLogic::kEnabled, - AntiStarvationLogic::kDisabled), - GetTestNameSuffix); - -TEST_P(VeryHighPriorityForCompositingAfterDelayExperimentTest, +TEST_F(VeryHighPriorityForCompositingAfterDelayExperimentTest, TestCompositorPolicy_CompositorStaysAtNormalPriority) { Vector<String> run_order; PostTestTasks(&run_order, "I1 D1 C1 D2 C2 P1"); @@ -3787,7 +3794,7 @@ TEST_P(VeryHighPriorityForCompositingAfterDelayExperimentTest, EXPECT_EQ(UseCase::kNone, CurrentUseCase()); } -TEST_P(VeryHighPriorityForCompositingAfterDelayExperimentTest, +TEST_F(VeryHighPriorityForCompositingAfterDelayExperimentTest, TestCompositorPolicy_FirstCompositorTaskSetToVeryHighPriority) { // 150ms task to complete the countdown and prioritze compositing. AdvanceTimeWithTask(0.15); @@ -3802,7 +3809,7 @@ TEST_P(VeryHighPriorityForCompositingAfterDelayExperimentTest, EXPECT_EQ(UseCase::kNone, CurrentUseCase()); } -TEST_P(VeryHighPriorityForCompositingAfterDelayExperimentTest, +TEST_F(VeryHighPriorityForCompositingAfterDelayExperimentTest, TestCompositorPolicy_FirstCompositorTaskStaysAtNormalPriority) { // 0.5ms task should not prioritize compositing. AdvanceTimeWithTask(0.05); @@ -3825,13 +3832,7 @@ class VeryHighPriorityForCompositingBudgetExperimentTest {}) {} }; -INSTANTIATE_TEST_SUITE_P(All, - VeryHighPriorityForCompositingBudgetExperimentTest, - testing::Values(AntiStarvationLogic::kEnabled, - AntiStarvationLogic::kDisabled), - GetTestNameSuffix); - -TEST_P(VeryHighPriorityForCompositingBudgetExperimentTest, +TEST_F(VeryHighPriorityForCompositingBudgetExperimentTest, TestCompositorPolicy_CompositorPriorityVeryHighToNormal) { Vector<String> run_order; PostTestTasks(&run_order, "I1 D1 C1 D2 C2 P1"); @@ -3858,7 +3859,7 @@ TEST_P(VeryHighPriorityForCompositingBudgetExperimentTest, EXPECT_EQ(UseCase::kNone, CurrentUseCase()); } -TEST_P(VeryHighPriorityForCompositingBudgetExperimentTest, +TEST_F(VeryHighPriorityForCompositingBudgetExperimentTest, TestCompositorPolicy_CompositorPriorityNormalToVeryHigh) { // 1000ms compositor task will exhaust the budget. RunSlowCompositorTask(); @@ -3897,14 +3898,7 @@ class VeryHighPriorityForCompositingAlternatingBeginMainFrameExperimentTest {}) {} }; -INSTANTIATE_TEST_SUITE_P( - , - VeryHighPriorityForCompositingAlternatingBeginMainFrameExperimentTest, - testing::Values(AntiStarvationLogic::kEnabled, - AntiStarvationLogic::kDisabled), - GetTestNameSuffix); - -TEST_P(VeryHighPriorityForCompositingAlternatingBeginMainFrameExperimentTest, +TEST_F(VeryHighPriorityForCompositingAlternatingBeginMainFrameExperimentTest, TestCompositorPolicy_AlternatingCompositorTasks) { Vector<String> run_order; PostTestTasks(&run_order, "C1 D1 C2 D2"); @@ -3934,14 +3928,7 @@ class VeryHighPriorityForCompositingAfterDelayUntilBeginMainFrameExperimentTest {}) {} }; -INSTANTIATE_TEST_SUITE_P( - , - VeryHighPriorityForCompositingAfterDelayUntilBeginMainFrameExperimentTest, - testing::Values(AntiStarvationLogic::kEnabled, - AntiStarvationLogic::kDisabled), - GetTestNameSuffix); - -TEST_P( +TEST_F( VeryHighPriorityForCompositingAfterDelayUntilBeginMainFrameExperimentTest, TestCompositorPolicy_FirstCompositorTaskSetToVeryHighPriority) { // 150ms task to complete the countdown and prioritze compositing. @@ -3973,14 +3960,7 @@ class VeryHighPriorityForCompositingBudgetBeginMainFrameExperimentTest {}) {} }; -INSTANTIATE_TEST_SUITE_P( - , - VeryHighPriorityForCompositingBudgetBeginMainFrameExperimentTest, - testing::Values(AntiStarvationLogic::kEnabled, - AntiStarvationLogic::kDisabled), - GetTestNameSuffix); - -TEST_P( +TEST_F( VeryHighPriorityForCompositingBudgetBeginMainFrameExperimentTest, TestCompositorPolicy_CompositorPriorityNonBeginMainFrameDoesntExhaustBudget) { // 1000ms compositor task will not exhaust the budget. @@ -3994,7 +3974,7 @@ TEST_P( EXPECT_EQ(UseCase::kNone, CurrentUseCase()); } -TEST_P(VeryHighPriorityForCompositingBudgetBeginMainFrameExperimentTest, +TEST_F(VeryHighPriorityForCompositingBudgetBeginMainFrameExperimentTest, TestCompositorPolicy_CompositorPriorityBeginMainFrameExhaustsBudget) { // 1000ms BeginMainFrame will exhaust the budget. DoMainFrame(); diff --git a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_task_queue.cc b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_task_queue.cc index d008643dc43..0d54d317672 100644 --- a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_task_queue.cc +++ b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_task_queue.cc @@ -63,6 +63,8 @@ const char* MainThreadTaskQueue::NameForQueueType( return "other_tq"; case MainThreadTaskQueue::QueueType::kWebScheduling: return "web_scheduling_tq"; + case MainThreadTaskQueue::QueueType::kNonWaking: + return "non_waking_tq"; case MainThreadTaskQueue::QueueType::kCount: NOTREACHED(); return nullptr; @@ -95,6 +97,7 @@ bool MainThreadTaskQueue::IsPerFrameTaskQueue( case MainThreadTaskQueue::QueueType::kInput: case MainThreadTaskQueue::QueueType::kDetached: case MainThreadTaskQueue::QueueType::kCleanup: + case MainThreadTaskQueue::QueueType::kNonWaking: case MainThreadTaskQueue::QueueType::kOther: return false; case MainThreadTaskQueue::QueueType::kCount: @@ -114,6 +117,7 @@ MainThreadTaskQueue::QueueClass MainThreadTaskQueue::QueueClassForQueueType( case QueueType::kTest: case QueueType::kV8: case QueueType::kIPC: + case QueueType::kNonWaking: case QueueType::kCleanup: return QueueClass::kNone; case QueueType::kFrameLoading: diff --git a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_task_queue.h b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_task_queue.h index c1ea93cd184..b9c51d21ea8 100644 --- a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_task_queue.h +++ b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_task_queue.h @@ -76,10 +76,11 @@ class PLATFORM_EXPORT MainThreadTaskQueue // 22 : kWebSchedulingBestEffort, obsolete. kWebScheduling = 24, + kNonWaking = 25, // Used to group multiple types when calculating Expected Queueing Time. kOther = 23, - kCount = 25 + kCount = 26 }; // Returns name of the given queue type. Returned string has application @@ -123,13 +124,14 @@ class PLATFORM_EXPORT MainThreadTaskQueue // Separate enum class for handling prioritisation decisions in task queues. enum class PrioritisationType { kVeryHigh = 0, - kHigh = 1, - kBestEffort = 2, - kRegular = 3, - kLoading = 4, - kLoadingControl = 5, - - kCount = 6 + kBestEffort = 1, + kRegular = 2, + kLoading = 3, + kLoadingControl = 4, + kFindInPage = 5, + kExperimentalDatabase = 6, + + kCount = 7 }; // kPrioritisationTypeWidthBits is the number of bits required diff --git a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/memory_purge_manager.cc b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/memory_purge_manager.cc index 811cc0cb55f..07afb6e13a7 100644 --- a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/memory_purge_manager.cc +++ b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/memory_purge_manager.cc @@ -76,6 +76,10 @@ void MemoryPurgeManager::OnPageDestroyed(PageLifecycleState state) { total_page_count_--; if (state == PageLifecycleState::kFrozen) frozen_page_count_--; + + if (!CanPurge()) + purge_timer_.Stop(); + DCHECK_LE(frozen_page_count_, total_page_count_); } @@ -110,6 +114,10 @@ void MemoryPurgeManager::OnRendererBackgrounded() { if (!base::FeatureList::IsEnabled( features::kPurgeRendererMemoryWhenBackgrounded)) return; + // A spare renderer has no pages. We would like to avoid purging memory + // on a spare renderer. + if (total_page_count_ == 0) + return; backgrounded_purge_pending_ = true; RequestMemoryPurgeWithDelay(GetTimeToPurgeAfterBackgrounded()); @@ -145,6 +153,9 @@ void MemoryPurgeManager::PerformMemoryPurge() { } bool MemoryPurgeManager::CanPurge() const { + if (total_page_count_ == 0) + return false; + if (backgrounded_purge_pending_) return true; diff --git a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/memory_purge_manager_unittest.cc b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/memory_purge_manager_unittest.cc index 3293c3151d3..3dea63c3bbb 100644 --- a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/memory_purge_manager_unittest.cc +++ b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/memory_purge_manager_unittest.cc @@ -25,8 +25,7 @@ class MemoryPurgeManagerTest : public testing::Test { MemoryPurgeManagerTest() : task_environment_(base::test::TaskEnvironment::MainThreadType::UI, base::test::TaskEnvironment::TimeSource::MOCK_TIME), - memory_purge_manager_(task_environment_.GetMainThreadTaskRunner()), - observed_memory_pressure_(false) {} + memory_purge_manager_(task_environment_.GetMainThreadTaskRunner()) {} void SetUp() override { memory_pressure_listener_ = @@ -49,34 +48,23 @@ class MemoryPurgeManagerTest : public testing::Test { {features::kPurgeRendererMemoryWhenBackgrounded}); } - void ExpectMemoryPressure( - base::TimeDelta delay = base::TimeDelta::FromMinutes(0)) { - FastForwardBy(delay); - EXPECT_TRUE(observed_memory_pressure_); - observed_memory_pressure_ = false; - } - - void ExpectNoMemoryPressure( - base::TimeDelta delay = base::TimeDelta::FromMinutes(0)) { - FastForwardBy(delay); - EXPECT_FALSE(observed_memory_pressure_); - } - void FastForwardBy(base::TimeDelta delta) { task_environment_.FastForwardBy(delta); } + unsigned MemoryPressureCount() const { return memory_pressure_count_; } + base::test::ScopedFeatureList scoped_feature_list_; base::test::TaskEnvironment task_environment_; std::unique_ptr<base::MemoryPressureListener> memory_pressure_listener_; MemoryPurgeManager memory_purge_manager_; - bool observed_memory_pressure_; + unsigned memory_pressure_count_ = 0; private: void OnMemoryPressure(base::MemoryPressureListener::MemoryPressureLevel) { - observed_memory_pressure_ = true; + memory_pressure_count_++; } DISALLOW_COPY_AND_ASSIGN(MemoryPurgeManagerTest); @@ -92,7 +80,8 @@ TEST_F(MemoryPurgeManagerTest, PageFrozenInBackgroundedRenderer) { memory_purge_manager_.OnPageCreated(PageLifecycleState::kActive); memory_purge_manager_.SetRendererBackgrounded(true); memory_purge_manager_.OnPageFrozen(); - ExpectMemoryPressure(); + FastForwardBy(base::TimeDelta::FromMinutes(0)); + EXPECT_EQ(1U, MemoryPressureCount()); } // Verify that OnPageFrozen() does not trigger a memory pressure notification in @@ -105,7 +94,8 @@ TEST_F(MemoryPurgeManagerTest, PageFrozenInForegroundedRenderer) { memory_purge_manager_.OnPageCreated(PageLifecycleState::kActive); memory_purge_manager_.SetRendererBackgrounded(false); memory_purge_manager_.OnPageFrozen(); - ExpectNoMemoryPressure(); + FastForwardBy(base::TimeDelta::FromMinutes(0)); + EXPECT_EQ(0U, MemoryPressureCount()); } TEST_F(MemoryPurgeManagerTest, PageResumedUndoMemoryPressureSuppression) { @@ -117,7 +107,9 @@ TEST_F(MemoryPurgeManagerTest, PageResumedUndoMemoryPressureSuppression) { memory_purge_manager_.SetRendererBackgrounded(true); memory_purge_manager_.OnPageFrozen(); - ExpectMemoryPressure(); + FastForwardBy(base::TimeDelta::FromMinutes(0)); + EXPECT_EQ(1U, MemoryPressureCount()); + EXPECT_TRUE(base::MemoryPressureListener::AreNotificationsSuppressed()); memory_purge_manager_.OnPageResumed(); EXPECT_FALSE(base::MemoryPressureListener::AreNotificationsSuppressed()); @@ -139,15 +131,18 @@ TEST_F(MemoryPurgeManagerTest, PageFrozenPurgeMemoryAllPagesFrozenDisabled) { memory_purge_manager_.OnPageCreated(PageLifecycleState::kActive); memory_purge_manager_.OnPageFrozen(); - ExpectMemoryPressure(); + FastForwardBy(base::TimeDelta::FromMinutes(0)); + EXPECT_EQ(1U, MemoryPressureCount()); EXPECT_FALSE(base::MemoryPressureListener::AreNotificationsSuppressed()); memory_purge_manager_.OnPageFrozen(); - ExpectMemoryPressure(); + FastForwardBy(base::TimeDelta::FromMinutes(0)); + EXPECT_EQ(2U, MemoryPressureCount()); EXPECT_FALSE(base::MemoryPressureListener::AreNotificationsSuppressed()); memory_purge_manager_.OnPageFrozen(); - ExpectMemoryPressure(); + FastForwardBy(base::TimeDelta::FromMinutes(0)); + EXPECT_EQ(3U, MemoryPressureCount()); EXPECT_TRUE(base::MemoryPressureListener::AreNotificationsSuppressed()); memory_purge_manager_.OnPageResumed(); @@ -177,15 +172,18 @@ TEST_F(MemoryPurgeManagerTest, PageFrozenPurgeMemoryAllPagesFrozenEnabled) { memory_purge_manager_.OnPageCreated(PageLifecycleState::kActive); memory_purge_manager_.OnPageFrozen(); - ExpectNoMemoryPressure(); + FastForwardBy(base::TimeDelta::FromMinutes(0)); + EXPECT_EQ(0U, MemoryPressureCount()); EXPECT_FALSE(base::MemoryPressureListener::AreNotificationsSuppressed()); memory_purge_manager_.OnPageFrozen(); - ExpectNoMemoryPressure(); + FastForwardBy(base::TimeDelta::FromMinutes(0)); + EXPECT_EQ(0U, MemoryPressureCount()); EXPECT_FALSE(base::MemoryPressureListener::AreNotificationsSuppressed()); memory_purge_manager_.OnPageFrozen(); - ExpectMemoryPressure(); + FastForwardBy(base::TimeDelta::FromMinutes(0)); + EXPECT_EQ(1U, MemoryPressureCount()); EXPECT_TRUE(base::MemoryPressureListener::AreNotificationsSuppressed()); memory_purge_manager_.OnPageResumed(); @@ -211,10 +209,12 @@ TEST_F(MemoryPurgeManagerTest, MemoryPurgeWithDelay) { memory_purge_manager_.OnPageFrozen(); // The memory pressure notification should not occur immediately - ExpectNoMemoryPressure(); + FastForwardBy(base::TimeDelta::FromMinutes(0)); + EXPECT_EQ(0U, MemoryPressureCount()); // The memory pressure notification should occur after 1 minute - ExpectMemoryPressure(kDelayForPurgeAfterFreeze); + FastForwardBy(kDelayForPurgeAfterFreeze); + EXPECT_EQ(1U, MemoryPressureCount()); memory_purge_manager_.OnPageDestroyed(PageLifecycleState::kFrozen); } @@ -227,12 +227,13 @@ TEST_F(MemoryPurgeManagerTest, CancelMemoryPurgeWithDelay) { memory_purge_manager_.SetRendererBackgrounded(true); memory_purge_manager_.OnPageFrozen(); FastForwardBy(base::TimeDelta::FromSeconds(40)); - ExpectNoMemoryPressure(); + EXPECT_EQ(0U, MemoryPressureCount()); // If the page is resumed before the memory purge timer expires, the purge // should be cancelled. memory_purge_manager_.OnPageResumed(); - ExpectNoMemoryPressure(kDelayForPurgeAfterFreeze); + FastForwardBy(base::TimeDelta::FromMinutes(0)); + EXPECT_EQ(0U, MemoryPressureCount()); memory_purge_manager_.OnPageDestroyed(PageLifecycleState::kActive); } @@ -245,11 +246,12 @@ TEST_F(MemoryPurgeManagerTest, MemoryPurgeWithDelayNewActivePageCreated) { memory_purge_manager_.SetRendererBackgrounded(true); memory_purge_manager_.OnPageFrozen(); FastForwardBy(base::TimeDelta::FromSeconds(40)); - ExpectNoMemoryPressure(); + EXPECT_EQ(0U, MemoryPressureCount()); // All pages are no longer frozen, the memory purge should be cancelled. memory_purge_manager_.OnPageCreated(PageLifecycleState::kActive); - ExpectNoMemoryPressure(kDelayForPurgeAfterFreeze); + FastForwardBy(kDelayForPurgeAfterFreeze); + EXPECT_EQ(0U, MemoryPressureCount()); memory_purge_manager_.OnPageDestroyed(PageLifecycleState::kFrozen); memory_purge_manager_.OnPageDestroyed(PageLifecycleState::kActive); @@ -263,11 +265,12 @@ TEST_F(MemoryPurgeManagerTest, MemoryPurgeWithDelayNewFrozenPageCreated) { memory_purge_manager_.SetRendererBackgrounded(true); memory_purge_manager_.OnPageFrozen(); FastForwardBy(base::TimeDelta::FromSeconds(40)); - ExpectNoMemoryPressure(); + EXPECT_EQ(0U, MemoryPressureCount()); // All pages are still frozen and the memory purge should occur. memory_purge_manager_.OnPageCreated(PageLifecycleState::kFrozen); - ExpectMemoryPressure(kDelayForPurgeAfterFreeze); + FastForwardBy(kDelayForPurgeAfterFreeze); + EXPECT_EQ(1U, MemoryPressureCount()); memory_purge_manager_.OnPageDestroyed(PageLifecycleState::kFrozen); memory_purge_manager_.OnPageDestroyed(PageLifecycleState::kFrozen); @@ -281,7 +284,8 @@ TEST_F(MemoryPurgeManagerTest, PurgeRendererMemoryWhenBackgroundedEnabled) { memory_purge_manager_.SetRendererBackgrounded(true); FastForwardBy(base::TimeDelta::FromMinutes( MemoryPurgeManager::kDefaultMaxTimeToPurgeAfterBackgrounded)); - ExpectMemoryPressure(); + // No page, no memory pressure. + EXPECT_EQ(0U, MemoryPressureCount()); } TEST_F(MemoryPurgeManagerTest, PurgeRendererMemoryWhenBackgroundedDisabled) { @@ -291,7 +295,7 @@ TEST_F(MemoryPurgeManagerTest, PurgeRendererMemoryWhenBackgroundedDisabled) { memory_purge_manager_.SetRendererBackgrounded(true); FastForwardBy(base::TimeDelta::Max()); - ExpectNoMemoryPressure(); + EXPECT_EQ(0U, MemoryPressureCount()); } TEST_F(MemoryPurgeManagerTest, @@ -302,11 +306,11 @@ TEST_F(MemoryPurgeManagerTest, memory_purge_manager_.SetRendererBackgrounded(true); FastForwardBy(base::TimeDelta::FromSeconds(30)); - ExpectNoMemoryPressure(); + EXPECT_EQ(0U, MemoryPressureCount()); memory_purge_manager_.SetRendererBackgrounded(false); FastForwardBy(base::TimeDelta::Max()); - ExpectNoMemoryPressure(); + EXPECT_EQ(0U, MemoryPressureCount()); } TEST_F(MemoryPurgeManagerTest, PageFrozenAndResumedWhileBackgrounded) { @@ -329,7 +333,8 @@ TEST_F(MemoryPurgeManagerTest, PageFrozenAndResumedWhileBackgrounded) { memory_purge_manager_.SetRendererBackgrounded(true); memory_purge_manager_.OnPageFrozen(); FastForwardBy(kBeforeBackgroundPurgeDelay); - ExpectNoMemoryPressure(); + EXPECT_EQ(0U, MemoryPressureCount()); + memory_purge_manager_.OnPageResumed(); FastForwardBy( base::TimeDelta::FromMinutes( @@ -337,7 +342,7 @@ TEST_F(MemoryPurgeManagerTest, PageFrozenAndResumedWhileBackgrounded) { kBeforeBackgroundPurgeDelay); // Since the renderer is still backgrounded, the memory purge should happen // even though there are no frozen pages. - ExpectMemoryPressure(); + EXPECT_EQ(1U, MemoryPressureCount()); memory_purge_manager_.OnPageDestroyed(PageLifecycleState::kActive); } @@ -357,10 +362,12 @@ TEST_F(MemoryPurgeManagerTest, memory_purge_manager_.SetRendererBackgrounded(true); memory_purge_manager_.OnPageFrozen(); - ExpectMemoryPressure(base::TimeDelta::FromMinutes( + FastForwardBy(base::TimeDelta::FromMinutes( MemoryPurgeManager::kDefaultMaxTimeToPurgeAfterBackgrounded)); + EXPECT_EQ(1U, MemoryPressureCount()); + FastForwardBy(kFreezePurgeDelay); - ExpectNoMemoryPressure(); + EXPECT_EQ(1U, MemoryPressureCount()); memory_purge_manager_.OnPageDestroyed(PageLifecycleState::kFrozen); } @@ -380,11 +387,29 @@ TEST_F(MemoryPurgeManagerTest, memory_purge_manager_.SetRendererBackgrounded(true); memory_purge_manager_.OnPageFrozen(); - ExpectMemoryPressure(kFreezePurgeDelay); + FastForwardBy(kFreezePurgeDelay); + EXPECT_EQ(1U, MemoryPressureCount()); + FastForwardBy(base::TimeDelta::Max()); - ExpectNoMemoryPressure(); + EXPECT_EQ(1U, MemoryPressureCount()); + + memory_purge_manager_.OnPageDestroyed(PageLifecycleState::kFrozen); +} + +TEST_F(MemoryPurgeManagerTest, NoMemoryPurgeIfNoPage) { + scoped_feature_list_.InitWithFeatures( + {features::kFreezePurgeMemoryAllPagesFrozen} /* enabled */, + {features::kPurgeRendererMemoryWhenBackgrounded} /* disabled */); + memory_purge_manager_.SetRendererBackgrounded(true); + memory_purge_manager_.OnPageCreated(PageLifecycleState::kActive); + + memory_purge_manager_.SetRendererBackgrounded(true); + memory_purge_manager_.OnPageFrozen(); memory_purge_manager_.OnPageDestroyed(PageLifecycleState::kFrozen); + + FastForwardBy(base::TimeDelta::FromMinutes(0)); + EXPECT_EQ(0U, MemoryPressureCount()); } } // namespace diff --git a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/non_waking_time_domain.cc b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/non_waking_time_domain.cc new file mode 100644 index 00000000000..13d6f4a9871 --- /dev/null +++ b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/non_waking_time_domain.cc @@ -0,0 +1,45 @@ +// Copyright 2020 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. + +#include "third_party/blink/renderer/platform/scheduler/main_thread/non_waking_time_domain.h" + +namespace blink { +namespace scheduler { + +NonWakingTimeDomain::NonWakingTimeDomain(const base::TickClock* tick_clock) + : tick_clock_(tick_clock) {} + +NonWakingTimeDomain::~NonWakingTimeDomain() = default; + +base::sequence_manager::LazyNow NonWakingTimeDomain::CreateLazyNow() const { + return base::sequence_manager::LazyNow(tick_clock_); +} + +base::TimeTicks NonWakingTimeDomain::Now() const { + return tick_clock_->NowTicks(); +} + +base::Optional<base::TimeDelta> NonWakingTimeDomain::DelayTillNextTask( + base::sequence_manager::LazyNow* lazy_now) { + // NonWakingTimeDomain should never generate wakeups on its own. + return base::nullopt; +} + +bool NonWakingTimeDomain::MaybeFastForwardToNextTask( + bool quit_when_idle_requested) { + return false; +} + +const char* NonWakingTimeDomain::GetName() const { + return "non_waking_time_domain"; +} + +void NonWakingTimeDomain::SetNextDelayedDoWork( + base::sequence_manager::LazyNow* lazy_now, + base::TimeTicks run_time) { + // Do not request a wake-up, unlike a regular TimeDomain. +} + +} // namespace scheduler +} // namespace blink diff --git a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/non_waking_time_domain.h b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/non_waking_time_domain.h new file mode 100644 index 00000000000..9641ed9aa1b --- /dev/null +++ b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/non_waking_time_domain.h @@ -0,0 +1,38 @@ +// Copyright 2020 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 THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_MAIN_THREAD_NON_WAKING_TIME_DOMAIN_H_ +#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_MAIN_THREAD_NON_WAKING_TIME_DOMAIN_H_ + +#include "base/task/sequence_manager/time_domain.h" +#include "base/time/tick_clock.h" + +namespace blink { +namespace scheduler { + +// A time domain which never generates wake-ups on its own. Useful for tasks +// which should run only when the system is non-idle. +class NonWakingTimeDomain : public base::sequence_manager::TimeDomain { + public: + explicit NonWakingTimeDomain(const base::TickClock* tick_clock); + ~NonWakingTimeDomain() override; + + // TimeDomain: + base::sequence_manager::LazyNow CreateLazyNow() const override; + base::TimeTicks Now() const override; + base::Optional<base::TimeDelta> DelayTillNextTask( + base::sequence_manager::LazyNow* lazy_now) override; + bool MaybeFastForwardToNextTask(bool quit_when_idle_requested) override; + const char* GetName() const override; + void SetNextDelayedDoWork(base::sequence_manager::LazyNow* lazy_now, + base::TimeTicks run_time) override; + + private: + const base::TickClock* tick_clock_; +}; + +} // namespace scheduler +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_MAIN_THREAD_NON_WAKING_TIME_DOMAIN_H_ diff --git a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/pending_user_input.h b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/pending_user_input.h index 64608d7eebb..62498217237 100644 --- a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/pending_user_input.h +++ b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/pending_user_input.h @@ -7,7 +7,7 @@ #include <array> -#include "third_party/blink/public/platform/web_input_event.h" +#include "third_party/blink/public/common/input/web_input_event.h" #include "third_party/blink/renderer/platform/scheduler/public/pending_user_input_type.h" #include "third_party/blink/renderer/platform/wtf/text/atomic_string.h" diff --git a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/task_type_names.cc b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/task_type_names.cc index 46cbd2b9c41..98927259f7b 100644 --- a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/task_type_names.cc +++ b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/task_type_names.cc @@ -107,6 +107,8 @@ const char* TaskTypeNames::TaskTypeToString(TaskType task_type) { return "MainThreadTaskQueueCleanup"; case TaskType::kMainThreadTaskQueueMemoryPurge: return "MainThreadTaskQueueMemoryPurge"; + case TaskType::kMainThreadTaskQueueNonWaking: + return "MainThreadTaskQueueNonWaking"; case TaskType::kInternalIntersectionObserver: return "InternalIntersectionObserver"; case TaskType::kCompositorThreadTaskQueueDefault: @@ -135,6 +137,8 @@ const char* TaskTypeNames::TaskTypeToString(TaskType task_type) { return "ExperimentalWebScheduling"; case TaskType::kInternalFrameLifecycleControl: return "InternalFrameLifecycleControl"; + case TaskType::kInternalFindInPage: + return "InternalFindInPage"; case TaskType::kCount: return "Count"; } diff --git a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/user_model.cc b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/user_model.cc index 361b57ef706..0b04962ea63 100644 --- a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/user_model.cc +++ b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/user_model.cc @@ -11,7 +11,6 @@ UserModel::UserModel() : pending_input_event_count_(0), is_gesture_active_(false), is_gesture_expected_(false) {} -UserModel::~UserModel() = default; void UserModel::DidStartProcessingInputEvent(blink::WebInputEvent::Type type, const base::TimeTicks now) { @@ -99,8 +98,7 @@ bool UserModel::IsGestureExpectedSoonImpl( base::TimeDelta::FromMilliseconds(kExpectSubsequentGestureMillis); return true; } else { - // If we've have a finished a gesture then a subsequent gesture is deemed - // likely. + // If we have finished a gesture then a subsequent gesture is deemed likely. base::TimeDelta expect_subsequent_gesture_for = base::TimeDelta::FromMilliseconds(kExpectSubsequentGestureMillis); if (last_continuous_gesture_time_.is_null() || diff --git a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/user_model.h b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/user_model.h index e29de4b9202..fb7d2b79468 100644 --- a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/user_model.h +++ b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/user_model.h @@ -8,8 +8,8 @@ #include "base/macros.h" #include "base/trace_event/trace_event.h" #include "base/trace_event/traced_value.h" +#include "third_party/blink/public/common/input/web_input_event.h" #include "third_party/blink/public/platform/scheduler/web_thread_scheduler.h" -#include "third_party/blink/public/platform/web_input_event.h" #include "third_party/blink/renderer/platform/platform_export.h" #include "third_party/blink/renderer/platform/wtf/allocator/allocator.h" @@ -21,7 +21,6 @@ class PLATFORM_EXPORT UserModel { public: UserModel(); - ~UserModel(); // Tells us that the system started processing an input event. Must be paired // with a call to DidFinishProcessingInputEvent. diff --git a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/web_scheduling_priority.cc b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/web_scheduling_priority.cc index c3c98447ec4..d680bb7669a 100644 --- a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/web_scheduling_priority.cc +++ b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/web_scheduling_priority.cc @@ -8,45 +8,33 @@ namespace blink { namespace { -const AtomicString& ImmediatePriorityKeyword() { - DEFINE_STATIC_LOCAL(const AtomicString, immediate_priority, ("immediate")); - return immediate_priority; +const AtomicString& UserBlockingPriorityKeyword() { + DEFINE_STATIC_LOCAL(const AtomicString, user_blocking_priority, + ("user-blocking")); + return user_blocking_priority; } -const AtomicString& HighPriorityKeyword() { - DEFINE_STATIC_LOCAL(const AtomicString, high_priority, ("high")); - return high_priority; +const AtomicString& UserVisiblePriorityKeyword() { + DEFINE_STATIC_LOCAL(const AtomicString, user_visible_priority, + ("user-visible")); + return user_visible_priority; } -const AtomicString& DefaultPriorityKeyword() { - DEFINE_STATIC_LOCAL(const AtomicString, default_priority, ("default")); - return default_priority; -} - -const AtomicString& LowPriorityKeyword() { - DEFINE_STATIC_LOCAL(const AtomicString, low_priority, ("low")); - return low_priority; -} - -const AtomicString& IdlePriorityKeyword() { - DEFINE_STATIC_LOCAL(const AtomicString, idle_priority, ("idle")); - return idle_priority; +const AtomicString& BackgroundPriorityKeyword() { + DEFINE_STATIC_LOCAL(const AtomicString, background_priority, ("background")); + return background_priority; } } // namespace AtomicString WebSchedulingPriorityToString(WebSchedulingPriority priority) { switch (priority) { - case WebSchedulingPriority::kImmediatePriority: - return ImmediatePriorityKeyword(); - case WebSchedulingPriority::kHighPriority: - return HighPriorityKeyword(); - case WebSchedulingPriority::kDefaultPriority: - return DefaultPriorityKeyword(); - case WebSchedulingPriority::kLowPriority: - return LowPriorityKeyword(); - case WebSchedulingPriority::kIdlePriority: - return IdlePriorityKeyword(); + case WebSchedulingPriority::kUserBlockingPriority: + return UserBlockingPriorityKeyword(); + case WebSchedulingPriority::kUserVisiblePriority: + return UserVisiblePriorityKeyword(); + case WebSchedulingPriority::kBackgroundPriority: + return BackgroundPriorityKeyword(); } NOTREACHED(); @@ -55,19 +43,14 @@ AtomicString WebSchedulingPriorityToString(WebSchedulingPriority priority) { WebSchedulingPriority WebSchedulingPriorityFromString( const AtomicString& priority) { - if (priority == ImmediatePriorityKeyword()) - return WebSchedulingPriority::kImmediatePriority; - if (priority == HighPriorityKeyword()) - return WebSchedulingPriority::kHighPriority; - if (priority == DefaultPriorityKeyword()) - return WebSchedulingPriority::kDefaultPriority; - if (priority == LowPriorityKeyword()) - return WebSchedulingPriority::kLowPriority; - if (priority == IdlePriorityKeyword()) - return WebSchedulingPriority::kIdlePriority; - + if (priority == UserBlockingPriorityKeyword()) + return WebSchedulingPriority::kUserBlockingPriority; + if (priority == UserVisiblePriorityKeyword()) + return WebSchedulingPriority::kUserVisiblePriority; + if (priority == BackgroundPriorityKeyword()) + return WebSchedulingPriority::kBackgroundPriority; NOTREACHED(); - return WebSchedulingPriority::kDefaultPriority; + return WebSchedulingPriority::kUserVisiblePriority; } } // namespace blink diff --git a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/widget_scheduler.cc b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/widget_scheduler.cc new file mode 100644 index 00000000000..0e7bc1f23a5 --- /dev/null +++ b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/widget_scheduler.cc @@ -0,0 +1,35 @@ +// Copyright 2019 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. + +#include "third_party/blink/renderer/platform/scheduler/main_thread/widget_scheduler.h" + +#include "third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.h" + +namespace blink { +namespace scheduler { + +WidgetScheduler::WidgetScheduler( + MainThreadSchedulerImpl* main_thread_scheduler) { + input_task_queue_ = main_thread_scheduler->NewTaskQueue( + MainThreadTaskQueue::QueueCreationParams( + MainThreadTaskQueue::QueueType::kInput) + .SetShouldMonitorQuiescence(true) + .SetFixedPriority( + base::make_optional(TaskQueue::QueuePriority::kHighestPriority))); + input_task_runner_ = + input_task_queue_->CreateTaskRunner(TaskType::kMainThreadTaskQueueInput); + input_task_queue_enabled_voter_ = + input_task_queue_->CreateQueueEnabledVoter(); +} + +WidgetScheduler::~WidgetScheduler() { + input_task_queue_->ShutdownTaskQueue(); +} + +scoped_refptr<base::SingleThreadTaskRunner> WidgetScheduler::InputTaskRunner() { + return input_task_runner_; +} + +} // namespace scheduler +} // namespace blink diff --git a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/widget_scheduler.h b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/widget_scheduler.h new file mode 100644 index 00000000000..83a5fdecb26 --- /dev/null +++ b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/widget_scheduler.h @@ -0,0 +1,37 @@ +// Copyright 2019 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 THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_MAIN_THREAD_WIDGET_SCHEDULER_H_ +#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_MAIN_THREAD_WIDGET_SCHEDULER_H_ + +#include <memory> + +#include "base/task/sequence_manager/task_queue.h" +#include "third_party/blink/public/platform/scheduler/web_widget_scheduler.h" + +namespace blink { +namespace scheduler { + +class MainThreadSchedulerImpl; +class MainThreadTaskQueue; + +class WidgetScheduler : public WebWidgetScheduler { + public: + WidgetScheduler(MainThreadSchedulerImpl*); + ~WidgetScheduler() override; + scoped_refptr<base::SingleThreadTaskRunner> InputTaskRunner() override; + + private: + scoped_refptr<MainThreadTaskQueue> input_task_queue_; + scoped_refptr<base::SingleThreadTaskRunner> input_task_runner_; + std::unique_ptr<base::sequence_manager::TaskQueue::QueueEnabledVoter> + input_task_queue_enabled_voter_; + + DISALLOW_COPY_AND_ASSIGN(WidgetScheduler); +}; + +} // namespace scheduler +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_MAIN_THREAD_WIDGET_SCHEDULER_H_ |