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// This is needed for stdint.h to define INT64_MAX in C++
1882dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis#define __STDC_LIMIT_MACROS
1982dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis
2086efcc0cbc1d94250b72ef1f2ea8700a04cd2781Greg Hackmann#include <inttypes.h>
2186efcc0cbc1d94250b72ef1f2ea8700a04cd2781Greg Hackmann
226547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis#include <cutils/log.h>
236547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis
2482dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis#include <ui/Fence.h>
25d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav#include <ui/FrameStats.h>
2682dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis
2782dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis#include <utils/String8.h>
2882dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis
2982dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis#include "FrameTracker.h"
306547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis#include "EventLog/EventLog.h"
3182dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis
3282dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennisnamespace android {
3382dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis
3482dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie GennisFrameTracker::FrameTracker() :
3582dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        mOffset(0),
366547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis        mNumFences(0),
376547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis        mDisplayPeriod(0) {
386547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    resetFrameCountersLocked();
3982dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis}
4082dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis
4182dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennisvoid FrameTracker::setDesiredPresentTime(nsecs_t presentTime) {
424b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis    Mutex::Autolock lock(mMutex);
4382dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis    mFrameRecords[mOffset].desiredPresentTime = presentTime;
4482dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis}
4582dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis
4682dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennisvoid FrameTracker::setFrameReadyTime(nsecs_t readyTime) {
474b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis    Mutex::Autolock lock(mMutex);
4882dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis    mFrameRecords[mOffset].frameReadyTime = readyTime;
4982dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis}
5082dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis
5182dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennisvoid FrameTracker::setFrameReadyFence(const sp<Fence>& readyFence) {
524b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis    Mutex::Autolock lock(mMutex);
5382dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis    mFrameRecords[mOffset].frameReadyFence = readyFence;
5482dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis    mNumFences++;
5582dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis}
5682dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis
5782dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennisvoid FrameTracker::setActualPresentTime(nsecs_t presentTime) {
584b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis    Mutex::Autolock lock(mMutex);
5982dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis    mFrameRecords[mOffset].actualPresentTime = presentTime;
6082dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis}
6182dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis
6282dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennisvoid FrameTracker::setActualPresentFence(const sp<Fence>& readyFence) {
634b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis    Mutex::Autolock lock(mMutex);
6482dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis    mFrameRecords[mOffset].actualPresentFence = readyFence;
6582dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis    mNumFences++;
6682dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis}
6782dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis
686547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennisvoid FrameTracker::setDisplayRefreshPeriod(nsecs_t displayPeriod) {
696547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    Mutex::Autolock lock(mMutex);
706547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    mDisplayPeriod = displayPeriod;
716547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis}
726547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis
7382dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennisvoid FrameTracker::advanceFrame() {
744b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis    Mutex::Autolock lock(mMutex);
756547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis
766547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    // Update the statistic to include the frame we just finished.
776547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    updateStatsLocked(mOffset);
786547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis
796547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    // Advance to the next frame.
8082dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis    mOffset = (mOffset+1) % NUM_FRAME_RECORDS;
8182dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis    mFrameRecords[mOffset].desiredPresentTime = INT64_MAX;
8282dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis    mFrameRecords[mOffset].frameReadyTime = INT64_MAX;
8382dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis    mFrameRecords[mOffset].actualPresentTime = INT64_MAX;
8482dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis
8582dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis    if (mFrameRecords[mOffset].frameReadyFence != NULL) {
8682dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        // We're clobbering an unsignaled fence, so we need to decrement the
8782dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        // fence count.
8882dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        mFrameRecords[mOffset].frameReadyFence = NULL;
8982dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        mNumFences--;
9082dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis    }
9182dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis
9282dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis    if (mFrameRecords[mOffset].actualPresentFence != NULL) {
9382dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        // We're clobbering an unsignaled fence, so we need to decrement the
9482dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        // fence count.
9582dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        mFrameRecords[mOffset].actualPresentFence = NULL;
9682dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        mNumFences--;
9782dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis    }
9882dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis
9982dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis    // Clean up the signaled fences to keep the number of open fence FDs in
10082dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis    // this process reasonable.
1014b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis    processFencesLocked();
10282dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis}
10382dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis
104d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslavvoid FrameTracker::clearStats() {
1054b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis    Mutex::Autolock lock(mMutex);
10682dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis    for (size_t i = 0; i < NUM_FRAME_RECORDS; i++) {
10782dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        mFrameRecords[i].desiredPresentTime = 0;
10882dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        mFrameRecords[i].frameReadyTime = 0;
10982dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        mFrameRecords[i].actualPresentTime = 0;
11082dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        mFrameRecords[i].frameReadyFence.clear();
11182dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        mFrameRecords[i].actualPresentFence.clear();
11282dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis    }
11382dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis    mNumFences = 0;
1144b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis    mFrameRecords[mOffset].desiredPresentTime = INT64_MAX;
1154b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis    mFrameRecords[mOffset].frameReadyTime = INT64_MAX;
1164b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis    mFrameRecords[mOffset].actualPresentTime = INT64_MAX;
11782dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis}
11882dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis
119d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslavvoid FrameTracker::getStats(FrameStats* outStats) const {
120d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav    Mutex::Autolock lock(mMutex);
121d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav    processFencesLocked();
122d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav
123d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav    outStats->refreshPeriodNano = mDisplayPeriod;
124d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav
125d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav    const size_t offset = mOffset;
126d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav    for (size_t i = 1; i < NUM_FRAME_RECORDS; i++) {
127d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav        const size_t index = (offset + i) % NUM_FRAME_RECORDS;
128d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav
129d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav        // Skip frame records with no data (if buffer not yet full).
130d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav        if (mFrameRecords[index].desiredPresentTime == 0) {
131d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav            continue;
132d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav        }
133d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav
134d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav        nsecs_t desiredPresentTimeNano = mFrameRecords[index].desiredPresentTime;
135d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav        outStats->desiredPresentTimesNano.push_back(desiredPresentTimeNano);
136d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav
137d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav        nsecs_t actualPresentTimeNano = mFrameRecords[index].actualPresentTime;
138d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav        outStats->actualPresentTimesNano.push_back(actualPresentTimeNano);
139d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav
140d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav        nsecs_t frameReadyTimeNano = mFrameRecords[index].frameReadyTime;
141d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav        outStats->frameReadyTimesNano.push_back(frameReadyTimeNano);
142d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav    }
143d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav}
144d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav
1456547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennisvoid FrameTracker::logAndResetStats(const String8& name) {
1466547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    Mutex::Autolock lock(mMutex);
1476547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    logStatsLocked(name);
1486547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    resetFrameCountersLocked();
1496547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis}
1506547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis
1514b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennisvoid FrameTracker::processFencesLocked() const {
15282dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis    FrameRecord* records = const_cast<FrameRecord*>(mFrameRecords);
15382dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis    int& numFences = const_cast<int&>(mNumFences);
15482dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis
15582dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis    for (int i = 1; i < NUM_FRAME_RECORDS && numFences > 0; i++) {
15682dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        size_t idx = (mOffset+NUM_FRAME_RECORDS-i) % NUM_FRAME_RECORDS;
1576547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis        bool updated = false;
15882dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis
15982dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        const sp<Fence>& rfence = records[idx].frameReadyFence;
16082dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        if (rfence != NULL) {
16182dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            records[idx].frameReadyTime = rfence->getSignalTime();
16282dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            if (records[idx].frameReadyTime < INT64_MAX) {
16382dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis                records[idx].frameReadyFence = NULL;
16482dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis                numFences--;
1656547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis                updated = true;
16682dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            }
16782dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        }
16882dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis
16982dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        const sp<Fence>& pfence = records[idx].actualPresentFence;
17082dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        if (pfence != NULL) {
17182dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            records[idx].actualPresentTime = pfence->getSignalTime();
17282dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            if (records[idx].actualPresentTime < INT64_MAX) {
17382dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis                records[idx].actualPresentFence = NULL;
17482dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis                numFences--;
1756547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis                updated = true;
1766547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis            }
1776547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis        }
1786547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis
1796547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis        if (updated) {
1806547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis            updateStatsLocked(idx);
1816547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis        }
1826547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    }
1836547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis}
1846547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis
1856547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennisvoid FrameTracker::updateStatsLocked(size_t newFrameIdx) const {
1866547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    int* numFrames = const_cast<int*>(mNumFrames);
1876547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis
1886547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    if (mDisplayPeriod > 0 && isFrameValidLocked(newFrameIdx)) {
1896547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis        size_t prevFrameIdx = (newFrameIdx+NUM_FRAME_RECORDS-1) %
1906547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis                NUM_FRAME_RECORDS;
1916547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis
1926547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis        if (isFrameValidLocked(prevFrameIdx)) {
1936547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis            nsecs_t newPresentTime =
1946547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis                    mFrameRecords[newFrameIdx].actualPresentTime;
1956547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis            nsecs_t prevPresentTime =
1966547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis                    mFrameRecords[prevFrameIdx].actualPresentTime;
1976547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis
1986547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis            nsecs_t duration = newPresentTime - prevPresentTime;
1996547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis            int numPeriods = int((duration + mDisplayPeriod/2) /
2006547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis                    mDisplayPeriod);
2016547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis
2026547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis            for (int i = 0; i < NUM_FRAME_BUCKETS-1; i++) {
2036547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis                int nextBucket = 1 << (i+1);
2046547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis                if (numPeriods < nextBucket) {
2056547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis                    numFrames[i]++;
2066547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis                    return;
2076547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis                }
20882dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            }
2096547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis
2106547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis            // The last duration bucket is a catch-all.
2116547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis            numFrames[NUM_FRAME_BUCKETS-1]++;
21282dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        }
21382dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis    }
21482dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis}
21582dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis
2166547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennisvoid FrameTracker::resetFrameCountersLocked() {
2176547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    for (int i = 0; i < NUM_FRAME_BUCKETS; i++) {
2186547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis        mNumFrames[i] = 0;
2196547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    }
2206547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis}
2216547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis
2226547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennisvoid FrameTracker::logStatsLocked(const String8& name) const {
2236547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    for (int i = 0; i < NUM_FRAME_BUCKETS; i++) {
2246547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis        if (mNumFrames[i] > 0) {
2256547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis            EventLog::logFrameDurations(name, mNumFrames, NUM_FRAME_BUCKETS);
2266547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis            return;
2276547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis        }
2286547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    }
2296547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis}
2306547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis
2316547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennisbool FrameTracker::isFrameValidLocked(size_t idx) const {
2326547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    return mFrameRecords[idx].actualPresentTime > 0 &&
2336547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis            mFrameRecords[idx].actualPresentTime < INT64_MAX;
2346547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis}
2356547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis
236d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslavvoid FrameTracker::dumpStats(String8& result) const {
2374b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis    Mutex::Autolock lock(mMutex);
2384b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis    processFencesLocked();
23982dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis
24082dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis    const size_t o = mOffset;
24182dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis    for (size_t i = 1; i < NUM_FRAME_RECORDS; i++) {
24282dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        const size_t index = (o+i) % NUM_FRAME_RECORDS;
24386efcc0cbc1d94250b72ef1f2ea8700a04cd2781Greg Hackmann        result.appendFormat("%" PRId64 "\t%" PRId64 "\t%" PRId64 "\n",
24482dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            mFrameRecords[index].desiredPresentTime,
24582dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            mFrameRecords[index].actualPresentTime,
24682dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            mFrameRecords[index].frameReadyTime);
24782dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis    }
24882dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis    result.append("\n");
24982dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis}
25082dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis
25182dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis} // namespace android
252