FrameInfo.h revision 2a8bb05a31ddd0d44d8513cba9fbd9b4ef9b97f6
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#ifndef FRAMEINFO_H_
17#define FRAMEINFO_H_
18
19#include "utils/Macros.h"
20
21#include <cutils/compiler.h>
22#include <utils/Timers.h>
23
24#include <memory.h>
25#include <string>
26
27namespace android {
28namespace uirenderer {
29
30#define UI_THREAD_FRAME_INFO_SIZE 9
31
32enum class FrameInfoIndex {
33    kFlags = 0,
34    kIntendedVsync,
35    kVsync,
36    kOldestInputEvent,
37    kNewestInputEvent,
38    kHandleInputStart,
39    kAnimationStart,
40    kPerformTraversalsStart,
41    kDrawStart,
42    // End of UI frame info
43
44    kSyncStart,
45    kIssueDrawCommandsStart,
46    kSwapBuffers,
47    kFrameCompleted,
48
49    // Must be the last value!
50    kNumIndexes
51};
52
53extern const std::string FrameInfoNames[];
54
55enum class FrameInfoFlags {
56    kWindowLayoutChanged = 1 << 0,
57    kRTAnimation = 1 << 1,
58    kSurfaceCanvas = 1 << 2,
59    kSkippedFrame = 1 << 3,
60};
61MAKE_FLAGS_ENUM(FrameInfoFlags)
62
63class ANDROID_API UiFrameInfoBuilder {
64public:
65    UiFrameInfoBuilder(int64_t* buffer) : mBuffer(buffer) {
66        memset(mBuffer, 0, UI_THREAD_FRAME_INFO_SIZE * sizeof(int64_t));
67    }
68
69    UiFrameInfoBuilder& setVsync(nsecs_t vsyncTime, nsecs_t intendedVsync) {
70        set(FrameInfoIndex::kVsync) = vsyncTime;
71        set(FrameInfoIndex::kIntendedVsync) = intendedVsync;
72        // Pretend the other fields are all at vsync, too, so that naive
73        // duration calculations end up being 0 instead of very large
74        set(FrameInfoIndex::kHandleInputStart) = vsyncTime;
75        set(FrameInfoIndex::kAnimationStart) = vsyncTime;
76        set(FrameInfoIndex::kPerformTraversalsStart) = vsyncTime;
77        set(FrameInfoIndex::kDrawStart) = vsyncTime;
78        return *this;
79    }
80
81    UiFrameInfoBuilder& addFlag(FrameInfoFlags flag) {
82        set(FrameInfoIndex::kFlags) |= static_cast<uint64_t>(flag);
83        return *this;
84    }
85
86private:
87    inline int64_t& set(FrameInfoIndex index) {
88        return mBuffer[static_cast<int>(index)];
89    }
90
91    int64_t* mBuffer;
92};
93
94class FrameInfo {
95public:
96    void importUiThreadInfo(int64_t* info);
97
98    void markSyncStart() {
99        set(FrameInfoIndex::kSyncStart) = systemTime(CLOCK_MONOTONIC);
100    }
101
102    void markIssueDrawCommandsStart() {
103        set(FrameInfoIndex::kIssueDrawCommandsStart) = systemTime(CLOCK_MONOTONIC);
104    }
105
106    void markSwapBuffers() {
107        set(FrameInfoIndex::kSwapBuffers) = systemTime(CLOCK_MONOTONIC);
108    }
109
110    void markFrameCompleted() {
111        set(FrameInfoIndex::kFrameCompleted) = systemTime(CLOCK_MONOTONIC);
112    }
113
114    void addFlag(FrameInfoFlags flag) {
115        set(FrameInfoIndex::kFlags) |= static_cast<uint64_t>(flag);
116    }
117
118    int64_t operator[](FrameInfoIndex index) const {
119        if (index == FrameInfoIndex::kNumIndexes) return 0;
120        return mFrameInfo[static_cast<int>(index)];
121    }
122
123    int64_t operator[](int index) const {
124        if (index < 0 || index >= static_cast<int>(FrameInfoIndex::kNumIndexes)) return 0;
125        return mFrameInfo[index];
126    }
127
128private:
129    inline int64_t& set(FrameInfoIndex index) {
130        return mFrameInfo[static_cast<int>(index)];
131    }
132
133    int64_t mFrameInfo[static_cast<int>(FrameInfoIndex::kNumIndexes)];
134};
135
136} /* namespace uirenderer */
137} /* namespace android */
138
139#endif /* FRAMEINFO_H_ */
140