blob: 7da1d936c176039d58a88b9e03972138b739e33b [file] [log] [blame]
Pablo Ceballos40845df2016-01-25 17:41:15 -08001/*
2 * Copyright 2016 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#include <inttypes.h>
18#include "FenceTracker.h"
19#include "Layer.h"
20
21namespace android {
22
23FenceTracker::FenceTracker() :
24 mFrameCounter(0),
25 mOffset(0),
26 mFrames() {}
27
28void FenceTracker::dump(String8* outString) {
29 Mutex::Autolock lock(mMutex);
30 checkFencesForCompletion();
31
32 for (size_t i = 0; i < MAX_FRAME_HISTORY; i++) {
33 int index = (mOffset + i) % MAX_FRAME_HISTORY;
34 const FrameRecord& frame = mFrames[index];
35
36 outString->appendFormat("Frame %" PRIu64 "\n", frame.frameId);
37 outString->appendFormat("- Refresh start\t%" PRId64 "\n",
38 frame.refreshStartTime);
39
40 if (frame.glesCompositionDoneTime) {
41 outString->appendFormat("- GLES done\t%" PRId64 "\n",
42 frame.glesCompositionDoneTime);
43 } else if (frame.glesCompositionDoneFence != Fence::NO_FENCE) {
44 outString->append("- GLES done\tNot signaled\n");
45 }
46 if (frame.retireTime) {
47 outString->appendFormat("- Retire\t%" PRId64 "\n",
48 frame.retireTime);
49 } else {
50 outString->append("- Retire\tNot signaled\n");
51 }
52 for (const auto& kv : frame.layers) {
53 const LayerRecord& layer = kv.second;
54 outString->appendFormat("-- %s\n", layer.name.string());
55 outString->appendFormat("---- Frame # %" PRIu64 " (%s)\n",
56 layer.frameNumber,
57 layer.isGlesComposition ? "GLES" : "HWC");
58 outString->appendFormat("---- Posted\t%" PRId64 "\n",
59 layer.postedTime);
60 if (layer.acquireTime) {
61 outString->appendFormat("---- Acquire\t%" PRId64 "\n",
62 layer.acquireTime);
63 } else {
64 outString->append("---- Acquire\tNot signaled\n");
65 }
66 if (layer.releaseTime) {
67 outString->appendFormat("---- Release\t%" PRId64 "\n",
68 layer.releaseTime);
69 } else {
70 outString->append("---- Release\tNot signaled\n");
71 }
72 }
73 }
74}
75
76static inline bool isValidTimestamp(nsecs_t time) {
77 return time > 0 && time < INT64_MAX;
78}
79
80void FenceTracker::checkFencesForCompletion() {
81 for (auto& frame : mFrames) {
82 if (frame.retireFence != Fence::NO_FENCE) {
83 nsecs_t time = frame.retireFence->getSignalTime();
84 if (isValidTimestamp(time)) {
85 frame.retireTime = time;
86 frame.retireFence = Fence::NO_FENCE;
87 }
88 }
89 if (frame.glesCompositionDoneFence != Fence::NO_FENCE) {
90 nsecs_t time = frame.glesCompositionDoneFence->getSignalTime();
91 if (isValidTimestamp(time)) {
92 frame.glesCompositionDoneTime = time;
93 frame.glesCompositionDoneFence = Fence::NO_FENCE;
94 }
95 }
96 for (auto& kv : frame.layers) {
97 LayerRecord& layer = kv.second;
98 if (layer.acquireFence != Fence::NO_FENCE) {
99 nsecs_t time = layer.acquireFence->getSignalTime();
100 if (isValidTimestamp(time)) {
101 layer.acquireTime = time;
102 layer.acquireFence = Fence::NO_FENCE;
103 }
104 }
105 if (layer.releaseFence != Fence::NO_FENCE) {
106 nsecs_t time = layer.releaseFence->getSignalTime();
107 if (isValidTimestamp(time)) {
108 layer.releaseTime = time;
109 layer.releaseFence = Fence::NO_FENCE;
110 }
111 }
112 }
113 }
114}
115
116void FenceTracker::addFrame(nsecs_t refreshStartTime, sp<Fence> retireFence,
117 const Vector<sp<Layer>>& layers, sp<Fence> glDoneFence) {
118 Mutex::Autolock lock(mMutex);
119 FrameRecord& frame = mFrames[mOffset];
120 FrameRecord& prevFrame = mFrames[(mOffset + MAX_FRAME_HISTORY - 1) %
121 MAX_FRAME_HISTORY];
122 frame.layers.clear();
123
124 bool wasGlesCompositionDone = false;
125 const size_t count = layers.size();
126 for (size_t i = 0; i < count; i++) {
127 String8 name;
128 uint64_t frameNumber;
129 bool glesComposition;
130 nsecs_t postedTime;
131 sp<Fence> acquireFence;
132 sp<Fence> prevReleaseFence;
133 int32_t key = layers[i]->getSequence();
134
135 layers[i]->getFenceData(&name, &frameNumber, &glesComposition,
136 &postedTime, &acquireFence, &prevReleaseFence);
137#ifdef USE_HWC2
138 if (glesComposition) {
139 frame.layers.emplace(std::piecewise_construct,
140 std::forward_as_tuple(key),
141 std::forward_as_tuple(name, frameNumber, glesComposition,
142 postedTime, 0, 0, acquireFence, prevReleaseFence));
143 wasGlesCompositionDone = true;
144 } else {
145 frame.layers.emplace(std::piecewise_construct,
146 std::forward_as_tuple(key),
147 std::forward_as_tuple(name, frameNumber, glesComposition,
148 postedTime, 0, 0, acquireFence, Fence::NO_FENCE));
149
150 auto prevLayer = prevFrame.layers.find(key);
151 if (prevLayer != prevFrame.layers.end()) {
152 prevLayer->second.releaseFence = prevReleaseFence;
153 }
154 }
155#else
156 frame.layers.emplace(std::piecewise_construct,
157 std::forward_as_tuple(key),
158 std::forward_as_tuple(name, frameNumber, glesComposition,
159 postedTime, 0, 0, acquireFence,
160 glesComposition ? Fence::NO_FENCE : prevReleaseFence));
161 if (glesComposition) {
162 wasGlesCompositionDone = true;
163 }
164#endif
165 frame.layers.emplace(std::piecewise_construct,
166 std::forward_as_tuple(key),
167 std::forward_as_tuple(name, frameNumber, glesComposition,
168 postedTime, 0, 0, acquireFence, prevReleaseFence));
169 }
170
171 frame.frameId = mFrameCounter;
172 frame.refreshStartTime = refreshStartTime;
173 frame.retireTime = 0;
174 frame.glesCompositionDoneTime = 0;
175 prevFrame.retireFence = retireFence;
176 frame.retireFence = Fence::NO_FENCE;
177 frame.glesCompositionDoneFence = wasGlesCompositionDone ? glDoneFence :
178 Fence::NO_FENCE;
179
180 mOffset = (mOffset + 1) % MAX_FRAME_HISTORY;
181 mFrameCounter++;
182
183 checkFencesForCompletion();
184}
185
186} // namespace android