1/*
2 * Copyright (C) 2020 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17syntax = "proto2";
18package perfetto.protos;
19
20// Generated by SurfaceFlinger's FrameTimeline (go/adaptive-scheduling-fr).
21// Used in comparing the expected timeline of a frame to the actual timeline.
22// Key terms:
23//    1) DisplayFrame - represents SurfaceFlinger's work on a frame(composited)
24//    2) SurfaceFrame - represents App's work on its frame
25//    3) Timeline = start to end of a component's(app/SF) work on a frame.
26// SurfaceFlinger composites frames from many apps together, so
27//    One DisplayFrame can map to N SurfaceFrame(s)
28// This relationship can be reconstructed by using
29//    DisplayFrame.token = SurfaceFrame.display_frame_token
30message FrameTimelineEvent {
31  // Specifies the reason(s) most likely to have caused the jank.
32  // Used as a bitmask.
33  enum JankType {
34    JANK_UNSPECIFIED = 0;
35    JANK_NONE = 1;
36    JANK_SF_SCHEDULING = 2;
37    JANK_PREDICTION_ERROR = 4;
38    JANK_DISPLAY_HAL = 8;
39    JANK_SF_CPU_DEADLINE_MISSED = 16;
40    JANK_SF_GPU_DEADLINE_MISSED = 32;
41    JANK_APP_DEADLINE_MISSED = 64;
42    JANK_BUFFER_STUFFING = 128;
43    JANK_UNKNOWN = 256;
44    JANK_SF_STUFFING = 512;
45  };
46
47  // Specifies how a frame was presented on screen w.r.t. timing.
48  // Can be different for SurfaceFrame and DisplayFrame.
49  enum PresentType {
50    PRESENT_UNSPECIFIED = 0;
51    PRESENT_ON_TIME = 1;
52    PRESENT_LATE = 2;
53    PRESENT_EARLY = 3;
54    PRESENT_DROPPED = 4;
55    PRESENT_UNKNOWN = 5;
56  };
57
58  // Specifies if the predictions for the frame are still valid, expired or
59  // unknown.
60  enum PredictionType {
61    PREDICTION_UNSPECIFIED = 0;
62    PREDICTION_VALID = 1;
63    PREDICTION_EXPIRED = 2;
64    PREDICTION_UNKNOWN = 3;
65  };
66
67  // Indicates the start of expected timeline slice for SurfaceFrames.
68  message ExpectedSurfaceFrameStart {
69    // Cookie used to correlate between the start and end messages of the same
70    // frame. Since all values except the ts are same for start and end, cookie
71    // helps in preventing redundant data transmission.
72    // The same cookie is used only by start and end messages of a single frame
73    // and is otherwise unique.
74    optional int64 cookie = 1;
75
76    // Token received by the app for its work. Can be shared between multiple
77    // layers of the same app (example: pip mode).
78    optional int64 token = 2;
79    // The corresponding DisplayFrame token is required to link the App's work
80    // with SurfaceFlinger's work. Many SurfaceFrames can be mapped to a single
81    // DisplayFrame.
82    // this.display_frame_token = DisplayFrame.token
83    optional int64 display_frame_token = 3;
84
85    // Pid of the app. Used in creating the timeline tracks (and slices) inside
86    // the respective process track group.
87    optional int32 pid = 4;
88    optional string layer_name = 5;
89  };
90
91  // Indicates the start of actual timeline slice for SurfaceFrames. Also
92  // includes the jank information.
93  message ActualSurfaceFrameStart {
94    // Cookie used to correlate between the start and end messages of the same
95    // frame. Since all values except the ts are same for start and end, cookie
96    // helps in preventing redundant data transmission.
97    // The same cookie is used only by start and end messages of a single frame
98    // and is otherwise unique.
99    optional int64 cookie = 1;
100
101    // Token received by the app for its work. Can be shared between multiple
102    // layers of the same app (example: pip mode).
103    optional int64 token = 2;
104    // The corresponding DisplayFrame token is required to link the App's work
105    // with SurfaceFlinger's work. Many SurfaceFrames can be mapped to a single
106    // DisplayFrame.
107    // this.display_frame_token = DisplayFrame.token
108    optional int64 display_frame_token = 3;
109
110    // Pid of the app. Used in creating the timeline tracks (and slices) inside
111    // the respective process track group.
112    optional int32 pid = 4;
113    optional string layer_name = 5;
114
115    optional PresentType present_type = 6;
116    optional bool on_time_finish = 7;
117    optional bool gpu_composition = 8;
118    // A bitmask of JankType. More than one reason can be attributed to a janky
119    // frame.
120    optional int32 jank_type = 9;
121    optional PredictionType prediction_type = 10;
122    optional bool is_buffer = 11;
123  };
124
125  // Indicates the start of expected timeline slice for DisplayFrames.
126  message ExpectedDisplayFrameStart {
127    // Cookie used to correlate between the start and end messages of the same
128    // frame. Since all values except the ts are same for start and end, cookie
129    // helps in preventing redundant data transmission.
130    // The same cookie is used only by start and end messages of a single frame
131    // and is otherwise unique.
132    optional int64 cookie = 1;
133
134    // Token received by SurfaceFlinger for its work
135    // this.token = SurfaceFrame.display_frame_token
136    optional int64 token = 2;
137
138    // Pid of SurfaceFlinger. Used in creating the timeline tracks (and slices)
139    // inside the SurfaceFlinger process group.
140    optional int32 pid = 3;
141  };
142
143  // Indicates the start of actual timeline slice for DisplayFrames. Also
144  // includes the jank information.
145  message ActualDisplayFrameStart {
146    // Cookie used to correlate between the start and end messages of the same
147    // frame. Since all values except the ts are same for start and end, cookie
148    // helps in preventing redundant data transmission.
149    // The same cookie is used only by start and end messages of a single frame
150    // and is otherwise unique.
151    optional int64 cookie = 1;
152
153    // Token received by SurfaceFlinger for its work
154    // this.token = SurfaceFrame.display_frame_token
155    optional int64 token = 2;
156
157    // Pid of SurfaceFlinger. Used in creating the timeline tracks (and slices)
158    // inside the SurfaceFlinger process group.
159    optional int32 pid = 3;
160
161    optional PresentType present_type = 4;
162    optional bool on_time_finish = 5;
163    optional bool gpu_composition = 6;
164    // A bitmask of JankType. More than one reason can be attributed to a janky
165    // frame.
166    optional int32 jank_type = 7;
167    optional PredictionType prediction_type = 8;
168  };
169
170  // FrameEnd just sends the cookie to indicate that the corresponding
171  // <display/surface>frame slice's end.
172  message FrameEnd { optional int64 cookie = 1; };
173
174  oneof event {
175    ExpectedDisplayFrameStart expected_display_frame_start = 1;
176    ActualDisplayFrameStart actual_display_frame_start = 2;
177
178    ExpectedSurfaceFrameStart expected_surface_frame_start = 3;
179    ActualSurfaceFrameStart actual_surface_frame_start = 4;
180
181    FrameEnd frame_end = 5;
182  }
183}
184