未验证 提交 e7939e09 编写于 作者: K Kaushik Iska 提交者: GitHub

Pause dart microtasks while UI thread is processing frame workloads (#25789)

上级 351a601c
......@@ -325,7 +325,7 @@ std::unique_ptr<Shell> ShellTest::CreateShell(
std::make_unique<ShellTestVsyncWaiter>(task_runners, vsync_clock));
} else {
return static_cast<std::unique_ptr<VsyncWaiter>>(
std::make_unique<VsyncWaiterFallback>(task_runners));
std::make_unique<VsyncWaiterFallback>(task_runners, true));
}
};
......
......@@ -1335,6 +1335,7 @@ 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) {
......
......@@ -91,7 +91,8 @@ void VsyncWaiter::ScheduleSecondaryCallback(uintptr_t id,
}
void VsyncWaiter::FireCallback(fml::TimePoint frame_start_time,
fml::TimePoint frame_target_time) {
fml::TimePoint frame_target_time,
bool pause_secondary_tasks) {
Callback callback;
std::vector<fml::closure> secondary_callbacks;
......@@ -114,6 +115,9 @@ 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
......@@ -124,11 +128,15 @@ void VsyncWaiter::FireCallback(fml::TimePoint frame_start_time,
TRACE_FLOW_BEGIN("flutter", kVsyncFlowName, flow_identifier);
task_runners_.GetUITaskRunner()->PostTaskForTime(
[callback, flow_identifier, frame_start_time, frame_target_time]() {
[this, callback, flow_identifier, frame_start_time, frame_target_time,
pause_secondary_tasks]() {
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);
}
......@@ -139,4 +147,16 @@ 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
......@@ -49,13 +49,17 @@ class VsyncWaiter : public std::enable_shared_from_this<VsyncWaiter> {
virtual void AwaitVSync() = 0;
void FireCallback(fml::TimePoint frame_start_time,
fml::TimePoint frame_target_time);
fml::TimePoint frame_target_time,
bool pause_secondary_tasks = true);
private:
std::mutex callback_mutex_;
Callback callback_;
std::unordered_map<uintptr_t, fml::closure> secondary_callbacks_;
void PauseDartMicroTasks();
void ResumeDartMicroTasks();
FML_DISALLOW_COPY_AND_ASSIGN(VsyncWaiter);
};
......
......@@ -21,8 +21,11 @@ static fml::TimePoint SnapToNextTick(fml::TimePoint value,
} // namespace
VsyncWaiterFallback::VsyncWaiterFallback(TaskRunners task_runners)
: VsyncWaiter(std::move(task_runners)), phase_(fml::TimePoint::Now()) {}
VsyncWaiterFallback::VsyncWaiterFallback(TaskRunners task_runners,
bool for_testing)
: VsyncWaiter(std::move(task_runners)),
phase_(fml::TimePoint::Now()),
for_testing_(for_testing) {}
VsyncWaiterFallback::~VsyncWaiterFallback() = default;
......@@ -36,7 +39,7 @@ void VsyncWaiterFallback::AwaitVSync() {
auto next =
SnapToNextTick(fml::TimePoint::Now(), phase_, kSingleFrameInterval);
FireCallback(next, next + kSingleFrameInterval);
FireCallback(next, next + kSingleFrameInterval, !for_testing_);
}
} // namespace flutter
......@@ -15,12 +15,14 @@ namespace flutter {
/// A |VsyncWaiter| that will fire at 60 fps irrespective of the vsync.
class VsyncWaiterFallback final : public VsyncWaiter {
public:
VsyncWaiterFallback(TaskRunners task_runners);
explicit VsyncWaiterFallback(TaskRunners task_runners,
bool for_testing = false);
~VsyncWaiterFallback() override;
private:
fml::TimePoint phase_;
const bool for_testing_;
// |VsyncWaiter|
void AwaitVSync() override;
......
......@@ -23,7 +23,8 @@ VsyncWaiterIOS::VsyncWaiterIOS(flutter::TaskRunners task_runners)
callback:std::bind(&VsyncWaiterIOS::FireCallback,
this,
std::placeholders::_1,
std::placeholders::_2)]) {}
std::placeholders::_2,
true)]) {}
VsyncWaiterIOS::~VsyncWaiterIOS() {
// This way, we will get no more callbacks from the display link that holds a weak (non-nilling)
......
......@@ -197,7 +197,7 @@ void VsyncWaiter::FireCallbackNow() {
}
fml::TimePoint previous_vsync = next_vsync - vsync_info.presentation_interval;
FireCallback(previous_vsync, next_vsync);
FireCallback(previous_vsync, next_vsync, false);
}
} // namespace flutter_runner
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册