182dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis/* 282dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis * Copyright (C) 2012 The Android Open Source Project 382dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis * 482dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis * Licensed under the Apache License, Version 2.0 (the "License"); 582dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis * you may not use this file except in compliance with the License. 682dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis * You may obtain a copy of the License at 782dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis * 882dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis * http://www.apache.org/licenses/LICENSE-2.0 982dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis * 1082dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis * Unless required by applicable law or agreed to in writing, software 1182dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis * distributed under the License is distributed on an "AS IS" BASIS, 1282dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1382dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis * See the License for the specific language governing permissions and 1482dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis * limitations under the License. 1582dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis */ 1682dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis 1782dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis#ifndef ANDROID_FRAMETRACKER_H 1882dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis#define ANDROID_FRAMETRACKER_H 1982dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis 2082dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis#include <stddef.h> 2182dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis 224b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis#include <utils/Mutex.h> 2382dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis#include <utils/Timers.h> 2482dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis#include <utils/RefBase.h> 2582dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis 2682dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennisnamespace android { 2782dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis 2882dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennisclass String8; 2982dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennisclass Fence; 3082dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis 3182dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis// FrameTracker tracks information about the most recently rendered frames. It 3282dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis// uses a circular buffer of frame records, and is *NOT* thread-safe - 3382dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis// mutexing must be done at a higher level if multi-threaded access is 3482dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis// possible. 3582dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis// 3682dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis// Some of the time values tracked may be set either as a specific timestamp 3782dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis// or a fence. When a non-NULL fence is set for a given time value, the 3882dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis// signal time of that fence is used instead of the timestamp. 3982dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennisclass FrameTracker { 4082dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis 4182dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennispublic: 4282dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis // NUM_FRAME_RECORDS is the size of the circular buffer used to track the 4382dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis // frame time history. 4482dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis enum { NUM_FRAME_RECORDS = 128 }; 4582dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis 466547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis enum { NUM_FRAME_BUCKETS = 7 }; 476547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis 4882dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis FrameTracker(); 4982dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis 5082dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis // setDesiredPresentTime sets the time at which the current frame 5182dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis // should be presented to the user under ideal (i.e. zero latency) 5282dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis // conditions. 5382dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis void setDesiredPresentTime(nsecs_t desiredPresentTime); 5482dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis 5582dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis // setFrameReadyTime sets the time at which the current frame became ready 5682dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis // to be presented to the user. For example, if the frame contents is 5782dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis // being written to memory by some asynchronous hardware, this would be 5882dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis // the time at which those writes completed. 5982dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis void setFrameReadyTime(nsecs_t readyTime); 6082dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis 6182dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis // setFrameReadyFence sets the fence that is used to get the time at which 6282dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis // the current frame became ready to be presented to the user. 6382dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis void setFrameReadyFence(const sp<Fence>& readyFence); 6482dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis 6582dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis // setActualPresentTime sets the timestamp at which the current frame became 6682dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis // visible to the user. 6782dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis void setActualPresentTime(nsecs_t displayTime); 6882dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis 6982dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis // setActualPresentFence sets the fence that is used to get the time 7082dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis // at which the current frame became visible to the user. 7182dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis void setActualPresentFence(const sp<Fence>& fence); 7282dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis 736547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis // setDisplayRefreshPeriod sets the display refresh period in nanoseconds. 746547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis // This is used to compute frame presentation duration statistics relative 756547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis // to this period. 766547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis void setDisplayRefreshPeriod(nsecs_t displayPeriod); 776547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis 7882dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis // advanceFrame advances the frame tracker to the next frame. 7982dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis void advanceFrame(); 8082dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis 8182dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis // clear resets all the tracked frame data to zero. 8282dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis void clear(); 8382dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis 846547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis // logAndResetStats dumps the current statistics to the binary event log 856547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis // and then resets the accumulated statistics to their initial values. 866547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis void logAndResetStats(const String8& name); 876547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis 8882dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis // dump appends the current frame display time history to the result string. 8982dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis void dump(String8& result) const; 9082dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis 9182dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennisprivate: 9282dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis struct FrameRecord { 9382dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis FrameRecord() : 9482dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis desiredPresentTime(0), 9582dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis frameReadyTime(0), 9682dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis actualPresentTime(0) {} 9782dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis nsecs_t desiredPresentTime; 9882dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis nsecs_t frameReadyTime; 9982dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis nsecs_t actualPresentTime; 10082dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis sp<Fence> frameReadyFence; 10182dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis sp<Fence> actualPresentFence; 10282dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis }; 10382dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis 10482dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis // processFences iterates over all the frame records that have a fence set 10582dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis // and replaces that fence with a timestamp if the fence has signaled. If 10682dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis // the fence is not signaled the record's displayTime is set to INT64_MAX. 10782dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis // 10882dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis // This method is const because although it modifies the frame records it 10982dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis // does so in such a way that the information represented should not 11082dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis // change. This allows it to be called from the dump method. 1114b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis void processFencesLocked() const; 11282dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis 1136547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis // updateStatsLocked updates the running statistics that are gathered 1146547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis // about the frame times. 1156547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis void updateStatsLocked(size_t newFrameIdx) const; 1166547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis 1176547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis // resetFrameCounteresLocked sets all elements of the mNumFrames array to 1186547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis // 0. 1196547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis void resetFrameCountersLocked(); 1206547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis 1216547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis // logStatsLocked dumps the current statistics to the binary event log. 1226547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis void logStatsLocked(const String8& name) const; 1236547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis 1246547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis // isFrameValidLocked returns true if the data for the given frame index is 1256547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis // valid and has all arrived (i.e. there are no oustanding fences). 1266547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis bool isFrameValidLocked(size_t idx) const; 1276547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis 12882dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis // mFrameRecords is the circular buffer storing the tracked data for each 12982dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis // frame. 13082dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis FrameRecord mFrameRecords[NUM_FRAME_RECORDS]; 13182dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis 13282dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis // mOffset is the offset into mFrameRecords of the current frame. 13382dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis size_t mOffset; 13482dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis 13582dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis // mNumFences is the total number of fences set in the frame records. It 13682dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis // is incremented each time a fence is added and decremented each time a 13782dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis // signaled fence is removed in processFences or if advanceFrame clobbers 13882dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis // a fence. 13982dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis // 14082dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis // The number of fences is tracked so that the run time of processFences 14182dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis // doesn't grow with NUM_FRAME_RECORDS. 14282dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis int mNumFences; 1434b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis 1446547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis // mNumFrames keeps a count of the number of frames with a duration in a 1456547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis // particular range of vsync periods. Element n of the array stores the 1466547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis // number of frames with duration in the half-inclusive range 1476547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis // [2^n, 2^(n+1)). The last element of the array contains the count for 1486547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis // all frames with duration greater than 2^(NUM_FRAME_BUCKETS-1). 1496547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis int32_t mNumFrames[NUM_FRAME_BUCKETS]; 1506547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis 1516547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis // mDisplayPeriod is the display refresh period of the display for which 1526547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis // this FrameTracker is gathering information. 1536547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis nsecs_t mDisplayPeriod; 1546547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis 1554b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis // mMutex is used to protect access to all member variables. 1564b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis mutable Mutex mMutex; 15782dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis}; 15882dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis 15982dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis} 16082dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis 16182dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis#endif // ANDROID_FRAMETRACKER_H 162