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
512d5b8d73929a38b019c6b6276d4a19542b990f0cJohn Reck    DequeueBufferDuration,
522d5b8d73929a38b019c6b6276d4a19542b990f0cJohn Reck    QueueBufferDuration,
532d5b8d73929a38b019c6b6276d4a19542b990f0cJohn Reck
54ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck    // Must be the last value!
5565ddb154c75126bbef8bf03494e6fd0d98ee0127John Reck    // Also must be kept in sync with FrameMetrics.java#FRAME_STATS_COUNT
561b54fb27ac48495ed0b33868fda5776fb49fe0f3Chris Craik    NumIndexes
57c87be99c6ead0720a8918ea38ce3b25e5c49e1c6John Reck};
58ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck
592a8bb05a31ddd0d44d8513cba9fbd9b4ef9b97f6John Reckextern const std::string FrameInfoNames[];
604db3d17debef68f72d23999d69ae68b75f59dda3John Reck
611b54fb27ac48495ed0b33868fda5776fb49fe0f3Chris Craiknamespace FrameInfoFlags {
621b54fb27ac48495ed0b33868fda5776fb49fe0f3Chris Craik    enum {
631b54fb27ac48495ed0b33868fda5776fb49fe0f3Chris Craik        WindowLayoutChanged = 1 << 0,
641b54fb27ac48495ed0b33868fda5776fb49fe0f3Chris Craik        RTAnimation = 1 << 1,
651b54fb27ac48495ed0b33868fda5776fb49fe0f3Chris Craik        SurfaceCanvas = 1 << 2,
661b54fb27ac48495ed0b33868fda5776fb49fe0f3Chris Craik        SkippedFrame = 1 << 3,
671b54fb27ac48495ed0b33868fda5776fb49fe0f3Chris Craik    };
68c87be99c6ead0720a8918ea38ce3b25e5c49e1c6John Reck};
69ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck
70ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reckclass ANDROID_API UiFrameInfoBuilder {
71ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reckpublic:
72faecb78a6b11c780db47bc940ca7662899ab5d5eChih-Hung Hsieh    explicit UiFrameInfoBuilder(int64_t* buffer) : mBuffer(buffer) {
73ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck        memset(mBuffer, 0, UI_THREAD_FRAME_INFO_SIZE * sizeof(int64_t));
74ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck    }
75ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck
76ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck    UiFrameInfoBuilder& setVsync(nsecs_t vsyncTime, nsecs_t intendedVsync) {
771b54fb27ac48495ed0b33868fda5776fb49fe0f3Chris Craik        set(FrameInfoIndex::Vsync) = vsyncTime;
781b54fb27ac48495ed0b33868fda5776fb49fe0f3Chris Craik        set(FrameInfoIndex::IntendedVsync) = intendedVsync;
79bf3c602284f9a344faf185c3a5e94a264ba44c4fJohn Reck        // Pretend the other fields are all at vsync, too, so that naive
80bf3c602284f9a344faf185c3a5e94a264ba44c4fJohn Reck        // duration calculations end up being 0 instead of very large
811b54fb27ac48495ed0b33868fda5776fb49fe0f3Chris Craik        set(FrameInfoIndex::HandleInputStart) = vsyncTime;
821b54fb27ac48495ed0b33868fda5776fb49fe0f3Chris Craik        set(FrameInfoIndex::AnimationStart) = vsyncTime;
831b54fb27ac48495ed0b33868fda5776fb49fe0f3Chris Craik        set(FrameInfoIndex::PerformTraversalsStart) = vsyncTime;
841b54fb27ac48495ed0b33868fda5776fb49fe0f3Chris Craik        set(FrameInfoIndex::DrawStart) = vsyncTime;
85ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck        return *this;
86ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck    }
87ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck
881b54fb27ac48495ed0b33868fda5776fb49fe0f3Chris Craik    UiFrameInfoBuilder& addFlag(int frameInfoFlag) {
891b54fb27ac48495ed0b33868fda5776fb49fe0f3Chris Craik        set(FrameInfoIndex::Flags) |= static_cast<uint64_t>(frameInfoFlag);
90ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck        return *this;
91ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck    }
92ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck
93ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reckprivate:
94c87be99c6ead0720a8918ea38ce3b25e5c49e1c6John Reck    inline int64_t& set(FrameInfoIndex index) {
95c87be99c6ead0720a8918ea38ce3b25e5c49e1c6John Reck        return mBuffer[static_cast<int>(index)];
96c87be99c6ead0720a8918ea38ce3b25e5c49e1c6John Reck    }
97c87be99c6ead0720a8918ea38ce3b25e5c49e1c6John Reck
98ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck    int64_t* mBuffer;
99ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck};
100ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck
101ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reckclass FrameInfo {
102ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reckpublic:
103ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck    void importUiThreadInfo(int64_t* info);
104ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck
105ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck    void markSyncStart() {
1061b54fb27ac48495ed0b33868fda5776fb49fe0f3Chris Craik        set(FrameInfoIndex::SyncStart) = systemTime(CLOCK_MONOTONIC);
107ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck    }
108ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck
109ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck    void markIssueDrawCommandsStart() {
1101b54fb27ac48495ed0b33868fda5776fb49fe0f3Chris Craik        set(FrameInfoIndex::IssueDrawCommandsStart) = systemTime(CLOCK_MONOTONIC);
111ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck    }
112ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck
113ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck    void markSwapBuffers() {
1141b54fb27ac48495ed0b33868fda5776fb49fe0f3Chris Craik        set(FrameInfoIndex::SwapBuffers) = systemTime(CLOCK_MONOTONIC);
115ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck    }
116ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck
117ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck    void markFrameCompleted() {
1181b54fb27ac48495ed0b33868fda5776fb49fe0f3Chris Craik        set(FrameInfoIndex::FrameCompleted) = systemTime(CLOCK_MONOTONIC);
119ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck    }
120ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck
1211b54fb27ac48495ed0b33868fda5776fb49fe0f3Chris Craik    void addFlag(int frameInfoFlag) {
1221b54fb27ac48495ed0b33868fda5776fb49fe0f3Chris Craik        set(FrameInfoIndex::Flags) |= static_cast<uint64_t>(frameInfoFlag);
123240ff6246a29602539fd0295274e1c769e743a2eJohn Reck    }
124240ff6246a29602539fd0295274e1c769e743a2eJohn Reck
12506f5bc70a667a02b14e31d3f53f91d3661e30666Andres Morales    const int64_t* data() const {
12606f5bc70a667a02b14e31d3f53f91d3661e30666Andres Morales        return mFrameInfo;
12706f5bc70a667a02b14e31d3f53f91d3661e30666Andres Morales    }
12806f5bc70a667a02b14e31d3f53f91d3661e30666Andres Morales
12941300274cf8efde2ca95d3c767b214d1edb97f8dJohn Reck    inline int64_t operator[](FrameInfoIndex index) const {
130be3fba05e823f740f65b2679929347dc3dd282adJohn Reck        return get(index);
131ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck    }
132ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck
13341300274cf8efde2ca95d3c767b214d1edb97f8dJohn Reck    inline int64_t operator[](int index) const {
1341b54fb27ac48495ed0b33868fda5776fb49fe0f3Chris Craik        if (index < 0 || index >= static_cast<int>(FrameInfoIndex::NumIndexes)) return 0;
135c87be99c6ead0720a8918ea38ce3b25e5c49e1c6John Reck        return mFrameInfo[index];
136ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck    }
137ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck
13841300274cf8efde2ca95d3c767b214d1edb97f8dJohn Reck    inline int64_t duration(FrameInfoIndex start, FrameInfoIndex end) const {
139be3fba05e823f740f65b2679929347dc3dd282adJohn Reck        int64_t endtime = get(end);
140be3fba05e823f740f65b2679929347dc3dd282adJohn Reck        int64_t starttime = get(start);
14141300274cf8efde2ca95d3c767b214d1edb97f8dJohn Reck        int64_t gap = endtime - starttime;
14241300274cf8efde2ca95d3c767b214d1edb97f8dJohn Reck        gap = starttime > 0 ? gap : 0;
143be3fba05e823f740f65b2679929347dc3dd282adJohn Reck        if (end > FrameInfoIndex::SyncQueued &&
144be3fba05e823f740f65b2679929347dc3dd282adJohn Reck                start < FrameInfoIndex::SyncQueued) {
145be3fba05e823f740f65b2679929347dc3dd282adJohn Reck            // Need to subtract out the time spent in a stalled state
146be3fba05e823f740f65b2679929347dc3dd282adJohn Reck            // as this will be captured by the previous frame's info
147be3fba05e823f740f65b2679929347dc3dd282adJohn Reck            int64_t offset = get(FrameInfoIndex::SyncStart)
148be3fba05e823f740f65b2679929347dc3dd282adJohn Reck                    - get(FrameInfoIndex::SyncQueued);
149be3fba05e823f740f65b2679929347dc3dd282adJohn Reck            if (offset > 0) {
150be3fba05e823f740f65b2679929347dc3dd282adJohn Reck                gap -= offset;
151be3fba05e823f740f65b2679929347dc3dd282adJohn Reck            }
152be3fba05e823f740f65b2679929347dc3dd282adJohn Reck        }
15341300274cf8efde2ca95d3c767b214d1edb97f8dJohn Reck        return gap > 0 ? gap : 0;
15441300274cf8efde2ca95d3c767b214d1edb97f8dJohn Reck    }
15541300274cf8efde2ca95d3c767b214d1edb97f8dJohn Reck
15641300274cf8efde2ca95d3c767b214d1edb97f8dJohn Reck    inline int64_t totalDuration() const {
15741300274cf8efde2ca95d3c767b214d1edb97f8dJohn Reck        return duration(FrameInfoIndex::IntendedVsync, FrameInfoIndex::FrameCompleted);
15841300274cf8efde2ca95d3c767b214d1edb97f8dJohn Reck    }
15941300274cf8efde2ca95d3c767b214d1edb97f8dJohn Reck
160c87be99c6ead0720a8918ea38ce3b25e5c49e1c6John Reck    inline int64_t& set(FrameInfoIndex index) {
161c87be99c6ead0720a8918ea38ce3b25e5c49e1c6John Reck        return mFrameInfo[static_cast<int>(index)];
162c87be99c6ead0720a8918ea38ce3b25e5c49e1c6John Reck    }
163c87be99c6ead0720a8918ea38ce3b25e5c49e1c6John Reck
164be3fba05e823f740f65b2679929347dc3dd282adJohn Reck    inline int64_t get(FrameInfoIndex index) const {
165be3fba05e823f740f65b2679929347dc3dd282adJohn Reck        if (index == FrameInfoIndex::NumIndexes) return 0;
166be3fba05e823f740f65b2679929347dc3dd282adJohn Reck        return mFrameInfo[static_cast<int>(index)];
167be3fba05e823f740f65b2679929347dc3dd282adJohn Reck    }
168be3fba05e823f740f65b2679929347dc3dd282adJohn Reck
169be3fba05e823f740f65b2679929347dc3dd282adJohn Reckprivate:
1701b54fb27ac48495ed0b33868fda5776fb49fe0f3Chris Craik    int64_t mFrameInfo[static_cast<int>(FrameInfoIndex::NumIndexes)];
171ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck};
172ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck
173ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck} /* namespace uirenderer */
174ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck} /* namespace android */
175ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck
176ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck#endif /* FRAMEINFO_H_ */
177