1 /*
2  * Copyright (C) 2015 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 
17 package android.graphics;
18 
19 import android.annotation.LongDef;
20 
21 import java.lang.annotation.Retention;
22 import java.lang.annotation.RetentionPolicy;
23 
24 /**
25  * Class that contains all the timing information for the current frame. This
26  * is used in conjunction with the hardware renderer to provide
27  * continous-monitoring jank events
28  *
29  * All times in nanoseconds from CLOCK_MONOTONIC/System.nanoTime()
30  *
31  * To minimize overhead from System.nanoTime() calls we infer durations of
32  * things by knowing the ordering of the events. For example, to know how
33  * long layout & measure took it's displayListRecordStart - performTraversalsStart.
34  *
35  * These constants must be kept in sync with FrameInfo.h in libhwui and are
36  * used for indexing into AttachInfo's frameInfo long[], which is intended
37  * to be quick to pass down to native via JNI, hence a pre-packed format
38  *
39  * @hide
40  */
41 public final class FrameInfo {
42 
43     public long[] frameInfo = new long[9];
44 
45     // Various flags set to provide extra metadata about the current frame
46     private static final int FLAGS = 0;
47 
48     // Is this the first-draw following a window layout?
49     public static final long FLAG_WINDOW_LAYOUT_CHANGED = 1;
50 
51     // A renderer associated with just a Surface, not with a ViewRootImpl instance.
52     public static final long FLAG_SURFACE_CANVAS = 1 << 2;
53 
54     @LongDef(flag = true, value = {
55             FLAG_WINDOW_LAYOUT_CHANGED, FLAG_SURFACE_CANVAS })
56     @Retention(RetentionPolicy.SOURCE)
57     public @interface FrameInfoFlags {}
58 
59     // The intended vsync time, unadjusted by jitter
60     private static final int INTENDED_VSYNC = 1;
61 
62     // Jitter-adjusted vsync time, this is what was used as input into the
63     // animation & drawing system
64     private static final int VSYNC = 2;
65 
66     // The time of the oldest input event
67     private static final int OLDEST_INPUT_EVENT = 3;
68 
69     // The time of the newest input event
70     private static final int NEWEST_INPUT_EVENT = 4;
71 
72     // When input event handling started
73     private static final int HANDLE_INPUT_START = 5;
74 
75     // When animation evaluations started
76     private static final int ANIMATION_START = 6;
77 
78     // When ViewRootImpl#performTraversals() started
79     private static final int PERFORM_TRAVERSALS_START = 7;
80 
81     // When View:draw() started
82     private static final int DRAW_START = 8;
83 
84     /** checkstyle */
setVsync(long intendedVsync, long usedVsync)85     public void setVsync(long intendedVsync, long usedVsync) {
86         frameInfo[INTENDED_VSYNC] = intendedVsync;
87         frameInfo[VSYNC] = usedVsync;
88         frameInfo[OLDEST_INPUT_EVENT] = Long.MAX_VALUE;
89         frameInfo[NEWEST_INPUT_EVENT] = 0;
90         frameInfo[FLAGS] = 0;
91     }
92 
93     /** checkstyle */
updateInputEventTime(long inputEventTime, long inputEventOldestTime)94     public void updateInputEventTime(long inputEventTime, long inputEventOldestTime) {
95         if (inputEventOldestTime < frameInfo[OLDEST_INPUT_EVENT]) {
96             frameInfo[OLDEST_INPUT_EVENT] = inputEventOldestTime;
97         }
98         if (inputEventTime > frameInfo[NEWEST_INPUT_EVENT]) {
99             frameInfo[NEWEST_INPUT_EVENT] = inputEventTime;
100         }
101     }
102 
103     /** checkstyle */
markInputHandlingStart()104     public void markInputHandlingStart() {
105         frameInfo[HANDLE_INPUT_START] = System.nanoTime();
106     }
107 
108     /** checkstyle */
markAnimationsStart()109     public void markAnimationsStart() {
110         frameInfo[ANIMATION_START] = System.nanoTime();
111     }
112 
113     /** checkstyle */
markPerformTraversalsStart()114     public void markPerformTraversalsStart() {
115         frameInfo[PERFORM_TRAVERSALS_START] = System.nanoTime();
116     }
117 
118     /** checkstyle */
markDrawStart()119     public void markDrawStart() {
120         frameInfo[DRAW_START] = System.nanoTime();
121     }
122 
123     /** checkstyle */
addFlags(@rameInfoFlags long flags)124     public void addFlags(@FrameInfoFlags long flags) {
125         frameInfo[FLAGS] |= flags;
126     }
127 
128 }
129