Split FrameTimelineEvent proto into separate start and end messages
The current way of sending SurfaceFrames and DisaplyFrames using scoped
values is not a clean approach. This change splits the
<Surface/Display>Frames into Start and End messages with minimal data
rendundancy through the usage of cookies.
Cherry-picked from aosp/1544044
Bug: 173426914
Test: None
Change-Id: I4f449fa132b609553c2d0d2edd3ddc4ae718c4b3
diff --git a/protos/perfetto/trace/android/frame_timeline_event.proto b/protos/perfetto/trace/android/frame_timeline_event.proto
index 65725f4..c6c4482 100644
--- a/protos/perfetto/trace/android/frame_timeline_event.proto
+++ b/protos/perfetto/trace/android/frame_timeline_event.proto
@@ -51,69 +51,113 @@
PRESENT_DROPPED = 4;
};
- // Represents the app's work on a frame.
- // Next id: 13
- message SurfaceFrame {
+ // Indicates the start of expected timeline slice for SurfaceFrames.
+ message ExpectedSurfaceFrameStart {
+ // Cookie used to correlate between the start and end messages of the same
+ // frame. Since all values except the ts are same for start and end, cookie
+ // helps in preventing redundant data transmission.
+ // The same cookie is used only by start and end messages of a single frame
+ // and is otherwise unique.
+ optional int64 cookie = 1;
+
// 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;
-
+ optional int64 token = 2;
// 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 int64 display_frame_token = 3;
// Pid of the app. Used in creating the timeline tracks (and slices) inside
// the respective process track group.
- optional int32 pid = 10;
- optional string layer_name = 11;
+ optional int32 pid = 4;
+ optional string layer_name = 5;
};
- // Represents the SurfaceFlinger's work on a frame.
- message DisplayFrame {
+ // Indicates the start of actual timeline slice for SurfaceFrames. Also
+ // includes the jank information.
+ message ActualSurfaceFrameStart {
+ // Cookie used to correlate between the start and end messages of the same
+ // frame. Since all values except the ts are same for start and end, cookie
+ // helps in preventing redundant data transmission.
+ // The same cookie is used only by start and end messages of a single frame
+ // and is otherwise unique.
+ optional int64 cookie = 1;
+
+ // Token received by the app for its work. Can be shared between multiple
+ // layers of the same app (example: pip mode).
+ optional int64 token = 2;
+ // 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 = 3;
+
+ // Pid of the app. Used in creating the timeline tracks (and slices) inside
+ // the respective process track group.
+ optional int32 pid = 4;
+ optional string layer_name = 5;
+
+ optional PresentType present_type = 6;
+ optional bool on_time_finish = 7;
+ optional bool gpu_composition = 8;
+ optional JankType jank_type = 9;
+ };
+
+ // Indicates the start of expected timeline slice for DisplayFrames.
+ message ExpectedDisplayFrameStart {
+ // Cookie used to correlate between the start and end messages of the same
+ // frame. Since all values except the ts are same for start and end, cookie
+ // helps in preventing redundant data transmission.
+ // The same cookie is used only by start and end messages of a single frame
+ // and is otherwise unique.
+ optional int64 cookie = 1;
+
// 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;
+ optional int64 token = 2;
// Pid of SurfaceFlinger. Used in creating the timeline tracks (and slices)
// inside the SurfaceFlinger process group.
- optional int32 pid = 10;
+ optional int32 pid = 3;
};
+ // Indicates the start of actual timeline slice for DisplayFrames. Also
+ // includes the jank information.
+ message ActualDisplayFrameStart {
+ // Cookie used to correlate between the start and end messages of the same
+ // frame. Since all values except the ts are same for start and end, cookie
+ // helps in preventing redundant data transmission.
+ // The same cookie is used only by start and end messages of a single frame
+ // and is otherwise unique.
+ optional int64 cookie = 1;
+
+ // Token received by SurfaceFlinger for its work
+ // this.token = SurfaceFrame.display_frame_token
+ optional int64 token = 2;
+
+ // Pid of SurfaceFlinger. Used in creating the timeline tracks (and slices)
+ // inside the SurfaceFlinger process group.
+ optional int32 pid = 3;
+
+ optional PresentType present_type = 4;
+ optional bool on_time_finish = 5;
+ optional bool gpu_composition = 6;
+ optional JankType jank_type = 7;
+ };
+
+ // FrameEnd just sends the cookie to indicate that the corresponding
+ // <display/surface>frame slice's end.
+ message FrameEnd { optional int64 cookie = 1; };
+
oneof event {
- DisplayFrame display_frame = 1;
- SurfaceFrame surface_frame = 2;
+ ExpectedDisplayFrameStart expected_display_frame_start = 1;
+ ActualDisplayFrameStart actual_display_frame_start = 2;
+
+ ExpectedSurfaceFrameStart expected_surface_frame_start = 3;
+ ActualSurfaceFrameStart actual_surface_frame_start = 4;
+
+ FrameEnd frame_end = 5;
}
}
diff --git a/protos/perfetto/trace/perfetto_trace.proto b/protos/perfetto/trace/perfetto_trace.proto
index ad28ead..e507fde 100644
--- a/protos/perfetto/trace/perfetto_trace.proto
+++ b/protos/perfetto/trace/perfetto_trace.proto
@@ -1864,70 +1864,114 @@
PRESENT_DROPPED = 4;
};
- // Represents the app's work on a frame.
- // Next id: 13
- message SurfaceFrame {
+ // Indicates the start of expected timeline slice for SurfaceFrames.
+ message ExpectedSurfaceFrameStart {
+ // Cookie used to correlate between the start and end messages of the same
+ // frame. Since all values except the ts are same for start and end, cookie
+ // helps in preventing redundant data transmission.
+ // The same cookie is used only by start and end messages of a single frame
+ // and is otherwise unique.
+ optional int64 cookie = 1;
+
// 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;
-
+ optional int64 token = 2;
// 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 int64 display_frame_token = 3;
// Pid of the app. Used in creating the timeline tracks (and slices) inside
// the respective process track group.
- optional int32 pid = 10;
- optional string layer_name = 11;
+ optional int32 pid = 4;
+ optional string layer_name = 5;
};
- // Represents the SurfaceFlinger's work on a frame.
- message DisplayFrame {
+ // Indicates the start of actual timeline slice for SurfaceFrames. Also
+ // includes the jank information.
+ message ActualSurfaceFrameStart {
+ // Cookie used to correlate between the start and end messages of the same
+ // frame. Since all values except the ts are same for start and end, cookie
+ // helps in preventing redundant data transmission.
+ // The same cookie is used only by start and end messages of a single frame
+ // and is otherwise unique.
+ optional int64 cookie = 1;
+
+ // Token received by the app for its work. Can be shared between multiple
+ // layers of the same app (example: pip mode).
+ optional int64 token = 2;
+ // 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 = 3;
+
+ // Pid of the app. Used in creating the timeline tracks (and slices) inside
+ // the respective process track group.
+ optional int32 pid = 4;
+ optional string layer_name = 5;
+
+ optional PresentType present_type = 6;
+ optional bool on_time_finish = 7;
+ optional bool gpu_composition = 8;
+ optional JankType jank_type = 9;
+ };
+
+ // Indicates the start of expected timeline slice for DisplayFrames.
+ message ExpectedDisplayFrameStart {
+ // Cookie used to correlate between the start and end messages of the same
+ // frame. Since all values except the ts are same for start and end, cookie
+ // helps in preventing redundant data transmission.
+ // The same cookie is used only by start and end messages of a single frame
+ // and is otherwise unique.
+ optional int64 cookie = 1;
+
// 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;
+ optional int64 token = 2;
// Pid of SurfaceFlinger. Used in creating the timeline tracks (and slices)
// inside the SurfaceFlinger process group.
- optional int32 pid = 10;
+ optional int32 pid = 3;
};
+ // Indicates the start of actual timeline slice for DisplayFrames. Also
+ // includes the jank information.
+ message ActualDisplayFrameStart {
+ // Cookie used to correlate between the start and end messages of the same
+ // frame. Since all values except the ts are same for start and end, cookie
+ // helps in preventing redundant data transmission.
+ // The same cookie is used only by start and end messages of a single frame
+ // and is otherwise unique.
+ optional int64 cookie = 1;
+
+ // Token received by SurfaceFlinger for its work
+ // this.token = SurfaceFrame.display_frame_token
+ optional int64 token = 2;
+
+ // Pid of SurfaceFlinger. Used in creating the timeline tracks (and slices)
+ // inside the SurfaceFlinger process group.
+ optional int32 pid = 3;
+
+ optional PresentType present_type = 4;
+ optional bool on_time_finish = 5;
+ optional bool gpu_composition = 6;
+ optional JankType jank_type = 7;
+ };
+
+ // FrameEnd just sends the cookie to indicate that the corresponding
+ // <display/surface>frame slice's end.
+ message FrameEnd { optional int64 cookie = 1; };
+
oneof event {
- DisplayFrame display_frame = 1;
- SurfaceFrame surface_frame = 2;
+ ExpectedDisplayFrameStart expected_display_frame_start = 1;
+ ActualDisplayFrameStart actual_display_frame_start = 2;
+
+ ExpectedSurfaceFrameStart expected_surface_frame_start = 3;
+ ActualSurfaceFrameStart actual_surface_frame_start = 4;
+
+ FrameEnd frame_end = 5;
}
}