summaryrefslogtreecommitdiff
path: root/chromium/third_party/blink/renderer/platform/scheduler/main_thread
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2021-05-20 09:47:09 +0200
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2021-06-07 11:15:42 +0000
commit189d4fd8fad9e3c776873be51938cd31a42b6177 (patch)
tree6497caeff5e383937996768766ab3bb2081a40b2 /chromium/third_party/blink/renderer/platform/scheduler/main_thread
parent8bc75099d364490b22f43a7ce366b366c08f4164 (diff)
downloadqtwebengine-chromium-189d4fd8fad9e3c776873be51938cd31a42b6177.tar.gz
BASELINE: Update Chromium to 90.0.4430.221
Change-Id: Iff4d9d18d2fcf1a576f3b1f453010f744a232920 Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Diffstat (limited to 'chromium/third_party/blink/renderer/platform/scheduler/main_thread')
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/main_thread/agent_group_scheduler_impl.cc55
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/main_thread/agent_group_scheduler_impl.h23
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/main_thread/auto_advancing_virtual_time_domain_unittest.cc1
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/main_thread/compositor_priority_experiments.cc2
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.cc108
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.h14
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl_unittest.cc190
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/main_thread/frame_task_queue_controller.cc21
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/main_thread/frame_task_queue_controller.h3
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/main_thread/idle_time_estimator.cc29
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/main_thread/idle_time_estimator.h7
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/main_thread/idle_time_estimator_unittest.cc92
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread.cc8
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread.h2
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_helper.cc18
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_helper.h4
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.cc412
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.h58
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl_unittest.cc78
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_task_queue.cc72
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_task_queue.h88
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_unittest.cc4
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl.cc58
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl.h8
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl_unittest.cc113
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/main_thread/render_widget_signals.cc14
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/main_thread/render_widget_signals.h3
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/main_thread/task_type_names.cc2
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/main_thread/user_model.cc31
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/main_thread/user_model.h3
30 files changed, 932 insertions, 589 deletions
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/agent_group_scheduler_impl.cc b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/agent_group_scheduler_impl.cc
index 0aacf6d7ce6..5acdacb3058 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/agent_group_scheduler_impl.cc
+++ b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/agent_group_scheduler_impl.cc
@@ -4,6 +4,7 @@
#include "third_party/blink/renderer/platform/scheduler/main_thread/agent_group_scheduler_impl.h"
+#include "third_party/blink/public/common/browser_interface_broker_proxy.h"
#include "third_party/blink/public/platform/task_type.h"
#include "third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.h"
#include "third_party/blink/renderer/platform/scheduler/public/dummy_schedulers.h"
@@ -25,19 +26,34 @@ MainThreadTaskQueue::QueueCreationParams DefaultTaskQueueCreationParams(
.SetAgentGroupScheduler(agent_group_scheduler_impl);
}
+MainThreadTaskQueue::QueueCreationParams CompositorTaskRunnerCreationParams(
+ AgentGroupSchedulerImpl* agent_group_scheduler_impl) {
+ return MainThreadTaskQueue::QueueCreationParams(
+ MainThreadTaskQueue::QueueType::kCompositor)
+ .SetShouldMonitorQuiescence(true)
+ .SetPrioritisationType(
+ MainThreadTaskQueue::QueueTraits::PrioritisationType::kCompositor)
+ .SetAgentGroupScheduler(agent_group_scheduler_impl);
+}
+
AgentGroupSchedulerImpl::AgentGroupSchedulerImpl(
MainThreadSchedulerImpl& main_thread_scheduler)
: default_task_queue_(main_thread_scheduler.NewTaskQueue(
DefaultTaskQueueCreationParams(this))),
default_task_runner_(default_task_queue_->CreateTaskRunner(
TaskType::kMainThreadTaskQueueDefault)),
+ compositor_task_queue_(main_thread_scheduler.NewTaskQueue(
+ CompositorTaskRunnerCreationParams(this))),
+ compositor_task_runner_(compositor_task_queue_->CreateTaskRunner(
+ TaskType::kMainThreadTaskQueueCompositor)),
main_thread_scheduler_(main_thread_scheduler) {
DCHECK(!default_task_queue_->GetFrameScheduler());
DCHECK_EQ(default_task_queue_->GetAgentGroupScheduler(), this);
}
AgentGroupSchedulerImpl::~AgentGroupSchedulerImpl() {
- default_task_queue_->ShutdownTaskQueue();
+ default_task_queue_->DetachFromMainThreadScheduler();
+ compositor_task_queue_->DetachFromMainThreadScheduler();
main_thread_scheduler_.RemoveAgentGroupScheduler(this);
}
@@ -48,9 +64,46 @@ std::unique_ptr<PageScheduler> AgentGroupSchedulerImpl::CreatePageScheduler(
return page_scheduler;
}
+scoped_refptr<base::SingleThreadTaskRunner>
+AgentGroupSchedulerImpl::DefaultTaskRunner() {
+ return default_task_runner_;
+}
+
+scoped_refptr<base::SingleThreadTaskRunner>
+AgentGroupSchedulerImpl::CompositorTaskRunner() {
+ if (main_thread_scheduler_.scheduling_settings()
+ .mbi_compositor_task_runner_per_agent_scheduling_group) {
+ return compositor_task_runner_;
+ }
+ // We temporarily redirect the per-AGS compositor task runner to the main
+ // thread's compositor task runner.
+ return main_thread_scheduler_.CompositorTaskRunner();
+}
+
+scoped_refptr<MainThreadTaskQueue>
+AgentGroupSchedulerImpl::CompositorTaskQueue() {
+ return compositor_task_queue_;
+}
+
+WebThreadScheduler& AgentGroupSchedulerImpl::GetMainThreadScheduler() {
+ return main_thread_scheduler_;
+}
+
AgentGroupScheduler& AgentGroupSchedulerImpl::AsAgentGroupScheduler() {
return *this;
}
+void AgentGroupSchedulerImpl::BindInterfaceBroker(
+ mojo::PendingRemote<mojom::BrowserInterfaceBroker> remote_broker) {
+ DCHECK(!broker_.is_bound());
+ broker_.Bind(std::move(remote_broker), default_task_runner_);
+}
+
+BrowserInterfaceBrokerProxy&
+AgentGroupSchedulerImpl::GetBrowserInterfaceBroker() {
+ DCHECK(broker_.is_bound());
+ return broker_;
+}
+
} // namespace scheduler
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/agent_group_scheduler_impl.h b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/agent_group_scheduler_impl.h
index 01dbd8588ba..7ea89714fdb 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/agent_group_scheduler_impl.h
+++ b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/agent_group_scheduler_impl.h
@@ -6,6 +6,9 @@
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_MAIN_THREAD_AGENT_GROUP_SCHEDULER_IMPL_H_
#include "base/memory/scoped_refptr.h"
+#include "base/task/sequence_manager/task_queue.h"
+#include "mojo/public/cpp/bindings/remote.h"
+#include "third_party/blink/public/common/browser_interface_broker_proxy.h"
#include "third_party/blink/renderer/platform/platform_export.h"
#include "third_party/blink/renderer/platform/scheduler/public/agent_group_scheduler.h"
@@ -17,6 +20,7 @@ namespace blink {
namespace scheduler {
class MainThreadSchedulerImpl;
class MainThreadTaskQueue;
+class WebThreadScheduler;
// AgentGroupScheduler implementation which schedules per-AgentSchedulingGroup
// tasks.
@@ -30,18 +34,25 @@ class PLATFORM_EXPORT AgentGroupSchedulerImpl : public AgentGroupScheduler {
std::unique_ptr<PageScheduler> CreatePageScheduler(
PageScheduler::Delegate*) override;
- scoped_refptr<base::SingleThreadTaskRunner> DefaultTaskRunner() override {
- return default_task_runner_;
- }
- MainThreadSchedulerImpl& GetMainThreadScheduler() {
- return main_thread_scheduler_;
- }
+ scoped_refptr<base::SingleThreadTaskRunner> DefaultTaskRunner() override;
+ scoped_refptr<base::SingleThreadTaskRunner> CompositorTaskRunner() override;
+ scoped_refptr<MainThreadTaskQueue> CompositorTaskQueue();
+ WebThreadScheduler& GetMainThreadScheduler() override;
AgentGroupScheduler& AsAgentGroupScheduler() override;
+ void BindInterfaceBroker(
+ mojo::PendingRemote<blink::mojom::BrowserInterfaceBroker> remote_broker)
+ override;
+ BrowserInterfaceBrokerProxy& GetBrowserInterfaceBroker() override;
+
private:
scoped_refptr<MainThreadTaskQueue> default_task_queue_;
scoped_refptr<base::SingleThreadTaskRunner> default_task_runner_;
+ scoped_refptr<MainThreadTaskQueue> compositor_task_queue_;
+ scoped_refptr<base::SingleThreadTaskRunner> compositor_task_runner_;
MainThreadSchedulerImpl& main_thread_scheduler_; // Not owned.
+
+ BrowserInterfaceBrokerProxy broker_;
};
} // namespace scheduler
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/auto_advancing_virtual_time_domain_unittest.cc b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/auto_advancing_virtual_time_domain_unittest.cc
index 9a4538263ee..d41bc4ea90e 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/auto_advancing_virtual_time_domain_unittest.cc
+++ b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/auto_advancing_virtual_time_domain_unittest.cc
@@ -36,6 +36,7 @@ class AutoAdvancingVirtualTimeDomainTest : public testing::Test {
nullptr, test_task_runner_, test_task_runner_->GetMockTickClock());
scheduler_helper_.reset(new NonMainThreadSchedulerHelper(
sequence_manager_.get(), nullptr, TaskType::kInternalTest));
+ scheduler_helper_->AttachToCurrentThread();
scheduler_helper_->AddTaskTimeObserver(&test_task_time_observer_);
task_queue_ = scheduler_helper_->DefaultNonMainThreadTaskQueue();
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 0a455119137..1954d462f81 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
@@ -182,7 +182,7 @@ CompositorPriorityExperiments::CompositorBudgetPoolController::
"CompositorBudgetPool", this, tracing_controller, now));
compositor_budget_pool_->SetMinBudgetLevelToRun(now, min_budget);
compositor_budget_pool_->SetTimeBudgetRecoveryRate(now, budget_recovery_rate);
- compositor_budget_pool_->AddQueue(now, compositor_queue->GetTaskQueue());
+ compositor_queue->AddToBudgetPool(now, compositor_budget_pool_.get());
}
CompositorPriorityExperiments::CompositorBudgetPoolController::
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 ff5aeb81906..1c15019931b 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
@@ -14,10 +14,14 @@
#include "base/task/sequence_manager/lazy_now.h"
#include "base/time/time.h"
#include "base/trace_event/blame_context.h"
+#include "components/power_scheduler/power_mode.h"
+#include "components/power_scheduler/power_mode_arbiter.h"
+#include "components/power_scheduler/power_mode_voter.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/back_forward_cache_utils.h"
#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
#include "third_party/blink/renderer/platform/scheduler/common/features.h"
#include "third_party/blink/renderer/platform/scheduler/common/throttling/budget_pool.h"
@@ -31,6 +35,7 @@
#include "third_party/blink/renderer/platform/scheduler/main_thread/task_type_names.h"
#include "third_party/blink/renderer/platform/scheduler/main_thread/web_scheduling_task_queue_impl.h"
#include "third_party/blink/renderer/platform/scheduler/worker/worker_scheduler_proxy.h"
+#include "third_party/perfetto/include/perfetto/tracing/traced_value.h"
namespace blink {
@@ -189,7 +194,10 @@ FrameSchedulerImpl::FrameSchedulerImpl(
waiting_for_meaningful_paint_(true,
"FrameScheduler.WaitingForMeaningfulPaint",
&tracing_controller_,
- YesNoStateToString) {
+ YesNoStateToString),
+ loading_power_mode_voter_(
+ power_scheduler::PowerModeArbiter::GetInstance()->NewVoter(
+ "PowerModeVoter.Loading")) {
frame_task_queue_controller_.reset(
new FrameTaskQueueController(main_thread_scheduler_, this, this));
}
@@ -384,18 +392,16 @@ QueueTraits FrameSchedulerImpl::CreateQueueTraitsForTaskType(TaskType type) {
QueueTraits::PrioritisationType::kJavaScriptTimer)
.SetCanBeIntensivelyThrottled(IsIntensiveWakeUpThrottlingEnabled());
case TaskType::kJavascriptTimerImmediate: {
- return DeferrableTaskQueueTraits()
- .SetPrioritisationType(
- QueueTraits::PrioritisationType::kJavaScriptTimer)
- .SetCanBeThrottled(!base::FeatureList::IsEnabled(
- features::kOptOutZeroTimeoutTimersFromThrottling));
+ // Immediate timers are not throttled.
+ return DeferrableTaskQueueTraits().SetPrioritisationType(
+ QueueTraits::PrioritisationType::kJavaScriptTimer);
}
case TaskType::kInternalLoading:
case TaskType::kNetworking:
case TaskType::kNetworkingWithURLLoaderAnnotation:
return LoadingTaskQueueTraits();
case TaskType::kNetworkingUnfreezable:
- return base::FeatureList::IsEnabled(features::kLoadingTasksUnfreezable)
+ return IsInflightNetworkRequestBackForwardCacheSupportEnabled()
? UnfreezableLoadingTaskQueueTraits()
: LoadingTaskQueueTraits();
case TaskType::kNetworkingControl:
@@ -425,6 +431,7 @@ QueueTraits FrameSchedulerImpl::CreateQueueTraitsForTaskType(TaskType type) {
case TaskType::kApplicationLifeCycle:
case TaskType::kBackgroundFetch:
case TaskType::kPermission:
+ case TaskType::kWakeLock:
// TODO(altimin): Move appropriate tasks to throttleable task queue.
return DeferrableTaskQueueTraits();
// PostedMessage can be used for navigation, so we shouldn't defer it
@@ -612,9 +619,14 @@ void FrameSchedulerImpl::DidCommitProvisionalLoad(
bool is_same_document = navigation_type == NavigationType::kSameDocument;
if (!is_same_document) {
+ loading_power_mode_voter_->VoteFor(power_scheduler::PowerMode::kLoading);
+ loading_power_mode_voter_->ResetVoteAfterTimeout(
+ power_scheduler::PowerModeVoter::kLoadingTimeout);
+
waiting_for_contentful_paint_ = true;
waiting_for_meaningful_paint_ = true;
}
+
if (is_main_frame && !is_same_document) {
task_time_ = base::TimeDelta();
// Ignore result here, based on the assumption that
@@ -670,7 +682,7 @@ void FrameSchedulerImpl::OnStartedUsingFeature(
"renderer.scheduler", "ActiveSchedulerTrackedFeature",
TRACE_ID_LOCAL(reinterpret_cast<intptr_t>(this) ^
static_cast<int>(feature)),
- "feature", FeatureToString(feature));
+ "feature", FeatureToHumanReadableString(feature));
}
}
@@ -773,32 +785,22 @@ void FrameSchedulerImpl::OnRemovedBackForwardCacheOptOut(
!back_forward_cache_opt_out_counts_.empty();
}
-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_to_main_frame", IsCrossOriginToMainFrame());
- state->SetString("frame_type",
- frame_type_ == FrameScheduler::FrameType::kMainFrame
- ? "MainFrame"
- : "Subframe");
- state->SetBoolean(
- "disable_background_timer_throttling",
- !RuntimeEnabledFeatures::TimerThrottlingForBackgroundTabsEnabled());
-
- {
- auto dictionary_scope =
- state->BeginDictionaryScoped("frame_task_queue_controller");
- frame_task_queue_controller_->AsValueInto(state);
- }
+void FrameSchedulerImpl::WriteIntoTracedValue(
+ perfetto::TracedValue context) const {
+ auto dict = std::move(context).WriteDictionary();
+ dict.Add("frame_visible", frame_visible_);
+ dict.Add("page_visible", parent_page_scheduler_->IsPageVisible());
+ dict.Add("cross_origin_to_main_frame", IsCrossOriginToMainFrame());
+ dict.Add("frame_type", frame_type_ == FrameScheduler::FrameType::kMainFrame
+ ? "MainFrame"
+ : "Subframe");
+ dict.Add("disable_background_timer_throttling",
+ !RuntimeEnabledFeatures::TimerThrottlingForBackgroundTabsEnabled());
- if (blame_context_) {
- auto dictionary_scope = state->BeginDictionaryScoped("blame_context");
- state->SetString(
- "id_ref",
- PointerToString(reinterpret_cast<void*>(blame_context_->id())));
- state->SetString("scope", blame_context_->scope());
- }
+ dict.Add("frame_task_queue_controller", frame_task_queue_controller_);
+
+ if (blame_context_)
+ dict.Add("blame_context", blame_context_);
}
void FrameSchedulerImpl::SetPageVisibilityForTracing(
@@ -845,12 +847,17 @@ void FrameSchedulerImpl::UpdatePolicy() {
bool task_queues_were_throttled = task_queues_throttled_;
task_queues_throttled_ = ShouldThrottleTaskQueues();
+ if (!task_queues_throttled_)
+ throttled_task_queue_handles_.clear();
+
for (const auto& task_queue_and_voter :
frame_task_queue_controller_->GetAllTaskQueuesAndVoters()) {
UpdateQueuePolicy(task_queue_and_voter.first, task_queue_and_voter.second);
- if (task_queues_were_throttled != task_queues_throttled_) {
- UpdateTaskQueueThrottling(task_queue_and_voter.first,
- task_queues_throttled_);
+ if (task_queues_throttled_ && !task_queues_were_throttled &&
+ task_queue_and_voter.first->CanBeThrottled()) {
+ MainThreadTaskQueue::ThrottleHandle handle =
+ task_queue_and_voter.first->Throttle();
+ throttled_task_queue_handles_.push_back(std::move(handle));
}
}
@@ -937,6 +944,8 @@ void FrameSchedulerImpl::OnLoad() {
// update.
main_thread_scheduler_->OnMainFrameLoad(*this);
}
+
+ loading_power_mode_voter_->VoteFor(power_scheduler::PowerMode::kIdle);
}
bool FrameSchedulerImpl::IsWaitingForContentfulPaint() const {
@@ -962,24 +971,14 @@ bool FrameSchedulerImpl::ShouldThrottleTaskQueues() const {
return false;
if (!parent_page_scheduler_->IsPageVisible())
return true;
+ if (base::FeatureList::IsEnabled(kThrottleVisibleNotFocusedTimers) &&
+ !parent_page_scheduler_->IsPageFocused()) {
+ return true;
+ }
return RuntimeEnabledFeatures::TimerThrottlingForHiddenFramesEnabled() &&
!frame_visible_ && IsCrossOriginToMainFrame();
}
-void FrameSchedulerImpl::UpdateTaskQueueThrottling(
- MainThreadTaskQueue* task_queue,
- bool should_throttle) {
- if (!task_queue->CanBeThrottled())
- return;
- if (should_throttle) {
- main_thread_scheduler_->task_queue_throttler()->IncreaseThrottleRefCount(
- task_queue->GetTaskQueue());
- } else {
- main_thread_scheduler_->task_queue_throttler()->DecreaseThrottleRefCount(
- task_queue->GetTaskQueue());
- }
-}
-
bool FrameSchedulerImpl::IsExemptFromBudgetBasedThrottling() const {
return opted_out_from_aggressive_throttling();
}
@@ -1214,7 +1213,8 @@ void FrameSchedulerImpl::OnTaskQueueCreated(
task_queue, frame_origin_type_, &lazy_now);
if (task_queues_throttled_) {
- UpdateTaskQueueThrottling(task_queue, true);
+ MainThreadTaskQueue::ThrottleHandle handle = task_queue->Throttle();
+ throttled_task_queue_handles_.push_back(std::move(handle));
}
}
}
@@ -1349,8 +1349,7 @@ MainThreadTaskQueue::QueueTraits
FrameSchedulerImpl::DeferrableTaskQueueTraits() {
return QueueTraits()
.SetCanBeDeferred(true)
- .SetCanBeFrozen(base::FeatureList::IsEnabled(
- blink::features::kStopNonTimersInBackground))
+ .SetCanBeFrozen(true)
.SetCanBePaused(true)
.SetCanRunWhenVirtualTimePaused(false)
.SetCanBePausedForAndroidWebview(true);
@@ -1359,8 +1358,7 @@ FrameSchedulerImpl::DeferrableTaskQueueTraits() {
// static
MainThreadTaskQueue::QueueTraits FrameSchedulerImpl::PausableTaskQueueTraits() {
return QueueTraits()
- .SetCanBeFrozen(base::FeatureList::IsEnabled(
- blink::features::kStopNonTimersInBackground))
+ .SetCanBeFrozen(true)
.SetCanBePaused(true)
.SetCanRunWhenVirtualTimePaused(false)
.SetCanBePausedForAndroidWebview(true);
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 66abb4e0dc5..f9d874d1b9d 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
@@ -18,6 +18,7 @@
#include "base/single_thread_task_runner.h"
#include "base/task/sequence_manager/task_queue.h"
#include "base/trace_event/trace_event.h"
+#include "components/power_scheduler/power_mode_voter.h"
#include "net/base/request_priority.h"
#include "services/metrics/public/cpp/ukm_source_id.h"
#include "third_party/blink/public/platform/task_type.h"
@@ -32,6 +33,7 @@
#include "third_party/blink/renderer/platform/scheduler/public/web_scheduling_priority.h"
#include "third_party/blink/renderer/platform/scheduler/worker/worker_scheduler_proxy.h"
#include "third_party/blink/renderer/platform/wtf/hash_map.h"
+#include "third_party/perfetto/include/perfetto/tracing/traced_value_forward.h"
namespace base {
namespace sequence_manager {
@@ -39,7 +41,6 @@ class TaskQueue;
} // namespace sequence_manager
namespace trace_event {
class BlameContext;
-class TracedValue;
} // namespace trace_event
} // namespace base
@@ -132,7 +133,6 @@ class PLATFORM_EXPORT FrameSchedulerImpl : public FrameScheduler,
// created by an SVGImage). Virtual for testing.
virtual bool IsOrdinary() const;
- void AsValueInto(base::trace_event::TracedValue* state) const;
bool IsExemptFromBudgetBasedThrottling() const override;
std::unique_ptr<blink::mojom::blink::PauseSubresourceLoadingHandle>
GetPauseSubresourceLoadingHandle() override;
@@ -203,6 +203,8 @@ class PLATFORM_EXPORT FrameSchedulerImpl : public FrameScheduler,
const base::UnguessableToken& GetAgentClusterId() const;
+ void WriteIntoTracedValue(perfetto::TracedValue context) const;
+
protected:
FrameSchedulerImpl(MainThreadSchedulerImpl* main_thread_scheduler,
PageSchedulerImpl* parent_page_scheduler,
@@ -258,11 +260,6 @@ class PLATFORM_EXPORT FrameSchedulerImpl : public FrameScheduler,
void UpdateQueuePolicy(
MainThreadTaskQueue* queue,
base::sequence_manager::TaskQueue::QueueEnabledVoter* voter);
- // Update throttling for |task_queue|. This changes the throttling ref counts
- // and should only be called for new queues if throttling is enabled, or if
- // the throttling state changes.
- void UpdateTaskQueueThrottling(MainThreadTaskQueue* task_queue,
- bool should_throttle);
void AddPauseSubresourceLoadingHandle();
void RemovePauseSubresourceLoadingHandle();
@@ -341,6 +338,7 @@ class PLATFORM_EXPORT FrameSchedulerImpl : public FrameScheduler,
TraceableState<bool, TracingCategoryName::kInfo> subresource_loading_paused_;
StateTracer<TracingCategoryName::kInfo> url_tracer_;
TraceableState<bool, TracingCategoryName::kInfo> task_queues_throttled_;
+ Vector<MainThreadTaskQueue::ThrottleHandle> throttled_task_queue_handles_;
TraceableState<bool, TracingCategoryName::kInfo>
preempted_for_cooperative_scheduling_;
// TODO(https://crbug.com/827113): Trace the count of opt-outs.
@@ -376,6 +374,8 @@ class PLATFORM_EXPORT FrameSchedulerImpl : public FrameScheduler,
TraceableState<bool, TracingCategoryName::kInfo>
waiting_for_meaningful_paint_;
+ std::unique_ptr<power_scheduler::PowerModeVoter> loading_power_mode_voter_;
+
// TODO(altimin): Remove after we have have 1:1 relationship between frames
// and documents.
base::WeakPtrFactory<FrameSchedulerImpl> document_bound_weak_factory_{this};
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 e076b0a5b53..6338f29ec7f 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
@@ -27,6 +27,7 @@
#include "third_party/blink/public/common/features.h"
#include "third_party/blink/public/common/switches.h"
#include "third_party/blink/public/platform/scheduler/web_agent_group_scheduler.h"
+#include "third_party/blink/public/platform/web_runtime_features.h"
#include "third_party/blink/renderer/platform/scheduler/common/features.h"
#include "third_party/blink/renderer/platform/scheduler/main_thread/frame_task_queue_controller.h"
#include "third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.h"
@@ -143,10 +144,11 @@ constexpr TaskType kAllFrameTaskTypes[] = {
TaskType::kInternalTranslation,
TaskType::kInternalInspector,
TaskType::kInternalNavigationAssociatedUnfreezable,
- TaskType::kInternalHighPriorityLocalFrame};
+ TaskType::kInternalHighPriorityLocalFrame,
+ TaskType::kWakeLock};
static_assert(
- static_cast<int>(TaskType::kCount) == 76,
+ static_cast<int>(TaskType::kCount) == 77,
"When adding a TaskType, make sure that kAllFrameTaskTypes is updated.");
void AppendToVectorTestTask(Vector<String>* vector, String value) {
@@ -288,6 +290,52 @@ class FrameSchedulerImplTest : public testing::Test {
}
}
+ // Helper for posting several tasks to specific queues. |task_descriptor| is a
+ // string with space delimited task identifiers. The first letter of each task
+ // identifier specifies the task queue:
+ // - 'L': Loading task queue
+ // - 'T': Throttleable task queue
+ // - 'P': Pausable task queue
+ // - 'U': Unpausable task queue
+ // - 'D': Deferrable task queue
+ void PostTestTasksToQueuesWithTrait(Vector<String>* run_order,
+ const String& task_descriptor) {
+ std::istringstream stream(task_descriptor.Utf8());
+ while (!stream.eof()) {
+ std::string task;
+ stream >> task;
+ switch (task[0]) {
+ case 'L':
+ LoadingTaskQueue()->GetTaskRunnerWithDefaultTaskType()->PostTask(
+ FROM_HERE, base::BindOnce(&AppendToVectorTestTask, run_order,
+ String::FromUTF8(task)));
+ break;
+ case 'T':
+ ThrottleableTaskQueue()->GetTaskRunnerWithDefaultTaskType()->PostTask(
+ FROM_HERE, base::BindOnce(&AppendToVectorTestTask, run_order,
+ String::FromUTF8(task)));
+ break;
+ case 'P':
+ PausableTaskQueue()->GetTaskRunnerWithDefaultTaskType()->PostTask(
+ FROM_HERE, base::BindOnce(&AppendToVectorTestTask, run_order,
+ String::FromUTF8(task)));
+ break;
+ case 'U':
+ UnpausableTaskQueue()->GetTaskRunnerWithDefaultTaskType()->PostTask(
+ FROM_HERE, base::BindOnce(&AppendToVectorTestTask, run_order,
+ String::FromUTF8(task)));
+ break;
+ case 'D':
+ DeferrableTaskQueue()->GetTaskRunnerWithDefaultTaskType()->PostTask(
+ FROM_HERE, base::BindOnce(&AppendToVectorTestTask, run_order,
+ String::FromUTF8(task)));
+ break;
+ default:
+ NOTREACHED();
+ }
+ }
+ }
+
static void ResetForNavigation(FrameSchedulerImpl* frame_scheduler) {
frame_scheduler->ResetForNavigation();
}
@@ -390,14 +438,12 @@ class FrameSchedulerImplTest : public testing::Test {
bool IsThrottled() {
EXPECT_TRUE(throttleable_task_queue());
- return scheduler_->task_queue_throttler()->IsThrottled(
- throttleable_task_queue()->GetTaskQueue());
+ return throttleable_task_queue()->IsThrottled();
}
bool IsTaskTypeThrottled(TaskType task_type) {
scoped_refptr<MainThreadTaskQueue> task_queue = GetTaskQueue(task_type);
- return scheduler_->task_queue_throttler()->IsThrottled(
- task_queue->GetTaskQueue());
+ return task_queue->IsThrottled();
}
SchedulingLifecycleState CalculateLifecycleState(
@@ -430,22 +476,6 @@ class FrameSchedulerImplTest : public testing::Test {
scoped_refptr<MainThreadTaskQueue> throttleable_task_queue_;
};
-class FrameSchedulerImplStopNonTimersInBackgroundEnabledTest
- : public FrameSchedulerImplTest {
- public:
- FrameSchedulerImplStopNonTimersInBackgroundEnabledTest()
- : FrameSchedulerImplTest({blink::features::kStopNonTimersInBackground},
- {}) {}
-};
-
-class FrameSchedulerImplStopNonTimersInBackgroundDisabledTest
- : public FrameSchedulerImplTest {
- public:
- FrameSchedulerImplStopNonTimersInBackgroundDisabledTest()
- : FrameSchedulerImplTest({},
- {blink::features::kStopNonTimersInBackground}) {}
-};
-
class FrameSchedulerImplStopInBackgroundDisabledTest
: public FrameSchedulerImplTest,
public ::testing::WithParamInterface<TaskType> {
@@ -505,10 +535,6 @@ void IncrementCounter(int* counter) {
++*counter;
}
-void RecordQueueName(String name, Vector<String>* tasks) {
- tasks->push_back(std::move(name));
-}
-
// 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,
@@ -857,8 +883,7 @@ TEST_F(FrameSchedulerImplTest, FreezeForegroundOnlyTasks) {
EXPECT_EQ(1, counter);
}
-TEST_F(FrameSchedulerImplStopNonTimersInBackgroundEnabledTest,
- PageFreezeAndUnfreezeFlagEnabled) {
+TEST_F(FrameSchedulerImplTest, PageFreezeAndUnfreeze) {
int counter = 0;
LoadingTaskQueue()->GetTaskRunnerWithDefaultTaskType()->PostTask(
FROM_HERE, base::BindOnce(&IncrementCounter, base::Unretained(&counter)));
@@ -882,13 +907,13 @@ TEST_F(FrameSchedulerImplStopNonTimersInBackgroundEnabledTest,
page_scheduler_->SetPageFrozen(false);
EXPECT_EQ(1, counter);
- // Same as RunUntilIdle but also advances the clock if necessary.
task_environment_.FastForwardUntilNoTasksRemain();
EXPECT_EQ(5, counter);
}
-TEST_F(FrameSchedulerImplStopNonTimersInBackgroundDisabledTest,
- PageFreezeAndUnfreezeFlagDisabled) {
+// Similar to PageFreezeAndUnfreeze, but unfreezes task queues by making the
+// page visible instead of by invoking SetPageFrozen(false).
+TEST_F(FrameSchedulerImplTest, PageFreezeAndPageVisible) {
int counter = 0;
LoadingTaskQueue()->GetTaskRunnerWithDefaultTaskType()->PostTask(
FROM_HERE, base::BindOnce(&IncrementCounter, base::Unretained(&counter)));
@@ -906,13 +931,13 @@ TEST_F(FrameSchedulerImplStopNonTimersInBackgroundDisabledTest,
EXPECT_EQ(0, counter);
base::RunLoop().RunUntilIdle();
- // throttleable tasks and loading tasks are frozen, others continue to run.
- EXPECT_EQ(3, counter);
+ // unpausable tasks continue to run.
+ EXPECT_EQ(1, counter);
- page_scheduler_->SetPageFrozen(false);
+ // Making the page visible should cause frozen queues to resume.
+ page_scheduler_->SetPageVisible(true);
- EXPECT_EQ(3, counter);
- // Same as RunUntilIdle but also advances the clock if necessary.
+ EXPECT_EQ(1, counter);
task_environment_.FastForwardUntilNoTasksRemain();
EXPECT_EQ(5, counter);
}
@@ -980,27 +1005,7 @@ TEST_F(FrameSchedulerImplTest, FramePostsCpuTasksThroughReloadRenavigate) {
TEST_F(FrameSchedulerImplTest, PageFreezeWithKeepActive) {
Vector<String> tasks;
- LoadingTaskQueue()->GetTaskRunnerWithDefaultTaskType()->PostTask(
- FROM_HERE,
- base::BindOnce(&RecordQueueName,
- LoadingTaskQueue()->GetTaskQueue()->GetName(), &tasks));
- ThrottleableTaskQueue()->GetTaskRunnerWithDefaultTaskType()->PostTask(
- FROM_HERE,
- base::BindOnce(&RecordQueueName,
- ThrottleableTaskQueue()->GetTaskQueue()->GetName(),
- &tasks));
- DeferrableTaskQueue()->GetTaskRunnerWithDefaultTaskType()->PostTask(
- FROM_HERE,
- base::BindOnce(&RecordQueueName,
- DeferrableTaskQueue()->GetTaskQueue()->GetName(), &tasks));
- PausableTaskQueue()->GetTaskRunnerWithDefaultTaskType()->PostTask(
- FROM_HERE,
- base::BindOnce(&RecordQueueName,
- PausableTaskQueue()->GetTaskQueue()->GetName(), &tasks));
- UnpausableTaskQueue()->GetTaskRunnerWithDefaultTaskType()->PostTask(
- FROM_HERE,
- base::BindOnce(&RecordQueueName,
- UnpausableTaskQueue()->GetTaskQueue()->GetName(), &tasks));
+ PostTestTasksToQueuesWithTrait(&tasks, "L1 T1 D1 P1 U1");
page_scheduler_->SetKeepActive(true); // say we have a Service Worker
page_scheduler_->SetPageVisible(false);
@@ -1009,30 +1014,19 @@ TEST_F(FrameSchedulerImplTest, PageFreezeWithKeepActive) {
EXPECT_THAT(tasks, UnorderedElementsAre());
base::RunLoop().RunUntilIdle();
// Everything runs except throttleable tasks (timers)
- EXPECT_THAT(tasks,
- UnorderedElementsAre(
- String(LoadingTaskQueue()->GetTaskQueue()->GetName()),
- String(DeferrableTaskQueue()->GetTaskQueue()->GetName()),
- String(PausableTaskQueue()->GetTaskQueue()->GetName()),
- String(UnpausableTaskQueue()->GetTaskQueue()->GetName())));
+ EXPECT_THAT(tasks, UnorderedElementsAre("L1", "D1", "P1", "U1"));
tasks.clear();
- LoadingTaskQueue()->GetTaskRunnerWithDefaultTaskType()->PostTask(
- FROM_HERE,
- base::BindOnce(&RecordQueueName,
- LoadingTaskQueue()->GetTaskQueue()->GetName(), &tasks));
+ PostTestTasksToQueuesWithTrait(&tasks, "L1");
EXPECT_THAT(tasks, UnorderedElementsAre());
base::RunLoop().RunUntilIdle();
// loading task runs
- EXPECT_THAT(tasks, UnorderedElementsAre(String(
- LoadingTaskQueue()->GetTaskQueue()->GetName())));
+ EXPECT_THAT(tasks, UnorderedElementsAre("L1"));
tasks.clear();
- LoadingTaskQueue()->GetTaskRunnerWithDefaultTaskType()->PostTask(
- FROM_HERE,
- base::BindOnce(&RecordQueueName,
- LoadingTaskQueue()->GetTaskQueue()->GetName(), &tasks));
+ PostTestTasksToQueuesWithTrait(&tasks, "L1");
+
// KeepActive is false when Service Worker stops.
page_scheduler_->SetKeepActive(false);
EXPECT_THAT(tasks, UnorderedElementsAre());
@@ -1044,37 +1038,7 @@ TEST_F(FrameSchedulerImplTest, PageFreezeWithKeepActive) {
EXPECT_THAT(tasks, UnorderedElementsAre());
base::RunLoop().RunUntilIdle();
// loading task runs
- EXPECT_THAT(tasks, UnorderedElementsAre(String(
- LoadingTaskQueue()->GetTaskQueue()->GetName())));
-}
-
-TEST_F(FrameSchedulerImplStopNonTimersInBackgroundEnabledTest,
- PageFreezeAndPageVisible) {
- int counter = 0;
- LoadingTaskQueue()->GetTaskRunnerWithDefaultTaskType()->PostTask(
- FROM_HERE, base::BindOnce(&IncrementCounter, base::Unretained(&counter)));
- ThrottleableTaskQueue()->GetTaskRunnerWithDefaultTaskType()->PostTask(
- FROM_HERE, base::BindOnce(&IncrementCounter, base::Unretained(&counter)));
- DeferrableTaskQueue()->GetTaskRunnerWithDefaultTaskType()->PostTask(
- FROM_HERE, base::BindOnce(&IncrementCounter, base::Unretained(&counter)));
- PausableTaskQueue()->GetTaskRunnerWithDefaultTaskType()->PostTask(
- FROM_HERE, base::BindOnce(&IncrementCounter, base::Unretained(&counter)));
- UnpausableTaskQueue()->GetTaskRunnerWithDefaultTaskType()->PostTask(
- FROM_HERE, base::BindOnce(&IncrementCounter, base::Unretained(&counter)));
-
- page_scheduler_->SetPageVisible(false);
- page_scheduler_->SetPageFrozen(true);
-
- EXPECT_EQ(0, counter);
- base::RunLoop().RunUntilIdle();
- EXPECT_EQ(1, counter);
-
- // Making the page visible should cause frozen queues to resume.
- page_scheduler_->SetPageVisible(true);
-
- EXPECT_EQ(1, counter);
- base::RunLoop().RunUntilIdle();
- EXPECT_EQ(5, counter);
+ EXPECT_THAT(tasks, UnorderedElementsAre("L1"));
}
class FrameSchedulerImplTestWithUnfreezableLoading
@@ -1082,7 +1046,9 @@ class FrameSchedulerImplTestWithUnfreezableLoading
public:
FrameSchedulerImplTestWithUnfreezableLoading()
: FrameSchedulerImplTest({blink::features::kLoadingTasksUnfreezable},
- {}) {}
+ {}) {
+ WebRuntimeFeatures::EnableBackForwardCache(true);
+ }
};
TEST_F(FrameSchedulerImplTestWithUnfreezableLoading,
@@ -2478,7 +2444,7 @@ TEST_F(FrameSchedulerImplTest, BackForwardCacheOptOut) {
auto feature_handle1 = frame_scheduler_->RegisterFeature(
SchedulingPolicy::Feature::kWebSocket,
- {SchedulingPolicy::RecordMetricsForBackForwardCache()});
+ {SchedulingPolicy::DisableBackForwardCache()});
EXPECT_THAT(
frame_scheduler_->GetActiveFeaturesTrackedForBackForwardCacheMetrics(),
@@ -2489,7 +2455,7 @@ TEST_F(FrameSchedulerImplTest, BackForwardCacheOptOut) {
auto feature_handle2 = frame_scheduler_->RegisterFeature(
SchedulingPolicy::Feature::kWebRTC,
- {SchedulingPolicy::RecordMetricsForBackForwardCache()});
+ {SchedulingPolicy::DisableBackForwardCache()});
EXPECT_THAT(
frame_scheduler_->GetActiveFeaturesTrackedForBackForwardCacheMetrics(),
@@ -2528,7 +2494,7 @@ TEST_F(FrameSchedulerImplTest, BackForwardCacheOptOut_FrameNavigated) {
auto feature_handle = frame_scheduler_->RegisterFeature(
SchedulingPolicy::Feature::kWebSocket,
- {SchedulingPolicy::RecordMetricsForBackForwardCache()});
+ {SchedulingPolicy::DisableBackForwardCache()});
EXPECT_THAT(
frame_scheduler_->GetActiveFeaturesTrackedForBackForwardCacheMetrics(),
@@ -2539,7 +2505,7 @@ TEST_F(FrameSchedulerImplTest, BackForwardCacheOptOut_FrameNavigated) {
frame_scheduler_->RegisterStickyFeature(
SchedulingPolicy::Feature::kMainResourceHasCacheControlNoStore,
- {SchedulingPolicy::RecordMetricsForBackForwardCache()});
+ {SchedulingPolicy::DisableBackForwardCache()});
EXPECT_THAT(
frame_scheduler_->GetActiveFeaturesTrackedForBackForwardCacheMetrics(),
@@ -2596,11 +2562,11 @@ TEST_F(FrameSchedulerImplTest, FeatureUpload) {
frame_scheduler->RegisterStickyFeature(
SchedulingPolicy::Feature::
kMainResourceHasCacheControlNoStore,
- {SchedulingPolicy::RecordMetricsForBackForwardCache()});
+ {SchedulingPolicy::DisableBackForwardCache()});
frame_scheduler->RegisterStickyFeature(
SchedulingPolicy::Feature::
kMainResourceHasCacheControlNoCache,
- {SchedulingPolicy::RecordMetricsForBackForwardCache()});
+ {SchedulingPolicy::DisableBackForwardCache()});
// Ensure that the feature upload is delayed.
testing::Mock::VerifyAndClearExpectations(delegate);
EXPECT_CALL(
@@ -2635,7 +2601,7 @@ TEST_F(FrameSchedulerImplTest, FeatureUpload_FrameDestruction) {
FeatureHandle* feature_handle) {
*feature_handle = frame_scheduler->RegisterFeature(
SchedulingPolicy::Feature::kWebSocket,
- {SchedulingPolicy::RecordMetricsForBackForwardCache()});
+ {SchedulingPolicy::DisableBackForwardCache()});
// Ensure that the feature upload is delayed.
testing::Mock::VerifyAndClearExpectations(delegate);
EXPECT_CALL(*delegate,
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 ced5549aa9f..6f161891430 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
@@ -17,6 +17,7 @@
#include "third_party/blink/renderer/platform/scheduler/main_thread/web_scheduling_task_queue_impl.h"
#include "third_party/blink/renderer/platform/scheduler/public/web_scheduling_priority.h"
#include "third_party/blink/renderer/platform/wtf/vector.h"
+#include "third_party/perfetto/include/perfetto/tracing/traced_value.h"
namespace blink {
namespace scheduler {
@@ -159,21 +160,11 @@ bool FrameTaskQueueController::RemoveResourceLoadingTaskQueue(
return true;
}
-void FrameTaskQueueController::AsValueInto(
- base::trace_event::TracedValue* state) const {
- {
- auto array_scope = state->BeginArrayScoped("task_queues");
- for (const auto& it : task_queues_) {
- state->AppendString(PointerToString(it.value.get()));
- }
- }
-
- {
- auto array_scope = state->BeginArrayScoped("resource_loading_task_queues");
- for (const auto& queue : resource_loading_task_queues_) {
- state->AppendString(PointerToString(queue.get()));
- }
- }
+void FrameTaskQueueController::WriteIntoTracedValue(
+ perfetto::TracedValue context) const {
+ auto dict = std::move(context).WriteDictionary();
+ dict.Add("task_queues", task_queues_.Values());
+ dict.Add("resource_loading_task_queues", resource_loading_task_queues_);
}
// static
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/frame_task_queue_controller.h b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/frame_task_queue_controller.h
index 956a65b5967..163434b51b7 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/frame_task_queue_controller.h
+++ b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/frame_task_queue_controller.h
@@ -18,6 +18,7 @@
#include "third_party/blink/renderer/platform/wtf/hash_map.h"
#include "third_party/blink/renderer/platform/wtf/hash_set.h"
#include "third_party/blink/renderer/platform/wtf/vector.h"
+#include "third_party/perfetto/include/perfetto/tracing/traced_value_forward.h"
namespace base {
namespace sequence_manager {
@@ -95,7 +96,7 @@ class PLATFORM_EXPORT FrameTaskQueueController {
bool RemoveResourceLoadingTaskQueue(
const scoped_refptr<MainThreadTaskQueue>&);
- void AsValueInto(base::trace_event::TracedValue* state) const;
+ void WriteIntoTracedValue(perfetto::TracedValue context) const;
private:
friend class FrameTaskQueueControllerTest;
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/idle_time_estimator.cc b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/idle_time_estimator.cc
index ad03fa3f884..59211b1c5ad 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/idle_time_estimator.cc
+++ b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/idle_time_estimator.cc
@@ -9,23 +9,16 @@
namespace blink {
namespace scheduler {
-IdleTimeEstimator::IdleTimeEstimator(
- const scoped_refptr<MainThreadTaskQueue>& compositor_task_runner,
- const base::TickClock* time_source,
- int sample_count,
- double estimation_percentile)
- : compositor_task_queue_(compositor_task_runner),
- per_frame_compositor_task_runtime_(sample_count),
+IdleTimeEstimator::IdleTimeEstimator(const base::TickClock* time_source,
+ int sample_count,
+ double estimation_percentile)
+ : per_frame_compositor_task_runtime_(sample_count),
time_source_(time_source),
estimation_percentile_(estimation_percentile),
nesting_level_(0),
- did_commit_(false) {
- compositor_task_queue_->GetTaskQueue()->AddTaskObserver(this);
-}
+ did_commit_(false) {}
-IdleTimeEstimator::~IdleTimeEstimator() {
- compositor_task_queue_->GetTaskQueue()->RemoveTaskObserver(this);
-}
+IdleTimeEstimator::~IdleTimeEstimator() = default;
base::TimeDelta IdleTimeEstimator::GetExpectedIdleDuration(
base::TimeDelta compositor_frame_interval) const {
@@ -73,5 +66,15 @@ void IdleTimeEstimator::DidProcessTask(const base::PendingTask& pending_task) {
}
}
+void IdleTimeEstimator::AddCompositorTaskQueue(
+ scoped_refptr<MainThreadTaskQueue> compositor_task_queue) {
+ compositor_task_queue->GetTaskQueue()->AddTaskObserver(this);
+}
+
+void IdleTimeEstimator::RemoveCompositorTaskQueue(
+ scoped_refptr<MainThreadTaskQueue> compositor_task_queue) {
+ compositor_task_queue->GetTaskQueue()->RemoveTaskObserver(this);
+}
+
} // namespace scheduler
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/idle_time_estimator.h b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/idle_time_estimator.h
index db4b01b4edc..f6a962a4ca9 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/idle_time_estimator.h
+++ b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/idle_time_estimator.h
@@ -19,7 +19,6 @@ namespace scheduler {
class PLATFORM_EXPORT IdleTimeEstimator : public base::TaskObserver {
public:
IdleTimeEstimator(
- const scoped_refptr<MainThreadTaskQueue>& compositor_task_runner,
const base::TickClock* time_source,
int sample_count,
double estimation_percentile);
@@ -40,8 +39,12 @@ class PLATFORM_EXPORT IdleTimeEstimator : public base::TaskObserver {
bool was_blocked_or_low_priority) override;
void DidProcessTask(const base::PendingTask& pending_task) override;
+ void AddCompositorTaskQueue(
+ scoped_refptr<MainThreadTaskQueue> compositor_task_queue);
+ void RemoveCompositorTaskQueue(
+ scoped_refptr<MainThreadTaskQueue> compositor_task_queue);
+
private:
- scoped_refptr<MainThreadTaskQueue> compositor_task_queue_;
cc::RollingTimeDeltaHistory per_frame_compositor_task_runtime_;
const base::TickClock* time_source_; // NOT OWNED
double estimation_percentile_;
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/idle_time_estimator_unittest.cc b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/idle_time_estimator_unittest.cc
index 47d40f37d25..1023113f744 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/idle_time_estimator_unittest.cc
+++ b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/idle_time_estimator_unittest.cc
@@ -19,19 +19,6 @@
namespace blink {
namespace scheduler {
-class IdleTimeEstimatorForTest : public IdleTimeEstimator {
- public:
- IdleTimeEstimatorForTest(
- const scoped_refptr<MainThreadTaskQueue>& compositor_task_runner,
- const base::TickClock* clock,
- int sample_count,
- double estimation_percentile)
- : IdleTimeEstimator(compositor_task_runner,
- clock,
- sample_count,
- estimation_percentile) {}
-};
-
class IdleTimeEstimatorTest : public testing::Test {
public:
IdleTimeEstimatorTest()
@@ -46,24 +33,30 @@ class IdleTimeEstimatorTest : public testing::Test {
manager_ = base::sequence_manager::SequenceManagerForTest::Create(
nullptr, task_environment_.GetMainThreadTaskRunner(),
task_environment_.GetMockTickClock());
- compositor_task_queue_ =
- manager_->CreateTaskQueueWithType<MainThreadTaskQueue>(
- base::sequence_manager::TaskQueue::Spec("test_tq"),
- MainThreadTaskQueue::QueueCreationParams(
- MainThreadTaskQueue::QueueType::kCompositor),
- nullptr);
- estimator_.reset(new IdleTimeEstimatorForTest(
- compositor_task_queue_, task_environment_.GetMockTickClock(), 10, 50));
+ estimator_ = std::make_unique<IdleTimeEstimator>(
+ task_environment_.GetMockTickClock(), 10, 50);
+ compositor_task_queue_1_ = NewTaskQueue();
+ compositor_task_queue_2_ = NewTaskQueue();
+ compositor_task_runner_1_ = compositor_task_queue_1_->CreateTaskRunner(
+ TaskType::kMainThreadTaskQueueCompositor);
+ compositor_task_runner_2_ = compositor_task_queue_2_->CreateTaskRunner(
+ TaskType::kMainThreadTaskQueueCompositor);
+ estimator_->AddCompositorTaskQueue(compositor_task_queue_1_);
+ estimator_->AddCompositorTaskQueue(compositor_task_queue_2_);
+ }
+
+ scoped_refptr<MainThreadTaskQueue> NewTaskQueue() {
+ return manager_->CreateTaskQueueWithType<MainThreadTaskQueue>(
+ base::sequence_manager::TaskQueue::Spec("test_tq"),
+ MainThreadTaskQueue::QueueCreationParams(
+ MainThreadTaskQueue::QueueType::kCompositor),
+ nullptr);
}
void SimulateFrameWithOneCompositorTask(int compositor_time) {
base::TimeDelta non_idle_time =
base::TimeDelta::FromMilliseconds(compositor_time);
- base::PendingTask task(FROM_HERE, base::OnceClosure());
- estimator_->WillProcessTask(task, /*was_blocked_or_low_priority=*/false);
- task_environment_.FastForwardBy(non_idle_time);
- estimator_->DidCommitFrameToCompositor();
- estimator_->DidProcessTask(task);
+ PostTask(compositor_task_runner_1_, compositor_time, /*commit=*/true);
if (non_idle_time < frame_length_)
task_environment_.FastForwardBy(frame_length_ - non_idle_time);
}
@@ -74,24 +67,37 @@ class IdleTimeEstimatorTest : public testing::Test {
base::TimeDelta::FromMilliseconds(compositor_time1);
base::TimeDelta non_idle_time2 =
base::TimeDelta::FromMilliseconds(compositor_time2);
- base::PendingTask task(FROM_HERE, base::OnceClosure());
- estimator_->WillProcessTask(task, /*was_blocked_or_low_priority=*/false);
- task_environment_.FastForwardBy(non_idle_time1);
- estimator_->DidProcessTask(task);
-
- estimator_->WillProcessTask(task, /*was_blocked_or_low_priority=*/false);
- task_environment_.FastForwardBy(non_idle_time2);
- estimator_->DidCommitFrameToCompositor();
- estimator_->DidProcessTask(task);
-
+ PostTask(compositor_task_runner_1_, compositor_time1, /*commit=*/false);
+ PostTask(compositor_task_runner_2_, compositor_time2, /*commit=*/true);
base::TimeDelta idle_time = frame_length_ - non_idle_time1 - non_idle_time2;
task_environment_.FastForwardBy(idle_time);
}
+ void PostTask(scoped_refptr<base::SingleThreadTaskRunner> task_runner,
+ int compositor_time,
+ bool commit) {
+ task_runner->PostTask(
+ FROM_HERE,
+ base::BindOnce(
+ [](base::test::TaskEnvironment* task_environment,
+ IdleTimeEstimator* estimator, int compositor_time, bool commit) {
+ base::TimeDelta non_idle_time =
+ base::TimeDelta::FromMilliseconds(compositor_time);
+ task_environment->FastForwardBy(non_idle_time);
+ if (commit)
+ estimator->DidCommitFrameToCompositor();
+ },
+ &task_environment_, estimator_.get(), compositor_time, commit));
+ task_environment_.RunUntilIdle();
+ }
+
base::test::TaskEnvironment task_environment_;
std::unique_ptr<base::sequence_manager::SequenceManager> manager_;
- scoped_refptr<MainThreadTaskQueue> compositor_task_queue_;
- std::unique_ptr<IdleTimeEstimatorForTest> estimator_;
+ std::unique_ptr<IdleTimeEstimator> estimator_;
+ scoped_refptr<MainThreadTaskQueue> compositor_task_queue_1_;
+ scoped_refptr<MainThreadTaskQueue> compositor_task_queue_2_;
+ scoped_refptr<base::SingleThreadTaskRunner> compositor_task_runner_1_;
+ scoped_refptr<base::SingleThreadTaskRunner> compositor_task_runner_2_;
const base::TimeDelta frame_length_;
base::sequence_manager::TestTaskTimeObserver test_task_time_observer_;
};
@@ -148,6 +154,16 @@ TEST_F(IdleTimeEstimatorTest, Estimation_MultipleTasks) {
estimator_->GetExpectedIdleDuration(frame_length_));
}
+TEST_F(IdleTimeEstimatorTest, Estimation_MultipleTasks_WithSingleObserver) {
+ // Observe only |compositor_task_queue_2_|
+ estimator_->RemoveCompositorTaskQueue(compositor_task_queue_1_);
+ SimulateFrameWithTwoCompositorTasks(1, 4);
+ SimulateFrameWithTwoCompositorTasks(1, 4);
+
+ EXPECT_EQ(base::TimeDelta::FromMilliseconds(12),
+ estimator_->GetExpectedIdleDuration(frame_length_));
+}
+
TEST_F(IdleTimeEstimatorTest, IgnoresNestedTasks) {
SimulateFrameWithOneCompositorTask(5);
SimulateFrameWithOneCompositorTask(5);
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread.cc b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread.cc
index 39602a63139..be2f8281775 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread.cc
+++ b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread.cc
@@ -12,16 +12,10 @@ namespace blink {
namespace scheduler {
MainThread::MainThread(MainThreadSchedulerImpl* scheduler)
- : task_runner_(scheduler->DefaultTaskRunner()),
- scheduler_(scheduler),
- thread_id_(base::PlatformThread::CurrentId()) {}
+ : task_runner_(scheduler->DefaultTaskRunner()), scheduler_(scheduler) {}
MainThread::~MainThread() = default;
-blink::PlatformThreadId MainThread::ThreadId() const {
- return thread_id_;
-}
-
blink::ThreadScheduler* MainThread::Scheduler() {
return scheduler_;
}
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread.h b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread.h
index 6a382c287f8..a9054728a56 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread.h
+++ b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread.h
@@ -25,7 +25,6 @@ class PLATFORM_EXPORT MainThread : public Thread {
// Thread implementation.
ThreadScheduler* Scheduler() override;
- PlatformThreadId ThreadId() const override;
scoped_refptr<base::SingleThreadTaskRunner> GetTaskRunner() const override;
void AddTaskTimeObserver(base::sequence_manager::TaskTimeObserver*) override;
@@ -35,7 +34,6 @@ class PLATFORM_EXPORT MainThread : public Thread {
private:
scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
MainThreadSchedulerImpl* scheduler_; // Not owned.
- PlatformThreadId thread_id_;
};
} // namespace scheduler
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_helper.cc b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_helper.cc
index a15e2a43d85..0a84c72edce 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_helper.cc
+++ b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_helper.cc
@@ -42,7 +42,7 @@ MainThreadSchedulerHelper::DefaultMainThreadTaskQueue() {
const scoped_refptr<base::SingleThreadTaskRunner>&
MainThreadSchedulerHelper::DefaultTaskRunner() {
- return default_task_queue_->GetTaskRunnerWithDefaultTaskType();
+ return default_task_runner();
}
scoped_refptr<MainThreadTaskQueue>
@@ -59,25 +59,11 @@ scoped_refptr<base::SingleThreadTaskRunner>
MainThreadSchedulerHelper::DeprecatedDefaultTaskRunner() {
// TODO(hajimehoshi): Introduce a different task queue from the default task
// queue and return the task runner created from it.
- return DefaultTaskRunner();
+ return default_task_runner();
}
scoped_refptr<MainThreadTaskQueue> MainThreadSchedulerHelper::NewTaskQueue(
const MainThreadTaskQueue::QueueCreationParams& params) {
-#if DCHECK_IS_ON()
- // This check is to ensure that we only create one queue with kCompositor
- // prioritisation type, ie one compositor task queue, since elsewhere we
- // assume there is only one when making priority decisions.
- if (params.queue_traits.prioritisation_type ==
- MainThreadTaskQueue::QueueTraits::PrioritisationType::kCompositor) {
- DCHECK(
- !created_compositor_task_queue_ ||
- params.queue_traits.prioritisation_type !=
- MainThreadTaskQueue::QueueTraits::PrioritisationType::kCompositor);
- created_compositor_task_queue_ = true;
- }
-#endif // DCHECK_IS_ON()
-
scoped_refptr<MainThreadTaskQueue> task_queue =
sequence_manager_->CreateTaskQueueWithType<MainThreadTaskQueue>(
params.spec, params, main_thread_scheduler_);
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_helper.h b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_helper.h
index dca77b6a301..9d1c2990a54 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_helper.h
+++ b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_helper.h
@@ -46,10 +46,6 @@ class PLATFORM_EXPORT MainThreadSchedulerHelper : public SchedulerHelper {
const scoped_refptr<MainThreadTaskQueue> default_task_queue_;
const scoped_refptr<MainThreadTaskQueue> control_task_queue_;
-#if DCHECK_IS_ON()
- bool created_compositor_task_queue_ = false;
-#endif // DCHECK_IS_ON()
-
DISALLOW_COPY_AND_ASSIGN(MainThreadSchedulerHelper);
};
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 7089d80e317..cf1ea90760b 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
@@ -25,6 +25,9 @@
#include "base/trace_event/trace_event.h"
#include "base/trace_event/traced_value.h"
#include "build/build_config.h"
+#include "components/power_scheduler/power_mode.h"
+#include "components/power_scheduler/power_mode_arbiter.h"
+#include "components/power_scheduler/power_mode_voter.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"
@@ -33,7 +36,6 @@
#include "third_party/blink/public/common/page/launching_process_state.h"
#include "third_party/blink/public/platform/scheduler/web_agent_group_scheduler.h"
#include "third_party/blink/public/platform/scheduler/web_renderer_process_type.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"
#include "third_party/blink/renderer/platform/scheduler/common/features.h"
@@ -236,8 +238,6 @@ MainThreadSchedulerImpl::MainThreadSchedulerImpl(
MainThreadTaskQueue::QueueCreationParams(
MainThreadTaskQueue::QueueType::kIPCTrackingForCachedPages)
.SetShouldNotifyObservers(false))),
- compositor_task_queue_enabled_voter_(
- compositor_task_queue_->GetTaskQueue()->CreateQueueEnabledVoter()),
memory_purge_task_queue_(helper_.NewTaskQueue(
MainThreadTaskQueue::QueueCreationParams(
MainThreadTaskQueue::QueueType::kIdle)
@@ -252,18 +252,21 @@ MainThreadSchedulerImpl::MainThreadSchedulerImpl(
helper_.ControlMainThreadTaskQueue()->CreateTaskRunner(
TaskType::kMainThreadTaskQueueControl)),
main_thread_only_(this,
- compositor_task_queue_,
helper_.GetClock(),
helper_.NowTicks()),
any_thread_(this),
policy_may_need_update_(&any_thread_lock_),
notify_agent_strategy_task_posted_(&any_thread_lock_) {
+ helper_.AttachToCurrentThread();
+
// Compositor task queue and default task queue should be managed by
// WebThreadScheduler. Control task queue should not.
task_runners_.emplace(helper_.DefaultMainThreadTaskQueue(), nullptr);
task_runners_.emplace(
compositor_task_queue_,
compositor_task_queue_->GetTaskQueue()->CreateQueueEnabledVoter());
+ main_thread_only().idle_time_estimator.AddCompositorTaskQueue(
+ compositor_task_queue_);
back_forward_cache_ipc_tracking_task_runner_ =
back_forward_cache_ipc_tracking_task_queue_->CreateTaskRunner(
@@ -347,7 +350,7 @@ MainThreadSchedulerImpl::~MainThreadSchedulerImpl() {
TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), "MainThreadScheduler",
this);
- for (auto& pair : task_runners_) {
+ for (const auto& pair : task_runners_) {
pair.first->ShutdownTaskQueue();
}
@@ -377,11 +380,9 @@ WebThreadScheduler* WebThreadScheduler::MainThreadScheduler() {
MainThreadSchedulerImpl::MainThreadOnly::MainThreadOnly(
MainThreadSchedulerImpl* main_thread_scheduler_impl,
- const scoped_refptr<MainThreadTaskQueue>& compositor_task_runner,
const base::TickClock* time_source,
base::TimeTicks now)
- : idle_time_estimator(compositor_task_runner,
- time_source,
+ : idle_time_estimator(time_source,
kShortIdlePeriodDurationSampleCount,
kShortIdlePeriodDurationPercentile),
current_use_case(UseCase::kNone,
@@ -494,7 +495,10 @@ MainThreadSchedulerImpl::MainThreadOnly::MainThreadOnly(
compositor_priority(TaskQueue::QueuePriority::kNormalPriority,
"Scheduler.CompositorPriority",
&main_thread_scheduler_impl->tracing_controller_,
- TaskQueue::PriorityToString) {}
+ TaskQueue::PriorityToString),
+ audible_power_mode_voter(
+ power_scheduler::PowerModeArbiter::GetInstance()->NewVoter(
+ "PowerModeVoter.Audible")) {}
MainThreadSchedulerImpl::MainThreadOnly::~MainThreadOnly() = default;
@@ -605,6 +609,13 @@ MainThreadSchedulerImpl::SchedulingSettings::SchedulingSettings() {
}
}
}
+
+ mbi_override_task_runner_handle =
+ base::FeatureList::IsEnabled(kMbiOverrideTaskRunnerHandle);
+
+ mbi_compositor_task_runner_per_agent_scheduling_group =
+ base::FeatureList::IsEnabled(
+ kMbiCompositorTaskRunnerPerAgentSchedulingGroup);
}
MainThreadSchedulerImpl::AnyThread::~AnyThread() = default;
@@ -742,6 +753,13 @@ scoped_refptr<MainThreadTaskQueue> MainThreadSchedulerImpl::NewTaskQueue(
voter = task_queue->GetTaskQueue()->CreateQueueEnabledVoter();
}
+ if (task_queue->GetPrioritisationType() ==
+ MainThreadTaskQueue::QueueTraits::PrioritisationType::kCompositor) {
+ DCHECK(!voter);
+ voter = task_queue->GetTaskQueue()->CreateQueueEnabledVoter();
+ main_thread_only().idle_time_estimator.AddCompositorTaskQueue(task_queue);
+ }
+
auto insert_result = task_runners_.emplace(task_queue, std::move(voter));
UpdateTaskQueueState(task_queue.get(), insert_result.first->second.get(),
@@ -888,9 +906,6 @@ void MainThreadSchedulerImpl::OnShutdownTaskQueue(
if (was_shutdown_)
return;
- if (task_queue_throttler_)
- task_queue_throttler_->ShutdownTaskQueue(task_queue->GetTaskQueue());
-
task_queue.get()->DetachOnIPCTaskPostedWhileInBackForwardCache();
task_runners_.erase(task_queue.get());
}
@@ -1083,7 +1098,6 @@ void MainThreadSchedulerImpl::SetRendererBackgrounded(bool backgrounded) {
main_thread_only().metrics_helper.OnRendererForegrounded(now);
}
- ParkableStringManager::Instance().SetRendererBackgrounded(backgrounded);
memory_purge_manager_.SetRendererBackgrounded(backgrounded);
}
@@ -1125,6 +1139,10 @@ void MainThreadSchedulerImpl::OnAudioStateChanged() {
return;
main_thread_only().is_audio_playing = is_audio_playing;
+
+ main_thread_only().audible_power_mode_voter->VoteFor(
+ is_audio_playing ? power_scheduler::PowerMode::kAudible
+ : power_scheduler::PowerMode::kIdle);
}
std::unique_ptr<ThreadScheduler::RendererPauseHandle>
@@ -1454,9 +1472,14 @@ bool MainThreadSchedulerImpl::ShouldYieldForHighPriorityWork() {
case UseCase::kMainThreadGesture:
case UseCase::kMainThreadCustomInputHandling:
case UseCase::kSynchronizedGesture:
- return compositor_task_queue_->GetTaskQueue()
- ->HasTaskToRunImmediately() ||
- main_thread_only().blocking_input_expected_soon;
+ for (const auto& pair : task_runners_) {
+ if (pair.first->GetPrioritisationType() ==
+ MainThreadTaskQueue::QueueTraits::PrioritisationType::
+ kCompositor &&
+ pair.first->GetTaskQueue()->HasTaskToRunImmediately())
+ return true;
+ }
+ return main_thread_only().blocking_input_expected_soon;
case UseCase::kTouchstart:
return true;
@@ -1706,8 +1729,6 @@ void MainThreadSchedulerImpl::UpdateStateForAllTaskQueues(
UpdateTaskQueueState(pair.first.get(), pair.second.get(), old_policy,
current_policy, should_update_priorities);
}
- compositor_task_queue_enabled_voter_->SetVoteToEnable(
- !current_policy.should_freeze_compositor_task_queue());
}
void MainThreadSchedulerImpl::UpdateTaskQueueState(
@@ -1741,6 +1762,12 @@ void MainThreadSchedulerImpl::UpdateTaskQueueState(
task_queue->GetTaskQueue()->SetTimeDomain(real_time_domain());
}
}
+
+ if (task_queue->GetPrioritisationType() ==
+ MainThreadTaskQueue::QueueTraits::PrioritisationType::kCompositor) {
+ task_queue_enabled_voter->SetVoteToEnable(
+ !new_policy.should_freeze_compositor_task_queue());
+ }
}
UseCase MainThreadSchedulerImpl::ComputeCurrentUseCase(
@@ -1947,7 +1974,7 @@ void MainThreadSchedulerImpl::VirtualTimePaused() {
for (const auto& pair : task_runners_) {
if (pair.first->CanRunWhenVirtualTimePaused())
continue;
- DCHECK(!task_queue_throttler_->IsThrottled(pair.first->GetTaskQueue()));
+ DCHECK(!pair.first->IsThrottled());
pair.first->GetTaskQueue()->InsertFence(
TaskQueue::InsertFencePosition::kNow);
}
@@ -1957,7 +1984,7 @@ void MainThreadSchedulerImpl::VirtualTimeResumed() {
for (const auto& pair : task_runners_) {
if (pair.first->CanRunWhenVirtualTimePaused())
continue;
- DCHECK(!task_queue_throttler_->IsThrottled(pair.first->GetTaskQueue()));
+ DCHECK(!pair.first->IsThrottled());
DCHECK(pair.first->GetTaskQueue()->HasActiveFence());
pair.first->GetTaskQueue()->RemoveFence();
}
@@ -2046,138 +2073,104 @@ void MainThreadSchedulerImpl::SetMaxVirtualTimeTaskStarvationCount(
ApplyVirtualTimePolicy();
}
-std::unique_ptr<base::trace_event::ConvertableToTraceFormat>
-MainThreadSchedulerImpl::AsValue(base::TimeTicks optional_now) const {
- base::AutoLock lock(any_thread_lock_);
- return AsValueLocked(optional_now);
-}
-
void MainThreadSchedulerImpl::CreateTraceEventObjectSnapshot() const {
TRACE_EVENT_OBJECT_SNAPSHOT_WITH_ID(
TRACE_DISABLED_BY_DEFAULT("renderer.scheduler.debug"),
- "MainThreadScheduler", this, AsValue(helper_.NowTicks()));
+ "MainThreadScheduler", this, [&](perfetto::TracedValue context) {
+ base::AutoLock lock(any_thread_lock_);
+ WriteIntoTracedValueLocked(std::move(context), helper_.NowTicks());
+ });
}
void MainThreadSchedulerImpl::CreateTraceEventObjectSnapshotLocked() const {
TRACE_EVENT_OBJECT_SNAPSHOT_WITH_ID(
TRACE_DISABLED_BY_DEFAULT("renderer.scheduler.debug"),
- "MainThreadScheduler", this, AsValueLocked(helper_.NowTicks()));
-}
-
-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);
+ "MainThreadScheduler", this, [&](perfetto::TracedValue context) {
+ WriteIntoTracedValueLocked(std::move(context), helper_.NowTicks());
+ });
}
-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,
+void MainThreadSchedulerImpl::WriteIntoTracedValueLocked(
+ perfetto::TracedValue context,
base::TimeTicks optional_now) const {
helper_.CheckOnValidThread();
any_thread_lock_.AssertAcquired();
+ auto dict = std::move(context).WriteDictionary();
+
if (optional_now.is_null())
optional_now = helper_.NowTicks();
- state->SetBoolean(
- "has_visible_render_widget_with_touch_handler",
- main_thread_only().has_visible_render_widget_with_touch_handler);
- state->SetString("current_use_case",
- UseCaseToString(main_thread_only().current_use_case));
- state->SetBoolean(
- "compositor_will_send_main_frame_not_expected",
- main_thread_only().compositor_will_send_main_frame_not_expected);
- state->SetBoolean("blocking_input_expected_soon",
- main_thread_only().blocking_input_expected_soon);
- state->SetString("idle_period_state",
- IdleHelper::IdlePeriodStateToString(
- idle_helper_.SchedulerIdlePeriodState()));
- state->SetBoolean("renderer_hidden", main_thread_only().renderer_hidden);
- state->SetBoolean("waiting_for_any_main_frame_contentful_paint",
- any_thread().waiting_for_any_main_frame_contentful_paint);
- state->SetBoolean("waiting_for_any_main_frame_meaningful_paint",
- any_thread().waiting_for_any_main_frame_meaningful_paint);
- state->SetBoolean("have_seen_input_since_navigation",
- any_thread().have_seen_input_since_navigation);
- state->SetBoolean(
+ dict.Add("has_visible_render_widget_with_touch_handler",
+ main_thread_only().has_visible_render_widget_with_touch_handler);
+ dict.Add("current_use_case",
+ UseCaseToString(main_thread_only().current_use_case));
+ dict.Add("compositor_will_send_main_frame_not_expected",
+ main_thread_only().compositor_will_send_main_frame_not_expected);
+ dict.Add("blocking_input_expected_soon",
+ main_thread_only().blocking_input_expected_soon);
+ dict.Add("idle_period_state", IdleHelper::IdlePeriodStateToString(
+ idle_helper_.SchedulerIdlePeriodState()));
+ dict.Add("renderer_hidden", main_thread_only().renderer_hidden);
+ dict.Add("waiting_for_any_main_frame_contentful_paint",
+ any_thread().waiting_for_any_main_frame_contentful_paint);
+ dict.Add("waiting_for_any_main_frame_meaningful_paint",
+ any_thread().waiting_for_any_main_frame_meaningful_paint);
+ dict.Add("have_seen_input_since_navigation",
+ any_thread().have_seen_input_since_navigation);
+ dict.Add(
"have_reported_blocking_intervention_in_current_policy",
main_thread_only().have_reported_blocking_intervention_in_current_policy);
- state->SetBoolean(
+ dict.Add(
"have_reported_blocking_intervention_since_navigation",
main_thread_only().have_reported_blocking_intervention_since_navigation);
- state->SetBoolean("renderer_backgrounded",
- main_thread_only().renderer_backgrounded);
- state->SetBoolean("keep_active_fetch_or_worker",
- main_thread_only().keep_active_fetch_or_worker);
- state->SetDouble("now", (optional_now - base::TimeTicks()).InMillisecondsF());
- state->SetDouble(
+ dict.Add("renderer_backgrounded", main_thread_only().renderer_backgrounded);
+ dict.Add("keep_active_fetch_or_worker",
+ main_thread_only().keep_active_fetch_or_worker);
+ dict.Add("now", (optional_now - base::TimeTicks()).InMillisecondsF());
+ dict.Add(
"fling_compositor_escalation_deadline",
(any_thread().fling_compositor_escalation_deadline - base::TimeTicks())
.InMillisecondsF());
- state->SetDouble("last_idle_period_end_time",
- (any_thread().last_idle_period_end_time - base::TimeTicks())
- .InMillisecondsF());
- state->SetBoolean("awaiting_touch_start_response",
- any_thread().awaiting_touch_start_response);
- state->SetBoolean("begin_main_frame_on_critical_path",
- any_thread().begin_main_frame_on_critical_path);
- state->SetBoolean("last_gesture_was_compositor_driven",
- any_thread().last_gesture_was_compositor_driven);
- state->SetBoolean("default_gesture_prevented",
- any_thread().default_gesture_prevented);
- state->SetBoolean("is_audio_playing", main_thread_only().is_audio_playing);
- state->SetBoolean("virtual_time_stopped",
- main_thread_only().virtual_time_stopped);
- state->SetDouble("virtual_time_pause_count",
- main_thread_only().virtual_time_pause_count);
- state->SetString(
- "virtual_time_policy",
- VirtualTimePolicyToString(main_thread_only().virtual_time_policy));
- state->SetBoolean("virtual_time", main_thread_only().use_virtual_time);
-
- {
- auto dictionary_scope = state->BeginDictionaryScoped("page_schedulers");
- for (PageSchedulerImpl* page_scheduler :
- main_thread_only().page_schedulers) {
- auto inner_dictionary = state->BeginDictionaryScopedWithCopiedName(
- PointerToString(page_scheduler));
- page_scheduler->AsValueInto(state);
- }
- }
-
- {
- auto dictionary_scope = state->BeginDictionaryScoped("policy");
- main_thread_only().current_policy.AsValueInto(state);
- }
+ dict.Add("last_idle_period_end_time",
+ (any_thread().last_idle_period_end_time - base::TimeTicks())
+ .InMillisecondsF());
+ dict.Add("awaiting_touch_start_response",
+ any_thread().awaiting_touch_start_response);
+ dict.Add("begin_main_frame_on_critical_path",
+ any_thread().begin_main_frame_on_critical_path);
+ dict.Add("last_gesture_was_compositor_driven",
+ any_thread().last_gesture_was_compositor_driven);
+ dict.Add("default_gesture_prevented", any_thread().default_gesture_prevented);
+ dict.Add("is_audio_playing", main_thread_only().is_audio_playing);
+ dict.Add("virtual_time_stopped", main_thread_only().virtual_time_stopped);
+ dict.Add("virtual_time_pause_count",
+ main_thread_only().virtual_time_pause_count);
+ dict.Add("virtual_time_policy",
+ VirtualTimePolicyToString(main_thread_only().virtual_time_policy));
+ dict.Add("virtual_time", main_thread_only().use_virtual_time);
+
+ dict.Add("page_schedulers", main_thread_only().page_schedulers);
+
+ dict.Add("policy", main_thread_only().current_policy);
// TODO(skyostil): Can we somehow trace how accurate these estimates were?
- state->SetDouble(
+ dict.Add(
"longest_jank_free_task_duration",
main_thread_only().longest_jank_free_task_duration->InMillisecondsF());
- state->SetDouble(
- "compositor_frame_interval",
- main_thread_only().compositor_frame_interval.InMillisecondsF());
- state->SetDouble(
- "estimated_next_frame_begin",
- (main_thread_only().estimated_next_frame_begin - base::TimeTicks())
- .InMillisecondsF());
- state->SetBoolean("in_idle_period", any_thread().in_idle_period);
+ dict.Add("compositor_frame_interval",
+ main_thread_only().compositor_frame_interval.InMillisecondsF());
+ dict.Add("estimated_next_frame_begin",
+ (main_thread_only().estimated_next_frame_begin - base::TimeTicks())
+ .InMillisecondsF());
+ dict.Add("in_idle_period", any_thread().in_idle_period);
- any_thread().user_model.AsValueInto(state);
- render_widget_scheduler_signals_.AsValueInto(state);
+ dict.Add("user_model", any_thread().user_model);
+ dict.Add("render_widget_scheduler_signals", render_widget_scheduler_signals_);
- {
- auto dictionary_scope =
- state->BeginDictionaryScoped("task_queue_throttler");
- task_queue_throttler_->AsValueInto(state, optional_now);
- }
+ dict.Add("task_queue_throttler", [&](perfetto::TracedValue context) {
+ task_queue_throttler_->WriteIntoTracedValue(std::move(context),
+ optional_now);
+ });
}
bool MainThreadSchedulerImpl::Policy::IsQueueEnabled(
@@ -2199,17 +2192,18 @@ MainThreadSchedulerImpl::Policy::GetTimeDomainType() const {
return TimeDomainType::kReal;
}
-void MainThreadSchedulerImpl::Policy::AsValueInto(
- base::trace_event::TracedValue* state) const {
- state->SetString("rail_mode", RAILModeToString(rail_mode()));
- state->SetString("use_case", UseCaseToString(use_case()));
+void MainThreadSchedulerImpl::Policy::WriteIntoTracedValue(
+ perfetto::TracedValue context) const {
+ auto dict = std::move(context).WriteDictionary();
+ dict.Add("rail_mode", RAILModeToString(rail_mode()));
+ dict.Add("use_case", UseCaseToString(use_case()));
- state->SetBoolean("should_disable_throttling", should_disable_throttling());
- state->SetBoolean("should_defer_task_queues", should_defer_task_queues());
- state->SetBoolean("should_pause_task_queues", should_pause_task_queues());
- state->SetBoolean("should_pause_task_queues_for_android_webview",
- should_pause_task_queues_for_android_webview());
- state->SetBoolean("use_virtual_time", use_virtual_time());
+ dict.Add("should_disable_throttling", should_disable_throttling());
+ dict.Add("should_defer_task_queues", should_defer_task_queues());
+ dict.Add("should_pause_task_queues", should_pause_task_queues());
+ dict.Add("should_pause_task_queues_for_android_webview",
+ should_pause_task_queues_for_android_webview());
+ dict.Add("use_virtual_time", use_virtual_time());
}
void MainThreadSchedulerImpl::OnIdlePeriodStarted() {
@@ -2440,6 +2434,14 @@ MainThreadSchedulerImpl::V8TaskRunner() {
scoped_refptr<base::SingleThreadTaskRunner>
MainThreadSchedulerImpl::CompositorTaskRunner() {
+ if (scheduling_settings()
+ .mbi_compositor_task_runner_per_agent_scheduling_group) {
+ NOTREACHED() << "When MbiPerAGSCompositorTaskRunner is enabled, "
+ "MainThreadSchedulerImpl::CompositorTaskRunner() shouldn't "
+ "be used. We are planning to remove "
+ "MainThreadSchedulerImpl::CompositorTaskRunner() in the "
+ "near future.";
+ }
return compositor_task_runner_;
}
@@ -2467,30 +2469,92 @@ MainThreadSchedulerImpl::GetCurrentAgentGroupScheduler() {
return current_agent_group_scheduler_;
}
-void MainThreadSchedulerImpl::SetCurrentAgentGroupScheduler(
- WebAgentGroupScheduler* agent_group_scheduler) {
- helper_.CheckOnValidThread();
- if (current_agent_group_scheduler_) {
- TRACE_EVENT_NESTABLE_ASYNC_END1(
- TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"),
- "scheduler.agent_scope", current_agent_group_scheduler_,
- "agent_group_scheduler", current_agent_group_scheduler_);
- } else {
- TRACE_EVENT_NESTABLE_ASYNC_END0(
- TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"),
- "scheduler.thread_scope", this);
- }
- current_agent_group_scheduler_ = agent_group_scheduler;
- if (current_agent_group_scheduler_) {
- TRACE_EVENT_NESTABLE_ASYNC_BEGIN1(
- TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"),
- "scheduler.agent_scope", current_agent_group_scheduler_,
- "agent_group_scheduler", current_agent_group_scheduler_);
+void MainThreadSchedulerImpl::BeginAgentGroupSchedulerScope(
+ WebAgentGroupScheduler* next_agent_group_scheduler) {
+ scoped_refptr<base::SingleThreadTaskRunner> next_task_runner;
+ const char* trace_event_scope_name;
+ void* trace_event_scope_id;
+
+ if (next_agent_group_scheduler) {
+ // If the |next_agent_group_scheduler| is not null, it means that a
+ // per-AgentSchedulingGroup task is about to start. In this case, a
+ // per-AgentGroupScheduler scope starts.
+ next_task_runner = next_agent_group_scheduler->DefaultTaskRunner(),
+ trace_event_scope_name = "scheduler.agent_scope";
+ trace_event_scope_id = next_agent_group_scheduler;
} else {
- TRACE_EVENT_NESTABLE_ASYNC_BEGIN0(
- TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"),
- "scheduler.thread_scope", this);
- }
+ // If the |next_agent_group_scheduler| is null, it means that a
+ // per-thread task is about to start. In this case, a per-thread scope
+ // starts.
+ next_task_runner = helper_.DefaultTaskRunner();
+ trace_event_scope_name = "scheduler.thread_scope";
+ trace_event_scope_id = this;
+ }
+
+ TRACE_EVENT_NESTABLE_ASYNC_BEGIN1(
+ TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), trace_event_scope_name,
+ trace_event_scope_id, "agent_group_scheduler",
+ static_cast<void*>(next_agent_group_scheduler));
+
+ WebAgentGroupScheduler* previous_agent_group_scheduler =
+ current_agent_group_scheduler_;
+ current_agent_group_scheduler_ = next_agent_group_scheduler;
+
+ scoped_refptr<base::SingleThreadTaskRunner> previous_task_runner =
+ base::ThreadTaskRunnerHandle::Get();
+ std::unique_ptr<base::ThreadTaskRunnerHandleOverride>
+ thread_task_runner_handle_override;
+ if (scheduling_settings().mbi_override_task_runner_handle &&
+ next_task_runner != previous_task_runner) {
+ // per-thread and per-AgentSchedulingGroup task runner allows nested
+ // runloop. |MainThreadSchedulerImpl| guarantees that
+ // |ThreadTaskRunnerHandle::Get()| and |SequencedTaskRunnerHandle::Get()|
+ // return a proper task runner even when a nested runloop is used. Because
+ // |MainThreadSchedulerImpl::OnTaskStarted()| always overrides
+ // TTRH/STRH::Get() properly. So there is no concern about returning an
+ // unexpected task runner from TTRH/STRH::Get() in this specific case.
+ thread_task_runner_handle_override =
+ std::unique_ptr<base::ThreadTaskRunnerHandleOverride>(
+ new base::ThreadTaskRunnerHandleOverride(
+ next_task_runner,
+ /*allow_nested_runloop=*/true));
+ }
+
+ main_thread_only().agent_group_scheduler_scope_stack.emplace_back(
+ AgentGroupSchedulerScope{
+ std::move(thread_task_runner_handle_override),
+ previous_agent_group_scheduler, next_agent_group_scheduler,
+ std::move(previous_task_runner), std::move(next_task_runner),
+ trace_event_scope_name, trace_event_scope_id});
+}
+
+void MainThreadSchedulerImpl::EndAgentGroupSchedulerScope() {
+ AgentGroupSchedulerScope& agent_group_scheduler_scope =
+ main_thread_only().agent_group_scheduler_scope_stack.back();
+
+ if (scheduling_settings().mbi_override_task_runner_handle) {
+ DCHECK_EQ(base::ThreadTaskRunnerHandle::Get(),
+ agent_group_scheduler_scope.current_task_runner);
+ DCHECK_EQ(base::SequencedTaskRunnerHandle::Get(),
+ agent_group_scheduler_scope.current_task_runner);
+ }
+ agent_group_scheduler_scope.thread_task_runner_handle_override = nullptr;
+ DCHECK_EQ(base::ThreadTaskRunnerHandle::Get(),
+ agent_group_scheduler_scope.previous_task_runner);
+ DCHECK_EQ(base::SequencedTaskRunnerHandle::Get(),
+ agent_group_scheduler_scope.previous_task_runner);
+
+ current_agent_group_scheduler_ =
+ agent_group_scheduler_scope.previous_agent_group_scheduler;
+
+ TRACE_EVENT_NESTABLE_ASYNC_END1(
+ TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"),
+ agent_group_scheduler_scope.trace_event_scope_name,
+ agent_group_scheduler_scope.trace_event_scope_id, "agent_group_scheduler",
+ static_cast<void*>(
+ agent_group_scheduler_scope.current_agent_group_scheduler));
+
+ main_thread_only().agent_group_scheduler_scope_stack.pop_back();
}
std::unique_ptr<ThreadScheduler::RendererPauseHandle>
@@ -2561,6 +2625,11 @@ void MainThreadSchedulerImpl::RemovePageScheduler(
SetOnIPCTaskPostedWhileInBackForwardCacheIfNeeded();
}
+ if (main_thread_only().is_audio_playing && page_scheduler->IsAudioPlaying()) {
+ // This page may have been the only one playing audio.
+ OnAudioStateChanged();
+ }
+
base::AutoLock lock(any_thread_lock_);
any_thread().waiting_for_any_main_frame_contentful_paint =
IsAnyMainFrameWaitingForFirstContentfulPaint();
@@ -2605,8 +2674,10 @@ void MainThreadSchedulerImpl::OnTaskStarted(
MainThreadTaskQueue* queue,
const base::sequence_manager::Task& task,
const TaskQueue::TaskTiming& task_timing) {
- SetCurrentAgentGroupScheduler(queue ? queue->GetAgentGroupScheduler()
- : nullptr);
+ if (scheduling_settings().mbi_override_task_runner_handle) {
+ BeginAgentGroupSchedulerScope(queue ? queue->GetAgentGroupScheduler()
+ : nullptr);
+ }
main_thread_only().running_queues.push(queue);
if (main_thread_only().nested_runloop)
@@ -2642,16 +2713,18 @@ void MainThreadSchedulerImpl::OnTaskCompleted(
if (task_timing->has_wall_time() && queue && queue->GetFrameScheduler())
queue->GetFrameScheduler()->AddTaskTime(task_timing->wall_duration());
main_thread_only().running_queues.pop();
+
+ // The overriding TaskRunnerHandle scope ends here.
+ if (scheduling_settings().mbi_override_task_runner_handle)
+ EndAgentGroupSchedulerScope();
+
if (main_thread_only().nested_runloop)
return;
DispatchOnTaskCompletionCallbacks();
- if (queue) {
- task_queue_throttler()->OnTaskRunTimeReported(queue->GetTaskQueue(),
- task_timing->start_time(),
- task_timing->end_time());
- }
+ if (queue)
+ queue->OnTaskRunTimeReported(task_timing);
// TODO(altimin): Per-page metrics should also be considered.
main_thread_only().metrics_helper.RecordTaskMetrics(queue.get(), task,
@@ -2668,10 +2741,6 @@ void MainThreadSchedulerImpl::OnTaskCompleted(
find_in_page_budget_pool_controller_->OnTaskCompleted(queue.get(),
task_timing);
-
- // GetCurrentAgentGroupScheduler() should return nullptr when
- // it's running thread global task runners.
- SetCurrentAgentGroupScheduler(nullptr);
}
void MainThreadSchedulerImpl::RecordTaskUkm(
@@ -2900,8 +2969,13 @@ TaskQueue::QueuePriority MainThreadSchedulerImpl::ComputeCompositorPriority()
void MainThreadSchedulerImpl::UpdateCompositorTaskQueuePriority() {
main_thread_only().compositor_priority = ComputeCompositorPriority();
- CompositorTaskQueue()->GetTaskQueue()->SetQueuePriority(
- ComputePriority(CompositorTaskQueue().get()));
+ for (const auto& pair : task_runners_) {
+ if (pair.first->GetPrioritisationType() !=
+ MainThreadTaskQueue::QueueTraits::PrioritisationType::kCompositor)
+ continue;
+ pair.first->GetTaskQueue()->SetQueuePriority(
+ ComputePriority(pair.first.get()));
+ }
}
base::Optional<TaskQueue::QueuePriority>
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 2ef822df859..89ea3cb1ef9 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
@@ -23,6 +23,7 @@
#include "base/task/sequence_manager/task_time_observer.h"
#include "base/trace_event/trace_log.h"
#include "build/build_config.h"
+#include "components/power_scheduler/power_mode_voter.h"
#include "third_party/blink/public/platform/scheduler/web_thread_scheduler.h"
#include "third_party/blink/renderer/platform/platform_export.h"
#include "third_party/blink/renderer/platform/scheduler/common/idle_helper.h"
@@ -50,14 +51,10 @@
#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
#include "third_party/blink/renderer/platform/wtf/hash_set.h"
#include "third_party/blink/renderer/platform/wtf/vector.h"
+#include "third_party/perfetto/include/perfetto/tracing/traced_value_forward.h"
namespace base {
-
class TaskObserver;
-
-namespace trace_event {
-class ConvertableToTraceFormat;
-}
} // namespace base
namespace blink {
@@ -143,6 +140,15 @@ class PLATFORM_EXPORT MainThreadSchedulerImpl
std::array<base::sequence_manager::TaskQueue::QueuePriority,
net::RequestPrioritySize::NUM_PRIORITIES>
net_to_blink_priority;
+
+ // If enabled, base::ThreadTaskRunnerHandle::Get() and
+ // base::SequencedTaskRunnerHandle::Get() returns the current active
+ // per-ASG task runner instead of the per-thread task runner.
+ bool mbi_override_task_runner_handle;
+
+ // If enabled, per-AgentGroupScheduler CompositorTaskRunner will be used
+ // instead of per-MainThreadScheduler CompositorTaskRunner.
+ bool mbi_compositor_task_runner_per_agent_scheduling_group;
};
static const char* UseCaseToString(UseCase use_case);
@@ -223,8 +229,6 @@ class PLATFORM_EXPORT MainThreadSchedulerImpl
scoped_refptr<base::SingleThreadTaskRunner> CompositorTaskRunner() override;
std::unique_ptr<WebAgentGroupScheduler> CreateAgentGroupScheduler() override;
WebAgentGroupScheduler* GetCurrentAgentGroupScheduler() override;
- void SetCurrentAgentGroupScheduler(
- WebAgentGroupScheduler* agent_group_scheduler);
std::unique_ptr<ThreadScheduler::RendererPauseHandle> PauseScheduler()
override;
base::TimeTicks MonotonicallyIncreasingVirtualTime() override;
@@ -494,6 +498,21 @@ class PLATFORM_EXPORT MainThreadSchedulerImpl
void AddAgentGroupScheduler(AgentGroupSchedulerImpl*);
+ struct AgentGroupSchedulerScope {
+ std::unique_ptr<base::ThreadTaskRunnerHandleOverride>
+ thread_task_runner_handle_override;
+ WebAgentGroupScheduler* previous_agent_group_scheduler;
+ WebAgentGroupScheduler* current_agent_group_scheduler;
+ scoped_refptr<base::SingleThreadTaskRunner> previous_task_runner;
+ scoped_refptr<base::SingleThreadTaskRunner> current_task_runner;
+ const char* trace_event_scope_name;
+ void* trace_event_scope_id;
+ };
+
+ void BeginAgentGroupSchedulerScope(
+ WebAgentGroupScheduler* next_agent_group_scheduler);
+ void EndAgentGroupSchedulerScope();
+
bool IsAnyMainFrameWaitingForFirstContentfulPaint() const;
bool IsAnyMainFrameWaitingForFirstMeaningfulPaint() const;
@@ -573,12 +592,12 @@ class PLATFORM_EXPORT MainThreadSchedulerImpl
use_case_ == other.use_case_;
}
- void AsValueInto(base::trace_event::TracedValue* state) const;
-
bool IsQueueEnabled(MainThreadTaskQueue* task_queue) const;
TimeDomainType GetTimeDomainType() const;
+ void WriteIntoTracedValue(perfetto::TracedValue context) const;
+
private:
RAILMode rail_mode_{RAILMode::kAnimation};
bool should_disable_throttling_{false};
@@ -632,14 +651,10 @@ class PLATFORM_EXPORT MainThreadSchedulerImpl
MainThreadTaskQueue* queue);
// Returns the serialized scheduler state for tracing.
- std::unique_ptr<base::trace_event::ConvertableToTraceFormat> AsValue(
- base::TimeTicks optional_now) const;
- std::unique_ptr<base::trace_event::ConvertableToTraceFormat> AsValueLocked(
- base::TimeTicks optional_now) const;
+ void WriteIntoTracedValueLocked(perfetto::TracedValue context,
+ 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
@@ -780,9 +795,6 @@ class PLATFORM_EXPORT MainThreadSchedulerImpl
// task.
void DispatchOnTaskCompletionCallbacks();
- void AsValueIntoLocked(base::trace_event::TracedValue*,
- base::TimeTicks optional_now) const;
-
bool AllPagesFrozen() const;
// Indicates that scheduler has been shutdown.
@@ -821,8 +833,6 @@ class PLATFORM_EXPORT MainThreadSchedulerImpl
scoped_refptr<MainThreadTaskQueue> virtual_time_control_task_queue_;
scoped_refptr<MainThreadTaskQueue>
back_forward_cache_ipc_tracking_task_queue_;
- std::unique_ptr<base::sequence_manager::TaskQueue::QueueEnabledVoter>
- compositor_task_queue_enabled_voter_;
using TaskQueueVoterMap = std::map<
scoped_refptr<MainThreadTaskQueue>,
@@ -862,7 +872,6 @@ class PLATFORM_EXPORT MainThreadSchedulerImpl
struct MainThreadOnly {
MainThreadOnly(
MainThreadSchedulerImpl* main_thread_scheduler_impl,
- const scoped_refptr<MainThreadTaskQueue>& compositor_task_runner,
const base::TickClock* time_source,
base::TimeTicks now);
~MainThreadOnly();
@@ -965,6 +974,10 @@ class PLATFORM_EXPORT MainThreadSchedulerImpl
// kNormalPriority and is updated via UpdateCompositorTaskQueuePriority().
TraceableState<TaskQueue::QueuePriority, TracingCategoryName::kDefault>
compositor_priority;
+
+ WTF::Vector<AgentGroupSchedulerScope> agent_group_scheduler_scope_stack;
+
+ std::unique_ptr<power_scheduler::PowerModeVoter> audible_power_mode_voter;
};
struct AnyThread {
@@ -1036,7 +1049,8 @@ class PLATFORM_EXPORT MainThreadSchedulerImpl
return any_thread_;
}
- // Don't access compositor_thread_only_, instead use CompositorThreadOnly().
+ // Don't access compositor_thread_only_, instead use
+ // |GetCompositorThreadOnly()|.
CompositorThreadOnly compositor_thread_only_;
CompositorThreadOnly& GetCompositorThreadOnly() {
compositor_thread_only_.CheckOnValidThread();
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 006a901f95a..56a4eb6f6e9 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
@@ -444,13 +444,23 @@ class MainThreadSchedulerImplTest : public testing::Test {
default_task_runner_ =
scheduler_->DefaultTaskQueue()->GetTaskRunnerWithDefaultTaskType();
- compositor_task_runner_ =
- scheduler_->CompositorTaskQueue()->GetTaskRunnerWithDefaultTaskType();
+ if (!scheduler_->scheduling_settings()
+ .mbi_compositor_task_runner_per_agent_scheduling_group) {
+ compositor_task_runner_ =
+ scheduler_->CompositorTaskQueue()->GetTaskRunnerWithDefaultTaskType();
+ }
idle_task_runner_ = scheduler_->IdleTaskRunner();
v8_task_runner_ =
scheduler_->V8TaskQueue()->GetTaskRunnerWithDefaultTaskType();
- agent_group_scheduler_ = scheduler_->CreateAgentGroupScheduler();
+ agent_group_scheduler_ = std::unique_ptr<AgentGroupSchedulerImpl>(
+ static_cast<AgentGroupSchedulerImpl*>(
+ scheduler_->CreateAgentGroupScheduler().release()));
+ if (scheduler_->scheduling_settings()
+ .mbi_compositor_task_runner_per_agent_scheduling_group) {
+ compositor_task_runner_ = agent_group_scheduler_->CompositorTaskQueue()
+ ->GetTaskRunnerWithDefaultTaskType();
+ }
page_scheduler_ = std::make_unique<NiceMock<MockPageSchedulerImpl>>(
scheduler_.get(),
static_cast<AgentGroupSchedulerImpl&>(*agent_group_scheduler_));
@@ -474,6 +484,15 @@ class MainThreadSchedulerImplTest : public testing::Test {
blink::TaskType::kInternalHighPriorityLocalFrame);
}
+ MainThreadTaskQueue* compositor_task_queue() {
+ if (scheduler_->scheduling_settings()
+ .mbi_compositor_task_runner_per_agent_scheduling_group) {
+ return agent_group_scheduler_->CompositorTaskQueue().get();
+ } else {
+ return scheduler_->CompositorTaskQueue().get();
+ }
+ }
+
MainThreadTaskQueue* loading_task_queue() {
auto queue_traits = FrameSchedulerImpl::LoadingTaskQueueTraits();
return main_frame_scheduler_->FrameTaskQueueControllerForTest()
@@ -946,7 +965,7 @@ class MainThreadSchedulerImplTest : public testing::Test {
scoped_refptr<base::TestMockTimeTaskRunner> test_task_runner_;
std::unique_ptr<MainThreadSchedulerImplForTest> scheduler_;
- std::unique_ptr<WebAgentGroupScheduler> agent_group_scheduler_;
+ std::unique_ptr<AgentGroupSchedulerImpl> agent_group_scheduler_;
std::unique_ptr<MockPageSchedulerImpl> page_scheduler_;
std::unique_ptr<FrameSchedulerImpl> main_frame_scheduler_;
std::unique_ptr<WebWidgetScheduler> widget_scheduler_;
@@ -2485,8 +2504,8 @@ TEST_F(MainThreadSchedulerImplTest, StopAndThrottleThrottleableQueue) {
auto pause_handle = scheduler_->PauseRenderer();
base::RunLoop().RunUntilIdle();
- scheduler_->task_queue_throttler()->IncreaseThrottleRefCount(
- throttleable_task_queue()->GetTaskQueue());
+ MainThreadTaskQueue::ThrottleHandle handle =
+ throttleable_task_queue()->Throttle();
base::RunLoop().RunUntilIdle();
EXPECT_THAT(run_order, testing::ElementsAre());
}
@@ -2495,8 +2514,8 @@ TEST_F(MainThreadSchedulerImplTest, ThrottleAndPauseRenderer) {
Vector<String> run_order;
PostTestTasks(&run_order, "T1 T2");
- scheduler_->task_queue_throttler()->IncreaseThrottleRefCount(
- throttleable_task_queue()->GetTaskQueue());
+ MainThreadTaskQueue::ThrottleHandle handle =
+ throttleable_task_queue()->Throttle();
base::RunLoop().RunUntilIdle();
auto pause_handle = scheduler_->PauseRenderer();
base::RunLoop().RunUntilIdle();
@@ -2883,9 +2902,8 @@ TEST_F(MainThreadSchedulerImplTest, SYNCHRONIZED_GESTURE_CompositingExpensive) {
// Throttleable tasks should not have been starved by the expensive compositor
// tasks.
- EXPECT_EQ(
- TaskQueue::kNormalPriority,
- scheduler_->CompositorTaskQueue()->GetTaskQueue()->GetQueuePriority());
+ EXPECT_EQ(TaskQueue::kNormalPriority,
+ compositor_task_queue()->GetTaskQueue()->GetQueuePriority());
EXPECT_EQ(1000u, run_order.size());
}
@@ -2926,9 +2944,8 @@ TEST_F(MainThreadSchedulerImplTest, MAIN_THREAD_CUSTOM_INPUT_HANDLING) {
// Throttleable tasks should not have been starved by the expensive compositor
// tasks.
- EXPECT_EQ(
- TaskQueue::kNormalPriority,
- scheduler_->CompositorTaskQueue()->GetTaskQueue()->GetQueuePriority());
+ EXPECT_EQ(TaskQueue::kNormalPriority,
+ compositor_task_queue()->GetTaskQueue()->GetQueuePriority());
EXPECT_EQ(1000u, run_order.size());
}
@@ -2967,9 +2984,8 @@ TEST_F(MainThreadSchedulerImplTest, MAIN_THREAD_GESTURE) {
EXPECT_EQ(UseCase::kMainThreadGesture, CurrentUseCase()) << "i = " << i;
}
- EXPECT_EQ(
- TaskQueue::kHighestPriority,
- scheduler_->CompositorTaskQueue()->GetTaskQueue()->GetQueuePriority());
+ EXPECT_EQ(TaskQueue::kHighestPriority,
+ compositor_task_queue()->GetTaskQueue()->GetQueuePriority());
EXPECT_EQ(279u, run_order.size());
}
@@ -3140,7 +3156,7 @@ TEST_F(MainThreadSchedulerImplTest, EnableVirtualTime) {
EXPECT_EQ(scheduler_->DefaultTaskQueue()->GetTaskQueue()->GetTimeDomain(),
scheduler_->GetVirtualTimeDomain());
- EXPECT_EQ(scheduler_->CompositorTaskQueue()->GetTaskQueue()->GetTimeDomain(),
+ EXPECT_EQ(compositor_task_queue()->GetTaskQueue()->GetTimeDomain(),
scheduler_->GetVirtualTimeDomain());
EXPECT_EQ(loading_task_queue()->GetTaskQueue()->GetTimeDomain(),
scheduler_->GetVirtualTimeDomain());
@@ -3199,15 +3215,13 @@ TEST_F(MainThreadSchedulerImplTest, EnableVirtualTimeAfterThrottling) {
frame_scheduler->SetCrossOriginToMainFrame(true);
frame_scheduler->SetFrameVisible(false);
- EXPECT_TRUE(scheduler_->task_queue_throttler()->IsThrottled(
- throttleable_tq->GetTaskQueue()));
+ EXPECT_TRUE(throttleable_tq->IsThrottled());
scheduler_->EnableVirtualTime(
MainThreadSchedulerImpl::BaseTimeOverridePolicy::DO_NOT_OVERRIDE);
EXPECT_EQ(throttleable_tq->GetTaskQueue()->GetTimeDomain(),
scheduler_->GetVirtualTimeDomain());
- EXPECT_FALSE(scheduler_->task_queue_throttler()->IsThrottled(
- throttleable_tq->GetTaskQueue()));
+ EXPECT_FALSE(throttleable_tq->IsThrottled());
}
TEST_F(MainThreadSchedulerImplTest, DisableVirtualTimeForTesting) {
@@ -3216,7 +3230,7 @@ TEST_F(MainThreadSchedulerImplTest, DisableVirtualTimeForTesting) {
scheduler_->DisableVirtualTimeForTesting();
EXPECT_EQ(scheduler_->DefaultTaskQueue()->GetTaskQueue()->GetTimeDomain(),
scheduler_->real_time_domain());
- EXPECT_EQ(scheduler_->CompositorTaskQueue()->GetTaskQueue()->GetTimeDomain(),
+ EXPECT_EQ(compositor_task_queue()->GetTaskQueue()->GetTimeDomain(),
scheduler_->real_time_domain());
EXPECT_EQ(loading_task_queue()->GetTaskQueue()->GetTimeDomain(),
scheduler_->real_time_domain());
@@ -3342,7 +3356,7 @@ TEST_F(MainThreadSchedulerImplTest, Tracing) {
FROM_HERE, base::BindOnce(NullTask),
base::TimeDelta::FromMilliseconds(10));
- EXPECT_FALSE(scheduler_->ToString().empty());
+ scheduler_->CreateTraceEventObjectSnapshot();
}
TEST_F(MainThreadSchedulerImplTest,
@@ -4130,6 +4144,22 @@ TEST_F(BestEffortNonMainQueuesUntilOnFMPTimeoutTest,
TaskQueue::QueuePriority::kNormalPriority);
}
+TEST_F(MainThreadSchedulerImplTest, ThrottleHandleThrottlesQueue) {
+ EXPECT_FALSE(throttleable_task_queue()->IsThrottled());
+ {
+ MainThreadTaskQueue::ThrottleHandle handle =
+ throttleable_task_queue()->Throttle();
+ EXPECT_TRUE(throttleable_task_queue()->IsThrottled());
+ {
+ MainThreadTaskQueue::ThrottleHandle handle_2 =
+ throttleable_task_queue()->Throttle();
+ EXPECT_TRUE(throttleable_task_queue()->IsThrottled());
+ }
+ EXPECT_TRUE(throttleable_task_queue()->IsThrottled());
+ }
+ EXPECT_FALSE(throttleable_task_queue()->IsThrottled());
+}
+
} // namespace main_thread_scheduler_impl_unittest
} // namespace scheduler
} // namespace blink
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 d2f53467c0e..0fba96bd10b 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
@@ -12,6 +12,7 @@
#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"
#include "third_party/blink/renderer/platform/wtf/wtf.h"
+#include "third_party/perfetto/include/perfetto/tracing/traced_value.h"
namespace blink {
namespace scheduler {
@@ -146,6 +147,12 @@ void MainThreadTaskQueue::OnTaskCompleted(
}
}
+void MainThreadTaskQueue::OnTaskRunTimeReported(
+ TaskQueue::TaskTiming* task_timing) {
+ main_thread_scheduler_->task_queue_throttler()->OnTaskRunTimeReported(
+ task_queue_.get(), task_timing->start_time(), task_timing->end_time());
+}
+
void MainThreadTaskQueue::DetachFromMainThreadScheduler() {
weak_ptr_factory_.InvalidateWeakPtrs();
@@ -203,8 +210,14 @@ WebAgentGroupScheduler* MainThreadTaskQueue::GetAgentGroupScheduler() {
}
void MainThreadTaskQueue::ClearReferencesToSchedulers() {
- if (main_thread_scheduler_)
+ if (main_thread_scheduler_) {
main_thread_scheduler_->OnShutdownTaskQueue(this);
+
+ if (main_thread_scheduler_->task_queue_throttler()) {
+ main_thread_scheduler_->task_queue_throttler()->ShutdownTaskQueue(
+ task_queue_.get());
+ }
+ }
main_thread_scheduler_ = nullptr;
agent_group_scheduler_ = nullptr;
frame_scheduler_ = nullptr;
@@ -243,5 +256,62 @@ MainThreadTaskQueue::web_scheduling_priority() const {
return web_scheduling_priority_;
}
+bool MainThreadTaskQueue::IsThrottled() const {
+ if (main_thread_scheduler_) {
+ return main_thread_scheduler_->task_queue_throttler()->IsThrottled(
+ task_queue_.get());
+ } else {
+ // When the frame detaches the task queue is removed from the throttler.
+ return false;
+ }
+}
+
+MainThreadTaskQueue::ThrottleHandle MainThreadTaskQueue::Throttle() {
+ DCHECK(CanBeThrottled());
+ return ThrottleHandle(
+ task_queue_.get()->AsWeakPtr(),
+ main_thread_scheduler_->task_queue_throttler()->AsWeakPtr());
+}
+
+void MainThreadTaskQueue::AddToBudgetPool(base::TimeTicks now,
+ BudgetPool* pool) {
+ pool->AddQueue(now, task_queue_.get());
+}
+
+void MainThreadTaskQueue::RemoveFromBudgetPool(base::TimeTicks now,
+ BudgetPool* pool) {
+ pool->RemoveQueue(now, task_queue_.get());
+}
+
+void MainThreadTaskQueue::SetImmediateWakeUpForTest() {
+ if (main_thread_scheduler_) {
+ main_thread_scheduler_->task_queue_throttler()->OnQueueNextWakeUpChanged(
+ task_queue_.get(), base::TimeTicks());
+ }
+}
+
+void MainThreadTaskQueue::WriteIntoTracedValue(
+ perfetto::TracedValue context) const {
+ auto dict = std::move(context).WriteDictionary();
+ dict.Add("type", queue_type_);
+ dict.Add("traits", queue_traits_);
+}
+
+void MainThreadTaskQueue::QueueTraits::WriteIntoTracedValue(
+ perfetto::TracedValue context) const {
+ auto dict = std::move(context).WriteDictionary();
+ dict.Add("can_be_deferred", can_be_deferred);
+ dict.Add("can_be_throttled", can_be_throttled);
+ dict.Add("can_be_intensively_throttled", can_be_intensively_throttled);
+ dict.Add("can_be_paused", can_be_paused);
+ dict.Add("can_be_frozen", can_be_frozen);
+ dict.Add("can_run_in_background", can_run_in_background);
+ dict.Add("can_run_when_virtual_time_paused",
+ can_run_when_virtual_time_paused);
+ dict.Add("can_be_paused_for_android_webview",
+ can_be_paused_for_android_webview);
+ dict.Add("prioritisation_type", prioritisation_type);
+}
+
} // namespace scheduler
} // namespace blink
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 b9248e18703..7aa393f6e1d 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
@@ -13,9 +13,12 @@
#include "base/task/sequence_manager/task_queue_impl.h"
#include "base/task/sequence_manager/time_domain.h"
#include "net/base/request_priority.h"
+#include "third_party/blink/renderer/platform/scheduler/common/throttling/budget_pool.h"
+#include "third_party/blink/renderer/platform/scheduler/common/throttling/task_queue_throttler.h"
#include "third_party/blink/renderer/platform/scheduler/main_thread/agent_group_scheduler_impl.h"
#include "third_party/blink/renderer/platform/scheduler/public/frame_scheduler.h"
#include "third_party/blink/renderer/platform/scheduler/public/web_scheduling_priority.h"
+#include "third_party/perfetto/include/perfetto/tracing/traced_value_forward.h"
namespace base {
namespace sequence_manager {
@@ -36,6 +39,10 @@ namespace agent_interference_recorder_test {
class AgentInterferenceRecorderTest;
}
+namespace task_queue_throttler_unittest {
+class TaskQueueThrottlerTest;
+}
+
class FrameSchedulerImpl;
class MainThreadSchedulerImpl;
@@ -92,6 +99,36 @@ class PLATFORM_EXPORT MainThreadTaskQueue
kCount = 27
};
+ // The ThrottleHandle controls throttling and unthrottling the queue. When
+ // a caller requests a queue to be throttled, this handle is returned and
+ // the queue will remain throttled as long as the handle is alive.
+ class ThrottleHandle {
+ public:
+ ThrottleHandle(base::WeakPtr<TaskQueue> task_queue,
+ base::WeakPtr<TaskQueueThrottler> throttler)
+ : task_queue_(std::move(task_queue)), throttler_(std::move(throttler)) {
+ if (task_queue_ && throttler_)
+ throttler_->IncreaseThrottleRefCount(task_queue_.get());
+ }
+ ~ThrottleHandle() {
+ if (task_queue_ && throttler_)
+ throttler_->DecreaseThrottleRefCount(task_queue_.get());
+ }
+
+ // Move-only.
+ ThrottleHandle(ThrottleHandle&& other)
+ : task_queue_(std::move(other.task_queue_)),
+ throttler_(std::move(other.throttler_)) {
+ other.task_queue_ = nullptr;
+ other.throttler_ = nullptr;
+ }
+ ThrottleHandle& operator=(ThrottleHandle&&);
+
+ private:
+ base::WeakPtr<TaskQueue> task_queue_;
+ base::WeakPtr<TaskQueueThrottler> throttler_;
+ };
+
// Returns name of the given queue type. Returned string has application
// lifetime.
static const char* NameForQueueType(QueueType queue_type);
@@ -228,6 +265,8 @@ class PLATFORM_EXPORT MainThreadTaskQueue
return key;
}
+ void WriteIntoTracedValue(perfetto::TracedValue context) const;
+
bool can_be_deferred : 1;
bool can_be_throttled : 1;
bool can_be_intensively_throttled : 1;
@@ -258,6 +297,17 @@ class PLATFORM_EXPORT MainThreadTaskQueue
return *this;
}
+ QueueCreationParams SetAgentGroupScheduler(
+ AgentGroupSchedulerImpl* scheduler) {
+ agent_group_scheduler = scheduler;
+ return *this;
+ }
+
+ QueueCreationParams SetFrameScheduler(FrameSchedulerImpl* scheduler) {
+ frame_scheduler = scheduler;
+ return *this;
+ }
+
// Forwarded calls to |queue_traits|
QueueCreationParams SetCanBeDeferred(bool value) {
@@ -311,17 +361,6 @@ class PLATFORM_EXPORT MainThreadTaskQueue
// Forwarded calls to |spec|.
- QueueCreationParams SetAgentGroupScheduler(
- AgentGroupSchedulerImpl* scheduler) {
- agent_group_scheduler = scheduler;
- return *this;
- }
-
- QueueCreationParams SetFrameScheduler(FrameSchedulerImpl* scheduler) {
- frame_scheduler = scheduler;
- return *this;
- }
-
QueueCreationParams SetShouldMonitorQuiescence(bool should_monitor) {
spec = spec.SetShouldMonitorQuiescence(should_monitor);
return *this;
@@ -440,13 +479,38 @@ class PLATFORM_EXPORT MainThreadTaskQueue
return task_queue_->task_runner();
}
+ bool IsThrottled() const;
+
+ // Throttles the task queue as long as the handle is kept alive.
+ MainThreadTaskQueue::ThrottleHandle Throttle();
+
+ // Called when a task finished running to update cpu-based throttling.
+ void OnTaskRunTimeReported(TaskQueue::TaskTiming* task_timing);
+
+ // Methods for setting and resetting budget pools for this task queue.
+ // Note that a task queue can be in multiple budget pools so a pool must
+ // be specified when resetting.
+ void AddToBudgetPool(base::TimeTicks now, BudgetPool* pool);
+ void RemoveFromBudgetPool(base::TimeTicks now, BudgetPool* pool);
+
+ // This method is only used for tests. If this queue is throttled it will
+ // notify the throttler that this queue should wake immediately.
+ void SetImmediateWakeUpForTest();
+
base::WeakPtr<MainThreadTaskQueue> AsWeakPtr() {
return weak_ptr_factory_.GetWeakPtr();
}
+ void WriteIntoTracedValue(perfetto::TracedValue context) const;
+
protected:
void SetFrameSchedulerForTest(FrameSchedulerImpl* frame_scheduler);
+ // Returns the underlying task queue. Only to be used for tests that need to
+ // test functionality of the task queue specifically without the wrapping
+ // MainThreadTaskQueue (ex TaskQueueThrottlerTest).
+ TaskQueue* GetTaskQueueForTest() { return task_queue_.get(); }
+
// TODO(kdillon): Remove references to TaskQueueImpl once TaskQueueImpl
// inherits from TaskQueue.
MainThreadTaskQueue(
@@ -463,6 +527,8 @@ class PLATFORM_EXPORT MainThreadTaskQueue
friend class blink::scheduler::main_thread_scheduler_impl_unittest::
MainThreadSchedulerImplTest;
friend class agent_interference_recorder_test::AgentInterferenceRecorderTest;
+ friend class blink::scheduler::task_queue_throttler_unittest::
+ TaskQueueThrottlerTest;
// Clear references to main thread scheduler and frame scheduler and dispatch
// appropriate notifications. This is the common part of ShutdownTaskQueue and
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_unittest.cc b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_unittest.cc
index 992fe514fdb..559600ee9f0 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_unittest.cc
+++ b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_unittest.cc
@@ -51,13 +51,13 @@ class MainThreadTest : public testing::Test {
void SetUp() override {
clock_.Advance(base::TimeDelta::FromMicroseconds(5000));
- scheduler_.reset(new MainThreadSchedulerImpl(
+ scheduler_ = std::make_unique<MainThreadSchedulerImpl>(
base::sequence_manager::CreateSequenceManagerOnCurrentThreadWithPump(
base::MessagePump::Create(base::MessagePumpType::DEFAULT),
base::sequence_manager::SequenceManager::Settings::Builder()
.SetTickClock(&clock_)
.Build()),
- base::nullopt));
+ base::nullopt);
scheduler_overrider_ =
std::make_unique<ScopedSchedulerOverrider>(scheduler_.get());
thread_ = Thread::Current();
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl.cc b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl.cc
index c1b6afdf5ac..5955efb7baf 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl.cc
+++ b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl.cc
@@ -28,6 +28,7 @@
#include "third_party/blink/renderer/platform/scheduler/main_thread/use_case.h"
#include "third_party/blink/renderer/platform/scheduler/public/frame_scheduler.h"
#include "third_party/blink/renderer/platform/scheduler/public/page_lifecycle_state.h"
+#include "third_party/perfetto/include/perfetto/tracing/traced_value.h"
namespace blink {
namespace scheduler {
@@ -170,13 +171,12 @@ constexpr base::TimeDelta PageSchedulerImpl::kDefaultThrottledWakeUpInterval;
PageSchedulerImpl::PageSchedulerImpl(
PageScheduler::Delegate* delegate,
AgentGroupSchedulerImpl& agent_group_scheduler)
- : main_thread_scheduler_(&agent_group_scheduler.GetMainThreadScheduler()),
+ : main_thread_scheduler_(static_cast<MainThreadSchedulerImpl*>(
+ &agent_group_scheduler.GetMainThreadScheduler())),
agent_group_scheduler_(agent_group_scheduler),
page_visibility_(kDefaultPageVisibility),
page_visibility_changed_time_(
- agent_group_scheduler.GetMainThreadScheduler()
- .GetTickClock()
- ->NowTicks()),
+ main_thread_scheduler_->GetTickClock()->NowTicks()),
audio_state_(AudioState::kSilent),
is_frozen_(false),
reported_background_throttling_since_navigation_(false),
@@ -185,9 +185,9 @@ PageSchedulerImpl::PageSchedulerImpl(
is_main_frame_local_(false),
is_cpu_time_throttled_(false),
are_wake_ups_intensively_throttled_(false),
- keep_active_(
- agent_group_scheduler.GetMainThreadScheduler().SchedulerKeepActive()),
+ keep_active_(main_thread_scheduler_->SchedulerKeepActive()),
had_recent_title_or_favicon_update_(false),
+ focused_(delegate ? delegate->IsFocused() : true),
delegate_(delegate),
delay_for_background_tab_freezing_(GetDelayForBackgroundTabFreezing()),
freeze_on_network_idle_enabled_(base::FeatureList::IsEnabled(
@@ -362,6 +362,13 @@ void PageSchedulerImpl::SetPageBackForwardCached(
}
}
+void PageSchedulerImpl::OnFocusChanged(bool focused) {
+ DCHECK_NE(focused_, focused);
+
+ focused_ = focused;
+ NotifyFrames();
+}
+
void PageSchedulerImpl::SetUpIPCTaskDetection() {
DCHECK(is_stored_in_back_forward_cache_);
has_ipc_detection_enabled_ = true;
@@ -581,6 +588,10 @@ void PageSchedulerImpl::OnTraceLogEnabled() {
}
}
+bool PageSchedulerImpl::IsPageFocused() const {
+ return focused_;
+}
+
bool PageSchedulerImpl::IsWaitingForMainFrameContentfulPaint() const {
return std::any_of(frame_schedulers_.begin(), frame_schedulers_.end(),
[](const FrameSchedulerImpl* fs) {
@@ -599,40 +610,33 @@ bool PageSchedulerImpl::IsWaitingForMainFrameMeaningfulPaint() const {
});
}
-void PageSchedulerImpl::AsValueInto(
- base::trace_event::TracedValue* state) const {
- state->SetBoolean("page_visible",
- page_visibility_ == PageVisibilityState::kVisible);
- state->SetBoolean("is_audio_playing", IsAudioPlaying());
- state->SetBoolean("is_frozen", is_frozen_);
- state->SetBoolean("reported_background_throttling_since_navigation",
- reported_background_throttling_since_navigation_);
- state->SetBoolean("is_page_freezable", IsBackgrounded());
+void PageSchedulerImpl::WriteIntoTracedValue(
+ perfetto::TracedValue context) const {
+ auto dict = std::move(context).WriteDictionary();
+ dict.Add("page_visible", page_visibility_ == PageVisibilityState::kVisible);
+ dict.Add("is_audio_playing", IsAudioPlaying());
+ dict.Add("is_frozen", is_frozen_);
+ dict.Add("reported_background_throttling_since_navigation",
+ reported_background_throttling_since_navigation_);
+ dict.Add("is_page_freezable", IsBackgrounded());
- {
- auto dictionary_scope = state->BeginDictionaryScoped("frame_schedulers");
- for (FrameSchedulerImpl* frame_scheduler : frame_schedulers_) {
- auto inner_dictionary = state->BeginDictionaryScopedWithCopiedName(
- PointerToString(frame_scheduler));
- frame_scheduler->AsValueInto(state);
- }
- }
+ dict.Add("frame_schedulers", frame_schedulers_);
}
void PageSchedulerImpl::AddQueueToWakeUpBudgetPool(
MainThreadTaskQueue* task_queue,
FrameOriginType frame_origin_type,
base::sequence_manager::LazyNow* lazy_now) {
- GetWakeUpBudgetPool(task_queue, frame_origin_type)
- ->AddQueue(lazy_now->Now(), task_queue->GetTaskQueue());
+ task_queue->AddToBudgetPool(
+ lazy_now->Now(), GetWakeUpBudgetPool(task_queue, frame_origin_type));
}
void PageSchedulerImpl::RemoveQueueFromWakeUpBudgetPool(
MainThreadTaskQueue* task_queue,
FrameOriginType frame_origin_type,
base::sequence_manager::LazyNow* lazy_now) {
- GetWakeUpBudgetPool(task_queue, frame_origin_type)
- ->RemoveQueue(lazy_now->Now(), task_queue->GetTaskQueue());
+ task_queue->RemoveFromBudgetPool(
+ lazy_now->Now(), GetWakeUpBudgetPool(task_queue, frame_origin_type));
}
WakeUpBudgetPool* PageSchedulerImpl::GetWakeUpBudgetPool(
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl.h b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl.h
index 27dfaabae38..5aee3226986 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl.h
+++ b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl.h
@@ -25,11 +25,11 @@
#include "third_party/blink/renderer/platform/scheduler/public/thread_scheduler.h"
#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
#include "third_party/blink/renderer/platform/wtf/hash_set.h"
+#include "third_party/perfetto/include/perfetto/tracing/traced_value_forward.h"
namespace base {
namespace trace_event {
class BlameContext;
-class TracedValue;
} // namespace trace_event
} // namespace base
@@ -63,6 +63,7 @@ class PLATFORM_EXPORT PageSchedulerImpl : public PageScheduler {
void SetPageVisible(bool page_visible) override;
void SetPageFrozen(bool) override;
void SetPageBackForwardCached(bool) override;
+ void OnFocusChanged(bool focused) override;
void SetKeepActive(bool) override;
bool IsMainFrameLocal() const override;
void SetIsMainFrameLocal(bool is_local) override;
@@ -126,6 +127,8 @@ class PLATFORM_EXPORT PageSchedulerImpl : public PageScheduler {
void OnTraceLogEnabled();
+ bool IsPageFocused() const;
+
// Virtual for testing.
virtual bool IsWaitingForMainFrameContentfulPaint() const;
virtual bool IsWaitingForMainFrameMeaningfulPaint() const;
@@ -148,7 +151,7 @@ class PLATFORM_EXPORT PageSchedulerImpl : public PageScheduler {
// frame it not a local one.
FrameSchedulerImpl* SelectFrameForUkmAttribution();
- void AsValueInto(base::trace_event::TracedValue* state) const;
+ void WriteIntoTracedValue(perfetto::TracedValue context) const;
base::WeakPtr<PageSchedulerImpl> GetWeakPtr() {
return weak_factory_.GetWeakPtr();
@@ -316,6 +319,7 @@ class PLATFORM_EXPORT PageSchedulerImpl : public PageScheduler {
bool are_wake_ups_intensively_throttled_;
bool keep_active_;
bool had_recent_title_or_favicon_update_;
+ bool focused_;
CPUTimeBudgetPool* cpu_time_budget_pool_ = nullptr;
// Wake up budget pools for each throttling scenario:
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl_unittest.cc b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl_unittest.cc
index 508f17c8cb5..534a809e6d3 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl_unittest.cc
+++ b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl_unittest.cc
@@ -21,6 +21,7 @@
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/common/features.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/frame_task_queue_controller.h"
#include "third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.h"
@@ -82,6 +83,7 @@ class MockPageSchedulerDelegate : public PageScheduler::Delegate {
void SetLocalMainFrameNetworkIsAlmostIdle(bool idle) { idle_ = idle; }
bool LocalMainFrameNetworkIsAlmostIdle() const override { return idle_; }
+ bool IsFocused() const override { return true; }
private:
void ReportIntervention(const WTF::String&) override {}
@@ -285,17 +287,6 @@ class PageSchedulerImplTest : public testing::Test {
base::test::ScopedFeatureList feature_list_;
};
-class PageSchedulerImplStopNonTimersInBackgroundEnabledTest
- : public PageSchedulerImplTest {
- public:
- PageSchedulerImplStopNonTimersInBackgroundEnabledTest()
- : PageSchedulerImplTest({blink::features::kStopInBackground,
- blink::features::kStopNonTimersInBackground},
- {}) {}
-
- ~PageSchedulerImplStopNonTimersInBackgroundEnabledTest() override = default;
-};
-
TEST_F(PageSchedulerImplTest, TestDestructionOfFrameSchedulersBefore) {
std::unique_ptr<blink::FrameScheduler> frame1(
page_scheduler_->CreateFrameScheduler(
@@ -1318,15 +1309,13 @@ TEST_F(PageSchedulerImplTest, OpenWebSocketExemptsFromBudgetThrottling) {
// Verify that freezing a page prevents tasks in its task queues from running.
// Then, verify that making the page visible unfreezes it and allows tasks in
// its task queues to run.
-TEST_F(PageSchedulerImplStopNonTimersInBackgroundEnabledTest,
- PageFreezeAndSetVisible) {
+TEST_F(PageSchedulerImplTest, PageFreezeAndSetVisible) {
TestFreeze(true);
}
// Same as before, but unfreeze the page explicitly instead of making it
// visible.
-TEST_F(PageSchedulerImplStopNonTimersInBackgroundEnabledTest,
- PageFreezeAndUnfreeze) {
+TEST_F(PageSchedulerImplTest, PageFreezeAndUnfreeze) {
TestFreeze(false);
}
@@ -1363,23 +1352,19 @@ TEST_F(PageSchedulerImplTest, PageSchedulerDestroyedWhileAudioChangePending) {
TEST_F(PageSchedulerImplTest, AudiblePagesAreNotThrottled) {
page_scheduler_->SetPageVisible(false);
- EXPECT_TRUE(scheduler_->task_queue_throttler()->IsThrottled(
- ThrottleableTaskQueue()->GetTaskQueue()));
+ EXPECT_TRUE(ThrottleableTaskQueue()->IsThrottled());
// No throttling when the page is audible.
page_scheduler_->AudioStateChanged(true);
- EXPECT_FALSE(scheduler_->task_queue_throttler()->IsThrottled(
- ThrottleableTaskQueue()->GetTaskQueue()));
+ EXPECT_FALSE(ThrottleableTaskQueue()->IsThrottled());
// No throttling for some time after audio signal disappears.
page_scheduler_->AudioStateChanged(false);
- EXPECT_FALSE(scheduler_->task_queue_throttler()->IsThrottled(
- ThrottleableTaskQueue()->GetTaskQueue()));
+ EXPECT_FALSE(ThrottleableTaskQueue()->IsThrottled());
// Eventually throttling is reenabled again.
test_task_runner_->FastForwardUntilNoTasksRemain();
- EXPECT_TRUE(scheduler_->task_queue_throttler()->IsThrottled(
- ThrottleableTaskQueue()->GetTaskQueue()));
+ EXPECT_TRUE(ThrottleableTaskQueue()->IsThrottled());
}
TEST_F(PageSchedulerImplTest, BudgetBasedThrottlingForPageScheduler) {
@@ -1762,6 +1747,88 @@ TEST_F(PageSchedulerImplPageTransitionTest,
UnorderedElementsAreArray(GetExpectedBuckets()));
}
+class PageSchedulerImplThrottleVisibleNotFocusedTimersEnabledTest
+ : public PageSchedulerImplTest {
+ public:
+ PageSchedulerImplThrottleVisibleNotFocusedTimersEnabledTest()
+ : PageSchedulerImplTest(
+ {blink::features::kStopInBackground,
+ blink::scheduler::kThrottleVisibleNotFocusedTimers},
+ {}) {}
+};
+
+TEST_F(PageSchedulerImplThrottleVisibleNotFocusedTimersEnabledTest,
+ PageVisibleWithFocus) {
+ page_scheduler_->SetPageVisible(true);
+ if (!page_scheduler_->IsPageFocused())
+ page_scheduler_->OnFocusChanged(true);
+
+ int run_count = 0;
+ ThrottleableTaskQueue()->GetTaskRunnerWithDefaultTaskType()->PostDelayedTask(
+ FROM_HERE,
+ MakeRepeatingTask(
+ ThrottleableTaskQueue()->GetTaskRunnerWithDefaultTaskType(),
+ &run_count, base::TimeDelta::FromMilliseconds(20)),
+ base::TimeDelta::FromMilliseconds(20));
+
+ test_task_runner_->FastForwardBy(base::TimeDelta::FromSeconds(1));
+ EXPECT_EQ(50, run_count);
+
+ // Create a new frame when the page has focus
+ int frame_run_count = 0;
+ std::unique_ptr<FrameSchedulerImpl> frame_scheduler2 =
+ CreateFrameScheduler(page_scheduler_.get(), nullptr, nullptr,
+ FrameScheduler::FrameType::kSubframe);
+ ThrottleableTaskQueueForScheduler(frame_scheduler2.get())
+ ->GetTaskRunnerWithDefaultTaskType()
+ ->PostDelayedTask(
+ FROM_HERE,
+ MakeRepeatingTask(
+ ThrottleableTaskQueueForScheduler(frame_scheduler2.get())
+ ->GetTaskRunnerWithDefaultTaskType(),
+ &frame_run_count, base::TimeDelta::FromMilliseconds(20)),
+ base::TimeDelta::FromMilliseconds(20));
+
+ test_task_runner_->FastForwardBy(base::TimeDelta::FromSeconds(1));
+ EXPECT_EQ(50, frame_run_count);
+}
+
+TEST_F(PageSchedulerImplThrottleVisibleNotFocusedTimersEnabledTest,
+ PageVisibleWithoutFocus) {
+ page_scheduler_->SetPageVisible(true);
+ if (page_scheduler_->IsPageFocused())
+ page_scheduler_->OnFocusChanged(false);
+
+ int run_count = 0;
+ ThrottleableTaskQueue()->GetTaskRunnerWithDefaultTaskType()->PostDelayedTask(
+ FROM_HERE,
+ MakeRepeatingTask(
+ ThrottleableTaskQueue()->GetTaskRunnerWithDefaultTaskType(),
+ &run_count, base::TimeDelta::FromMilliseconds(20)),
+ base::TimeDelta::FromMilliseconds(20));
+
+ test_task_runner_->FastForwardBy(base::TimeDelta::FromSeconds(1));
+ EXPECT_EQ(1, run_count);
+
+ // Create a new frame when the page doesn't have focus
+ int frame_run_count = 0;
+ std::unique_ptr<FrameSchedulerImpl> frame_scheduler2 =
+ CreateFrameScheduler(page_scheduler_.get(), nullptr, nullptr,
+ FrameScheduler::FrameType::kSubframe);
+ ThrottleableTaskQueueForScheduler(frame_scheduler2.get())
+ ->GetTaskRunnerWithDefaultTaskType()
+ ->PostDelayedTask(
+ FROM_HERE,
+ MakeRepeatingTask(
+ ThrottleableTaskQueueForScheduler(frame_scheduler2.get())
+ ->GetTaskRunnerWithDefaultTaskType(),
+ &frame_run_count, base::TimeDelta::FromMilliseconds(20)),
+ base::TimeDelta::FromMilliseconds(20));
+
+ test_task_runner_->FastForwardBy(base::TimeDelta::FromSeconds(1));
+ EXPECT_EQ(1, frame_run_count);
+}
+
} // namespace page_scheduler_impl_unittest
} // namespace scheduler
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/render_widget_signals.cc b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/render_widget_signals.cc
index 4d13b8ad29b..1441803981e 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/render_widget_signals.cc
+++ b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/render_widget_signals.cc
@@ -7,6 +7,7 @@
#include "base/check_op.h"
#include "base/memory/ptr_util.h"
#include "third_party/blink/public/platform/scheduler/web_render_widget_scheduling_state.h"
+#include "third_party/perfetto/include/perfetto/tracing/traced_value.h"
namespace blink {
namespace scheduler {
@@ -51,13 +52,12 @@ void RenderWidgetSignals::DecNumVisibleRenderWidgetsWithTouchHandlers() {
observer_->SetHasVisibleRenderWidgetWithTouchHandler(false);
}
-void RenderWidgetSignals::AsValueInto(
- base::trace_event::TracedValue* state) const {
- auto dictionary_scope =
- state->BeginDictionaryScoped("renderer_widget_signals");
- state->SetInteger("num_visible_render_widgets", num_visible_render_widgets_);
- state->SetInteger("num_visible_render_widgets_with_touch_handlers",
- num_visible_render_widgets_with_touch_handlers_);
+void RenderWidgetSignals::WriteIntoTracedValue(
+ perfetto::TracedValue context) const {
+ auto dict = std::move(context).WriteDictionary();
+ dict.Add("num_visible_render_widgets", num_visible_render_widgets_);
+ dict.Add("num_visible_render_widgets_with_touch_handlers",
+ num_visible_render_widgets_with_touch_handlers_);
}
} // namespace scheduler
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/render_widget_signals.h b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/render_widget_signals.h
index f484d89c8f2..81a2d411ed9 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/render_widget_signals.h
+++ b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/render_widget_signals.h
@@ -11,6 +11,7 @@
#include "base/trace_event/traced_value.h"
#include "third_party/blink/renderer/platform/platform_export.h"
#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
+#include "third_party/perfetto/include/perfetto/tracing/traced_value_forward.h"
namespace blink {
namespace scheduler {
@@ -43,7 +44,7 @@ class PLATFORM_EXPORT RenderWidgetSignals {
std::unique_ptr<WebRenderWidgetSchedulingState>
NewRenderWidgetSchedulingState();
- void AsValueInto(base::trace_event::TracedValue* state) const;
+ void WriteIntoTracedValue(perfetto::TracedValue context) const;
private:
friend class WebRenderWidgetSchedulingState;
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 6084494be0a..a1a5df6aa69 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
@@ -145,6 +145,8 @@ const char* TaskTypeNames::TaskTypeToString(TaskType task_type) {
return "InternalHighPriorityLocalFrame";
case TaskType::kMainThreadTaskQueueIPCTracking:
return "MainThreadTaskQueueIPCTracking";
+ case TaskType::kWakeLock:
+ return "WakeLock";
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 14ed5d50e33..e955335dc93 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
@@ -3,6 +3,7 @@
// found in the LICENSE file.
#include "third_party/blink/renderer/platform/scheduler/main_thread/user_model.h"
+#include "third_party/perfetto/include/perfetto/tracing/traced_value.h"
namespace blink {
namespace scheduler {
@@ -140,25 +141,17 @@ void UserModel::Reset(base::TimeTicks now) {
pending_input_event_count_ = 0;
}
-void UserModel::AsValueInto(base::trace_event::TracedValue* state) const {
- auto dictionary_scope = state->BeginDictionaryScoped("user_model");
- state->SetInteger("pending_input_event_count", pending_input_event_count_);
- state->SetDouble(
- "last_input_signal_time",
- (last_input_signal_time_ - base::TimeTicks()).InMillisecondsF());
- state->SetDouble(
- "last_gesture_start_time",
- (last_gesture_start_time_ - base::TimeTicks()).InMillisecondsF());
- state->SetDouble(
- "last_continuous_gesture_time",
- (last_continuous_gesture_time_ - base::TimeTicks()).InMillisecondsF());
- state->SetDouble("last_gesture_expected_start_time",
- (last_gesture_expected_start_time_ - base::TimeTicks())
- .InMillisecondsF());
- state->SetDouble("last_reset_time",
- (last_reset_time_ - base::TimeTicks()).InMillisecondsF());
- state->SetBoolean("is_gesture_expected", is_gesture_expected_);
- state->SetBoolean("is_gesture_active", is_gesture_active_);
+void UserModel::WriteIntoTracedValue(perfetto::TracedValue context) const {
+ auto dict = std::move(context).WriteDictionary();
+ dict.Add("pending_input_event_count", pending_input_event_count_);
+ dict.Add("last_input_signal_time", last_input_signal_time_);
+ dict.Add("last_gesture_start_time", last_gesture_start_time_);
+ dict.Add("last_continuous_gesture_time", last_continuous_gesture_time_);
+ dict.Add("last_gesture_expected_start_time",
+ last_gesture_expected_start_time_);
+ dict.Add("last_reset_time", last_reset_time_);
+ dict.Add("is_gesture_expected", is_gesture_expected_);
+ dict.Add("is_gesture_active", is_gesture_active_);
}
} // namespace scheduler
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 fb7d2b79468..7affc23ce28 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
@@ -12,6 +12,7 @@
#include "third_party/blink/public/platform/scheduler/web_thread_scheduler.h"
#include "third_party/blink/renderer/platform/platform_export.h"
#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
+#include "third_party/perfetto/include/perfetto/tracing/traced_value_forward.h"
namespace blink {
namespace scheduler {
@@ -48,7 +49,7 @@ class PLATFORM_EXPORT UserModel {
const base::TimeTicks now,
base::TimeDelta* prediction_valid_duration) const;
- void AsValueInto(base::trace_event::TracedValue* state) const;
+ void WriteIntoTracedValue(perfetto::TracedValue context) const;
// The time we should stay in a priority-escalated mode after an input event.
static const int kGestureEstimationLimitMillis = 100;