FrameTracker.cpp revision 4b0eba949cc026ffb2c75313042d8a7bcb3fcf86
1/* 2 * Copyright (C) 2012 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17// This is needed for stdint.h to define INT64_MAX in C++ 18#define __STDC_LIMIT_MACROS 19 20#include <ui/Fence.h> 21 22#include <utils/String8.h> 23 24#include "FrameTracker.h" 25 26namespace android { 27 28FrameTracker::FrameTracker() : 29 mOffset(0), 30 mNumFences(0) { 31} 32 33void FrameTracker::setDesiredPresentTime(nsecs_t presentTime) { 34 Mutex::Autolock lock(mMutex); 35 mFrameRecords[mOffset].desiredPresentTime = presentTime; 36} 37 38void FrameTracker::setFrameReadyTime(nsecs_t readyTime) { 39 Mutex::Autolock lock(mMutex); 40 mFrameRecords[mOffset].frameReadyTime = readyTime; 41} 42 43void FrameTracker::setFrameReadyFence(const sp<Fence>& readyFence) { 44 Mutex::Autolock lock(mMutex); 45 mFrameRecords[mOffset].frameReadyFence = readyFence; 46 mNumFences++; 47} 48 49void FrameTracker::setActualPresentTime(nsecs_t presentTime) { 50 Mutex::Autolock lock(mMutex); 51 mFrameRecords[mOffset].actualPresentTime = presentTime; 52} 53 54void FrameTracker::setActualPresentFence(const sp<Fence>& readyFence) { 55 Mutex::Autolock lock(mMutex); 56 mFrameRecords[mOffset].actualPresentFence = readyFence; 57 mNumFences++; 58} 59 60void FrameTracker::advanceFrame() { 61 Mutex::Autolock lock(mMutex); 62 mOffset = (mOffset+1) % NUM_FRAME_RECORDS; 63 mFrameRecords[mOffset].desiredPresentTime = INT64_MAX; 64 mFrameRecords[mOffset].frameReadyTime = INT64_MAX; 65 mFrameRecords[mOffset].actualPresentTime = INT64_MAX; 66 67 if (mFrameRecords[mOffset].frameReadyFence != NULL) { 68 // We're clobbering an unsignaled fence, so we need to decrement the 69 // fence count. 70 mFrameRecords[mOffset].frameReadyFence = NULL; 71 mNumFences--; 72 } 73 74 if (mFrameRecords[mOffset].actualPresentFence != NULL) { 75 // We're clobbering an unsignaled fence, so we need to decrement the 76 // fence count. 77 mFrameRecords[mOffset].actualPresentFence = NULL; 78 mNumFences--; 79 } 80 81 // Clean up the signaled fences to keep the number of open fence FDs in 82 // this process reasonable. 83 processFencesLocked(); 84} 85 86void FrameTracker::clear() { 87 Mutex::Autolock lock(mMutex); 88 for (size_t i = 0; i < NUM_FRAME_RECORDS; i++) { 89 mFrameRecords[i].desiredPresentTime = 0; 90 mFrameRecords[i].frameReadyTime = 0; 91 mFrameRecords[i].actualPresentTime = 0; 92 mFrameRecords[i].frameReadyFence.clear(); 93 mFrameRecords[i].actualPresentFence.clear(); 94 } 95 mNumFences = 0; 96 mFrameRecords[mOffset].desiredPresentTime = INT64_MAX; 97 mFrameRecords[mOffset].frameReadyTime = INT64_MAX; 98 mFrameRecords[mOffset].actualPresentTime = INT64_MAX; 99} 100 101void FrameTracker::processFencesLocked() const { 102 FrameRecord* records = const_cast<FrameRecord*>(mFrameRecords); 103 int& numFences = const_cast<int&>(mNumFences); 104 105 for (int i = 1; i < NUM_FRAME_RECORDS && numFences > 0; i++) { 106 size_t idx = (mOffset+NUM_FRAME_RECORDS-i) % NUM_FRAME_RECORDS; 107 108 const sp<Fence>& rfence = records[idx].frameReadyFence; 109 if (rfence != NULL) { 110 records[idx].frameReadyTime = rfence->getSignalTime(); 111 if (records[idx].frameReadyTime < INT64_MAX) { 112 records[idx].frameReadyFence = NULL; 113 numFences--; 114 } 115 } 116 117 const sp<Fence>& pfence = records[idx].actualPresentFence; 118 if (pfence != NULL) { 119 records[idx].actualPresentTime = pfence->getSignalTime(); 120 if (records[idx].actualPresentTime < INT64_MAX) { 121 records[idx].actualPresentFence = NULL; 122 numFences--; 123 } 124 } 125 } 126} 127 128void FrameTracker::dump(String8& result) const { 129 Mutex::Autolock lock(mMutex); 130 processFencesLocked(); 131 132 const size_t o = mOffset; 133 for (size_t i = 1; i < NUM_FRAME_RECORDS; i++) { 134 const size_t index = (o+i) % NUM_FRAME_RECORDS; 135 result.appendFormat("%lld\t%lld\t%lld\n", 136 mFrameRecords[index].desiredPresentTime, 137 mFrameRecords[index].actualPresentTime, 138 mFrameRecords[index].frameReadyTime); 139 } 140 result.append("\n"); 141} 142 143} // namespace android 144