Add a proto for frametimeline events
This change adds a new proto for the upcoming frametimeline events that
will be emitted from SurfaceFlinger's FrameTimeline module. This is
useful in tracking the expected vs actual timeline for app frames.
Bug: 170914689
Test: None yet - just a proto file
Change-Id: I8de245e2063ef87900951401df31807780fd0f5a
diff --git a/Android.bp b/Android.bp
index 226c350..6e55ff5 100644
--- a/Android.bp
+++ b/Android.bp
@@ -3321,6 +3321,7 @@
name: "perfetto_protos_perfetto_trace_android_cpp_gen",
srcs: [
"protos/perfetto/trace/android/android_log.proto",
+ "protos/perfetto/trace/android/frame_timeline_event.proto",
"protos/perfetto/trace/android/gpu_mem_event.proto",
"protos/perfetto/trace/android/graphics_frame_event.proto",
"protos/perfetto/trace/android/initial_display_state.proto",
@@ -3333,6 +3334,7 @@
cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
out: [
"external/perfetto/protos/perfetto/trace/android/android_log.gen.cc",
+ "external/perfetto/protos/perfetto/trace/android/frame_timeline_event.gen.cc",
"external/perfetto/protos/perfetto/trace/android/gpu_mem_event.gen.cc",
"external/perfetto/protos/perfetto/trace/android/graphics_frame_event.gen.cc",
"external/perfetto/protos/perfetto/trace/android/initial_display_state.gen.cc",
@@ -3345,6 +3347,7 @@
name: "perfetto_protos_perfetto_trace_android_cpp_gen_headers",
srcs: [
"protos/perfetto/trace/android/android_log.proto",
+ "protos/perfetto/trace/android/frame_timeline_event.proto",
"protos/perfetto/trace/android/gpu_mem_event.proto",
"protos/perfetto/trace/android/graphics_frame_event.proto",
"protos/perfetto/trace/android/initial_display_state.proto",
@@ -3357,6 +3360,7 @@
cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
out: [
"external/perfetto/protos/perfetto/trace/android/android_log.gen.h",
+ "external/perfetto/protos/perfetto/trace/android/frame_timeline_event.gen.h",
"external/perfetto/protos/perfetto/trace/android/gpu_mem_event.gen.h",
"external/perfetto/protos/perfetto/trace/android/graphics_frame_event.gen.h",
"external/perfetto/protos/perfetto/trace/android/initial_display_state.gen.h",
@@ -3373,6 +3377,7 @@
name: "perfetto_protos_perfetto_trace_android_lite_gen",
srcs: [
"protos/perfetto/trace/android/android_log.proto",
+ "protos/perfetto/trace/android/frame_timeline_event.proto",
"protos/perfetto/trace/android/gpu_mem_event.proto",
"protos/perfetto/trace/android/graphics_frame_event.proto",
"protos/perfetto/trace/android/initial_display_state.proto",
@@ -3384,6 +3389,7 @@
cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
out: [
"external/perfetto/protos/perfetto/trace/android/android_log.pb.cc",
+ "external/perfetto/protos/perfetto/trace/android/frame_timeline_event.pb.cc",
"external/perfetto/protos/perfetto/trace/android/gpu_mem_event.pb.cc",
"external/perfetto/protos/perfetto/trace/android/graphics_frame_event.pb.cc",
"external/perfetto/protos/perfetto/trace/android/initial_display_state.pb.cc",
@@ -3396,6 +3402,7 @@
name: "perfetto_protos_perfetto_trace_android_lite_gen_headers",
srcs: [
"protos/perfetto/trace/android/android_log.proto",
+ "protos/perfetto/trace/android/frame_timeline_event.proto",
"protos/perfetto/trace/android/gpu_mem_event.proto",
"protos/perfetto/trace/android/graphics_frame_event.proto",
"protos/perfetto/trace/android/initial_display_state.proto",
@@ -3407,6 +3414,7 @@
cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
out: [
"external/perfetto/protos/perfetto/trace/android/android_log.pb.h",
+ "external/perfetto/protos/perfetto/trace/android/frame_timeline_event.pb.h",
"external/perfetto/protos/perfetto/trace/android/gpu_mem_event.pb.h",
"external/perfetto/protos/perfetto/trace/android/graphics_frame_event.pb.h",
"external/perfetto/protos/perfetto/trace/android/initial_display_state.pb.h",
@@ -3423,6 +3431,7 @@
name: "perfetto_protos_perfetto_trace_android_zero_gen",
srcs: [
"protos/perfetto/trace/android/android_log.proto",
+ "protos/perfetto/trace/android/frame_timeline_event.proto",
"protos/perfetto/trace/android/gpu_mem_event.proto",
"protos/perfetto/trace/android/graphics_frame_event.proto",
"protos/perfetto/trace/android/initial_display_state.proto",
@@ -3435,6 +3444,7 @@
cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
out: [
"external/perfetto/protos/perfetto/trace/android/android_log.pbzero.cc",
+ "external/perfetto/protos/perfetto/trace/android/frame_timeline_event.pbzero.cc",
"external/perfetto/protos/perfetto/trace/android/gpu_mem_event.pbzero.cc",
"external/perfetto/protos/perfetto/trace/android/graphics_frame_event.pbzero.cc",
"external/perfetto/protos/perfetto/trace/android/initial_display_state.pbzero.cc",
@@ -3447,6 +3457,7 @@
name: "perfetto_protos_perfetto_trace_android_zero_gen_headers",
srcs: [
"protos/perfetto/trace/android/android_log.proto",
+ "protos/perfetto/trace/android/frame_timeline_event.proto",
"protos/perfetto/trace/android/gpu_mem_event.proto",
"protos/perfetto/trace/android/graphics_frame_event.proto",
"protos/perfetto/trace/android/initial_display_state.proto",
@@ -3459,6 +3470,7 @@
cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
out: [
"external/perfetto/protos/perfetto/trace/android/android_log.pbzero.h",
+ "external/perfetto/protos/perfetto/trace/android/frame_timeline_event.pbzero.h",
"external/perfetto/protos/perfetto/trace/android/gpu_mem_event.pbzero.h",
"external/perfetto/protos/perfetto/trace/android/graphics_frame_event.pbzero.h",
"external/perfetto/protos/perfetto/trace/android/initial_display_state.pbzero.h",
diff --git a/BUILD b/BUILD
index 7cb3963..9c8710e 100644
--- a/BUILD
+++ b/BUILD
@@ -2224,6 +2224,7 @@
name = "protos_perfetto_trace_android_protos",
srcs = [
"protos/perfetto/trace/android/android_log.proto",
+ "protos/perfetto/trace/android/frame_timeline_event.proto",
"protos/perfetto/trace/android/gpu_mem_event.proto",
"protos/perfetto/trace/android/graphics_frame_event.proto",
"protos/perfetto/trace/android/initial_display_state.proto",
diff --git a/protos/perfetto/trace/android/BUILD.gn b/protos/perfetto/trace/android/BUILD.gn
index 2bece63..c957f64 100644
--- a/protos/perfetto/trace/android/BUILD.gn
+++ b/protos/perfetto/trace/android/BUILD.gn
@@ -19,6 +19,7 @@
sources = [
"android_log.proto",
+ "frame_timeline_event.proto",
"gpu_mem_event.proto",
"graphics_frame_event.proto",
"initial_display_state.proto",
diff --git a/protos/perfetto/trace/android/frame_timeline_event.proto b/protos/perfetto/trace/android/frame_timeline_event.proto
new file mode 100644
index 0000000..a075c62
--- /dev/null
+++ b/protos/perfetto/trace/android/frame_timeline_event.proto
@@ -0,0 +1,113 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+syntax = "proto2";
+package perfetto.protos;
+
+// Generated by SurfaceFlinger's FrameTimeline (go/adaptive-scheduling-fr).
+// Used in comparing the expected timeline of a frame to the actual timeline.
+// Key terms:
+// 1) DisplayFrame - represents SurfaceFlinger's work on a frame(composited)
+// 2) SurfaceFrame - represents App's work on its frame
+// 3) Timeline = start to end of a component's(app/SF) work on a frame.
+// SurfaceFlinger composites frames from many apps together, so
+// One DisplayFrame can map to N SurfaceFrame(s)
+// This relationship can be reconstructed by using
+// DisplayFrame.token = SurfaceFrame.display_frame_token
+message FrameTimelineEvent {
+ // Specifies which component was the main source for the jank.
+ enum JankType {
+ JANK_UNSPECIFIED = 0;
+ JANK_NONE = 1;
+ JANK_SF_SCHEDULING = 2;
+ JANK_PREDICTION_ERROR = 3;
+ JANK_DISPLAY_HAL = 4;
+ JANK_SF_DEADLINE_MISSED = 5;
+ JANK_APP_DEADLINE_MISSED = 6;
+ JANK_BUFFER_STUFFING = 7;
+ JANK_UNKNOWN = 8;
+ };
+
+ // Specifies how a frame was presented on screen w.r.t. timing.
+ // Can be different for SurfaceFrame and DisplayFrame.
+ enum PresentType {
+ PRESENT_UNSPECIFIED = 0;
+ PRESENT_ON_TIME = 1;
+ PRESENT_LATE = 2;
+ PRESENT_EARLY = 3;
+ PRESENT_DROPPED = 4;
+ };
+
+ // Represents the app's work on a frame.
+ // Next id: 13
+ message SurfaceFrame {
+ // Token received by the app for its work. Can be shared between multiple
+ // layers of the same app (example: pip mode).
+ optional int64 token = 1;
+
+ // The corresponding DisplayFrame token is required to link the App's work
+ // with SurfaceFlinger's work. Many SurfaceFrames can be mapped to a single
+ // DisplayFrame.
+ // this.display_frame_token = DisplayFrame.token
+ optional int64 display_frame_token = 12;
+
+ optional PresentType present_type = 2;
+ optional bool on_time_finish = 3;
+ optional bool gpu_composition = 4;
+ optional JankType jank_type = 5;
+
+ // Timestamps in nanoseconds using CLOCK_MONOTONIC.
+ // Expected timeline = expected_start to expected_end.
+ optional int64 expected_start_ns = 6;
+ optional int64 expected_end_ns = 7;
+
+ // (b/172587309) Apps currently do not provide actual start time.
+ // Actual timeline = expected_start to actual_end.
+ optional int64 actual_start_ns = 8;
+ // If two SufaceFrames have the same token and same pid, then
+ // actual timeline =
+ // expected_start to max(frame1.actual_end, frame2.actual_end)
+ optional int64 actual_end_ns = 9;
+
+ optional string layer_name = 10;
+ optional int32 pid = 11;
+ };
+
+ // Represents the SurfaceFlinger's work on a frame.
+ message DisplayFrame {
+ // Token received by SurfaceFlinger for its work
+ // this.token = SurfaceFrame.display_frame_token
+ optional int64 token = 1;
+ optional PresentType present_type = 2;
+ optional bool on_time_finish = 3;
+ optional bool gpu_composition = 4;
+ optional JankType jank_type = 5;
+
+ // Timestamps in nanoseconds using CLOCK_MONOTONIC.
+ // Expected timeline = expected_start to expected_end.
+ optional int64 expected_start_ns = 6;
+ optional int64 expected_end_ns = 7;
+
+ // Actual timeline = actual_start to actual_end.
+ optional int64 actual_start_ns = 8;
+ optional int64 actual_end_ns = 9;
+ };
+
+ oneof event {
+ DisplayFrame display_frame = 1;
+ SurfaceFrame surface_frame = 2;
+ }
+}
diff --git a/protos/perfetto/trace/perfetto_trace.proto b/protos/perfetto/trace/perfetto_trace.proto
index 46ed65d..fa3bd78 100644
--- a/protos/perfetto/trace/perfetto_trace.proto
+++ b/protos/perfetto/trace/perfetto_trace.proto
@@ -1754,6 +1754,105 @@
// End of protos/perfetto/trace/android/android_log.proto
+// Begin of protos/perfetto/trace/android/frame_timeline_event.proto
+
+// Generated by SurfaceFlinger's FrameTimeline (go/adaptive-scheduling-fr).
+// Used in comparing the expected timeline of a frame to the actual timeline.
+// Key terms:
+// 1) DisplayFrame - represents SurfaceFlinger's work on a frame(composited)
+// 2) SurfaceFrame - represents App's work on its frame
+// 3) Timeline = start to end of a component's(app/SF) work on a frame.
+// SurfaceFlinger composites frames from many apps together, so
+// One DisplayFrame can map to N SurfaceFrame(s)
+// This relationship can be reconstructed by using
+// DisplayFrame.token = SurfaceFrame.display_frame_token
+message FrameTimelineEvent {
+ // Specifies which component was the main source for the jank.
+ enum JankType {
+ JANK_UNSPECIFIED = 0;
+ JANK_NONE = 1;
+ JANK_SF_SCHEDULING = 2;
+ JANK_PREDICTION_ERROR = 3;
+ JANK_DISPLAY_HAL = 4;
+ JANK_SF_DEADLINE_MISSED = 5;
+ JANK_APP_DEADLINE_MISSED = 6;
+ JANK_BUFFER_STUFFING = 7;
+ JANK_UNKNOWN = 8;
+ };
+
+ // Specifies how a frame was presented on screen w.r.t. timing.
+ // Can be different for SurfaceFrame and DisplayFrame.
+ enum PresentType {
+ PRESENT_UNSPECIFIED = 0;
+ PRESENT_ON_TIME = 1;
+ PRESENT_LATE = 2;
+ PRESENT_EARLY = 3;
+ PRESENT_DROPPED = 4;
+ };
+
+ // Represents the app's work on a frame.
+ // Next id: 13
+ message SurfaceFrame {
+ // Token received by the app for its work. Can be shared between multiple
+ // layers of the same app (example: pip mode).
+ optional int64 token = 1;
+
+ // The corresponding DisplayFrame token is required to link the App's work
+ // with SurfaceFlinger's work. Many SurfaceFrames can be mapped to a single
+ // DisplayFrame.
+ // this.display_frame_token = DisplayFrame.token
+ optional int64 display_frame_token = 12;
+
+ optional PresentType present_type = 2;
+ optional bool on_time_finish = 3;
+ optional bool gpu_composition = 4;
+ optional JankType jank_type = 5;
+
+ // Timestamps in nanoseconds using CLOCK_MONOTONIC.
+ // Expected timeline = expected_start to expected_end.
+ optional int64 expected_start_ns = 6;
+ optional int64 expected_end_ns = 7;
+
+ // (b/172587309) Apps currently do not provide actual start time.
+ // Actual timeline = expected_start to actual_end.
+ optional int64 actual_start_ns = 8;
+ // If two SufaceFrames have the same token and same pid, then
+ // actual timeline =
+ // expected_start to max(frame1.actual_end, frame2.actual_end)
+ optional int64 actual_end_ns = 9;
+
+ optional string layer_name = 10;
+ optional int32 pid = 11;
+ };
+
+ // Represents the SurfaceFlinger's work on a frame.
+ message DisplayFrame {
+ // Token received by SurfaceFlinger for its work
+ // this.token = SurfaceFrame.display_frame_token
+ optional int64 token = 1;
+ optional PresentType present_type = 2;
+ optional bool on_time_finish = 3;
+ optional bool gpu_composition = 4;
+ optional JankType jank_type = 5;
+
+ // Timestamps in nanoseconds using CLOCK_MONOTONIC.
+ // Expected timeline = expected_start to expected_end.
+ optional int64 expected_start_ns = 6;
+ optional int64 expected_end_ns = 7;
+
+ // Actual timeline = actual_start to actual_end.
+ optional int64 actual_start_ns = 8;
+ optional int64 actual_end_ns = 9;
+ };
+
+ oneof event {
+ DisplayFrame display_frame = 1;
+ SurfaceFrame surface_frame = 2;
+ }
+}
+
+// End of protos/perfetto/trace/android/frame_timeline_event.proto
+
// Begin of protos/perfetto/trace/android/gpu_mem_event.proto
// Generated by Android's GpuService.
@@ -7902,7 +8001,7 @@
// See the [Buffers and Dataflow](/docs/concepts/buffers.md) doc for details.
//
// Next reserved id: 13 (up to 15).
-// Next id: 76.
+// Next id: 77.
message TracePacket {
// The timestamp of the TracePacket.
// By default this timestamps refers to the trace clock (CLOCK_BOOTTIME on
@@ -7961,6 +8060,7 @@
InitialDisplayState initial_display_state = 70;
GpuMemTotalEvent gpu_mem_total_event = 71;
MemoryTrackerSnapshot memory_tracker_snapshot = 73;
+ FrameTimelineEvent frame_timeline_event = 76;
// Only used in profile packets.
ProfiledFrameSymbols profiled_frame_symbols = 55;
diff --git a/protos/perfetto/trace/trace_packet.proto b/protos/perfetto/trace/trace_packet.proto
index 9b233ef..667c62a 100644
--- a/protos/perfetto/trace/trace_packet.proto
+++ b/protos/perfetto/trace/trace_packet.proto
@@ -20,6 +20,7 @@
import "protos/perfetto/config/trace_config.proto";
import "protos/perfetto/trace/extension_descriptor.proto";
import "protos/perfetto/trace/android/android_log.proto";
+import "protos/perfetto/trace/android/frame_timeline_event.proto";
import "protos/perfetto/trace/android/gpu_mem_event.proto";
import "protos/perfetto/trace/android/graphics_frame_event.proto";
import "protos/perfetto/trace/android/initial_display_state.proto";
@@ -82,7 +83,7 @@
// See the [Buffers and Dataflow](/docs/concepts/buffers.md) doc for details.
//
// Next reserved id: 13 (up to 15).
-// Next id: 76.
+// Next id: 77.
message TracePacket {
// The timestamp of the TracePacket.
// By default this timestamps refers to the trace clock (CLOCK_BOOTTIME on
@@ -141,6 +142,7 @@
InitialDisplayState initial_display_state = 70;
GpuMemTotalEvent gpu_mem_total_event = 71;
MemoryTrackerSnapshot memory_tracker_snapshot = 73;
+ FrameTimelineEvent frame_timeline_event = 76;
// Only used in profile packets.
ProfiledFrameSymbols profiled_frame_symbols = 55;