#include "flutter/shell/common/vsync_waiter.h"
#include "flutter/fml/task_runner.h"
#include "flutter/fml/trace_event.h"
namespace flutter {
#if defined(OS_FUCHSIA)
static constexpr const char* kVsyncTraceName = "vsync callback";
#else
static constexpr const char* kVsyncTraceName = "VSYNC";
#endif
static constexpr const char* kVsyncFlowName = "VsyncFlow";
VsyncWaiter::VsyncWaiter(TaskRunners task_runners)
: task_runners_(std::move(task_runners)) {}
VsyncWaiter::~VsyncWaiter() = default;
void VsyncWaiter::AsyncWaitForVsync(Callback callback) {
if (!callback) {
return;
}
TRACE_EVENT0("flutter", "AsyncWaitForVsync");
{
std::scoped_lock lock(callback_mutex_);
if (callback_) {
TRACE_EVENT_INSTANT0("flutter", "MultipleCallsToVsyncInFrameInterval");
return;
}
callback_ = std::move(callback);
}
AwaitVSync();
}
void VsyncWaiter::FireCallback(fml::TimePoint frame_start_time,
fml::TimePoint frame_target_time) {
Callback callback;
{
std::scoped_lock lock(callback_mutex_);
callback = std::move(callback_);
}
if (!callback) {
TRACE_EVENT_INSTANT0("flutter", "MismatchedFrameCallback");
return;
}
auto flow_identifier = fml::tracing::TraceNonce();
TRACE_EVENT0("flutter", "VsyncFireCallback");
TRACE_FLOW_BEGIN("flutter", kVsyncFlowName, flow_identifier);
task_runners_.GetUITaskRunner()->PostTaskForTime(
[callback, flow_identifier, frame_start_time, frame_target_time]() {
FML_TRACE_EVENT("flutter", kVsyncTraceName, "StartTime",
frame_start_time, "TargetTime", frame_target_time);
fml::tracing::TraceEventAsyncComplete(
"flutter", "VsyncSchedulingOverhead", fml::TimePoint::Now(),
frame_start_time);
callback(frame_start_time, frame_target_time);
TRACE_FLOW_END("flutter", kVsyncFlowName, flow_identifier);
},
frame_start_time);
}
float VsyncWaiter::GetDisplayRefreshRate() const {
return kUnknownRefreshRateFPS;
}
}