0

Boost RendererMain thread priority if an input scenario is detected

This feature is behind a flag kInputScenarioPriorityBoost for
experiments. If enabled, the default thread type of RendererMain will
be reduced to kDefault and boost to kDisplayCritical during typing.

Bug: 365586676
Change-Id: Icf235ea6a035b793f1b6aebb3b804d7ca56f0d08
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6308410
Reviewed-by: Joe Mason <joenotcharles@google.com>
Reviewed-by: Etienne Pierre-Doray <etiennep@chromium.org>
Commit-Queue: Jiahe Zhang <jiahe.zhang@intel.com>
Cr-Commit-Position: refs/heads/main@{#1428165}
This commit is contained in:
Jiahe Zhang
2025-03-04 23:41:20 -08:00
committed by Chromium LUCI CQ
parent 2970502df0
commit cb54d6bdd9
9 changed files with 63 additions and 3 deletions

@ -620,6 +620,11 @@ BASE_FEATURE(kLogJsConsoleMessages,
#endif
);
// Boosts the thread priority of RendererMain if an input scenario is detected.
BASE_FEATURE(kInputScenarioPriorityBoost,
"InputScenarioPriorityBoost",
base::FEATURE_DISABLED_BY_DEFAULT);
// The MBI mode controls whether or not communication over the
// AgentSchedulingGroup is ordered with respect to the render-process-global
// legacy IPC channel, as well as the granularity of AgentSchedulingGroup

@ -151,6 +151,7 @@ CONTENT_EXPORT BASE_DECLARE_FEATURE(kLowerPAMemoryLimitForNonMainRenderers);
CONTENT_EXPORT BASE_DECLARE_FEATURE(kMBIMode);
CONTENT_EXPORT BASE_DECLARE_FEATURE(kWebRtcHWDecoding);
CONTENT_EXPORT BASE_DECLARE_FEATURE(kWebRtcHWEncoding);
CONTENT_EXPORT BASE_DECLARE_FEATURE(kInputScenarioPriorityBoost);
enum class MBIMode {
// In this mode, the AgentSchedulingGroup will use the process-wide legacy IPC

@ -34,6 +34,7 @@
#include "content/common/content_switches_internal.h"
#include "content/common/features.h"
#include "content/common/skia_utils.h"
#include "content/public/common/content_features.h"
#include "content/public/common/content_switches.h"
#include "content/public/common/main_function_params.h"
#include "content/public/renderer/content_renderer_client.h"
@ -224,6 +225,11 @@ int RendererMain(MainFunctionParams parameters) {
std::unique_ptr<blink::scheduler::WebThreadScheduler> main_thread_scheduler =
blink::scheduler::WebThreadScheduler::CreateMainThreadScheduler(
CreateMainThreadMessagePump());
bool input_scenario_priority_boost_enabled =
base::FeatureList::IsEnabled(features::kInputScenarioPriorityBoost);
if (input_scenario_priority_boost_enabled) {
main_thread_scheduler->EnableInputScenarioPriorityBoost();
}
platform.PlatformInitialize();
@ -273,8 +279,12 @@ int RendererMain(MainFunctionParams parameters) {
// Consider CrRendererMain a display critical thread. While some Javascript
// running on the main thread might not be, experiments demonstrated that
// overall this improves user-perceived performance.
base::PlatformThread::SetCurrentThreadType(
base::ThreadType::kDisplayCritical);
// If kInputScenarioPriorityBoost is enabled, the main thread will only be
// display critical when user input is detected.
base::ThreadType thread_type = input_scenario_priority_boost_enabled
? base::ThreadType::kDefault
: base::ThreadType::kDisplayCritical;
base::PlatformThread::SetCurrentThreadType(thread_type);
std::unique_ptr<RenderProcess> render_process = RenderProcessImpl::Create();
// It's not a memory leak since RenderThread has the same lifetime

@ -93,6 +93,9 @@ class BLINK_PLATFORM_EXPORT WebThreadScheduler
// once.
virtual void SetRendererProcessType(WebRendererProcessType type);
// Enables the kInputScenarioPriorityBoost feature for the main thread.
virtual void EnableInputScenarioPriorityBoost();
// IPC::Channel::UrgentMessageDelegate implementation:
void OnUrgentMessageReceived() override;
void OnUrgentMessageProcessed() override;

@ -173,6 +173,7 @@ blink_platform_sources("scheduler") {
"//base",
"//cc",
"//components/miracle_parameter/common",
"//components/performance_manager/scenario_api",
"//device/base/synchronization",
"//services/metrics/public/mojom",
"//third_party/blink/renderer/platform:allow_discouraged_type",

@ -74,6 +74,10 @@ void WebThreadScheduler::SetRendererProcessType(WebRendererProcessType type) {
NOTREACHED();
}
void WebThreadScheduler::EnableInputScenarioPriorityBoost() {
NOTREACHED();
}
void WebThreadScheduler::OnUrgentMessageReceived() {
NOTREACHED();
}

@ -16,7 +16,8 @@ specific_include_rules = {
"+base/task/sequence_manager/enqueue_order.h"
],
"main_thread_scheduler_impl.cc": [
"+base/android/pre_freeze_background_memory_trimmer.h"
"+base/android/pre_freeze_background_memory_trimmer.h",
"+components/performance_manager/scenario_api/performance_scenarios.h"
],
"memory_purge_manager.cc": [
"+base/android/pre_freeze_background_memory_trimmer.h"
@ -27,4 +28,7 @@ specific_include_rules = {
"main_thread_unittest.cc": [
"+base/message_loop/message_pump_type.h",
],
"main_thread_scheduler_impl.h": [
"+base/threading/scoped_thread_priority.h",
],
}

@ -30,6 +30,7 @@
#include "base/trace_event/trace_event.h"
#include "base/trace_event/traced_value.h"
#include "build/build_config.h"
#include "components/performance_manager/scenario_api/performance_scenarios.h"
#include "components/viz/common/frame_sinks/begin_frame_args.h"
#include "third_party/blink/public/common/features.h"
#include "third_party/blink/public/common/input/web_input_event.h"
@ -1943,6 +1944,10 @@ void MainThreadSchedulerImpl::SetRendererProcessType(
main_thread_only().process_type = type;
}
void MainThreadSchedulerImpl::EnableInputScenarioPriorityBoost() {
input_scenario_priority_boost_enabled_ = true;
}
Vector<WebInputEventAttribution>
MainThreadSchedulerImpl::GetPendingUserInputInfo(
bool include_continuous) const {
@ -2257,6 +2262,28 @@ void MainThreadSchedulerImpl::OnTaskStarted(
main_thread_only().task_priority_for_tracing =
queue ? std::optional<TaskPriority>(queue->GetQueuePriority())
: std::nullopt;
if (input_scenario_priority_boost_enabled_) {
// Check if the input scenario has changed and update the main thread
// priority boost accordingly.
performance_scenarios::InputScenario input_scenario =
GetInputScenario(performance_scenarios::ScenarioScope::kCurrentProcess)
->load(std::memory_order_relaxed);
switch (input_scenario) {
case performance_scenarios::InputScenario::kNoInput:
if (main_thread_priority_boost_.has_value()) {
main_thread_priority_boost_.reset();
}
break;
case performance_scenarios::InputScenario::kTyping:
if (!main_thread_priority_boost_.has_value()) {
main_thread_priority_boost_.emplace(
base::ThreadType::kDisplayCritical);
}
break;
}
}
}
void MainThreadSchedulerImpl::OnTaskCompleted(

@ -24,6 +24,7 @@
#include "base/task/sequence_manager/task_time_observer.h"
#include "base/task/sequenced_task_runner.h"
#include "base/task/single_thread_task_runner.h"
#include "base/threading/scoped_thread_priority.h"
#include "base/time/time.h"
#include "base/trace_event/trace_log.h"
#include "build/build_config.h"
@ -183,6 +184,7 @@ class PLATFORM_EXPORT MainThreadSchedulerImpl
void ResumeTimersForAndroidWebView() override;
#endif
void SetRendererProcessType(WebRendererProcessType type) override;
void EnableInputScenarioPriorityBoost() override;
void OnUrgentMessageReceived() override;
void OnUrgentMessageProcessed() override;
@ -850,6 +852,9 @@ class PLATFORM_EXPORT MainThreadSchedulerImpl
PollableThreadSafeFlag policy_may_need_update_;
WeakPersistent<AgentGroupScheduler> current_agent_group_scheduler_;
bool input_scenario_priority_boost_enabled_ = false;
std::optional<base::ScopedBoostPriority> main_thread_priority_boost_;
// This is accessed from both the main and IO (IPC) threads. It's incremented
// when an urgent IPC task is posted and decremented when that IPC task runs
// (or doesn't, e.g. if the interface is closed). This gets checked at the end