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