Commit 0755c943 authored by Alexander Timin's avatar Alexander Timin Committed by Commit Bot

[blink] Use per-frame task runner in AsyncMethodRunner

Posting async tasks to the default timer queue can lead to media tasks
being throttled, which may lead to videos being stopped in background.

R=haraken@chromium.org,hajimehoshi@chromium.org
BUG=779962, 786332

Change-Id: Ic50890f909ed824a9d8048d5ef5af590b3cd086b
Reviewed-on: https://chromium-review.googlesource.com/822931Reviewed-by: default avatarHajime Hoshi <hajimehoshi@chromium.org>
Reviewed-by: default avatarKentaro Hara <haraken@chromium.org>
Commit-Queue: Alexander Timin <altimin@chromium.org>
Cr-Commit-Position: refs/heads/master@{#524292}
parent 9ee1f839
......@@ -17,6 +17,7 @@
#include "platform/AsyncMethodRunner.h"
#include "platform/bindings/ScriptWrappable.h"
#include "platform/fonts/FontSelector.h"
#include "public/platform/TaskType.h"
// Mac OS X 10.6 SDK defines check() macro that interferes with our check()
// method
......@@ -44,9 +45,11 @@ class CORE_EXPORT FontFaceSet : public EventTargetWithInlineData,
ready_(new ReadyProperty(GetExecutionContext(),
this,
ReadyProperty::kReady)),
// TODO(scheduler-dev): Create an internal task type for fonts.
async_runner_(AsyncMethodRunner<FontFaceSet>::Create(
this,
&FontFaceSet::HandlePendingEventsAndPromises)) {}
&FontFaceSet::HandlePendingEventsAndPromises,
context.GetTaskRunner(TaskType::kUnthrottled))) {}
~FontFaceSet() = default;
DEFINE_ATTRIBUTE_EVENT_LISTENER(loading);
......
......@@ -33,6 +33,7 @@
#include "modules/gamepad/GamepadDispatcher.h"
#include "modules/gamepad/GamepadEvent.h"
#include "modules/gamepad/GamepadList.h"
#include "public/platform/TaskType.h"
namespace {
......@@ -173,8 +174,10 @@ void NavigatorGamepad::DispatchOneEvent() {
DomWindow()->DispatchEvent(
GamepadEvent::Create(event_name, false, true, gamepad));
if (!pending_events_.IsEmpty())
if (!pending_events_.IsEmpty()) {
DCHECK(dispatch_one_event_runner_);
dispatch_one_event_runner_->RunAsync();
}
}
NavigatorGamepad::NavigatorGamepad(Navigator& navigator)
......@@ -182,9 +185,13 @@ NavigatorGamepad::NavigatorGamepad(Navigator& navigator)
DOMWindowClient(navigator.DomWindow()),
PlatformEventController(
navigator.GetFrame() ? navigator.GetFrame()->GetDocument() : nullptr),
dispatch_one_event_runner_(AsyncMethodRunner<NavigatorGamepad>::Create(
this,
&NavigatorGamepad::DispatchOneEvent)) {
dispatch_one_event_runner_(
navigator.GetFrame() ? AsyncMethodRunner<NavigatorGamepad>::Create(
this,
&NavigatorGamepad::DispatchOneEvent,
navigator.GetFrame()->GetTaskRunner(
TaskType::kMiscPlatformAPI))
: nullptr) {
if (navigator.DomWindow())
navigator.DomWindow()->RegisterEventListenerObserver(this);
}
......@@ -197,11 +204,13 @@ const char* NavigatorGamepad::SupplementName() {
void NavigatorGamepad::RegisterWithDispatcher() {
GamepadDispatcher::Instance().AddController(this);
dispatch_one_event_runner_->Unpause();
if (dispatch_one_event_runner_)
dispatch_one_event_runner_->Unpause();
}
void NavigatorGamepad::UnregisterWithDispatcher() {
dispatch_one_event_runner_->Pause();
if (dispatch_one_event_runner_)
dispatch_one_event_runner_->Pause();
GamepadDispatcher::Instance().RemoveController(this);
}
......@@ -245,7 +254,8 @@ void NavigatorGamepad::DidRemoveAllEventListeners(LocalDOMWindow*) {
void NavigatorGamepad::DidRemoveGamepadEventListeners() {
has_event_listener_ = false;
dispatch_one_event_runner_->Stop();
if (dispatch_one_event_runner_)
dispatch_one_event_runner_->Stop();
pending_events_.clear();
StopUpdating();
}
......@@ -268,8 +278,10 @@ void NavigatorGamepad::SampleAndCheckConnectedGamepads() {
// recreate the buffer.
gamepads_ = GamepadList::Create();
}
if (!pending_events_.IsEmpty())
if (!pending_events_.IsEmpty()) {
DCHECK(dispatch_one_event_runner_);
dispatch_one_event_runner_->RunAsync();
}
}
SampleGamepads<Gamepad>(gamepads_.Get());
}
......
......@@ -17,6 +17,7 @@
#include "platform/wtf/PtrUtil.h"
#include "platform/wtf/Time.h"
#include "public/platform/Platform.h"
#include "public/platform/TaskType.h"
#include "public/platform/WebMediaStream.h"
namespace blink {
......@@ -168,9 +169,12 @@ MediaRecorder::MediaRecorder(ExecutionContext* context,
audio_bits_per_second_(0),
video_bits_per_second_(0),
state_(State::kInactive),
// MediaStream recording should use DOM manipulation task source.
// https://www.w3.org/TR/mediastream-recording/
dispatch_scheduled_event_runner_(AsyncMethodRunner<MediaRecorder>::Create(
this,
&MediaRecorder::DispatchScheduledEvent)) {
&MediaRecorder::DispatchScheduledEvent,
context->GetTaskRunner(TaskType::kDOMManipulation))) {
DCHECK(stream_->getTracks().size());
recorder_handler_ = Platform::Current()->CreateMediaRecorderHandler();
......
......@@ -54,6 +54,7 @@
#include "platform/instrumentation/tracing/TraceEvent.h"
#include "platform/runtime_enabled_features.h"
#include "platform/wtf/MathExtras.h"
#include "public/platform/TaskType.h"
#include "public/platform/WebSourceBuffer.h"
#ifndef BLINK_SBLOG
......@@ -129,12 +130,14 @@ SourceBuffer::SourceBuffer(std::unique_ptr<WebSourceBuffer> web_source_buffer,
pending_append_data_offset_(0),
append_buffer_async_part_runner_(AsyncMethodRunner<SourceBuffer>::Create(
this,
&SourceBuffer::AppendBufferAsyncPart)),
&SourceBuffer::AppendBufferAsyncPart,
GetExecutionContext()->GetTaskRunner(TaskType::kMediaElementEvent))),
pending_remove_start_(-1),
pending_remove_end_(-1),
remove_async_part_runner_(AsyncMethodRunner<SourceBuffer>::Create(
this,
&SourceBuffer::RemoveAsyncPart)) {
&SourceBuffer::RemoveAsyncPart,
GetExecutionContext()->GetTaskRunner(TaskType::kMediaElementEvent))) {
BLINK_SBLOG << __func__ << " this=" << this;
DCHECK(web_source_buffer_);
......
......@@ -20,6 +20,7 @@
#include "modules/mediastream/UserMediaRequest.h"
#include "platform/bindings/ScriptState.h"
#include "platform/wtf/Functional.h"
#include "public/platform/TaskType.h"
#include "services/service_manager/public/cpp/interface_provider.h"
using blink::mojom::blink::MediaDeviceType;
......@@ -69,9 +70,12 @@ MediaDevices::MediaDevices(ExecutionContext* context)
: PausableObject(context),
observing_(false),
stopped_(false),
dispatch_scheduled_event_runner_(AsyncMethodRunner<MediaDevices>::Create(
this,
&MediaDevices::DispatchScheduledEvent)) {}
dispatch_scheduled_event_runner_(
context ? AsyncMethodRunner<MediaDevices>::Create(
this,
&MediaDevices::DispatchScheduledEvent,
context->GetTaskRunner(TaskType::kMediaElementEvent))
: nullptr) {}
MediaDevices::~MediaDevices() {}
......@@ -191,15 +195,18 @@ void MediaDevices::ContextDestroyed(ExecutionContext*) {
}
void MediaDevices::Pause() {
DCHECK(dispatch_scheduled_event_runner_);
dispatch_scheduled_event_runner_->Pause();
}
void MediaDevices::Unpause() {
DCHECK(dispatch_scheduled_event_runner_);
dispatch_scheduled_event_runner_->Unpause();
}
void MediaDevices::ScheduleDispatchEvent(Event* event) {
scheduled_events_.push_back(event);
DCHECK(dispatch_scheduled_event_runner_);
dispatch_scheduled_event_runner_->RunAsync();
}
......
......@@ -100,6 +100,8 @@ class MODULES_EXPORT MediaDevices final
bool observing_;
bool stopped_;
// Async runner may be null when there is no valid execution context.
// No async work may be posted in this scenario.
Member<AsyncMethodRunner<MediaDevices>> dispatch_scheduled_event_runner_;
HeapVector<Member<Event>> scheduled_events_;
mojom::blink::MediaDevicesDispatcherHostPtr dispatcher_host_;
......
......@@ -164,8 +164,9 @@ void Notification::SchedulePrepareShow() {
DCHECK_EQ(state_, State::kLoading);
DCHECK(!prepare_show_method_runner_);
prepare_show_method_runner_ =
AsyncMethodRunner<Notification>::Create(this, &Notification::PrepareShow);
prepare_show_method_runner_ = AsyncMethodRunner<Notification>::Create(
this, &Notification::PrepareShow,
GetExecutionContext()->GetTaskRunner(TaskType::kMiscPlatformAPI));
prepare_show_method_runner_->RunAsync();
}
......
......@@ -91,6 +91,7 @@
#include "platform/wtf/PtrUtil.h"
#include "platform/wtf/Time.h"
#include "public/platform/Platform.h"
#include "public/platform/TaskType.h"
#include "public/platform/WebCryptoAlgorithmParams.h"
#include "public/platform/WebMediaStream.h"
#include "public/platform/WebRTCAnswerOptions.h"
......@@ -492,10 +493,13 @@ RTCPeerConnection::RTCPeerConnection(ExecutionContext* context,
signaling_state_(kSignalingStateStable),
ice_gathering_state_(kICEGatheringStateNew),
ice_connection_state_(kICEConnectionStateNew),
// WebRTC spec specifies kNetworking as task source.
// https://www.w3.org/TR/webrtc/#operation
dispatch_scheduled_event_runner_(
AsyncMethodRunner<RTCPeerConnection>::Create(
this,
&RTCPeerConnection::DispatchScheduledEvent)),
&RTCPeerConnection::DispatchScheduledEvent,
context->GetTaskRunner(TaskType::kNetworking))),
stopped_(false),
closed_(false),
has_data_channels_(false) {
......
......@@ -45,8 +45,10 @@ class AsyncMethodRunner final
public:
typedef void (TargetClass::*TargetMethod)();
static AsyncMethodRunner* Create(TargetClass* object, TargetMethod method) {
return new AsyncMethodRunner(object, method);
static AsyncMethodRunner* Create(TargetClass* object,
TargetMethod method,
scoped_refptr<WebTaskRunner> task_runner) {
return new AsyncMethodRunner(object, method, std::move(task_runner));
}
~AsyncMethodRunner() {}
......@@ -112,8 +114,12 @@ class AsyncMethodRunner final
void Trace(blink::Visitor* visitor) { visitor->Trace(object_); }
private:
AsyncMethodRunner(TargetClass* object, TargetMethod method)
: timer_(this, &AsyncMethodRunner<TargetClass>::Fired),
AsyncMethodRunner(TargetClass* object,
TargetMethod method,
scoped_refptr<WebTaskRunner> task_runner)
: timer_(std::move(task_runner),
this,
&AsyncMethodRunner<TargetClass>::Fired),
object_(object),
method_(method),
paused_(false),
......@@ -121,7 +127,7 @@ class AsyncMethodRunner final
void Fired(TimerBase*) { (object_->*method_)(); }
Timer<AsyncMethodRunner<TargetClass>> timer_;
TaskRunnerTimer<AsyncMethodRunner<TargetClass>> timer_;
Member<TargetClass> object_;
TargetMethod method_;
......
......@@ -46,7 +46,6 @@ TimerBase::TimerBase(scoped_refptr<WebTaskRunner> web_task_runner)
thread_(CurrentThread()),
#endif
weak_ptr_factory_(this) {
DCHECK(web_task_runner_);
}
TimerBase::~TimerBase() {
......
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