Commit 3397c26d authored by Hongchan Choi's avatar Hongchan Choi Committed by Chromium LUCI CQ

Install a server-side feature switch for RealtimeAudioWorkletThread

This patch introduces a new server-side setting that enables
the real-time priority thread for the RealtimeAudioWorkletThread object.
Without the server interaction, the object will fall back to the
NORMAL priority.

See also: https://critique-ng.corp.google.com/cl/332043086

Bug: 1119403
Change-Id: I1067ccd5a8da4be2fb82450028f5697fbbfcdb59
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2412221Reviewed-by: default avatarRaymond Toy <rtoy@chromium.org>
Reviewed-by: default avatarKentaro Hara <haraken@chromium.org>
Commit-Queue: Hongchan Choi <hongchan@chromium.org>
Cr-Commit-Position: refs/heads/master@{#836186}
parent 400606c7
...@@ -372,6 +372,12 @@ const base::Feature kBlockingFocusWithoutUserActivation{ ...@@ -372,6 +372,12 @@ const base::Feature kBlockingFocusWithoutUserActivation{
const base::Feature kAudioWorkletRealtimeThread{ const base::Feature kAudioWorkletRealtimeThread{
"AudioWorkletRealtimeThread", base::FEATURE_DISABLED_BY_DEFAULT}; "AudioWorkletRealtimeThread", base::FEATURE_DISABLED_BY_DEFAULT};
// A server-side switch for the REALTIME_AUDIO thread priority of
// RealtimeAudioWorkletThread object. When disabled, it will use the NORMAL
// priority thread.
const base::Feature kAudioWorkletThreadRealtimePriority{
"AudioWorkletThreadRealtimePriority", base::FEATURE_DISABLED_BY_DEFAULT};
// A feature to reduce the set of resources fetched by No-State Prefetch. // A feature to reduce the set of resources fetched by No-State Prefetch.
const base::Feature kLightweightNoStatePrefetch { const base::Feature kLightweightNoStatePrefetch {
"LightweightNoStatePrefetch", "LightweightNoStatePrefetch",
......
...@@ -106,6 +106,8 @@ BLINK_COMMON_EXPORT extern const base::Feature ...@@ -106,6 +106,8 @@ BLINK_COMMON_EXPORT extern const base::Feature
kBlockingFocusWithoutUserActivation; kBlockingFocusWithoutUserActivation;
BLINK_COMMON_EXPORT extern const base::Feature kAudioWorkletRealtimeThread; BLINK_COMMON_EXPORT extern const base::Feature kAudioWorkletRealtimeThread;
BLINK_COMMON_EXPORT extern const base::Feature
kAudioWorkletThreadRealtimePriority;
BLINK_COMMON_EXPORT extern const base::Feature kLightweightNoStatePrefetch; BLINK_COMMON_EXPORT extern const base::Feature kLightweightNoStatePrefetch;
......
...@@ -115,7 +115,7 @@ AudioWorkletMessagingProxy::CreateWorkletThreadWithConstraints( ...@@ -115,7 +115,7 @@ AudioWorkletMessagingProxy::CreateWorkletThreadWithConstraints(
// If the flag is set, it overrides the default thread priority for // If the flag is set, it overrides the default thread priority for
// subframes. This is only allowed for the experimental purposes, and this // subframes. This is only allowed for the experimental purposes, and this
// flag will be deprecated in M90. // flag will be deprecated in M90. (See crbug.com/1156842)
if (is_top_level_frame || if (is_top_level_frame ||
base::FeatureList::IsEnabled(features::kAudioWorkletRealtimeThread)) { base::FeatureList::IsEnabled(features::kAudioWorkletRealtimeThread)) {
return std::make_unique<RealtimeAudioWorkletThread>(worker_reporting_proxy); return std::make_unique<RealtimeAudioWorkletThread>(worker_reporting_proxy);
......
...@@ -325,43 +325,55 @@ struct ThreadPriorityTestParam { ...@@ -325,43 +325,55 @@ struct ThreadPriorityTestParam {
const bool use_top_level_await; const bool use_top_level_await;
const bool has_realtime_constraint; const bool has_realtime_constraint;
const bool is_top_level_frame; const bool is_top_level_frame;
const bool is_flag_enabled; const bool is_enabled_by_finch;
const bool is_enabled_by_flag;
const base::ThreadPriority expected_priority; const base::ThreadPriority expected_priority;
}; };
constexpr ThreadPriorityTestParam kThreadPriorityTestParams[] = { constexpr ThreadPriorityTestParam kThreadPriorityTestParams[] = {
// A real-time priority thread is guaranteed when the context has real-time // RT thread enabled by Finch.
// constraint and is spawned from a top-level frame. The flag setting {true, true, true, true, true, base::ThreadPriority::REALTIME_AUDIO},
// is ignored. {true, true, true, true, false, base::ThreadPriority::REALTIME_AUDIO},
{false, true, true, true, base::ThreadPriority::REALTIME_AUDIO},
{false, true, true, false, base::ThreadPriority::REALTIME_AUDIO}, // RT thread disabled by Finch.
// With top-level-await module: {true, true, true, false, true, base::ThreadPriority::NORMAL},
{true, true, true, true, base::ThreadPriority::REALTIME_AUDIO}, {true, true, true, false, false, base::ThreadPriority::NORMAL},
{true, true, true, false, base::ThreadPriority::REALTIME_AUDIO},
// Non-main frame, RT thread enabled by Finch: depends the local flag.
// A DISPLAY priority thread is given when the context has real-time {true, true, false, true, true, base::ThreadPriority::REALTIME_AUDIO},
// constraint but is spawned from a sub frame. {true, true, false, true, false, base::ThreadPriority::DISPLAY},
{false, true, false, false, base::ThreadPriority::DISPLAY},
// With top-level-await module: // Non-main frame, RT thread disabled by Finch.
{true, true, false, false, base::ThreadPriority::DISPLAY}, {true, true, false, false, true, base::ThreadPriority::NORMAL},
{true, true, false, false, false, base::ThreadPriority::NORMAL},
// Enabling the real-time thread flag will override thread priority logic
// for a real-time context. // The OfflineAudioContext always uses a NORMAL priority thread.
{false, true, false, true, base::ThreadPriority::REALTIME_AUDIO}, {true, false, true, true, true, base::ThreadPriority::NORMAL},
// With top-level-await module: {true, false, true, true, false, base::ThreadPriority::NORMAL},
{true, true, false, true, base::ThreadPriority::REALTIME_AUDIO}, {true, false, true, false, true, base::ThreadPriority::NORMAL},
{true, false, true, false, false, base::ThreadPriority::NORMAL},
// OfflineAudioWorkletThread is always a NORMAL priority no matter what {true, false, false, true, true, base::ThreadPriority::NORMAL},
// the flag setting or the originating frame level is. {true, false, false, true, false, base::ThreadPriority::NORMAL},
{false, false, true, true, base::ThreadPriority::NORMAL}, {true, false, false, false, true, base::ThreadPriority::NORMAL},
{false, false, true, false, base::ThreadPriority::NORMAL}, {true, false, false, false, false, base::ThreadPriority::NORMAL},
{false, false, false, true, base::ThreadPriority::NORMAL},
{false, false, false, false, base::ThreadPriority::NORMAL}, // Top-level await does not affect the test result.
// With top-level-await module: {false, true, true, true, true, base::ThreadPriority::REALTIME_AUDIO},
{true, false, true, true, base::ThreadPriority::NORMAL}, {false, true, true, true, false, base::ThreadPriority::REALTIME_AUDIO},
{true, false, true, false, base::ThreadPriority::NORMAL}, {false, true, true, false, true, base::ThreadPriority::NORMAL},
{true, false, false, true, base::ThreadPriority::NORMAL}, {false, true, true, false, false, base::ThreadPriority::NORMAL},
{true, false, false, false, base::ThreadPriority::NORMAL}, {false, true, false, true, true, base::ThreadPriority::REALTIME_AUDIO},
{false, true, false, true, false, base::ThreadPriority::DISPLAY},
{false, true, false, false, true, base::ThreadPriority::NORMAL},
{false, true, false, false, false, base::ThreadPriority::NORMAL},
{false, false, true, true, true, base::ThreadPriority::NORMAL},
{false, false, true, true, false, base::ThreadPriority::NORMAL},
{false, false, true, false, true, base::ThreadPriority::NORMAL},
{false, false, true, false, false, base::ThreadPriority::NORMAL},
{false, false, false, true, true, base::ThreadPriority::NORMAL},
{false, false, false, true, false, base::ThreadPriority::NORMAL},
{false, false, false, false, true, base::ThreadPriority::NORMAL},
{false, false, false, false, false, base::ThreadPriority::NORMAL},
}; };
class AudioWorkletThreadPriorityTest class AudioWorkletThreadPriorityTest
...@@ -371,13 +383,19 @@ class AudioWorkletThreadPriorityTest ...@@ -371,13 +383,19 @@ class AudioWorkletThreadPriorityTest
AudioWorkletThreadPriorityTest() AudioWorkletThreadPriorityTest()
: AudioWorkletThreadTestBase(GetParam().use_top_level_await) {} : AudioWorkletThreadTestBase(GetParam().use_top_level_await) {}
void InitAndSetRealtimePriorityFlag(bool is_flag_enabled) { void InitWithRealtimePrioritySettings(bool is_enabled_by_finch,
if (is_flag_enabled) { bool is_enabled_by_flag) {
feature_list_.InitAndEnableFeature(features::kAudioWorkletRealtimeThread); std::vector<base::Feature> enabled;
} else { std::vector<base::Feature> disabled;
feature_list_.InitAndDisableFeature( if (is_enabled_by_finch)
features::kAudioWorkletRealtimeThread); enabled.push_back(features::kAudioWorkletThreadRealtimePriority);
} else
disabled.push_back(features::kAudioWorkletThreadRealtimePriority);
if (is_enabled_by_flag)
enabled.push_back(features::kAudioWorkletRealtimeThread);
else
disabled.push_back(features::kAudioWorkletRealtimeThread);
feature_list_.InitWithFeatures(enabled, disabled);
} }
void CreateCheckThreadPriority(bool has_realtime_constraint, void CreateCheckThreadPriority(bool has_realtime_constraint,
...@@ -434,7 +452,8 @@ class AudioWorkletThreadPriorityTest ...@@ -434,7 +452,8 @@ class AudioWorkletThreadPriorityTest
TEST_P(AudioWorkletThreadPriorityTest, CheckThreadPriority) { TEST_P(AudioWorkletThreadPriorityTest, CheckThreadPriority) {
const auto& test_param = GetParam(); const auto& test_param = GetParam();
InitAndSetRealtimePriorityFlag(test_param.is_flag_enabled); InitWithRealtimePrioritySettings(test_param.is_enabled_by_finch,
test_param.is_enabled_by_flag);
CreateCheckThreadPriority(test_param.has_realtime_constraint, CreateCheckThreadPriority(test_param.has_realtime_constraint,
test_param.is_top_level_frame, test_param.is_top_level_frame,
test_param.expected_priority); test_param.expected_priority);
......
...@@ -4,6 +4,8 @@ ...@@ -4,6 +4,8 @@
#include "third_party/blink/renderer/modules/webaudio/realtime_audio_worklet_thread.h" #include "third_party/blink/renderer/modules/webaudio/realtime_audio_worklet_thread.h"
#include "base/feature_list.h"
#include "third_party/blink/public/common/features.h"
#include "third_party/blink/renderer/modules/webaudio/audio_worklet_global_scope.h" #include "third_party/blink/renderer/modules/webaudio/audio_worklet_global_scope.h"
#include "third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h" #include "third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h"
...@@ -24,9 +26,15 @@ RealtimeAudioWorkletThread::RealtimeAudioWorkletThread( ...@@ -24,9 +26,15 @@ RealtimeAudioWorkletThread::RealtimeAudioWorkletThread(
ThreadCreationParams params = ThreadCreationParams params =
ThreadCreationParams(ThreadType::kRealtimeAudioWorkletThread); ThreadCreationParams(ThreadType::kRealtimeAudioWorkletThread);
// TODO(crbug.com/1022888): The worklet thread priority is always NORMAL // Use a higher priority thread only when it is allowed by Finch.
// on OS_LINUX and OS_CHROMEOS regardless of the thread priority setting. if (base::FeatureList::IsEnabled(
features::kAudioWorkletThreadRealtimePriority)) {
// TODO(crbug.com/1022888): The worklet thread priority is always NORMAL on
// Linux and Chrome OS regardless of this thread priority setting.
params.thread_priority = base::ThreadPriority::REALTIME_AUDIO; params.thread_priority = base::ThreadPriority::REALTIME_AUDIO;
} else {
params.thread_priority = base::ThreadPriority::NORMAL;
}
if (++s_ref_count_ == 1) if (++s_ref_count_ == 1)
EnsureSharedBackingThread(params); EnsureSharedBackingThread(params);
......
...@@ -4,6 +4,8 @@ ...@@ -4,6 +4,8 @@
#include "third_party/blink/renderer/modules/webaudio/semi_realtime_audio_worklet_thread.h" #include "third_party/blink/renderer/modules/webaudio/semi_realtime_audio_worklet_thread.h"
#include "base/feature_list.h"
#include "third_party/blink/public/common/features.h"
#include "third_party/blink/renderer/modules/webaudio/audio_worklet_global_scope.h" #include "third_party/blink/renderer/modules/webaudio/audio_worklet_global_scope.h"
#include "third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h" #include "third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h"
...@@ -24,9 +26,15 @@ SemiRealtimeAudioWorkletThread::SemiRealtimeAudioWorkletThread( ...@@ -24,9 +26,15 @@ SemiRealtimeAudioWorkletThread::SemiRealtimeAudioWorkletThread(
ThreadCreationParams params = ThreadCreationParams params =
ThreadCreationParams(ThreadType::kSemiRealtimeAudioWorkletThread); ThreadCreationParams(ThreadType::kSemiRealtimeAudioWorkletThread);
// TODO(crbug.com/1022888): The worklet thread priority is always NORMAL // Use a higher priority thread only when it is allowed by Finch.
// on OS_LINUX and OS_CHROMEOS regardless of this thread priority setting. if (base::FeatureList::IsEnabled(
features::kAudioWorkletThreadRealtimePriority)) {
// TODO(crbug.com/1022888): The worklet thread priority is always NORMAL on
// Linux and Chrome OS regardless of this thread priority setting.
params.thread_priority = base::ThreadPriority::DISPLAY; params.thread_priority = base::ThreadPriority::DISPLAY;
} else {
params.thread_priority = base::ThreadPriority::NORMAL;
}
if (++s_ref_count_ == 1) if (++s_ref_count_ == 1)
EnsureSharedBackingThread(params); EnsureSharedBackingThread(params);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment