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