1e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza/* 2e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza * Copyright 2016 The Android Open Source Project 3e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza * 4e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza * Licensed under the Apache License, Version 2.0 (the "License"); 5e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza * you may not use this file except in compliance with the License. 6e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza * You may obtain a copy of the License at 7e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza * 8e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza * http://www.apache.org/licenses/LICENSE-2.0 9e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza * 10e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza * Unless required by applicable law or agreed to in writing, software 11e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza * distributed under the License is distributed on an "AS IS" BASIS, 12e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza * See the License for the specific language governing permissions and 14e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza * limitations under the License. 15e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza */ 16e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza 17e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza#undef LOG_TAG 18e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza#define LOG_TAG "OccupancyTracker" 19e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza 20e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza#include <gui/OccupancyTracker.h> 21e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza#include <binder/Parcel.h> 22e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza#include <utils/String8.h> 23e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza#include <utils/Trace.h> 24e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza 25e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza#include <inttypes.h> 26e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza 27e77c7669bee30b7c0099172cf0c38cef92412040Dan Stozanamespace android { 28e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza 29e77c7669bee30b7c0099172cf0c38cef92412040Dan Stozastatus_t OccupancyTracker::Segment::writeToParcel(Parcel* parcel) const { 30e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza status_t result = parcel->writeInt64(totalTime); 31e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza if (result != OK) { 32e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza return result; 33e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza } 34e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza result = parcel->writeUint64(static_cast<uint64_t>(numFrames)); 35e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza if (result != OK) { 36e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza return result; 37e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza } 38e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza result = parcel->writeFloat(occupancyAverage); 39e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza if (result != OK) { 40e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza return result; 41e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza } 42e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza return parcel->writeBool(usedThirdBuffer); 43e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza} 44e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza 45e77c7669bee30b7c0099172cf0c38cef92412040Dan Stozastatus_t OccupancyTracker::Segment::readFromParcel(const Parcel* parcel) { 46e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza status_t result = parcel->readInt64(&totalTime); 47e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza if (result != OK) { 48e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza return result; 49e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza } 50e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza uint64_t uintNumFrames = 0; 51e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza result = parcel->readUint64(&uintNumFrames); 52e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza if (result != OK) { 53e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza return result; 54e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza } 55e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza numFrames = static_cast<size_t>(uintNumFrames); 56e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza result = parcel->readFloat(&occupancyAverage); 57e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza if (result != OK) { 58e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza return result; 59e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza } 60e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza return parcel->readBool(&usedThirdBuffer); 61e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza} 62e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza 63e77c7669bee30b7c0099172cf0c38cef92412040Dan Stozavoid OccupancyTracker::registerOccupancyChange(size_t occupancy) { 64e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza ATRACE_CALL(); 65e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza nsecs_t now = systemTime(); 66e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza nsecs_t delta = now - mLastOccupancyChangeTime; 67e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza if (delta > NEW_SEGMENT_DELAY) { 68e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza recordPendingSegment(); 69e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza } else { 70e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza mPendingSegment.totalTime += delta; 71e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza if (mPendingSegment.mOccupancyTimes.count(mLastOccupancy)) { 72e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza mPendingSegment.mOccupancyTimes[mLastOccupancy] += delta; 73e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza } else { 74e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza mPendingSegment.mOccupancyTimes[mLastOccupancy] = delta; 75e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza } 76e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza } 77e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza if (occupancy > mLastOccupancy) { 78e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza ++mPendingSegment.numFrames; 79e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza } 80e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza mLastOccupancyChangeTime = now; 81e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza mLastOccupancy = occupancy; 82e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza} 83e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza 84e77c7669bee30b7c0099172cf0c38cef92412040Dan Stozastd::vector<OccupancyTracker::Segment> OccupancyTracker::getSegmentHistory( 85e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza bool forceFlush) { 86e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza if (forceFlush) { 87e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza recordPendingSegment(); 88e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza } 89e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza std::vector<Segment> segments(mSegmentHistory.cbegin(), 90e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza mSegmentHistory.cend()); 91e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza mSegmentHistory.clear(); 92e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza return segments; 93e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza} 94e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza 95e77c7669bee30b7c0099172cf0c38cef92412040Dan Stozavoid OccupancyTracker::recordPendingSegment() { 96e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza // Only record longer segments to get a better measurement of actual double- 97e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza // vs. triple-buffered time 98e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza if (mPendingSegment.numFrames > LONG_SEGMENT_THRESHOLD) { 99e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza float occupancyAverage = 0.0f; 100e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza bool usedThirdBuffer = false; 101e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza for (const auto& timePair : mPendingSegment.mOccupancyTimes) { 102e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza size_t occupancy = timePair.first; 103e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza float timeRatio = static_cast<float>(timePair.second) / 104e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza mPendingSegment.totalTime; 105e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza occupancyAverage += timeRatio * occupancy; 106e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza usedThirdBuffer = usedThirdBuffer || (occupancy > 1); 107e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza } 108e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza mSegmentHistory.push_front({mPendingSegment.totalTime, 109e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza mPendingSegment.numFrames, occupancyAverage, usedThirdBuffer}); 110e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza if (mSegmentHistory.size() > MAX_HISTORY_SIZE) { 111e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza mSegmentHistory.pop_back(); 112e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza } 113e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza } 114e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza mPendingSegment.clear(); 115e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza} 116e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza 117e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza} // namespace android 118