1ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck/*
2ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck * Copyright (C) 2015 The Android Open Source Project
3ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck *
4ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck * Licensed under the Apache License, Version 2.0 (the "License");
5ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck * you may not use this file except in compliance with the License.
6ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck * You may obtain a copy of the License at
7ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck *
8ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck *      http://www.apache.org/licenses/LICENSE-2.0
9ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck *
10ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck * Unless required by applicable law or agreed to in writing, software
11ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck * distributed under the License is distributed on an "AS IS" BASIS,
12ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck * See the License for the specific language governing permissions and
14ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck * limitations under the License.
15ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck */
16ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck#ifndef FRAMEINFO_H_
17ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck#define FRAMEINFO_H_
18ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck
19ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck#include "utils/Macros.h"
20ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck
21ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck#include <cutils/compiler.h>
22ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck#include <utils/Timers.h>
23ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck
24ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck#include <memory.h>
254db3d17debef68f72d23999d69ae68b75f59dda3John Reck#include <string>
26ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck
27ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Recknamespace android {
28ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Recknamespace uirenderer {
29ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck
30ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck#define UI_THREAD_FRAME_INFO_SIZE 9
31ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck
32c87be99c6ead0720a8918ea38ce3b25e5c49e1c6John Reckenum class FrameInfoIndex {
331b54fb27ac48495ed0b33868fda5776fb49fe0f3Chris Craik    Flags = 0,
341b54fb27ac48495ed0b33868fda5776fb49fe0f3Chris Craik    IntendedVsync,
351b54fb27ac48495ed0b33868fda5776fb49fe0f3Chris Craik    Vsync,
361b54fb27ac48495ed0b33868fda5776fb49fe0f3Chris Craik    OldestInputEvent,
371b54fb27ac48495ed0b33868fda5776fb49fe0f3Chris Craik    NewestInputEvent,
381b54fb27ac48495ed0b33868fda5776fb49fe0f3Chris Craik    HandleInputStart,
391b54fb27ac48495ed0b33868fda5776fb49fe0f3Chris Craik    AnimationStart,
401b54fb27ac48495ed0b33868fda5776fb49fe0f3Chris Craik    PerformTraversalsStart,
411b54fb27ac48495ed0b33868fda5776fb49fe0f3Chris Craik    DrawStart,
42ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck    // End of UI frame info
43ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck
44be3fba05e823f740f65b2679929347dc3dd282adJohn Reck    SyncQueued,
45be3fba05e823f740f65b2679929347dc3dd282adJohn Reck
461b54fb27ac48495ed0b33868fda5776fb49fe0f3Chris Craik    SyncStart,
471b54fb27ac48495ed0b33868fda5776fb49fe0f3Chris Craik    IssueDrawCommandsStart,
481b54fb27ac48495ed0b33868fda5776fb49fe0f3Chris Craik    SwapBuffers,
491b54fb27ac48495ed0b33868fda5776fb49fe0f3Chris Craik    FrameCompleted,
50ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck
51ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck    // Must be the last value!
521b54fb27ac48495ed0b33868fda5776fb49fe0f3Chris Craik    NumIndexes
53c87be99c6ead0720a8918ea38ce3b25e5c49e1c6John Reck};
54ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck
552a8bb05a31ddd0d44d8513cba9fbd9b4ef9b97f6John Reckextern const std::string FrameInfoNames[];
564db3d17debef68f72d23999d69ae68b75f59dda3John Reck
571b54fb27ac48495ed0b33868fda5776fb49fe0f3Chris Craiknamespace FrameInfoFlags {
581b54fb27ac48495ed0b33868fda5776fb49fe0f3Chris Craik    enum {
591b54fb27ac48495ed0b33868fda5776fb49fe0f3Chris Craik        WindowLayoutChanged = 1 << 0,
601b54fb27ac48495ed0b33868fda5776fb49fe0f3Chris Craik        RTAnimation = 1 << 1,
611b54fb27ac48495ed0b33868fda5776fb49fe0f3Chris Craik        SurfaceCanvas = 1 << 2,
621b54fb27ac48495ed0b33868fda5776fb49fe0f3Chris Craik        SkippedFrame = 1 << 3,
631b54fb27ac48495ed0b33868fda5776fb49fe0f3Chris Craik    };
64c87be99c6ead0720a8918ea38ce3b25e5c49e1c6John Reck};
65ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck
66ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reckclass ANDROID_API UiFrameInfoBuilder {
67ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reckpublic:
68ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck    UiFrameInfoBuilder(int64_t* buffer) : mBuffer(buffer) {
69ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck        memset(mBuffer, 0, UI_THREAD_FRAME_INFO_SIZE * sizeof(int64_t));
70ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck    }
71ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck
72ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck    UiFrameInfoBuilder& setVsync(nsecs_t vsyncTime, nsecs_t intendedVsync) {
731b54fb27ac48495ed0b33868fda5776fb49fe0f3Chris Craik        set(FrameInfoIndex::Vsync) = vsyncTime;
741b54fb27ac48495ed0b33868fda5776fb49fe0f3Chris Craik        set(FrameInfoIndex::IntendedVsync) = intendedVsync;
75bf3c602284f9a344faf185c3a5e94a264ba44c4fJohn Reck        // Pretend the other fields are all at vsync, too, so that naive
76bf3c602284f9a344faf185c3a5e94a264ba44c4fJohn Reck        // duration calculations end up being 0 instead of very large
771b54fb27ac48495ed0b33868fda5776fb49fe0f3Chris Craik        set(FrameInfoIndex::HandleInputStart) = vsyncTime;
781b54fb27ac48495ed0b33868fda5776fb49fe0f3Chris Craik        set(FrameInfoIndex::AnimationStart) = vsyncTime;
791b54fb27ac48495ed0b33868fda5776fb49fe0f3Chris Craik        set(FrameInfoIndex::PerformTraversalsStart) = vsyncTime;
801b54fb27ac48495ed0b33868fda5776fb49fe0f3Chris Craik        set(FrameInfoIndex::DrawStart) = vsyncTime;
81ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck        return *this;
82ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck    }
83ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck
841b54fb27ac48495ed0b33868fda5776fb49fe0f3Chris Craik    UiFrameInfoBuilder& addFlag(int frameInfoFlag) {
851b54fb27ac48495ed0b33868fda5776fb49fe0f3Chris Craik        set(FrameInfoIndex::Flags) |= static_cast<uint64_t>(frameInfoFlag);
86ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck        return *this;
87ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck    }
88ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck
89ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reckprivate:
90c87be99c6ead0720a8918ea38ce3b25e5c49e1c6John Reck    inline int64_t& set(FrameInfoIndex index) {
91c87be99c6ead0720a8918ea38ce3b25e5c49e1c6John Reck        return mBuffer[static_cast<int>(index)];
92c87be99c6ead0720a8918ea38ce3b25e5c49e1c6John Reck    }
93c87be99c6ead0720a8918ea38ce3b25e5c49e1c6John Reck
94ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck    int64_t* mBuffer;
95ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck};
96ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck
97ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reckclass FrameInfo {
98ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reckpublic:
99ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck    void importUiThreadInfo(int64_t* info);
100ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck
101ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck    void markSyncStart() {
1021b54fb27ac48495ed0b33868fda5776fb49fe0f3Chris Craik        set(FrameInfoIndex::SyncStart) = systemTime(CLOCK_MONOTONIC);
103ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck    }
104ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck
105ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck    void markIssueDrawCommandsStart() {
1061b54fb27ac48495ed0b33868fda5776fb49fe0f3Chris Craik        set(FrameInfoIndex::IssueDrawCommandsStart) = systemTime(CLOCK_MONOTONIC);
107ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck    }
108ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck
109ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck    void markSwapBuffers() {
1101b54fb27ac48495ed0b33868fda5776fb49fe0f3Chris Craik        set(FrameInfoIndex::SwapBuffers) = systemTime(CLOCK_MONOTONIC);
111ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck    }
112ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck
113ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck    void markFrameCompleted() {
1141b54fb27ac48495ed0b33868fda5776fb49fe0f3Chris Craik        set(FrameInfoIndex::FrameCompleted) = systemTime(CLOCK_MONOTONIC);
115ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck    }
116ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck
1171b54fb27ac48495ed0b33868fda5776fb49fe0f3Chris Craik    void addFlag(int frameInfoFlag) {
1181b54fb27ac48495ed0b33868fda5776fb49fe0f3Chris Craik        set(FrameInfoIndex::Flags) |= static_cast<uint64_t>(frameInfoFlag);
119240ff6246a29602539fd0295274e1c769e743a2eJohn Reck    }
120240ff6246a29602539fd0295274e1c769e743a2eJohn Reck
12106f5bc70a667a02b14e31d3f53f91d3661e30666Andres Morales    const int64_t* data() const {
12206f5bc70a667a02b14e31d3f53f91d3661e30666Andres Morales        return mFrameInfo;
12306f5bc70a667a02b14e31d3f53f91d3661e30666Andres Morales    }
12406f5bc70a667a02b14e31d3f53f91d3661e30666Andres Morales
12541300274cf8efde2ca95d3c767b214d1edb97f8dJohn Reck    inline int64_t operator[](FrameInfoIndex index) const {
126be3fba05e823f740f65b2679929347dc3dd282adJohn Reck        return get(index);
127ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck    }
128ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck
12941300274cf8efde2ca95d3c767b214d1edb97f8dJohn Reck    inline int64_t operator[](int index) const {
1301b54fb27ac48495ed0b33868fda5776fb49fe0f3Chris Craik        if (index < 0 || index >= static_cast<int>(FrameInfoIndex::NumIndexes)) return 0;
131c87be99c6ead0720a8918ea38ce3b25e5c49e1c6John Reck        return mFrameInfo[index];
132ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck    }
133ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck
13441300274cf8efde2ca95d3c767b214d1edb97f8dJohn Reck    inline int64_t duration(FrameInfoIndex start, FrameInfoIndex end) const {
135be3fba05e823f740f65b2679929347dc3dd282adJohn Reck        int64_t endtime = get(end);
136be3fba05e823f740f65b2679929347dc3dd282adJohn Reck        int64_t starttime = get(start);
13741300274cf8efde2ca95d3c767b214d1edb97f8dJohn Reck        int64_t gap = endtime - starttime;
13841300274cf8efde2ca95d3c767b214d1edb97f8dJohn Reck        gap = starttime > 0 ? gap : 0;
139be3fba05e823f740f65b2679929347dc3dd282adJohn Reck        if (end > FrameInfoIndex::SyncQueued &&
140be3fba05e823f740f65b2679929347dc3dd282adJohn Reck                start < FrameInfoIndex::SyncQueued) {
141be3fba05e823f740f65b2679929347dc3dd282adJohn Reck            // Need to subtract out the time spent in a stalled state
142be3fba05e823f740f65b2679929347dc3dd282adJohn Reck            // as this will be captured by the previous frame's info
143be3fba05e823f740f65b2679929347dc3dd282adJohn Reck            int64_t offset = get(FrameInfoIndex::SyncStart)
144be3fba05e823f740f65b2679929347dc3dd282adJohn Reck                    - get(FrameInfoIndex::SyncQueued);
145be3fba05e823f740f65b2679929347dc3dd282adJohn Reck            if (offset > 0) {
146be3fba05e823f740f65b2679929347dc3dd282adJohn Reck                gap -= offset;
147be3fba05e823f740f65b2679929347dc3dd282adJohn Reck            }
148be3fba05e823f740f65b2679929347dc3dd282adJohn Reck        }
14941300274cf8efde2ca95d3c767b214d1edb97f8dJohn Reck        return gap > 0 ? gap : 0;
15041300274cf8efde2ca95d3c767b214d1edb97f8dJohn Reck    }
15141300274cf8efde2ca95d3c767b214d1edb97f8dJohn Reck
15241300274cf8efde2ca95d3c767b214d1edb97f8dJohn Reck    inline int64_t totalDuration() const {
15341300274cf8efde2ca95d3c767b214d1edb97f8dJohn Reck        return duration(FrameInfoIndex::IntendedVsync, FrameInfoIndex::FrameCompleted);
15441300274cf8efde2ca95d3c767b214d1edb97f8dJohn Reck    }
15541300274cf8efde2ca95d3c767b214d1edb97f8dJohn Reck
156c87be99c6ead0720a8918ea38ce3b25e5c49e1c6John Reck    inline int64_t& set(FrameInfoIndex index) {
157c87be99c6ead0720a8918ea38ce3b25e5c49e1c6John Reck        return mFrameInfo[static_cast<int>(index)];
158c87be99c6ead0720a8918ea38ce3b25e5c49e1c6John Reck    }
159c87be99c6ead0720a8918ea38ce3b25e5c49e1c6John Reck
160be3fba05e823f740f65b2679929347dc3dd282adJohn Reck    inline int64_t get(FrameInfoIndex index) const {
161be3fba05e823f740f65b2679929347dc3dd282adJohn Reck        if (index == FrameInfoIndex::NumIndexes) return 0;
162be3fba05e823f740f65b2679929347dc3dd282adJohn Reck        return mFrameInfo[static_cast<int>(index)];
163be3fba05e823f740f65b2679929347dc3dd282adJohn Reck    }
164be3fba05e823f740f65b2679929347dc3dd282adJohn Reck
165be3fba05e823f740f65b2679929347dc3dd282adJohn Reckprivate:
1661b54fb27ac48495ed0b33868fda5776fb49fe0f3Chris Craik    int64_t mFrameInfo[static_cast<int>(FrameInfoIndex::NumIndexes)];
167ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck};
168ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck
169ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck} /* namespace uirenderer */
170ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck} /* namespace android */
171ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck
172ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck#endif /* FRAMEINFO_H_ */
173