Avoid generating VSYNC trace events from Flutter common code. (flutter/engine#16248)

Chrome Trace viewer treats events labeled "VSYNC" as special and highlights them (when the "Highlight Vsync" checkbox is enabled). Ideally VSYNC events are generated by the host system at their source. System VSYNC events are indeed present in full-system systraces. Flutter-level traces (as seen in Observatory/Flutter devtools) do not contain the system VSYNC events, so we rely on the engine to generate them (as close to where they would be generated by the system ideally).

Currently the common (platform-independent code) generates VSYNC events at the time when the UI thread starts processing a frame. This has two drawbacks:
1. The traces are generated with a delay (we wait for the callback to be have been scheduled on the UI thread instead of tracing as soon as the system notified us.
2. When inspecting system-wide traces we'll have both the system and the Flutter app (or potentially multiple Flutter apps) generate VSYNC events at the same time. This confuses both the developers and the trace viewer.

This change moves the VSYNC event generation to the platform-specific embedder implementations:
1. On Android/iOS we always generate the VSYNC event since Android/iOS developers use Flutter tools to debug the apps.
2. On Fuchsia we do not generate VSYNC events since the systraces always contain them.
3. In the Embedder wrapper we don not generate VSYNC events and rely on the actual embedder to do this in a way appropriate for the target system.
This commit is contained in:
Kirill Nikolaev
2020-03-05 16:59:43 +01:00
committed by GitHub
parent 041ef5f142
commit 810209faf5
3 changed files with 5 additions and 13 deletions

View File

@@ -9,18 +9,6 @@
namespace flutter {
#if defined(OS_FUCHSIA)
// In general, traces on Fuchsia are recorded across the whole system.
// Because of this, emitting a "VSYNC" event per flutter process is
// undesirable, as the events will collide with each other. We
// instead let another area of the system emit them.
static constexpr const char* kVsyncTraceName = "vsync callback";
#else // defined(OS_FUCHSIA)
// Note: The tag name must be "VSYNC" (it is special) so that the
// "Highlight Vsync" checkbox in the timeline can be enabled.
static constexpr const char* kVsyncTraceName = "VSYNC";
#endif // defined(OS_FUCHSIA)
static constexpr const char* kVsyncFlowName = "VsyncFlow";
VsyncWaiter::VsyncWaiter(TaskRunners task_runners)
@@ -114,7 +102,7 @@ void VsyncWaiter::FireCallback(fml::TimePoint frame_start_time,
task_runners_.GetUITaskRunner()->PostTaskForTime(
[callback, flow_identifier, frame_start_time, frame_target_time]() {
FML_TRACE_EVENT("flutter", kVsyncTraceName, "StartTime",
FML_TRACE_EVENT("flutter", "VsyncProcessCallback", "StartTime",
frame_start_time, "TargetTime", frame_target_time);
fml::tracing::TraceEventAsyncComplete(
"flutter", "VsyncSchedulingOverhead", fml::TimePoint::Now(),

View File

@@ -57,6 +57,8 @@ void VsyncWaiterAndroid::OnNativeVsync(JNIEnv* env,
jlong frameTimeNanos,
jlong frameTargetTimeNanos,
jlong java_baton) {
TRACE_EVENT0("flutter", "VSYNC");
auto frame_time = fml::TimePoint::FromEpochDelta(
fml::TimeDelta::FromNanoseconds(frameTimeNanos));
auto target_time = fml::TimePoint::FromEpochDelta(

View File

@@ -114,6 +114,8 @@ float VsyncWaiterIOS::GetDisplayRefreshRate() const {
}
- (void)onDisplayLink:(CADisplayLink*)link {
TRACE_EVENT0("flutter", "VSYNC");
CFTimeInterval delay = CACurrentMediaTime() - link.timestamp;
fml::TimePoint frame_start_time = fml::TimePoint::Now() - fml::TimeDelta::FromSecondsF(delay);
fml::TimePoint frame_target_time = frame_start_time + fml::TimeDelta::FromSecondsF(link.duration);