blob: 5c66ff9c93c7463aa6c4019c2540368b0d14c6c1 [file] [log] [blame]
Jamie Gennis82dbc742012-11-08 19:23:28 -08001/*
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 mFrameRecords[mOffset].desiredPresentTime = presentTime;
35}
36
37void FrameTracker::setFrameReadyTime(nsecs_t readyTime) {
38 mFrameRecords[mOffset].frameReadyTime = readyTime;
39}
40
41void FrameTracker::setFrameReadyFence(const sp<Fence>& readyFence) {
42 mFrameRecords[mOffset].frameReadyFence = readyFence;
43 mNumFences++;
44}
45
46void FrameTracker::setActualPresentTime(nsecs_t presentTime) {
47 mFrameRecords[mOffset].actualPresentTime = presentTime;
48}
49
50void FrameTracker::setActualPresentFence(const sp<Fence>& readyFence) {
51 mFrameRecords[mOffset].actualPresentFence = readyFence;
52 mNumFences++;
53}
54
55void FrameTracker::advanceFrame() {
56 mOffset = (mOffset+1) % NUM_FRAME_RECORDS;
57 mFrameRecords[mOffset].desiredPresentTime = INT64_MAX;
58 mFrameRecords[mOffset].frameReadyTime = INT64_MAX;
59 mFrameRecords[mOffset].actualPresentTime = INT64_MAX;
60
61 if (mFrameRecords[mOffset].frameReadyFence != NULL) {
62 // We're clobbering an unsignaled fence, so we need to decrement the
63 // fence count.
64 mFrameRecords[mOffset].frameReadyFence = NULL;
65 mNumFences--;
66 }
67
68 if (mFrameRecords[mOffset].actualPresentFence != NULL) {
69 // We're clobbering an unsignaled fence, so we need to decrement the
70 // fence count.
71 mFrameRecords[mOffset].actualPresentFence = NULL;
72 mNumFences--;
73 }
74
75 // Clean up the signaled fences to keep the number of open fence FDs in
76 // this process reasonable.
77 processFences();
78}
79
80void FrameTracker::clear() {
81 for (size_t i = 0; i < NUM_FRAME_RECORDS; i++) {
82 mFrameRecords[i].desiredPresentTime = 0;
83 mFrameRecords[i].frameReadyTime = 0;
84 mFrameRecords[i].actualPresentTime = 0;
85 mFrameRecords[i].frameReadyFence.clear();
86 mFrameRecords[i].actualPresentFence.clear();
87 }
88 mNumFences = 0;
89}
90
91void FrameTracker::processFences() const {
92 FrameRecord* records = const_cast<FrameRecord*>(mFrameRecords);
93 int& numFences = const_cast<int&>(mNumFences);
94
95 for (int i = 1; i < NUM_FRAME_RECORDS && numFences > 0; i++) {
96 size_t idx = (mOffset+NUM_FRAME_RECORDS-i) % NUM_FRAME_RECORDS;
97
98 const sp<Fence>& rfence = records[idx].frameReadyFence;
99 if (rfence != NULL) {
100 records[idx].frameReadyTime = rfence->getSignalTime();
101 if (records[idx].frameReadyTime < INT64_MAX) {
102 records[idx].frameReadyFence = NULL;
103 numFences--;
104 }
105 }
106
107 const sp<Fence>& pfence = records[idx].actualPresentFence;
108 if (pfence != NULL) {
109 records[idx].actualPresentTime = pfence->getSignalTime();
110 if (records[idx].actualPresentTime < INT64_MAX) {
111 records[idx].actualPresentFence = NULL;
112 numFences--;
113 }
114 }
115 }
116}
117
118void FrameTracker::dump(String8& result) const {
119 processFences();
120
121 const size_t o = mOffset;
122 for (size_t i = 1; i < NUM_FRAME_RECORDS; i++) {
123 const size_t index = (o+i) % NUM_FRAME_RECORDS;
124 result.appendFormat("%lld\t%lld\t%lld\n",
125 mFrameRecords[index].desiredPresentTime,
126 mFrameRecords[index].actualPresentTime,
127 mFrameRecords[index].frameReadyTime);
128 }
129 result.append("\n");
130}
131
132} // namespace android