From ee29c854cf1644b7a64dd189694cdf2a22e8ea00 Mon Sep 17 00:00:00 2001 From: Kaushik Iska Date: Wed, 21 Apr 2021 07:23:38 -0700 Subject: [PATCH 1/2] Revert "Start microtasks only for non-tests" This reverts commit 20d6b1c0fa4073e373bc914716799851ceef5d30. --- shell/common/shell_test.cc | 2 +- shell/common/shell_unittests.cc | 1 - shell/common/vsync_waiter.cc | 24 ++----------------- shell/common/vsync_waiter.h | 6 +---- shell/common/vsync_waiter_fallback.cc | 9 +++---- shell/common/vsync_waiter_fallback.h | 4 +--- .../ios/framework/Source/vsync_waiter_ios.mm | 3 +-- .../platform/fuchsia/flutter/vsync_waiter.cc | 2 +- 8 files changed, 10 insertions(+), 41 deletions(-) diff --git a/shell/common/shell_test.cc b/shell/common/shell_test.cc index 00c12f05ca3cf..e763696618b9b 100644 --- a/shell/common/shell_test.cc +++ b/shell/common/shell_test.cc @@ -325,7 +325,7 @@ std::unique_ptr ShellTest::CreateShell( std::make_unique(task_runners, vsync_clock)); } else { return static_cast>( - std::make_unique(task_runners, true)); + std::make_unique(task_runners)); } }; diff --git a/shell/common/shell_unittests.cc b/shell/common/shell_unittests.cc index d31c138fda7a4..5a2108544671b 100644 --- a/shell/common/shell_unittests.cc +++ b/shell/common/shell_unittests.cc @@ -1335,7 +1335,6 @@ TEST_F(ShellTest, ReportTimingsIsCalledImmediatelyAfterTheFirstFrame) { }; AddNativeCallback("NativeReportTimingsCallback", CREATE_NATIVE_ENTRY(nativeTimingCallback)); - ASSERT_TRUE(configuration.IsValid()); RunEngine(shell.get(), std::move(configuration)); for (int i = 0; i < 10; i += 1) { diff --git a/shell/common/vsync_waiter.cc b/shell/common/vsync_waiter.cc index 40ced727abcfe..886f6724db61c 100644 --- a/shell/common/vsync_waiter.cc +++ b/shell/common/vsync_waiter.cc @@ -91,8 +91,7 @@ void VsyncWaiter::ScheduleSecondaryCallback(uintptr_t id, } void VsyncWaiter::FireCallback(fml::TimePoint frame_start_time, - fml::TimePoint frame_target_time, - bool pause_secondary_tasks) { + fml::TimePoint frame_target_time) { Callback callback; std::vector secondary_callbacks; @@ -115,9 +114,6 @@ void VsyncWaiter::FireCallback(fml::TimePoint frame_start_time, if (callback) { auto flow_identifier = fml::tracing::TraceNonce(); - if (pause_secondary_tasks) { - PauseDartMicroTasks(); - } // The base trace ensures that flows have a root to begin from if one does // not exist. The trace viewer will ignore traces that have no base event @@ -128,15 +124,11 @@ void VsyncWaiter::FireCallback(fml::TimePoint frame_start_time, TRACE_FLOW_BEGIN("flutter", kVsyncFlowName, flow_identifier); task_runners_.GetUITaskRunner()->PostTaskForTime( - [this, callback, flow_identifier, frame_start_time, frame_target_time, - pause_secondary_tasks]() { + [callback, flow_identifier, frame_start_time, frame_target_time]() { FML_TRACE_EVENT("flutter", kVsyncTraceName, "StartTime", frame_start_time, "TargetTime", frame_target_time); callback(frame_start_time, frame_target_time); TRACE_FLOW_END("flutter", kVsyncFlowName, flow_identifier); - if (pause_secondary_tasks) { - ResumeDartMicroTasks(); - } }, frame_start_time); } @@ -147,16 +139,4 @@ void VsyncWaiter::FireCallback(fml::TimePoint frame_start_time, } } -void VsyncWaiter::PauseDartMicroTasks() { - auto ui_task_queue_id = task_runners_.GetUITaskRunner()->GetTaskQueueId(); - auto task_queues = fml::MessageLoopTaskQueues::GetInstance(); - task_queues->PauseSecondarySource(ui_task_queue_id); -} - -void VsyncWaiter::ResumeDartMicroTasks() { - auto ui_task_queue_id = task_runners_.GetUITaskRunner()->GetTaskQueueId(); - auto task_queues = fml::MessageLoopTaskQueues::GetInstance(); - task_queues->ResumeSecondarySource(ui_task_queue_id); -} - } // namespace flutter diff --git a/shell/common/vsync_waiter.h b/shell/common/vsync_waiter.h index d593c7014b073..084399011df4b 100644 --- a/shell/common/vsync_waiter.h +++ b/shell/common/vsync_waiter.h @@ -49,17 +49,13 @@ class VsyncWaiter : public std::enable_shared_from_this { virtual void AwaitVSync() = 0; void FireCallback(fml::TimePoint frame_start_time, - fml::TimePoint frame_target_time, - bool pause_secondary_tasks = true); + fml::TimePoint frame_target_time); private: std::mutex callback_mutex_; Callback callback_; std::unordered_map secondary_callbacks_; - void PauseDartMicroTasks(); - void ResumeDartMicroTasks(); - FML_DISALLOW_COPY_AND_ASSIGN(VsyncWaiter); }; diff --git a/shell/common/vsync_waiter_fallback.cc b/shell/common/vsync_waiter_fallback.cc index 8bf51c5ce2f4e..514dc02fac5e6 100644 --- a/shell/common/vsync_waiter_fallback.cc +++ b/shell/common/vsync_waiter_fallback.cc @@ -21,11 +21,8 @@ static fml::TimePoint SnapToNextTick(fml::TimePoint value, } // namespace -VsyncWaiterFallback::VsyncWaiterFallback(TaskRunners task_runners, - bool for_testing) - : VsyncWaiter(std::move(task_runners)), - phase_(fml::TimePoint::Now()), - for_testing_(for_testing) {} +VsyncWaiterFallback::VsyncWaiterFallback(TaskRunners task_runners) + : VsyncWaiter(std::move(task_runners)), phase_(fml::TimePoint::Now()) {} VsyncWaiterFallback::~VsyncWaiterFallback() = default; @@ -39,7 +36,7 @@ void VsyncWaiterFallback::AwaitVSync() { auto next = SnapToNextTick(fml::TimePoint::Now(), phase_, kSingleFrameInterval); - FireCallback(next, next + kSingleFrameInterval, !for_testing_); + FireCallback(next, next + kSingleFrameInterval); } } // namespace flutter diff --git a/shell/common/vsync_waiter_fallback.h b/shell/common/vsync_waiter_fallback.h index b2ae63f72045b..5226dda019504 100644 --- a/shell/common/vsync_waiter_fallback.h +++ b/shell/common/vsync_waiter_fallback.h @@ -15,14 +15,12 @@ namespace flutter { /// A |VsyncWaiter| that will fire at 60 fps irrespective of the vsync. class VsyncWaiterFallback final : public VsyncWaiter { public: - explicit VsyncWaiterFallback(TaskRunners task_runners, - bool for_testing = false); + VsyncWaiterFallback(TaskRunners task_runners); ~VsyncWaiterFallback() override; private: fml::TimePoint phase_; - const bool for_testing_; // |VsyncWaiter| void AwaitVSync() override; diff --git a/shell/platform/darwin/ios/framework/Source/vsync_waiter_ios.mm b/shell/platform/darwin/ios/framework/Source/vsync_waiter_ios.mm index 37d9b23c0c7f9..d71ecd7d783df 100644 --- a/shell/platform/darwin/ios/framework/Source/vsync_waiter_ios.mm +++ b/shell/platform/darwin/ios/framework/Source/vsync_waiter_ios.mm @@ -23,8 +23,7 @@ callback:std::bind(&VsyncWaiterIOS::FireCallback, this, std::placeholders::_1, - std::placeholders::_2, - true)]) {} + std::placeholders::_2)]) {} VsyncWaiterIOS::~VsyncWaiterIOS() { // This way, we will get no more callbacks from the display link that holds a weak (non-nilling) diff --git a/shell/platform/fuchsia/flutter/vsync_waiter.cc b/shell/platform/fuchsia/flutter/vsync_waiter.cc index fd8f60122a0fa..5a8fe59be137d 100644 --- a/shell/platform/fuchsia/flutter/vsync_waiter.cc +++ b/shell/platform/fuchsia/flutter/vsync_waiter.cc @@ -197,7 +197,7 @@ void VsyncWaiter::FireCallbackNow() { } fml::TimePoint previous_vsync = next_vsync - vsync_info.presentation_interval; - FireCallback(previous_vsync, next_vsync, false); + FireCallback(previous_vsync, next_vsync); } } // namespace flutter_runner From c6680f8c2b6324f79056c9fe2b0670aecf7a449a Mon Sep 17 00:00:00 2001 From: Kaushik Iska Date: Wed, 21 Apr 2021 07:23:58 -0700 Subject: [PATCH 2/2] Revert "TaskSources register tasks with MessageLoopTaskQueues dispatcher (#25307)" This reverts commit f2f09b69691403d08fac3cb56e00bfc619a371af. --- ci/licenses_golden/licenses_flutter | 5 - fml/BUILD.gn | 4 - fml/delayed_task.cc | 16 +-- fml/delayed_task.h | 7 +- fml/message_loop_task_queues.cc | 124 +++++------------- fml/message_loop_task_queues.h | 33 ++--- fml/task_queue_id.h | 32 ----- fml/task_source.cc | 103 --------------- fml/task_source.h | 85 ------------ fml/task_source_grade.h | 28 ---- fml/task_source_unittests.cc | 100 -------------- runtime/dart_isolate.cc | 15 +-- shell/common/vsync_waiter.cc | 1 - .../embedder/tests/embedder_unittests_gl.cc | 52 -------- 14 files changed, 61 insertions(+), 544 deletions(-) delete mode 100644 fml/task_queue_id.h delete mode 100644 fml/task_source.cc delete mode 100644 fml/task_source.h delete mode 100644 fml/task_source_grade.h delete mode 100644 fml/task_source_unittests.cc diff --git a/ci/licenses_golden/licenses_flutter b/ci/licenses_golden/licenses_flutter index d6d82f05202d0..f9602772b8ff4 100755 --- a/ci/licenses_golden/licenses_flutter +++ b/ci/licenses_golden/licenses_flutter @@ -269,13 +269,8 @@ FILE: ../../../flutter/fml/synchronization/sync_switch_unittest.cc FILE: ../../../flutter/fml/synchronization/waitable_event.cc FILE: ../../../flutter/fml/synchronization/waitable_event.h FILE: ../../../flutter/fml/synchronization/waitable_event_unittest.cc -FILE: ../../../flutter/fml/task_queue_id.h FILE: ../../../flutter/fml/task_runner.cc FILE: ../../../flutter/fml/task_runner.h -FILE: ../../../flutter/fml/task_source.cc -FILE: ../../../flutter/fml/task_source.h -FILE: ../../../flutter/fml/task_source_grade.h -FILE: ../../../flutter/fml/task_source_unittests.cc FILE: ../../../flutter/fml/thread.cc FILE: ../../../flutter/fml/thread.h FILE: ../../../flutter/fml/thread_local.cc diff --git a/fml/BUILD.gn b/fml/BUILD.gn index 3a720fae2f9fb..9eaccd086207a 100644 --- a/fml/BUILD.gn +++ b/fml/BUILD.gn @@ -70,11 +70,8 @@ source_set("fml") { "synchronization/sync_switch.h", "synchronization/waitable_event.cc", "synchronization/waitable_event.h", - "task_queue_id.h", "task_runner.cc", "task_runner.h", - "task_source.cc", - "task_source.h", "thread.cc", "thread.h", "thread_local.cc", @@ -264,7 +261,6 @@ if (enable_unittests) { "synchronization/semaphore_unittest.cc", "synchronization/sync_switch_unittest.cc", "synchronization/waitable_event_unittest.cc", - "task_source_unittests.cc", "thread_local_unittests.cc", "thread_unittests.cc", "time/time_delta_unittest.cc", diff --git a/fml/delayed_task.cc b/fml/delayed_task.cc index bb72daa7cb78e..997176d7694e0 100644 --- a/fml/delayed_task.cc +++ b/fml/delayed_task.cc @@ -10,17 +10,13 @@ namespace fml { DelayedTask::DelayedTask(size_t order, const fml::closure& task, - fml::TimePoint target_time, - fml::TaskSourceGrade task_source_grade) - : order_(order), - task_(task), - target_time_(target_time), - task_source_grade_(task_source_grade) {} - -DelayedTask::~DelayedTask() = default; + fml::TimePoint target_time) + : order_(order), task_(task), target_time_(target_time) {} DelayedTask::DelayedTask(const DelayedTask& other) = default; +DelayedTask::~DelayedTask() = default; + const fml::closure& DelayedTask::GetTask() const { return task_; } @@ -29,10 +25,6 @@ fml::TimePoint DelayedTask::GetTargetTime() const { return target_time_; } -fml::TaskSourceGrade DelayedTask::GetTaskSourceGrade() const { - return task_source_grade_; -} - bool DelayedTask::operator>(const DelayedTask& other) const { if (target_time_ == other.target_time_) { return order_ > other.order_; diff --git a/fml/delayed_task.h b/fml/delayed_task.h index 6552a68652918..ba6fc8cfe4c9d 100644 --- a/fml/delayed_task.h +++ b/fml/delayed_task.h @@ -8,7 +8,6 @@ #include #include "flutter/fml/closure.h" -#include "flutter/fml/task_source_grade.h" #include "flutter/fml/time/time_point.h" namespace fml { @@ -17,8 +16,7 @@ class DelayedTask { public: DelayedTask(size_t order, const fml::closure& task, - fml::TimePoint target_time, - fml::TaskSourceGrade task_source_grade); + fml::TimePoint target_time); DelayedTask(const DelayedTask& other); @@ -28,15 +26,12 @@ class DelayedTask { fml::TimePoint GetTargetTime() const; - fml::TaskSourceGrade GetTaskSourceGrade() const; - bool operator>(const DelayedTask& other) const; private: size_t order_; fml::closure task_; fml::TimePoint target_time_; - fml::TaskSourceGrade task_source_grade_; }; using DelayedTaskQueue = std::priority_queue -#include #include "flutter/fml/make_copyable.h" #include "flutter/fml/message_loop_impl.h" -#include "flutter/fml/task_source.h" -#include "flutter/fml/thread_local.h" namespace fml { @@ -20,41 +17,19 @@ std::mutex MessageLoopTaskQueues::creation_mutex_; const size_t TaskQueueId::kUnmerged = ULONG_MAX; -// Guarded by creation_mutex_. fml::RefPtr MessageLoopTaskQueues::instance_; -namespace { - -// iOS prior to version 9 prevents c++11 thread_local and __thread specefier, -// having us resort to boxed enum containers. -class TaskSourceGradeHolder { - public: - TaskSourceGrade task_source_grade; - - explicit TaskSourceGradeHolder(TaskSourceGrade task_source_grade_arg) - : task_source_grade(task_source_grade_arg) {} -}; -} // namespace - -// Guarded by creation_mutex_. -FML_THREAD_LOCAL ThreadLocalUniquePtr - tls_task_source_grade; - -TaskQueueEntry::TaskQueueEntry(TaskQueueId created_for_arg) - : owner_of(_kUnmerged), - subsumed_by(_kUnmerged), - created_for(created_for_arg) { +TaskQueueEntry::TaskQueueEntry() + : owner_of(_kUnmerged), subsumed_by(_kUnmerged) { wakeable = NULL; task_observers = TaskObservers(); - task_source = std::make_unique(created_for); + delayed_tasks = DelayedTaskQueue(); } fml::RefPtr MessageLoopTaskQueues::GetInstance() { std::scoped_lock creation(creation_mutex_); if (!instance_) { instance_ = fml::MakeRefCounted(); - tls_task_source_grade.reset( - new TaskSourceGradeHolder{TaskSourceGrade::kUnspecified}); } return instance_; } @@ -63,7 +38,7 @@ TaskQueueId MessageLoopTaskQueues::CreateTaskQueue() { std::lock_guard guard(queue_mutex_); TaskQueueId loop_id = TaskQueueId(task_queue_id_counter_); ++task_queue_id_counter_; - queue_entries_[loop_id] = std::make_unique(loop_id); + queue_entries_[loop_id] = std::make_unique(); return loop_id; } @@ -88,36 +63,24 @@ void MessageLoopTaskQueues::DisposeTasks(TaskQueueId queue_id) { const auto& queue_entry = queue_entries_.at(queue_id); FML_DCHECK(queue_entry->subsumed_by == _kUnmerged); TaskQueueId subsumed = queue_entry->owner_of; - queue_entry->task_source->ShutDown(); + queue_entry->delayed_tasks = {}; if (subsumed != _kUnmerged) { - queue_entries_.at(subsumed)->task_source->ShutDown(); + queue_entries_.at(subsumed)->delayed_tasks = {}; } } -TaskSourceGrade MessageLoopTaskQueues::GetCurrentTaskSourceGrade() { - std::scoped_lock creation(creation_mutex_); - return tls_task_source_grade.get()->task_source_grade; -} - -void MessageLoopTaskQueues::RegisterTask( - TaskQueueId queue_id, - const fml::closure& task, - fml::TimePoint target_time, - fml::TaskSourceGrade task_source_grade) { +void MessageLoopTaskQueues::RegisterTask(TaskQueueId queue_id, + const fml::closure& task, + fml::TimePoint target_time) { std::lock_guard guard(queue_mutex_); size_t order = order_++; const auto& queue_entry = queue_entries_.at(queue_id); - queue_entry->task_source->RegisterTask( - {order, task, target_time, task_source_grade}); + queue_entry->delayed_tasks.push({order, task, target_time}); TaskQueueId loop_to_wake = queue_id; if (queue_entry->subsumed_by != _kUnmerged) { loop_to_wake = queue_entry->subsumed_by; } - - // This can happen when the secondary tasks are paused. - if (HasPendingTasksUnlocked(loop_to_wake)) { - WakeUpUnlocked(loop_to_wake, GetNextWakeTimeUnlocked(loop_to_wake)); - } + WakeUpUnlocked(loop_to_wake, GetNextWakeTimeUnlocked(loop_to_wake)); } bool MessageLoopTaskQueues::HasPendingTasks(TaskQueueId queue_id) const { @@ -131,7 +94,8 @@ fml::closure MessageLoopTaskQueues::GetNextTaskToRun(TaskQueueId queue_id, if (!HasPendingTasksUnlocked(queue_id)) { return nullptr; } - TaskSource::TopTask top = PeekNextTaskUnlocked(queue_id); + TaskQueueId top_queue = _kUnmerged; + const auto& top = PeekNextTaskUnlocked(queue_id, top_queue); if (!HasPendingTasksUnlocked(queue_id)) { WakeUpUnlocked(queue_id, fml::TimePoint::Max()); @@ -139,17 +103,11 @@ fml::closure MessageLoopTaskQueues::GetNextTaskToRun(TaskQueueId queue_id, WakeUpUnlocked(queue_id, GetNextWakeTimeUnlocked(queue_id)); } - if (top.task.GetTargetTime() > from_time) { + if (top.GetTargetTime() > from_time) { return nullptr; } - fml::closure invocation = top.task.GetTask(); - queue_entries_.at(top.task_queue_id) - ->task_source->PopTask(top.task.GetTaskSourceGrade()); - { - std::scoped_lock creation(creation_mutex_); - const auto task_source_grade = top.task.GetTaskSourceGrade(); - tls_task_source_grade.reset(new TaskSourceGradeHolder{task_source_grade}); - } + fml::closure invocation = top.GetTask(); + queue_entries_.at(top_queue)->delayed_tasks.pop(); return invocation; } @@ -168,12 +126,12 @@ size_t MessageLoopTaskQueues::GetNumPendingTasks(TaskQueueId queue_id) const { } size_t total_tasks = 0; - total_tasks += queue_entry->task_source->GetNumPendingTasks(); + total_tasks += queue_entry->delayed_tasks.size(); TaskQueueId subsumed = queue_entry->owner_of; if (subsumed != _kUnmerged) { const auto& subsumed_entry = queue_entries_.at(subsumed); - total_tasks += subsumed_entry->task_source->GetNumPendingTasks(); + total_tasks += subsumed_entry->delayed_tasks.size(); } return total_tasks; } @@ -290,20 +248,6 @@ TaskQueueId MessageLoopTaskQueues::GetSubsumedTaskQueueId( return queue_entries_.at(owner)->owner_of; } -void MessageLoopTaskQueues::PauseSecondarySource(TaskQueueId queue_id) { - std::lock_guard guard(queue_mutex_); - queue_entries_.at(queue_id)->task_source->PauseSecondary(); -} - -void MessageLoopTaskQueues::ResumeSecondarySource(TaskQueueId queue_id) { - std::lock_guard guard(queue_mutex_); - queue_entries_.at(queue_id)->task_source->ResumeSecondary(); - // Schedule a wake as needed. - if (HasPendingTasksUnlocked(queue_id)) { - WakeUpUnlocked(queue_id, GetNextWakeTimeUnlocked(queue_id)); - } -} - // Subsumed queues will never have pending tasks. // Owning queues will consider both their and their subsumed tasks. bool MessageLoopTaskQueues::HasPendingTasksUnlocked( @@ -314,7 +258,7 @@ bool MessageLoopTaskQueues::HasPendingTasksUnlocked( return false; } - if (!entry->task_source->IsEmpty()) { + if (!entry->delayed_tasks.empty()) { return true; } @@ -323,35 +267,37 @@ bool MessageLoopTaskQueues::HasPendingTasksUnlocked( // this is not an owner and queue is empty. return false; } else { - return !queue_entries_.at(subsumed)->task_source->IsEmpty(); + return !queue_entries_.at(subsumed)->delayed_tasks.empty(); } } fml::TimePoint MessageLoopTaskQueues::GetNextWakeTimeUnlocked( TaskQueueId queue_id) const { - return PeekNextTaskUnlocked(queue_id).task.GetTargetTime(); + TaskQueueId tmp = _kUnmerged; + return PeekNextTaskUnlocked(queue_id, tmp).GetTargetTime(); } -TaskSource::TopTask MessageLoopTaskQueues::PeekNextTaskUnlocked( - TaskQueueId owner) const { +const DelayedTask& MessageLoopTaskQueues::PeekNextTaskUnlocked( + TaskQueueId owner, + TaskQueueId& top_queue_id) const { FML_DCHECK(HasPendingTasksUnlocked(owner)); const auto& entry = queue_entries_.at(owner); const TaskQueueId subsumed = entry->owner_of; if (subsumed == _kUnmerged) { - return entry->task_source->Top(); + top_queue_id = owner; + return entry->delayed_tasks.top(); } - TaskSource* owner_tasks = entry->task_source.get(); - TaskSource* subsumed_tasks = queue_entries_.at(subsumed)->task_source.get(); + const auto& owner_tasks = entry->delayed_tasks; + const auto& subsumed_tasks = queue_entries_.at(subsumed)->delayed_tasks; // we are owning another task queue - const bool subsumed_has_task = !subsumed_tasks->IsEmpty(); - const bool owner_has_task = !owner_tasks->IsEmpty(); - fml::TaskQueueId top_queue_id = owner; + const bool subsumed_has_task = !subsumed_tasks.empty(); + const bool owner_has_task = !owner_tasks.empty(); if (owner_has_task && subsumed_has_task) { - const auto owner_task = owner_tasks->Top(); - const auto subsumed_task = subsumed_tasks->Top(); - if (owner_task.task > subsumed_task.task) { + const auto owner_task = owner_tasks.top(); + const auto subsumed_task = subsumed_tasks.top(); + if (owner_task > subsumed_task) { top_queue_id = subsumed; } else { top_queue_id = owner; @@ -361,7 +307,7 @@ TaskSource::TopTask MessageLoopTaskQueues::PeekNextTaskUnlocked( } else { top_queue_id = subsumed; } - return queue_entries_.at(top_queue_id)->task_source->Top(); + return queue_entries_.at(top_queue_id)->delayed_tasks.top(); } } // namespace fml diff --git a/fml/message_loop_task_queues.h b/fml/message_loop_task_queues.h index 3d7f2bcb87227..a555faf60e699 100644 --- a/fml/message_loop_task_queues.h +++ b/fml/message_loop_task_queues.h @@ -14,12 +14,22 @@ #include "flutter/fml/macros.h" #include "flutter/fml/memory/ref_counted.h" #include "flutter/fml/synchronization/shared_mutex.h" -#include "flutter/fml/task_queue_id.h" -#include "flutter/fml/task_source.h" #include "flutter/fml/wakeable.h" namespace fml { +class TaskQueueId { + public: + static const size_t kUnmerged; + + explicit TaskQueueId(size_t value) : value_(value) {} + + operator int() const { return value_; } + + private: + size_t value_ = kUnmerged; +}; + static const TaskQueueId _kUnmerged = TaskQueueId(TaskQueueId::kUnmerged); // This is keyed by the |TaskQueueId| and contains all the queue @@ -29,7 +39,7 @@ class TaskQueueEntry { using TaskObservers = std::map; Wakeable* wakeable; TaskObservers task_observers; - std::unique_ptr task_source; + DelayedTaskQueue delayed_tasks; // Note: Both of these can be _kUnmerged, which indicates that // this queue has not been merged or subsumed. OR exactly one @@ -38,9 +48,7 @@ class TaskQueueEntry { TaskQueueId owner_of; TaskQueueId subsumed_by; - TaskQueueId created_for; - - explicit TaskQueueEntry(TaskQueueId created_for); + TaskQueueEntry(); private: FML_DISALLOW_COPY_ASSIGN_AND_MOVE(TaskQueueEntry); @@ -71,9 +79,7 @@ class MessageLoopTaskQueues void RegisterTask(TaskQueueId queue_id, const fml::closure& task, - fml::TimePoint target_time, - fml::TaskSourceGrade task_source_grade = - fml::TaskSourceGrade::kUnspecified); + fml::TimePoint target_time); bool HasPendingTasks(TaskQueueId queue_id) const; @@ -81,8 +87,6 @@ class MessageLoopTaskQueues size_t GetNumPendingTasks(TaskQueueId queue_id) const; - static TaskSourceGrade GetCurrentTaskSourceGrade(); - // Observers methods. void AddTaskObserver(TaskQueueId queue_id, @@ -122,10 +126,6 @@ class MessageLoopTaskQueues // otherwise. TaskQueueId GetSubsumedTaskQueueId(TaskQueueId owner) const; - void PauseSecondarySource(TaskQueueId queue_id); - - void ResumeSecondarySource(TaskQueueId queue_id); - private: class MergedQueuesRunner; @@ -137,7 +137,8 @@ class MessageLoopTaskQueues bool HasPendingTasksUnlocked(TaskQueueId queue_id) const; - TaskSource::TopTask PeekNextTaskUnlocked(TaskQueueId owner) const; + const DelayedTask& PeekNextTaskUnlocked(TaskQueueId owner, + TaskQueueId& top_queue_id) const; fml::TimePoint GetNextWakeTimeUnlocked(TaskQueueId queue_id) const; diff --git a/fml/task_queue_id.h b/fml/task_queue_id.h deleted file mode 100644 index 2395f9db92be6..0000000000000 --- a/fml/task_queue_id.h +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright 2013 The Flutter Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef FLUTTER_FML_TASK_QUEUE_ID_H_ -#define FLUTTER_FML_TASK_QUEUE_ID_H_ - -#include "flutter/fml/logging.h" - -namespace fml { - -/** - * `MessageLoopTaskQueues` task dispatcher's internal task queue identifier. - */ -class TaskQueueId { - public: - /// This constant indicates whether a task queue has been subsumed by a task - /// runner. - static const size_t kUnmerged; - - /// Intializes a task queue with the given value as it's ID. - explicit TaskQueueId(size_t value) : value_(value) {} - - operator size_t() const { return value_; } - - private: - size_t value_ = kUnmerged; -}; - -} // namespace fml - -#endif // FLUTTER_FML_TASK_QUEUE_ID_H_ diff --git a/fml/task_source.cc b/fml/task_source.cc deleted file mode 100644 index e62e1952e65a5..0000000000000 --- a/fml/task_source.cc +++ /dev/null @@ -1,103 +0,0 @@ -// Copyright 2013 The Flutter Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#define FML_USED_ON_EMBEDDER - -#include "flutter/fml/task_source.h" - -namespace fml { - -TaskSource::TaskSource(TaskQueueId task_queue_id) - : task_queue_id_(task_queue_id) {} - -TaskSource::~TaskSource() { - ShutDown(); -} - -void TaskSource::ShutDown() { - primary_task_queue_ = {}; - secondary_task_queue_ = {}; -} - -void TaskSource::RegisterTask(const DelayedTask& task) { - switch (task.GetTaskSourceGrade()) { - case TaskSourceGrade::kUserInteraction: - primary_task_queue_.push(task); - break; - case TaskSourceGrade::kUnspecified: - primary_task_queue_.push(task); - break; - case TaskSourceGrade::kDartMicroTasks: - secondary_task_queue_.push(task); - break; - } -} - -void TaskSource::PopTask(TaskSourceGrade grade) { - switch (grade) { - case TaskSourceGrade::kUserInteraction: - primary_task_queue_.pop(); - break; - case TaskSourceGrade::kUnspecified: - primary_task_queue_.pop(); - break; - case TaskSourceGrade::kDartMicroTasks: - secondary_task_queue_.pop(); - break; - } -} - -size_t TaskSource::GetNumPendingTasks() const { - size_t size = primary_task_queue_.size(); - if (secondary_pause_requests_ == 0) { - size += secondary_task_queue_.size(); - } - return size; -} - -bool TaskSource::IsEmpty() const { - return GetNumPendingTasks() == 0; -} - -TaskSource::TopTask TaskSource::Top() const { - FML_CHECK(!IsEmpty()); - if (secondary_pause_requests_ > 0 || secondary_task_queue_.empty()) { - const auto& primary_top = primary_task_queue_.top(); - return { - .task_queue_id = task_queue_id_, - .task = primary_top, - }; - } else if (primary_task_queue_.empty()) { - const auto& secondary_top = secondary_task_queue_.top(); - return { - .task_queue_id = task_queue_id_, - .task = secondary_top, - }; - } else { - const auto& primary_top = primary_task_queue_.top(); - const auto& secondary_top = secondary_task_queue_.top(); - if (primary_top > secondary_top) { - return { - .task_queue_id = task_queue_id_, - .task = secondary_top, - }; - } else { - return { - .task_queue_id = task_queue_id_, - .task = primary_top, - }; - } - } -} - -void TaskSource::PauseSecondary() { - secondary_pause_requests_++; -} - -void TaskSource::ResumeSecondary() { - secondary_pause_requests_--; - FML_DCHECK(secondary_pause_requests_ >= 0); -} - -} // namespace fml diff --git a/fml/task_source.h b/fml/task_source.h deleted file mode 100644 index 64e151d9482ec..0000000000000 --- a/fml/task_source.h +++ /dev/null @@ -1,85 +0,0 @@ -// Copyright 2013 The Flutter Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef FLUTTER_FML_TASK_SOURCE_H_ -#define FLUTTER_FML_TASK_SOURCE_H_ - -#include "flutter/fml/delayed_task.h" -#include "flutter/fml/task_queue_id.h" -#include "flutter/fml/task_source_grade.h" - -namespace fml { - -class MessageLoopTaskQueues; - -/** - * A Source of tasks for the `MessageLoopTaskQueues` task dispatcher. This is a - * wrapper around a primary and secondary task heap with the difference between - * them being that the secondary task heap can be paused and resumed by the task - * dispatcher. `TaskSourceGrade` determines what task heap the task is assigned - * to. - * - * Registering Tasks - * ----------------- - * The task dispatcher associates a task source with each `TaskQueueID`. When - * the user of the task dispatcher registers a task, the task is in-turn - * registered with the `TaskSource` corresponding to the `TaskQueueID`. - * - * Processing Tasks - * ---------------- - * Task dispatcher provides the event loop a way to acquire tasks to run via - * `GetNextTaskToRun`. Task dispatcher asks the underlying `TaskSource` for the - * next task. - */ -class TaskSource { - public: - struct TopTask { - TaskQueueId task_queue_id; - const DelayedTask& task; - }; - - /// Construts a TaskSource with the given `task_queue_id`. - explicit TaskSource(TaskQueueId task_queue_id); - - ~TaskSource(); - - /// Drops the pending tasks from both primary and secondary task heaps. - void ShutDown(); - - /// Adds a task to the corresponding task heap as dictated by the - /// `TaskSourceGrade` of the `DelayedTask`. - void RegisterTask(const DelayedTask& task); - - /// Pops the task heap corresponding to the `TaskSourceGrade`. - void PopTask(TaskSourceGrade grade); - - /// Returns the number of pending tasks. Excludes the tasks from the secondary - /// heap if it's paused. - size_t GetNumPendingTasks() const; - - /// Returns true if `GetNumPendingTasks` is zero. - bool IsEmpty() const; - - /// Returns the top task based on scheduled time, taking into account whether - /// the secondary heap has been paused or not. - TopTask Top() const; - - /// Pause providing tasks from secondary task heap. - void PauseSecondary(); - - /// Resume providing tasks from secondary task heap. - void ResumeSecondary(); - - private: - const fml::TaskQueueId task_queue_id_; - fml::DelayedTaskQueue primary_task_queue_; - fml::DelayedTaskQueue secondary_task_queue_; - int secondary_pause_requests_ = 0; - - FML_DISALLOW_COPY_ASSIGN_AND_MOVE(TaskSource); -}; - -} // namespace fml - -#endif // FLUTTER_FML_TASK_SOURCE_H_ diff --git a/fml/task_source_grade.h b/fml/task_source_grade.h deleted file mode 100644 index d7447f511f1e5..0000000000000 --- a/fml/task_source_grade.h +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright 2013 The Flutter Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef FLUTTER_FML_TASK_SOURCE_GRADE_H_ -#define FLUTTER_FML_TASK_SOURCE_GRADE_H_ - -namespace fml { - -/** - * Categories of work dispatched to `MessageLoopTaskQueues` dispatcher. By - * specifying the `TaskSourceGrade`, you indicate the task's importance to the - * dispatcher. - */ -enum class TaskSourceGrade { - /// This `TaskSourceGrade` indicates that a task is critical to user - /// interaction. - kUserInteraction, - /// This `TaskSourceGrade` indicates that a task corresponds to servicing a - /// dart micro task. These aren't critical to user interaction. - kDartMicroTasks, - /// The absence of a specialized `TaskSourceGrade`. - kUnspecified, -}; - -} // namespace fml - -#endif // FLUTTER_FML_TASK_SOURCE_GRADE_H_ diff --git a/fml/task_source_unittests.cc b/fml/task_source_unittests.cc deleted file mode 100644 index e44e9e3b87fd3..0000000000000 --- a/fml/task_source_unittests.cc +++ /dev/null @@ -1,100 +0,0 @@ -// Copyright 2013 The Flutter Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include -#include - -#include "flutter/fml/macros.h" -#include "flutter/fml/task_source.h" -#include "flutter/fml/time/time_delta.h" -#include "flutter/fml/time/time_point.h" -#include "gtest/gtest.h" - -namespace fml { -namespace testing { - -TEST(TaskSourceTests, SimpleInitialization) { - TaskSource task_source = TaskSource(TaskQueueId(1)); - task_source.RegisterTask( - {1, [] {}, fml::TimePoint::Now(), TaskSourceGrade::kUnspecified}); - ASSERT_EQ(task_source.GetNumPendingTasks(), 1u); -} - -TEST(TaskSourceTests, MultipleTaskGrades) { - TaskSource task_source = TaskSource(TaskQueueId(1)); - task_source.RegisterTask( - {1, [] {}, fml::TimePoint::Now(), TaskSourceGrade::kUnspecified}); - task_source.RegisterTask( - {2, [] {}, fml::TimePoint::Now(), TaskSourceGrade::kUserInteraction}); - task_source.RegisterTask( - {3, [] {}, fml::TimePoint::Now(), TaskSourceGrade::kDartMicroTasks}); - ASSERT_EQ(task_source.GetNumPendingTasks(), 3u); -} - -TEST(TaskSourceTests, SimpleOrdering) { - TaskSource task_source = TaskSource(TaskQueueId(1)); - auto time_stamp = fml::TimePoint::Now(); - int value = 0; - task_source.RegisterTask( - {1, [&] { value = 1; }, time_stamp, TaskSourceGrade::kUnspecified}); - task_source.RegisterTask({2, [&] { value = 7; }, - time_stamp + fml::TimeDelta::FromMilliseconds(1), - TaskSourceGrade::kUnspecified}); - task_source.Top().task.GetTask()(); - task_source.PopTask(TaskSourceGrade::kUnspecified); - ASSERT_EQ(value, 1); - task_source.Top().task.GetTask()(); - task_source.PopTask(TaskSourceGrade::kUnspecified); - ASSERT_EQ(value, 7); -} - -TEST(TaskSourceTests, SimpleOrderingMultiTaskHeaps) { - TaskSource task_source = TaskSource(TaskQueueId(1)); - auto time_stamp = fml::TimePoint::Now(); - int value = 0; - task_source.RegisterTask( - {1, [&] { value = 1; }, time_stamp, TaskSourceGrade::kDartMicroTasks}); - task_source.RegisterTask({2, [&] { value = 7; }, - time_stamp + fml::TimeDelta::FromMilliseconds(1), - TaskSourceGrade::kUserInteraction}); - auto top_task = task_source.Top(); - top_task.task.GetTask()(); - task_source.PopTask(top_task.task.GetTaskSourceGrade()); - ASSERT_EQ(value, 1); - - auto second_task = task_source.Top(); - second_task.task.GetTask()(); - task_source.PopTask(second_task.task.GetTaskSourceGrade()); - ASSERT_EQ(value, 7); -} - -TEST(TaskSourceTests, OrderingMultiTaskHeapsSecondaryPaused) { - TaskSource task_source = TaskSource(TaskQueueId(1)); - auto time_stamp = fml::TimePoint::Now(); - int value = 0; - task_source.RegisterTask( - {1, [&] { value = 1; }, time_stamp, TaskSourceGrade::kDartMicroTasks}); - task_source.RegisterTask({2, [&] { value = 7; }, - time_stamp + fml::TimeDelta::FromMilliseconds(1), - TaskSourceGrade::kUserInteraction}); - - task_source.PauseSecondary(); - - auto top_task = task_source.Top(); - top_task.task.GetTask()(); - task_source.PopTask(top_task.task.GetTaskSourceGrade()); - ASSERT_EQ(value, 7); - - ASSERT_TRUE(task_source.IsEmpty()); - - task_source.ResumeSecondary(); - - auto second_task = task_source.Top(); - second_task.task.GetTask()(); - task_source.PopTask(second_task.task.GetTaskSourceGrade()); - ASSERT_EQ(value, 1); -} - -} // namespace testing -} // namespace fml diff --git a/runtime/dart_isolate.cc b/runtime/dart_isolate.cc index 8371e3f225c88..1938f64532dd4 100644 --- a/runtime/dart_isolate.cc +++ b/runtime/dart_isolate.cc @@ -18,9 +18,6 @@ #include "flutter/runtime/dart_vm.h" #include "flutter/runtime/dart_vm_lifecycle.h" #include "flutter/runtime/isolate_configuration.h" -#include "fml/message_loop_task_queues.h" -#include "fml/task_source.h" -#include "fml/time/time_point.h" #include "third_party/dart/runtime/include/dart_api.h" #include "third_party/dart/runtime/include/dart_tools_api.h" #include "third_party/tonic/converter/dart_converter.h" @@ -458,14 +455,10 @@ void DartIsolate::SetMessageHandlingTaskRunner( message_handling_task_runner_ = runner; message_handler().Initialize([runner](std::function task) { - auto task_queues = fml::MessageLoopTaskQueues::GetInstance(); - task_queues->RegisterTask( - runner->GetTaskQueueId(), - [task = std::move(task)]() { - TRACE_EVENT0("flutter", "DartIsolate::HandleMessage"); - task(); - }, - fml::TimePoint::Now(), fml::TaskSourceGrade::kDartMicroTasks); + runner->PostTask([task = std::move(task)]() { + TRACE_EVENT0("flutter", "DartIsolate::HandleMessage"); + task(); + }); }); } diff --git a/shell/common/vsync_waiter.cc b/shell/common/vsync_waiter.cc index 886f6724db61c..f1cb89342874c 100644 --- a/shell/common/vsync_waiter.cc +++ b/shell/common/vsync_waiter.cc @@ -6,7 +6,6 @@ #include "flutter/fml/task_runner.h" #include "flutter/fml/trace_event.h" -#include "fml/message_loop_task_queues.h" namespace flutter { diff --git a/shell/platform/embedder/tests/embedder_unittests_gl.cc b/shell/platform/embedder/tests/embedder_unittests_gl.cc index 7a5f4750b16cb..b6744999753eb 100644 --- a/shell/platform/embedder/tests/embedder_unittests_gl.cc +++ b/shell/platform/embedder/tests/embedder_unittests_gl.cc @@ -14,11 +14,9 @@ #include "flutter/fml/make_copyable.h" #include "flutter/fml/mapping.h" #include "flutter/fml/message_loop.h" -#include "flutter/fml/message_loop_task_queues.h" #include "flutter/fml/paths.h" #include "flutter/fml/synchronization/count_down_latch.h" #include "flutter/fml/synchronization/waitable_event.h" -#include "flutter/fml/task_source.h" #include "flutter/fml/thread.h" #include "flutter/lib/ui/painting/image.h" #include "flutter/runtime/dart_vm.h" @@ -3445,55 +3443,5 @@ TEST_F(EmbedderTest, SnapshotRenderTargetScalesDownToDriverMax) { latch.Wait(); } -TEST_F(EmbedderTest, ObjectsPostedViaPortsServicedOnSecondaryTaskHeap) { - auto& context = GetEmbedderContext(EmbedderTestContextType::kOpenGLContext); - EmbedderConfigBuilder builder(context); - builder.SetOpenGLRendererConfig(SkISize::Make(800, 1024)); - builder.SetDartEntrypoint("objects_can_be_posted"); - - // Synchronously acquire the send port from the Dart end. We will be using - // this to send message. The Dart end will just echo those messages back to us - // for inspection. - FlutterEngineDartPort port = 0; - fml::AutoResetWaitableEvent event; - context.AddNativeCallback("SignalNativeCount", - CREATE_NATIVE_ENTRY([&](Dart_NativeArguments args) { - port = tonic::DartConverter::FromDart( - Dart_GetNativeArgument(args, 0)); - event.Signal(); - })); - auto engine = builder.LaunchEngine(); - ASSERT_TRUE(engine.is_valid()); - event.Wait(); - ASSERT_NE(port, 0); - - using Trampoline = std::function; - Trampoline trampoline; - - context.AddNativeCallback("SendObjectToNativeCode", - CREATE_NATIVE_ENTRY([&](Dart_NativeArguments args) { - FML_CHECK(trampoline); - auto trampoline_copy = trampoline; - trampoline = nullptr; - trampoline_copy(Dart_GetNativeArgument(args, 0)); - })); - - // Send a boolean value and assert that it's received by the right heap. - { - FlutterEngineDartObject object = {}; - object.type = kFlutterEngineDartObjectTypeBool; - object.bool_value = true; - trampoline = [&](Dart_Handle handle) { - ASSERT_TRUE(tonic::DartConverter::FromDart(handle)); - auto task_grade = fml::MessageLoopTaskQueues::GetCurrentTaskSourceGrade(); - EXPECT_EQ(task_grade, fml::TaskSourceGrade::kDartMicroTasks); - event.Signal(); - }; - ASSERT_EQ(FlutterEnginePostDartObject(engine.get(), port, &object), - kSuccess); - event.Wait(); - } -} - } // namespace testing } // namespace flutter