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{
const base::Feature kAudioWorkletRealtimeThread{
"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.
const base::Feature kLightweightNoStatePrefetch {
"LightweightNoStatePrefetch",
......
......@@ -106,6 +106,8 @@ BLINK_COMMON_EXPORT extern const base::Feature
kBlockingFocusWithoutUserActivation;
BLINK_COMMON_EXPORT extern const base::Feature kAudioWorkletRealtimeThread;
BLINK_COMMON_EXPORT extern const base::Feature
kAudioWorkletThreadRealtimePriority;
BLINK_COMMON_EXPORT extern const base::Feature kLightweightNoStatePrefetch;
......
......@@ -115,7 +115,7 @@ AudioWorkletMessagingProxy::CreateWorkletThreadWithConstraints(
// If the flag is set, it overrides the default thread priority for
// 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 ||
base::FeatureList::IsEnabled(features::kAudioWorkletRealtimeThread)) {
return std::make_unique<RealtimeAudioWorkletThread>(worker_reporting_proxy);
......
......@@ -325,43 +325,55 @@ struct ThreadPriorityTestParam {
const bool use_top_level_await;
const bool has_realtime_constraint;
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;
};
constexpr ThreadPriorityTestParam kThreadPriorityTestParams[] = {
// A real-time priority thread is guaranteed when the context has real-time
// constraint and is spawned from a top-level frame. The flag setting
// is ignored.
{false, true, true, true, base::ThreadPriority::REALTIME_AUDIO},
{false, true, true, false, base::ThreadPriority::REALTIME_AUDIO},
// With top-level-await module:
{true, true, true, true, base::ThreadPriority::REALTIME_AUDIO},
{true, true, true, false, base::ThreadPriority::REALTIME_AUDIO},
// A DISPLAY priority thread is given when the context has real-time
// constraint but is spawned from a sub frame.
{false, true, false, false, base::ThreadPriority::DISPLAY},
// With top-level-await module:
{true, true, false, false, base::ThreadPriority::DISPLAY},
// Enabling the real-time thread flag will override thread priority logic
// for a real-time context.
{false, true, false, true, base::ThreadPriority::REALTIME_AUDIO},
// With top-level-await module:
{true, true, false, true, base::ThreadPriority::REALTIME_AUDIO},
// OfflineAudioWorkletThread is always a NORMAL priority no matter what
// the flag setting or the originating frame level is.
{false, false, true, true, base::ThreadPriority::NORMAL},
{false, false, true, false, base::ThreadPriority::NORMAL},
{false, false, false, true, base::ThreadPriority::NORMAL},
{false, false, false, false, base::ThreadPriority::NORMAL},
// With top-level-await module:
{true, false, true, true, base::ThreadPriority::NORMAL},
{true, false, true, false, base::ThreadPriority::NORMAL},
{true, false, false, true, base::ThreadPriority::NORMAL},
{true, false, false, false, base::ThreadPriority::NORMAL},
// RT thread enabled by Finch.
{true, true, true, true, true, base::ThreadPriority::REALTIME_AUDIO},
{true, true, true, true, false, base::ThreadPriority::REALTIME_AUDIO},
// RT thread disabled by Finch.
{true, true, true, false, true, base::ThreadPriority::NORMAL},
{true, true, true, false, false, base::ThreadPriority::NORMAL},
// Non-main frame, RT thread enabled by Finch: depends the local flag.
{true, true, false, true, true, base::ThreadPriority::REALTIME_AUDIO},
{true, true, false, true, false, base::ThreadPriority::DISPLAY},
// Non-main frame, RT thread disabled by Finch.
{true, true, false, false, true, base::ThreadPriority::NORMAL},
{true, true, false, false, false, base::ThreadPriority::NORMAL},
// The OfflineAudioContext always uses a NORMAL priority thread.
{true, false, true, true, true, base::ThreadPriority::NORMAL},
{true, false, true, true, false, base::ThreadPriority::NORMAL},
{true, false, true, false, true, base::ThreadPriority::NORMAL},
{true, false, true, false, false, base::ThreadPriority::NORMAL},
{true, false, false, true, true, base::ThreadPriority::NORMAL},
{true, false, false, true, false, base::ThreadPriority::NORMAL},
{true, false, false, false, true, base::ThreadPriority::NORMAL},
{true, false, false, false, false, base::ThreadPriority::NORMAL},
// Top-level await does not affect the test result.
{false, true, true, true, true, base::ThreadPriority::REALTIME_AUDIO},
{false, true, true, true, false, base::ThreadPriority::REALTIME_AUDIO},
{false, true, true, false, true, base::ThreadPriority::NORMAL},
{false, true, true, 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
......@@ -371,13 +383,19 @@ class AudioWorkletThreadPriorityTest
AudioWorkletThreadPriorityTest()
: AudioWorkletThreadTestBase(GetParam().use_top_level_await) {}
void InitAndSetRealtimePriorityFlag(bool is_flag_enabled) {
if (is_flag_enabled) {
feature_list_.InitAndEnableFeature(features::kAudioWorkletRealtimeThread);
} else {
feature_list_.InitAndDisableFeature(
features::kAudioWorkletRealtimeThread);
}
void InitWithRealtimePrioritySettings(bool is_enabled_by_finch,
bool is_enabled_by_flag) {
std::vector<base::Feature> enabled;
std::vector<base::Feature> disabled;
if (is_enabled_by_finch)
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,
......@@ -434,7 +452,8 @@ class AudioWorkletThreadPriorityTest
TEST_P(AudioWorkletThreadPriorityTest, CheckThreadPriority) {
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,
test_param.is_top_level_frame,
test_param.expected_priority);
......
......@@ -4,6 +4,8 @@
#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/platform/instrumentation/tracing/trace_event.h"
......@@ -24,9 +26,15 @@ RealtimeAudioWorkletThread::RealtimeAudioWorkletThread(
ThreadCreationParams params =
ThreadCreationParams(ThreadType::kRealtimeAudioWorkletThread);
// TODO(crbug.com/1022888): The worklet thread priority is always NORMAL
// on OS_LINUX and OS_CHROMEOS regardless of the thread priority setting.
// Use a higher priority thread only when it is allowed by Finch.
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;
} else {
params.thread_priority = base::ThreadPriority::NORMAL;
}
if (++s_ref_count_ == 1)
EnsureSharedBackingThread(params);
......
......@@ -4,6 +4,8 @@
#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/platform/instrumentation/tracing/trace_event.h"
......@@ -24,9 +26,15 @@ SemiRealtimeAudioWorkletThread::SemiRealtimeAudioWorkletThread(
ThreadCreationParams params =
ThreadCreationParams(ThreadType::kSemiRealtimeAudioWorkletThread);
// TODO(crbug.com/1022888): The worklet thread priority is always NORMAL
// on OS_LINUX and OS_CHROMEOS regardless of this thread priority setting.
// Use a higher priority thread only when it is allowed by Finch.
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;
} else {
params.thread_priority = base::ThreadPriority::NORMAL;
}
if (++s_ref_count_ == 1)
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