• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
26 namespace android {
27 
FrameTracker()28 FrameTracker::FrameTracker() :
29         mOffset(0),
30         mNumFences(0) {
31 }
32 
setDesiredPresentTime(nsecs_t presentTime)33 void FrameTracker::setDesiredPresentTime(nsecs_t presentTime) {
34     Mutex::Autolock lock(mMutex);
35     mFrameRecords[mOffset].desiredPresentTime = presentTime;
36 }
37 
setFrameReadyTime(nsecs_t readyTime)38 void FrameTracker::setFrameReadyTime(nsecs_t readyTime) {
39     Mutex::Autolock lock(mMutex);
40     mFrameRecords[mOffset].frameReadyTime = readyTime;
41 }
42 
setFrameReadyFence(const sp<Fence> & readyFence)43 void FrameTracker::setFrameReadyFence(const sp<Fence>& readyFence) {
44     Mutex::Autolock lock(mMutex);
45     mFrameRecords[mOffset].frameReadyFence = readyFence;
46     mNumFences++;
47 }
48 
setActualPresentTime(nsecs_t presentTime)49 void FrameTracker::setActualPresentTime(nsecs_t presentTime) {
50     Mutex::Autolock lock(mMutex);
51     mFrameRecords[mOffset].actualPresentTime = presentTime;
52 }
53 
setActualPresentFence(const sp<Fence> & readyFence)54 void FrameTracker::setActualPresentFence(const sp<Fence>& readyFence) {
55     Mutex::Autolock lock(mMutex);
56     mFrameRecords[mOffset].actualPresentFence = readyFence;
57     mNumFences++;
58 }
59 
advanceFrame()60 void 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 
clear()86 void 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 
processFencesLocked() const101 void 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 
dump(String8 & result) const128 void 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