2 * Copyright (C) 2015 The Android Open Source Project
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
19 #include "utils/Macros.h"
21 #include <cutils/compiler.h>
22 #include <utils/Timers.h>
28 namespace uirenderer {
30 #define UI_THREAD_FRAME_INFO_SIZE 9
32 enum class FrameInfoIndex {
40 PerformTraversalsStart,
42 // End of UI frame info
47 IssueDrawCommandsStart,
51 // Must be the last value!
55 extern const std::string FrameInfoNames[];
57 namespace FrameInfoFlags {
59 WindowLayoutChanged = 1 << 0,
61 SurfaceCanvas = 1 << 2,
62 SkippedFrame = 1 << 3,
66 class ANDROID_API UiFrameInfoBuilder {
68 UiFrameInfoBuilder(int64_t* buffer) : mBuffer(buffer) {
69 memset(mBuffer, 0, UI_THREAD_FRAME_INFO_SIZE * sizeof(int64_t));
72 UiFrameInfoBuilder& setVsync(nsecs_t vsyncTime, nsecs_t intendedVsync) {
73 set(FrameInfoIndex::Vsync) = vsyncTime;
74 set(FrameInfoIndex::IntendedVsync) = intendedVsync;
75 // Pretend the other fields are all at vsync, too, so that naive
76 // duration calculations end up being 0 instead of very large
77 set(FrameInfoIndex::HandleInputStart) = vsyncTime;
78 set(FrameInfoIndex::AnimationStart) = vsyncTime;
79 set(FrameInfoIndex::PerformTraversalsStart) = vsyncTime;
80 set(FrameInfoIndex::DrawStart) = vsyncTime;
84 UiFrameInfoBuilder& addFlag(int frameInfoFlag) {
85 set(FrameInfoIndex::Flags) |= static_cast<uint64_t>(frameInfoFlag);
90 inline int64_t& set(FrameInfoIndex index) {
91 return mBuffer[static_cast<int>(index)];
99 void importUiThreadInfo(int64_t* info);
101 void markSyncStart() {
102 set(FrameInfoIndex::SyncStart) = systemTime(CLOCK_MONOTONIC);
105 void markIssueDrawCommandsStart() {
106 set(FrameInfoIndex::IssueDrawCommandsStart) = systemTime(CLOCK_MONOTONIC);
109 void markSwapBuffers() {
110 set(FrameInfoIndex::SwapBuffers) = systemTime(CLOCK_MONOTONIC);
113 void markFrameCompleted() {
114 set(FrameInfoIndex::FrameCompleted) = systemTime(CLOCK_MONOTONIC);
117 void addFlag(int frameInfoFlag) {
118 set(FrameInfoIndex::Flags) |= static_cast<uint64_t>(frameInfoFlag);
121 const int64_t* data() const {
125 inline int64_t operator[](FrameInfoIndex index) const {
129 inline int64_t operator[](int index) const {
130 if (index < 0 || index >= static_cast<int>(FrameInfoIndex::NumIndexes)) return 0;
131 return mFrameInfo[index];
134 inline int64_t duration(FrameInfoIndex start, FrameInfoIndex end) const {
135 int64_t endtime = get(end);
136 int64_t starttime = get(start);
137 int64_t gap = endtime - starttime;
138 gap = starttime > 0 ? gap : 0;
139 if (end > FrameInfoIndex::SyncQueued &&
140 start < FrameInfoIndex::SyncQueued) {
141 // Need to subtract out the time spent in a stalled state
142 // as this will be captured by the previous frame's info
143 int64_t offset = get(FrameInfoIndex::SyncStart)
144 - get(FrameInfoIndex::SyncQueued);
149 return gap > 0 ? gap : 0;
152 inline int64_t totalDuration() const {
153 return duration(FrameInfoIndex::IntendedVsync, FrameInfoIndex::FrameCompleted);
156 inline int64_t& set(FrameInfoIndex index) {
157 return mFrameInfo[static_cast<int>(index)];
160 inline int64_t get(FrameInfoIndex index) const {
161 if (index == FrameInfoIndex::NumIndexes) return 0;
162 return mFrameInfo[static_cast<int>(index)];
166 int64_t mFrameInfo[static_cast<int>(FrameInfoIndex::NumIndexes)];
169 } /* namespace uirenderer */
170 } /* namespace android */
172 #endif /* FRAMEINFO_H_ */