| // 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 "flutter/shell/common/vsync_waiter_fallback.h" |
| |
| #include <memory> |
| |
| #include "flutter/fml/logging.h" |
| #include "flutter/fml/message_loop.h" |
| #include "flutter/fml/trace_event.h" |
| |
| namespace flutter { |
| namespace { |
| |
| static fml::TimePoint SnapToNextTick(fml::TimePoint value, |
| fml::TimePoint tick_phase, |
| fml::TimeDelta tick_interval) { |
| fml::TimeDelta offset = (tick_phase - value) % tick_interval; |
| if (offset != fml::TimeDelta::Zero()) { |
| offset = offset + tick_interval; |
| } |
| return value + offset; |
| } |
| |
| } // namespace |
| |
| VsyncWaiterFallback::VsyncWaiterFallback(const TaskRunners& task_runners, |
| bool for_testing) |
| : VsyncWaiter(task_runners), |
| phase_(fml::TimePoint::Now()), |
| for_testing_(for_testing) {} |
| |
| VsyncWaiterFallback::~VsyncWaiterFallback() = default; |
| |
| // |VsyncWaiter| |
| void VsyncWaiterFallback::AwaitVSync() { |
| TRACE_EVENT0("flutter", "VSYNC"); |
| |
| constexpr fml::TimeDelta kSingleFrameInterval = |
| fml::TimeDelta::FromSecondsF(1.0 / 60.0); |
| auto frame_start_time = |
| SnapToNextTick(fml::TimePoint::Now(), phase_, kSingleFrameInterval); |
| auto frame_target_time = frame_start_time + kSingleFrameInterval; |
| std::weak_ptr<VsyncWaiterFallback> weak_this = |
| std::static_pointer_cast<VsyncWaiterFallback>(shared_from_this()); |
| |
| task_runners_.GetUITaskRunner()->PostTaskForTime( |
| [frame_start_time, frame_target_time, weak_this]() { |
| if (auto vsync_waiter = weak_this.lock()) { |
| vsync_waiter->FireCallback(frame_start_time, frame_target_time, |
| !vsync_waiter->for_testing_); |
| } |
| }, |
| frame_start_time); |
| } |
| |
| } // namespace flutter |