blob: afb09de94b9d4e75e98ee3711cbdc97332df0eea [file] [log] [blame]
Brian Andersond6927fb2016-07-23 23:37:30 -07001/*
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 <gui/FrameTimestamps.h>
18
Brian Anderson8cc8b102016-10-21 12:43:09 -070019#define LOG_TAG "FrameEvents"
20
David Stevens7347f0b2020-01-15 20:19:22 +090021#include <LibGuiProperties.sysprop.h>
Yiwei Zhang5434a782018-12-05 18:06:32 -080022#include <android-base/stringprintf.h>
Brian Anderson3d4039d2016-09-23 16:31:30 -070023#include <cutils/compiler.h> // For CC_[UN]LIKELY
Brian Andersond6927fb2016-07-23 23:37:30 -070024#include <inttypes.h>
Brian Anderson175a7202016-10-10 16:52:56 -070025#include <utils/Log.h>
Brian Andersond6927fb2016-07-23 23:37:30 -070026
27#include <algorithm>
28#include <limits>
Brian Anderson3890c392016-07-25 12:48:08 -070029#include <numeric>
Brian Andersond6927fb2016-07-23 23:37:30 -070030
31namespace android {
32
Yiwei Zhang5434a782018-12-05 18:06:32 -080033using base::StringAppendF;
Brian Andersond6927fb2016-07-23 23:37:30 -070034
35// ============================================================================
Brian Andersond6927fb2016-07-23 23:37:30 -070036// FrameEvents
37// ============================================================================
38
Brian Anderson3890c392016-07-25 12:48:08 -070039bool FrameEvents::hasPostedInfo() const {
Brian Andersoned816e62016-10-26 16:12:21 -070040 return FrameEvents::isValidTimestamp(postedTime);
Brian Anderson3890c392016-07-25 12:48:08 -070041}
42
43bool FrameEvents::hasRequestedPresentInfo() const {
Brian Andersoned816e62016-10-26 16:12:21 -070044 return FrameEvents::isValidTimestamp(requestedPresentTime);
Brian Anderson3890c392016-07-25 12:48:08 -070045}
46
47bool FrameEvents::hasLatchInfo() const {
Brian Andersoned816e62016-10-26 16:12:21 -070048 return FrameEvents::isValidTimestamp(latchTime);
Brian Anderson3890c392016-07-25 12:48:08 -070049}
50
51bool FrameEvents::hasFirstRefreshStartInfo() const {
Brian Andersoned816e62016-10-26 16:12:21 -070052 return FrameEvents::isValidTimestamp(firstRefreshStartTime);
Brian Anderson3890c392016-07-25 12:48:08 -070053}
54
55bool FrameEvents::hasLastRefreshStartInfo() const {
56 // The last refresh start time may continue to update until a new frame
Brian Anderson4e606e32017-03-16 15:34:57 -070057 // is latched. We know we have the final value once the release info is set.
58 return addReleaseCalled;
Brian Anderson3890c392016-07-25 12:48:08 -070059}
60
Brian Andersonf6386862016-10-31 16:34:13 -070061bool FrameEvents::hasDequeueReadyInfo() const {
Brian Andersoned816e62016-10-26 16:12:21 -070062 return FrameEvents::isValidTimestamp(dequeueReadyTime);
Brian Andersonf6386862016-10-31 16:34:13 -070063}
64
Brian Anderson3890c392016-07-25 12:48:08 -070065bool FrameEvents::hasAcquireInfo() const {
Brian Anderson3d4039d2016-09-23 16:31:30 -070066 return acquireFence->isValid();
Brian Anderson3890c392016-07-25 12:48:08 -070067}
68
69bool FrameEvents::hasGpuCompositionDoneInfo() const {
70 // We may not get a gpuCompositionDone in addPostComposite if
71 // client/gles compositing isn't needed.
72 return addPostCompositeCalled;
73}
74
75bool FrameEvents::hasDisplayPresentInfo() const {
76 // We may not get a displayPresent in addPostComposite for HWC1.
77 return addPostCompositeCalled;
78}
79
Brian Anderson3890c392016-07-25 12:48:08 -070080bool FrameEvents::hasReleaseInfo() const {
81 return addReleaseCalled;
82}
83
Brian Anderson3d4039d2016-09-23 16:31:30 -070084void FrameEvents::checkFencesForCompletion() {
85 acquireFence->getSignalTime();
86 gpuCompositionDoneFence->getSignalTime();
87 displayPresentFence->getSignalTime();
Brian Anderson3d4039d2016-09-23 16:31:30 -070088 releaseFence->getSignalTime();
Brian Andersond6927fb2016-07-23 23:37:30 -070089}
90
Yiwei Zhang5434a782018-12-05 18:06:32 -080091static void dumpFenceTime(std::string& outString, const char* name, bool pending,
92 const FenceTime& fenceTime) {
93 StringAppendF(&outString, "--- %s", name);
Brian Anderson3d4039d2016-09-23 16:31:30 -070094 nsecs_t signalTime = fenceTime.getCachedSignalTime();
95 if (Fence::isValidTimestamp(signalTime)) {
Yiwei Zhang5434a782018-12-05 18:06:32 -080096 StringAppendF(&outString, "%" PRId64 "\n", signalTime);
Brian Anderson3d4039d2016-09-23 16:31:30 -070097 } else if (pending || signalTime == Fence::SIGNAL_TIME_PENDING) {
Yiwei Zhang5434a782018-12-05 18:06:32 -080098 outString.append("Pending\n");
Brian Anderson3d4039d2016-09-23 16:31:30 -070099 } else if (&fenceTime == FenceTime::NO_FENCE.get()){
Yiwei Zhang5434a782018-12-05 18:06:32 -0800100 outString.append("N/A\n");
Brian Anderson3d4039d2016-09-23 16:31:30 -0700101 } else {
Yiwei Zhang5434a782018-12-05 18:06:32 -0800102 outString.append("Error\n");
Brian Anderson3d4039d2016-09-23 16:31:30 -0700103 }
Brian Andersond6927fb2016-07-23 23:37:30 -0700104}
105
Yiwei Zhang5434a782018-12-05 18:06:32 -0800106void FrameEvents::dump(std::string& outString) const {
Brian Andersond6927fb2016-07-23 23:37:30 -0700107 if (!valid) {
108 return;
109 }
110
Yiwei Zhang5434a782018-12-05 18:06:32 -0800111 StringAppendF(&outString, "-- Frame %" PRIu64 "\n", frameNumber);
112 StringAppendF(&outString, "--- Posted \t%" PRId64 "\n", postedTime);
113 StringAppendF(&outString, "--- Req. Present\t%" PRId64 "\n", requestedPresentTime);
Brian Andersond6927fb2016-07-23 23:37:30 -0700114
Yiwei Zhang5434a782018-12-05 18:06:32 -0800115 outString.append("--- Latched \t");
Brian Andersoned816e62016-10-26 16:12:21 -0700116 if (FrameEvents::isValidTimestamp(latchTime)) {
Yiwei Zhang5434a782018-12-05 18:06:32 -0800117 StringAppendF(&outString, "%" PRId64 "\n", latchTime);
Brian Andersond6927fb2016-07-23 23:37:30 -0700118 } else {
Yiwei Zhang5434a782018-12-05 18:06:32 -0800119 outString.append("Pending\n");
Brian Andersond6927fb2016-07-23 23:37:30 -0700120 }
121
Yiwei Zhang5434a782018-12-05 18:06:32 -0800122 outString.append("--- Refresh (First)\t");
Brian Andersoned816e62016-10-26 16:12:21 -0700123 if (FrameEvents::isValidTimestamp(firstRefreshStartTime)) {
Yiwei Zhang5434a782018-12-05 18:06:32 -0800124 StringAppendF(&outString, "%" PRId64 "\n", firstRefreshStartTime);
Brian Andersond6927fb2016-07-23 23:37:30 -0700125 } else {
Yiwei Zhang5434a782018-12-05 18:06:32 -0800126 outString.append("Pending\n");
Brian Andersond6927fb2016-07-23 23:37:30 -0700127 }
128
Yiwei Zhang5434a782018-12-05 18:06:32 -0800129 outString.append("--- Refresh (Last)\t");
Brian Andersoned816e62016-10-26 16:12:21 -0700130 if (FrameEvents::isValidTimestamp(lastRefreshStartTime)) {
Yiwei Zhang5434a782018-12-05 18:06:32 -0800131 StringAppendF(&outString, "%" PRId64 "\n", lastRefreshStartTime);
Brian Andersond6927fb2016-07-23 23:37:30 -0700132 } else {
Yiwei Zhang5434a782018-12-05 18:06:32 -0800133 outString.append("Pending\n");
Brian Andersond6927fb2016-07-23 23:37:30 -0700134 }
135
Brian Anderson3d4039d2016-09-23 16:31:30 -0700136 dumpFenceTime(outString, "Acquire \t",
137 true, *acquireFence);
138 dumpFenceTime(outString, "GPU Composite Done\t",
139 !addPostCompositeCalled, *gpuCompositionDoneFence);
140 dumpFenceTime(outString, "Display Present \t",
141 !addPostCompositeCalled, *displayPresentFence);
Brian Andersonf6386862016-10-31 16:34:13 -0700142
Yiwei Zhang5434a782018-12-05 18:06:32 -0800143 outString.append("--- DequeueReady \t");
Brian Andersoned816e62016-10-26 16:12:21 -0700144 if (FrameEvents::isValidTimestamp(dequeueReadyTime)) {
Yiwei Zhang5434a782018-12-05 18:06:32 -0800145 StringAppendF(&outString, "%" PRId64 "\n", dequeueReadyTime);
Brian Andersonf6386862016-10-31 16:34:13 -0700146 } else {
Yiwei Zhang5434a782018-12-05 18:06:32 -0800147 outString.append("Pending\n");
Brian Andersonf6386862016-10-31 16:34:13 -0700148 }
149
Brian Anderson3d4039d2016-09-23 16:31:30 -0700150 dumpFenceTime(outString, "Release \t",
151 true, *releaseFence);
Brian Andersond6927fb2016-07-23 23:37:30 -0700152}
153
154
155// ============================================================================
156// FrameEventHistory
157// ============================================================================
158
159namespace {
160
161struct FrameNumberEqual {
Chih-Hung Hsiehaaf62162018-12-20 15:45:04 -0800162 explicit FrameNumberEqual(uint64_t frameNumber) : mFrameNumber(frameNumber) {}
Brian Andersond6927fb2016-07-23 23:37:30 -0700163 bool operator()(const FrameEvents& frame) {
164 return frame.valid && mFrameNumber == frame.frameNumber;
165 }
166 const uint64_t mFrameNumber;
167};
168
169} // namespace
170
Brian Lindahl957985b2023-01-31 15:42:47 -0700171const size_t FrameEventHistory::INITIAL_MAX_FRAME_HISTORY =
David Stevens7347f0b2020-01-15 20:19:22 +0900172 sysprop::LibGuiProperties::frame_event_history_size().value_or(8);
173
Brian Lindahl957985b2023-01-31 15:42:47 -0700174FrameEventHistory::FrameEventHistory()
175 : mFrames(std::vector<FrameEvents>(INITIAL_MAX_FRAME_HISTORY)) {}
David Stevens7347f0b2020-01-15 20:19:22 +0900176
Brian Anderson3890c392016-07-25 12:48:08 -0700177FrameEventHistory::~FrameEventHistory() = default;
Brian Andersond6927fb2016-07-23 23:37:30 -0700178
179FrameEvents* FrameEventHistory::getFrame(uint64_t frameNumber) {
180 auto frame = std::find_if(
181 mFrames.begin(), mFrames.end(), FrameNumberEqual(frameNumber));
182 return frame == mFrames.end() ? nullptr : &(*frame);
183}
184
185FrameEvents* FrameEventHistory::getFrame(uint64_t frameNumber, size_t* iHint) {
186 *iHint = std::min(*iHint, mFrames.size());
187 auto hint = mFrames.begin() + *iHint;
188 auto frame = std::find_if(
189 hint, mFrames.end(), FrameNumberEqual(frameNumber));
190 if (frame == mFrames.end()) {
191 frame = std::find_if(
192 mFrames.begin(), hint, FrameNumberEqual(frameNumber));
193 if (frame == hint) {
194 return nullptr;
195 }
196 }
197 *iHint = static_cast<size_t>(std::distance(mFrames.begin(), frame));
198 return &(*frame);
199}
200
201void FrameEventHistory::checkFencesForCompletion() {
202 for (auto& frame : mFrames) {
203 frame.checkFencesForCompletion();
204 }
205}
206
207// Uses !|valid| as the MSB.
208static bool FrameNumberLessThan(
209 const FrameEvents& lhs, const FrameEvents& rhs) {
210 if (lhs.valid == rhs.valid) {
211 return lhs.frameNumber < rhs.frameNumber;
212 }
213 return lhs.valid;
214}
215
Yiwei Zhang5434a782018-12-05 18:06:32 -0800216void FrameEventHistory::dump(std::string& outString) const {
Brian Andersond6927fb2016-07-23 23:37:30 -0700217 auto earliestFrame = std::min_element(
218 mFrames.begin(), mFrames.end(), &FrameNumberLessThan);
219 if (!earliestFrame->valid) {
Yiwei Zhang5434a782018-12-05 18:06:32 -0800220 outString.append("-- N/A\n");
Brian Andersond6927fb2016-07-23 23:37:30 -0700221 return;
222 }
223 for (auto frame = earliestFrame; frame != mFrames.end(); ++frame) {
224 frame->dump(outString);
225 }
226 for (auto frame = mFrames.begin(); frame != earliestFrame; ++frame) {
227 frame->dump(outString);
228 }
229}
230
Brian Anderson3890c392016-07-25 12:48:08 -0700231// ============================================================================
232// ProducerFrameEventHistory
233// ============================================================================
Brian Andersond6927fb2016-07-23 23:37:30 -0700234
Brian Anderson3890c392016-07-25 12:48:08 -0700235ProducerFrameEventHistory::~ProducerFrameEventHistory() = default;
236
Brian Anderson0a61b0c2016-12-07 14:55:56 -0800237nsecs_t ProducerFrameEventHistory::snapToNextTick(
238 nsecs_t timestamp, nsecs_t tickPhase, nsecs_t tickInterval) {
239 nsecs_t tickOffset = (tickPhase - timestamp) % tickInterval;
240 // Integer modulo rounds towards 0 and not -inf before taking the remainder,
241 // so adjust the offset if it is negative.
242 if (tickOffset < 0) {
243 tickOffset += tickInterval;
244 }
245 return timestamp + tickOffset;
246}
247
248nsecs_t ProducerFrameEventHistory::getNextCompositeDeadline(
249 const nsecs_t now) const{
250 return snapToNextTick(
251 now, mCompositorTiming.deadline, mCompositorTiming.interval);
252}
253
Brian Anderson3890c392016-07-25 12:48:08 -0700254void ProducerFrameEventHistory::updateAcquireFence(
Brian Anderson3d4039d2016-09-23 16:31:30 -0700255 uint64_t frameNumber, std::shared_ptr<FenceTime>&& acquire) {
Brian Anderson3890c392016-07-25 12:48:08 -0700256 FrameEvents* frame = getFrame(frameNumber, &mAcquireOffset);
Brian Andersond6927fb2016-07-23 23:37:30 -0700257 if (frame == nullptr) {
Brian Andersond6927fb2016-07-23 23:37:30 -0700258 return;
259 }
260
Brian Anderson3890c392016-07-25 12:48:08 -0700261 if (acquire->isValid()) {
Brian Anderson3d4039d2016-09-23 16:31:30 -0700262 mAcquireTimeline.push(acquire);
263 frame->acquireFence = std::move(acquire);
Brian Anderson3890c392016-07-25 12:48:08 -0700264 } else {
265 // If there isn't an acquire fence, assume that buffer was
266 // ready for the consumer when posted.
Brian Anderson3d4039d2016-09-23 16:31:30 -0700267 frame->acquireFence = std::make_shared<FenceTime>(frame->postedTime);
Brian Anderson3890c392016-07-25 12:48:08 -0700268 }
269}
270
Brian Anderson3890c392016-07-25 12:48:08 -0700271void ProducerFrameEventHistory::applyDelta(
272 const FrameEventHistoryDelta& delta) {
Brian Anderson0a61b0c2016-12-07 14:55:56 -0800273 mCompositorTiming = delta.mCompositorTiming;
274
Brian Lindahl957985b2023-01-31 15:42:47 -0700275 // Deltas should have enough reserved capacity for the consumer-side, therefore if there's a
276 // different capacity, we re-sized on the consumer side and now need to resize on the producer
277 // side.
278 if (delta.mDeltas.capacity() > mFrames.capacity()) {
279 resize(delta.mDeltas.capacity());
280 }
281
Brian Anderson3890c392016-07-25 12:48:08 -0700282 for (auto& d : delta.mDeltas) {
283 // Avoid out-of-bounds access.
Brian Anderson8cc8b102016-10-21 12:43:09 -0700284 if (CC_UNLIKELY(d.mIndex >= mFrames.size())) {
285 ALOGE("applyDelta: Bad index.");
Brian Anderson3890c392016-07-25 12:48:08 -0700286 return;
287 }
288
289 FrameEvents& frame = mFrames[d.mIndex];
290
291 frame.addPostCompositeCalled = d.mAddPostCompositeCalled != 0;
Brian Anderson3890c392016-07-25 12:48:08 -0700292 frame.addReleaseCalled = d.mAddReleaseCalled != 0;
293
294 frame.postedTime = d.mPostedTime;
295 frame.requestedPresentTime = d.mRequestedPresentTime;
296 frame.latchTime = d.mLatchTime;
297 frame.firstRefreshStartTime = d.mFirstRefreshStartTime;
298 frame.lastRefreshStartTime = d.mLastRefreshStartTime;
Brian Andersonf6386862016-10-31 16:34:13 -0700299 frame.dequeueReadyTime = d.mDequeueReadyTime;
Brian Anderson3890c392016-07-25 12:48:08 -0700300
Brian Anderson3d4039d2016-09-23 16:31:30 -0700301 if (frame.frameNumber != d.mFrameNumber) {
302 // We got a new frame. Initialize some of the fields.
Brian Anderson3890c392016-07-25 12:48:08 -0700303 frame.frameNumber = d.mFrameNumber;
Brian Anderson3d4039d2016-09-23 16:31:30 -0700304 frame.acquireFence = FenceTime::NO_FENCE;
305 frame.gpuCompositionDoneFence = FenceTime::NO_FENCE;
306 frame.displayPresentFence = FenceTime::NO_FENCE;
Brian Anderson3d4039d2016-09-23 16:31:30 -0700307 frame.releaseFence = FenceTime::NO_FENCE;
Brian Anderson3890c392016-07-25 12:48:08 -0700308 // The consumer only sends valid frames.
309 frame.valid = true;
Brian Andersond6927fb2016-07-23 23:37:30 -0700310 }
Brian Anderson3d4039d2016-09-23 16:31:30 -0700311
312 applyFenceDelta(&mGpuCompositionDoneTimeline,
313 &frame.gpuCompositionDoneFence, d.mGpuCompositionDoneFence);
314 applyFenceDelta(&mPresentTimeline,
315 &frame.displayPresentFence, d.mDisplayPresentFence);
Brian Anderson3d4039d2016-09-23 16:31:30 -0700316 applyFenceDelta(&mReleaseTimeline,
317 &frame.releaseFence, d.mReleaseFence);
Brian Andersond6927fb2016-07-23 23:37:30 -0700318 }
319}
320
Brian Anderson3d4039d2016-09-23 16:31:30 -0700321void ProducerFrameEventHistory::updateSignalTimes() {
322 mAcquireTimeline.updateSignalTimes();
323 mGpuCompositionDoneTimeline.updateSignalTimes();
324 mPresentTimeline.updateSignalTimes();
Brian Anderson3d4039d2016-09-23 16:31:30 -0700325 mReleaseTimeline.updateSignalTimes();
326}
327
Brian Anderson3da8d272016-07-28 16:20:47 -0700328void ProducerFrameEventHistory::applyFenceDelta(FenceTimeline* timeline,
329 std::shared_ptr<FenceTime>* dst, const FenceTime::Snapshot& src) const {
Brian Anderson5ea5e592016-12-01 16:54:33 -0800330 if (CC_UNLIKELY(dst == nullptr || dst->get() == nullptr)) {
Brian Anderson3da8d272016-07-28 16:20:47 -0700331 ALOGE("applyFenceDelta: dst is null.");
332 return;
333 }
334
335 switch (src.state) {
336 case FenceTime::Snapshot::State::EMPTY:
337 return;
338 case FenceTime::Snapshot::State::FENCE:
Brian Anderson8cc8b102016-10-21 12:43:09 -0700339 ALOGE_IF((*dst)->isValid(), "applyFenceDelta: Unexpected fence.");
Brian Anderson3da8d272016-07-28 16:20:47 -0700340 *dst = createFenceTime(src.fence);
341 timeline->push(*dst);
342 return;
343 case FenceTime::Snapshot::State::SIGNAL_TIME:
344 if ((*dst)->isValid()) {
345 (*dst)->applyTrustedSnapshot(src);
346 } else {
347 *dst = std::make_shared<FenceTime>(src.signalTime);
348 }
349 return;
350 }
351}
352
353std::shared_ptr<FenceTime> ProducerFrameEventHistory::createFenceTime(
354 const sp<Fence>& fence) const {
355 return std::make_shared<FenceTime>(fence);
356}
357
Brian Lindahl957985b2023-01-31 15:42:47 -0700358void ProducerFrameEventHistory::resize(size_t newSize) {
359 // we don't want to drop events by resizing too small, so don't resize in the negative direction
360 if (newSize <= mFrames.size()) {
361 return;
362 }
363
364 // This algorithm for resizing needs to be the same as ConsumerFrameEventHistory::resize,
365 // because the indexes need to match when communicating the FrameEventDeltas.
366
367 // We need to find the oldest frame, because that frame needs to move to index 0 in the new
368 // frame history.
369 size_t oldestFrameIndex = 0;
370 size_t oldestFrameNumber = INT32_MAX;
371 for (size_t i = 0; i < mFrames.size(); ++i) {
372 if (mFrames[i].frameNumber < oldestFrameNumber && mFrames[i].valid) {
373 oldestFrameNumber = mFrames[i].frameNumber;
374 oldestFrameIndex = i;
375 }
376 }
377
378 // move the existing frame information into a new vector, so that the oldest frames are at
379 // index 0, and the latest frames are at the end of the vector
380 std::vector<FrameEvents> newFrames(newSize);
381 size_t oldI = oldestFrameIndex;
382 size_t newI = 0;
383 do {
384 if (mFrames[oldI].valid) {
385 newFrames[newI++] = std::move(mFrames[oldI]);
386 }
387 oldI = (oldI + 1) % mFrames.size();
388 } while (oldI != oldestFrameIndex);
389
390 mFrames = std::move(newFrames);
391 mAcquireOffset = 0; // this is just a hint, so setting this to anything is fine
392}
Brian Anderson3890c392016-07-25 12:48:08 -0700393
394// ============================================================================
395// ConsumerFrameEventHistory
396// ============================================================================
397
David Stevens7347f0b2020-01-15 20:19:22 +0900398ConsumerFrameEventHistory::ConsumerFrameEventHistory()
Brian Lindahl957985b2023-01-31 15:42:47 -0700399 : mFramesDirty(std::vector<FrameEventDirtyFields>(INITIAL_MAX_FRAME_HISTORY)) {}
David Stevens7347f0b2020-01-15 20:19:22 +0900400
Brian Anderson3890c392016-07-25 12:48:08 -0700401ConsumerFrameEventHistory::~ConsumerFrameEventHistory() = default;
402
Brian Anderson5ea5e592016-12-01 16:54:33 -0800403void ConsumerFrameEventHistory::onDisconnect() {
404 mCurrentConnectId++;
405 mProducerWantsEvents = false;
406}
407
Valerie Hau0ca3f992020-01-30 16:07:35 -0800408void ConsumerFrameEventHistory::setProducerWantsEvents() {
409 mProducerWantsEvents = true;
410}
411
Brian Anderson0a61b0c2016-12-07 14:55:56 -0800412void ConsumerFrameEventHistory::initializeCompositorTiming(
413 const CompositorTiming& compositorTiming) {
414 mCompositorTiming = compositorTiming;
415}
416
Brian Anderson3890c392016-07-25 12:48:08 -0700417void ConsumerFrameEventHistory::addQueue(const NewFrameEventsEntry& newEntry) {
418 // Overwrite all fields of the frame with default values unless set here.
419 FrameEvents newTimestamps;
Brian Anderson5ea5e592016-12-01 16:54:33 -0800420 newTimestamps.connectId = mCurrentConnectId;
Brian Anderson3890c392016-07-25 12:48:08 -0700421 newTimestamps.frameNumber = newEntry.frameNumber;
422 newTimestamps.postedTime = newEntry.postedTime;
423 newTimestamps.requestedPresentTime = newEntry.requestedPresentTime;
424 newTimestamps.acquireFence = newEntry.acquireFence;
425 newTimestamps.valid = true;
426 mFrames[mQueueOffset] = newTimestamps;
Brian Anderson7c3ba8a2016-07-25 12:48:08 -0700427
428 // Note: We avoid sending the acquire fence back to the caller since
429 // they have the original one already, so there is no need to set the
430 // acquire dirty bit.
Brian Anderson3890c392016-07-25 12:48:08 -0700431 mFramesDirty[mQueueOffset].setDirty<FrameEvent::POSTED>();
Brian Anderson3890c392016-07-25 12:48:08 -0700432
433 mQueueOffset = (mQueueOffset + 1) % mFrames.size();
434}
435
436void ConsumerFrameEventHistory::addLatch(
437 uint64_t frameNumber, nsecs_t latchTime) {
438 FrameEvents* frame = getFrame(frameNumber, &mCompositionOffset);
439 if (frame == nullptr) {
Brian Anderson4565daa2016-12-13 15:41:28 -0800440 ALOGE_IF(mProducerWantsEvents, "addLatch: Did not find frame.");
Brian Anderson3890c392016-07-25 12:48:08 -0700441 return;
442 }
443 frame->latchTime = latchTime;
444 mFramesDirty[mCompositionOffset].setDirty<FrameEvent::LATCH>();
445}
446
447void ConsumerFrameEventHistory::addPreComposition(
448 uint64_t frameNumber, nsecs_t refreshStartTime) {
449 FrameEvents* frame = getFrame(frameNumber, &mCompositionOffset);
450 if (frame == nullptr) {
Brian Anderson4565daa2016-12-13 15:41:28 -0800451 ALOGE_IF(mProducerWantsEvents,
452 "addPreComposition: Did not find frame.");
Brian Anderson3890c392016-07-25 12:48:08 -0700453 return;
454 }
455 frame->lastRefreshStartTime = refreshStartTime;
456 mFramesDirty[mCompositionOffset].setDirty<FrameEvent::LAST_REFRESH_START>();
Brian Andersoned816e62016-10-26 16:12:21 -0700457 if (!FrameEvents::isValidTimestamp(frame->firstRefreshStartTime)) {
Brian Anderson3890c392016-07-25 12:48:08 -0700458 frame->firstRefreshStartTime = refreshStartTime;
459 mFramesDirty[mCompositionOffset].setDirty<FrameEvent::FIRST_REFRESH_START>();
460 }
461}
462
463void ConsumerFrameEventHistory::addPostComposition(uint64_t frameNumber,
Brian Anderson3d4039d2016-09-23 16:31:30 -0700464 const std::shared_ptr<FenceTime>& gpuCompositionDone,
Brian Anderson0a61b0c2016-12-07 14:55:56 -0800465 const std::shared_ptr<FenceTime>& displayPresent,
466 const CompositorTiming& compositorTiming) {
467 mCompositorTiming = compositorTiming;
468
Brian Anderson3890c392016-07-25 12:48:08 -0700469 FrameEvents* frame = getFrame(frameNumber, &mCompositionOffset);
470 if (frame == nullptr) {
Brian Anderson4565daa2016-12-13 15:41:28 -0800471 ALOGE_IF(mProducerWantsEvents,
472 "addPostComposition: Did not find frame.");
Brian Anderson3890c392016-07-25 12:48:08 -0700473 return;
474 }
475 // Only get GPU and present info for the first composite.
476 if (!frame->addPostCompositeCalled) {
477 frame->addPostCompositeCalled = true;
478 frame->gpuCompositionDoneFence = gpuCompositionDone;
Brian Andersonb04c6f02016-10-21 12:57:46 -0700479 mFramesDirty[mCompositionOffset].setDirty<FrameEvent::GPU_COMPOSITION_DONE>();
Brian Anderson3890c392016-07-25 12:48:08 -0700480 if (!frame->displayPresentFence->isValid()) {
481 frame->displayPresentFence = displayPresent;
482 mFramesDirty[mCompositionOffset].setDirty<FrameEvent::DISPLAY_PRESENT>();
483 }
484 }
485}
486
Brian Andersonf6386862016-10-31 16:34:13 -0700487void ConsumerFrameEventHistory::addRelease(uint64_t frameNumber,
488 nsecs_t dequeueReadyTime, std::shared_ptr<FenceTime>&& release) {
Brian Andersond6927fb2016-07-23 23:37:30 -0700489 FrameEvents* frame = getFrame(frameNumber, &mReleaseOffset);
Brian Anderson5ea5e592016-12-01 16:54:33 -0800490 if (frame == nullptr) {
491 ALOGE_IF(mProducerWantsEvents, "addRelease: Did not find frame.");
Brian Andersond6927fb2016-07-23 23:37:30 -0700492 return;
493 }
Brian Anderson3890c392016-07-25 12:48:08 -0700494 frame->addReleaseCalled = true;
Brian Andersonf6386862016-10-31 16:34:13 -0700495 frame->dequeueReadyTime = dequeueReadyTime;
Brian Anderson3d4039d2016-09-23 16:31:30 -0700496 frame->releaseFence = std::move(release);
Brian Anderson3890c392016-07-25 12:48:08 -0700497 mFramesDirty[mReleaseOffset].setDirty<FrameEvent::RELEASE>();
Brian Andersond6927fb2016-07-23 23:37:30 -0700498}
499
David Stevens7347f0b2020-01-15 20:19:22 +0900500void ConsumerFrameEventHistory::getFrameDelta(FrameEventHistoryDelta* delta,
501 const std::vector<FrameEvents>::iterator& frame) {
Brian Anderson4565daa2016-12-13 15:41:28 -0800502 mProducerWantsEvents = true;
Brian Anderson3d4039d2016-09-23 16:31:30 -0700503 size_t i = static_cast<size_t>(std::distance(mFrames.begin(), frame));
504 if (mFramesDirty[i].anyDirty()) {
Brian Anderson5ea5e592016-12-01 16:54:33 -0800505 // Make sure only to send back deltas for the current connection
506 // since the producer won't have the correct state to apply a delta
507 // from a previous connection.
508 if (mFrames[i].connectId == mCurrentConnectId) {
509 delta->mDeltas.emplace_back(i, *frame, mFramesDirty[i]);
510 }
Brian Anderson3d4039d2016-09-23 16:31:30 -0700511 mFramesDirty[i].reset();
512 }
513}
514
Brian Anderson3890c392016-07-25 12:48:08 -0700515void ConsumerFrameEventHistory::getAndResetDelta(
516 FrameEventHistoryDelta* delta) {
Brian Anderson5ea5e592016-12-01 16:54:33 -0800517 mProducerWantsEvents = true;
Brian Anderson0a61b0c2016-12-07 14:55:56 -0800518 delta->mCompositorTiming = mCompositorTiming;
519
Brian Anderson3d4039d2016-09-23 16:31:30 -0700520 // Write these in order of frame number so that it is easy to
521 // add them to a FenceTimeline in the proper order producer side.
Brian Anderson3890c392016-07-25 12:48:08 -0700522 delta->mDeltas.reserve(mFramesDirty.size());
Brian Anderson3d4039d2016-09-23 16:31:30 -0700523 auto earliestFrame = std::min_element(
524 mFrames.begin(), mFrames.end(), &FrameNumberLessThan);
525 for (auto frame = earliestFrame; frame != mFrames.end(); ++frame) {
526 getFrameDelta(delta, frame);
527 }
528 for (auto frame = mFrames.begin(); frame != earliestFrame; ++frame) {
529 getFrameDelta(delta, frame);
Brian Anderson3890c392016-07-25 12:48:08 -0700530 }
531}
532
Brian Lindahl957985b2023-01-31 15:42:47 -0700533void ConsumerFrameEventHistory::resize(size_t newSize) {
534 // we don't want to drop events by resizing too small, so don't resize in the negative direction
535 if (newSize <= mFrames.size()) {
536 return;
537 }
538
539 // This algorithm for resizing needs to be the same as ProducerFrameEventHistory::resize,
540 // because the indexes need to match when communicating the FrameEventDeltas.
541
542 // move the existing frame information into a new vector, so that the oldest frames are at
543 // index 0, and the latest frames are towards the end of the vector
544 std::vector<FrameEvents> newFrames(newSize);
545 std::vector<FrameEventDirtyFields> newFramesDirty(newSize);
546 size_t oldestFrameIndex = mQueueOffset;
547 size_t oldI = oldestFrameIndex;
548 size_t newI = 0;
549 do {
550 if (mFrames[oldI].valid) {
551 newFrames[newI] = std::move(mFrames[oldI]);
552 newFramesDirty[newI] = mFramesDirty[oldI];
553 newI += 1;
554 }
555 oldI = (oldI + 1) % mFrames.size();
556 } while (oldI != oldestFrameIndex);
557
558 mFrames = std::move(newFrames);
559 mFramesDirty = std::move(newFramesDirty);
560 mQueueOffset = newI;
561 mCompositionOffset = 0; // this is just a hint, so setting this to anything is fine
562}
Brian Anderson3890c392016-07-25 12:48:08 -0700563
564// ============================================================================
565// FrameEventsDelta
566// ============================================================================
567
568FrameEventsDelta::FrameEventsDelta(
569 size_t index,
570 const FrameEvents& frameTimestamps,
571 const FrameEventDirtyFields& dirtyFields)
572 : mIndex(index),
573 mFrameNumber(frameTimestamps.frameNumber),
574 mAddPostCompositeCalled(frameTimestamps.addPostCompositeCalled),
Brian Anderson3890c392016-07-25 12:48:08 -0700575 mAddReleaseCalled(frameTimestamps.addReleaseCalled),
576 mPostedTime(frameTimestamps.postedTime),
577 mRequestedPresentTime(frameTimestamps.requestedPresentTime),
578 mLatchTime(frameTimestamps.latchTime),
579 mFirstRefreshStartTime(frameTimestamps.firstRefreshStartTime),
Brian Andersonf6386862016-10-31 16:34:13 -0700580 mLastRefreshStartTime(frameTimestamps.lastRefreshStartTime),
581 mDequeueReadyTime(frameTimestamps.dequeueReadyTime) {
Brian Andersonb04c6f02016-10-21 12:57:46 -0700582 if (dirtyFields.isDirty<FrameEvent::GPU_COMPOSITION_DONE>()) {
Brian Anderson3d4039d2016-09-23 16:31:30 -0700583 mGpuCompositionDoneFence =
584 frameTimestamps.gpuCompositionDoneFence->getSnapshot();
585 }
586 if (dirtyFields.isDirty<FrameEvent::DISPLAY_PRESENT>()) {
587 mDisplayPresentFence =
588 frameTimestamps.displayPresentFence->getSnapshot();
589 }
Brian Anderson3d4039d2016-09-23 16:31:30 -0700590 if (dirtyFields.isDirty<FrameEvent::RELEASE>()) {
591 mReleaseFence = frameTimestamps.releaseFence->getSnapshot();
592 }
Brian Anderson3890c392016-07-25 12:48:08 -0700593}
594
Brian Anderson0a61b0c2016-12-07 14:55:56 -0800595constexpr size_t FrameEventsDelta::minFlattenedSize() {
596 return sizeof(FrameEventsDelta::mFrameNumber) +
Brian Anderson4e606e32017-03-16 15:34:57 -0700597 sizeof(uint16_t) + // mIndex
Brian Anderson3890c392016-07-25 12:48:08 -0700598 sizeof(uint8_t) + // mAddPostCompositeCalled
Brian Anderson3890c392016-07-25 12:48:08 -0700599 sizeof(uint8_t) + // mAddReleaseCalled
600 sizeof(FrameEventsDelta::mPostedTime) +
601 sizeof(FrameEventsDelta::mRequestedPresentTime) +
602 sizeof(FrameEventsDelta::mLatchTime) +
603 sizeof(FrameEventsDelta::mFirstRefreshStartTime) +
Brian Andersonf6386862016-10-31 16:34:13 -0700604 sizeof(FrameEventsDelta::mLastRefreshStartTime) +
605 sizeof(FrameEventsDelta::mDequeueReadyTime);
Brian Anderson3890c392016-07-25 12:48:08 -0700606}
607
608// Flattenable implementation
609size_t FrameEventsDelta::getFlattenedSize() const {
610 auto fences = allFences(this);
611 return minFlattenedSize() +
612 std::accumulate(fences.begin(), fences.end(), size_t(0),
Brian Anderson3d4039d2016-09-23 16:31:30 -0700613 [](size_t a, const FenceTime::Snapshot* fence) {
614 return a + fence->getFlattenedSize();
Brian Anderson3890c392016-07-25 12:48:08 -0700615 });
616}
617
618size_t FrameEventsDelta::getFdCount() const {
619 auto fences = allFences(this);
620 return std::accumulate(fences.begin(), fences.end(), size_t(0),
Brian Anderson3d4039d2016-09-23 16:31:30 -0700621 [](size_t a, const FenceTime::Snapshot* fence) {
622 return a + fence->getFdCount();
Brian Anderson3890c392016-07-25 12:48:08 -0700623 });
624}
625
626status_t FrameEventsDelta::flatten(void*& buffer, size_t& size, int*& fds,
627 size_t& count) const {
628 if (size < getFlattenedSize() || count < getFdCount()) {
629 return NO_MEMORY;
630 }
631
Brian Lindahl957985b2023-01-31 15:42:47 -0700632 if (mIndex >= UINT8_MAX || mIndex < 0) {
Brian Anderson3890c392016-07-25 12:48:08 -0700633 return BAD_VALUE;
634 }
635
636 FlattenableUtils::write(buffer, size, mFrameNumber);
637
Brian Anderson4e606e32017-03-16 15:34:57 -0700638 // These are static_cast to uint16_t/uint8_t for alignment.
639 FlattenableUtils::write(buffer, size, static_cast<uint16_t>(mIndex));
Brian Anderson3890c392016-07-25 12:48:08 -0700640 FlattenableUtils::write(
641 buffer, size, static_cast<uint8_t>(mAddPostCompositeCalled));
642 FlattenableUtils::write(
Brian Anderson3890c392016-07-25 12:48:08 -0700643 buffer, size, static_cast<uint8_t>(mAddReleaseCalled));
644
645 FlattenableUtils::write(buffer, size, mPostedTime);
646 FlattenableUtils::write(buffer, size, mRequestedPresentTime);
647 FlattenableUtils::write(buffer, size, mLatchTime);
648 FlattenableUtils::write(buffer, size, mFirstRefreshStartTime);
649 FlattenableUtils::write(buffer, size, mLastRefreshStartTime);
Brian Andersonf6386862016-10-31 16:34:13 -0700650 FlattenableUtils::write(buffer, size, mDequeueReadyTime);
Brian Anderson3890c392016-07-25 12:48:08 -0700651
652 // Fences
653 for (auto fence : allFences(this)) {
Brian Anderson3d4039d2016-09-23 16:31:30 -0700654 status_t status = fence->flatten(buffer, size, fds, count);
Brian Anderson3890c392016-07-25 12:48:08 -0700655 if (status != NO_ERROR) {
656 return status;
657 }
658 }
659 return NO_ERROR;
660}
661
662status_t FrameEventsDelta::unflatten(void const*& buffer, size_t& size,
663 int const*& fds, size_t& count) {
664 if (size < minFlattenedSize()) {
665 return NO_MEMORY;
666 }
667
668 FlattenableUtils::read(buffer, size, mFrameNumber);
669
Brian Anderson4e606e32017-03-16 15:34:57 -0700670 // These were written as uint16_t/uint8_t for alignment.
671 uint16_t temp16 = 0;
672 FlattenableUtils::read(buffer, size, temp16);
673 mIndex = temp16;
Brian Lindahl957985b2023-01-31 15:42:47 -0700674 if (mIndex >= UINT8_MAX) {
Brian Anderson3890c392016-07-25 12:48:08 -0700675 return BAD_VALUE;
676 }
Brian Anderson4e606e32017-03-16 15:34:57 -0700677 uint8_t temp8 = 0;
678 FlattenableUtils::read(buffer, size, temp8);
679 mAddPostCompositeCalled = static_cast<bool>(temp8);
680 FlattenableUtils::read(buffer, size, temp8);
681 mAddReleaseCalled = static_cast<bool>(temp8);
Brian Anderson3890c392016-07-25 12:48:08 -0700682
683 FlattenableUtils::read(buffer, size, mPostedTime);
684 FlattenableUtils::read(buffer, size, mRequestedPresentTime);
685 FlattenableUtils::read(buffer, size, mLatchTime);
686 FlattenableUtils::read(buffer, size, mFirstRefreshStartTime);
687 FlattenableUtils::read(buffer, size, mLastRefreshStartTime);
Brian Andersonf6386862016-10-31 16:34:13 -0700688 FlattenableUtils::read(buffer, size, mDequeueReadyTime);
Brian Anderson3890c392016-07-25 12:48:08 -0700689
690 // Fences
691 for (auto fence : allFences(this)) {
Brian Anderson3d4039d2016-09-23 16:31:30 -0700692 status_t status = fence->unflatten(buffer, size, fds, count);
Brian Anderson3890c392016-07-25 12:48:08 -0700693 if (status != NO_ERROR) {
694 return status;
695 }
696 }
697 return NO_ERROR;
698}
699
Brian Lindahl957985b2023-01-31 15:42:47 -0700700uint64_t FrameEventsDelta::getFrameNumber() const {
701 return mFrameNumber;
702}
703
704bool FrameEventsDelta::getLatchTime(nsecs_t* latchTime) const {
705 if (mLatchTime == FrameEvents::TIMESTAMP_PENDING) {
706 return false;
707 }
708 *latchTime = mLatchTime;
709 return true;
710}
711
712bool FrameEventsDelta::getDisplayPresentFence(sp<Fence>* fence) const {
713 if (mDisplayPresentFence.fence == Fence::NO_FENCE) {
714 return false;
715 }
716 *fence = mDisplayPresentFence.fence;
717 return true;
718}
Brian Anderson3890c392016-07-25 12:48:08 -0700719
720// ============================================================================
721// FrameEventHistoryDelta
722// ============================================================================
723
Brian Anderson3d4039d2016-09-23 16:31:30 -0700724FrameEventHistoryDelta& FrameEventHistoryDelta::operator=(
Chih-Hung Hsieh5bc849f2018-09-25 14:21:50 -0700725 FrameEventHistoryDelta&& src) noexcept {
Brian Anderson0a61b0c2016-12-07 14:55:56 -0800726 mCompositorTiming = src.mCompositorTiming;
727
Brian Anderson3d4039d2016-09-23 16:31:30 -0700728 if (CC_UNLIKELY(!mDeltas.empty())) {
Brian Anderson8cc8b102016-10-21 12:43:09 -0700729 ALOGE("FrameEventHistoryDelta assign clobbering history.");
Brian Anderson3d4039d2016-09-23 16:31:30 -0700730 }
731 mDeltas = std::move(src.mDeltas);
Brian Anderson3d4039d2016-09-23 16:31:30 -0700732 return *this;
733}
734
Brian Anderson0a61b0c2016-12-07 14:55:56 -0800735constexpr size_t FrameEventHistoryDelta::minFlattenedSize() {
736 return sizeof(uint32_t) + // mDeltas.size()
737 sizeof(mCompositorTiming);
Brian Anderson3890c392016-07-25 12:48:08 -0700738}
739
740size_t FrameEventHistoryDelta::getFlattenedSize() const {
741 return minFlattenedSize() +
742 std::accumulate(mDeltas.begin(), mDeltas.end(), size_t(0),
743 [](size_t a, const FrameEventsDelta& delta) {
744 return a + delta.getFlattenedSize();
745 });
746}
747
748size_t FrameEventHistoryDelta::getFdCount() const {
749 return std::accumulate(mDeltas.begin(), mDeltas.end(), size_t(0),
750 [](size_t a, const FrameEventsDelta& delta) {
751 return a + delta.getFdCount();
752 });
753}
754
755status_t FrameEventHistoryDelta::flatten(
756 void*& buffer, size_t& size, int*& fds, size_t& count) const {
Brian Lindahl957985b2023-01-31 15:42:47 -0700757 if (mDeltas.size() > UINT8_MAX) {
Brian Anderson3890c392016-07-25 12:48:08 -0700758 return BAD_VALUE;
759 }
760 if (size < getFlattenedSize()) {
761 return NO_MEMORY;
762 }
763
Brian Anderson0a61b0c2016-12-07 14:55:56 -0800764 FlattenableUtils::write(buffer, size, mCompositorTiming);
765
Brian Anderson3890c392016-07-25 12:48:08 -0700766 FlattenableUtils::write(
767 buffer, size, static_cast<uint32_t>(mDeltas.size()));
768 for (auto& d : mDeltas) {
769 status_t status = d.flatten(buffer, size, fds, count);
770 if (status != NO_ERROR) {
771 return status;
772 }
773 }
774 return NO_ERROR;
775}
776
777status_t FrameEventHistoryDelta::unflatten(
778 void const*& buffer, size_t& size, int const*& fds, size_t& count) {
779 if (size < minFlattenedSize()) {
780 return NO_MEMORY;
781 }
782
Brian Anderson0a61b0c2016-12-07 14:55:56 -0800783 FlattenableUtils::read(buffer, size, mCompositorTiming);
784
Brian Anderson3890c392016-07-25 12:48:08 -0700785 uint32_t deltaCount = 0;
786 FlattenableUtils::read(buffer, size, deltaCount);
Brian Lindahl957985b2023-01-31 15:42:47 -0700787 if (deltaCount > UINT8_MAX) {
Brian Anderson3890c392016-07-25 12:48:08 -0700788 return BAD_VALUE;
789 }
790 mDeltas.resize(deltaCount);
791 for (auto& d : mDeltas) {
792 status_t status = d.unflatten(buffer, size, fds, count);
793 if (status != NO_ERROR) {
794 return status;
795 }
796 }
797 return NO_ERROR;
798}
799
Brian Lindahl957985b2023-01-31 15:42:47 -0700800std::vector<FrameEventsDelta>::const_iterator FrameEventHistoryDelta::begin() const {
801 return mDeltas.begin();
802}
803
804std::vector<FrameEventsDelta>::const_iterator FrameEventHistoryDelta::end() const {
805 return mDeltas.end();
806}
Brian Anderson3890c392016-07-25 12:48:08 -0700807
Brian Andersond6927fb2016-07-23 23:37:30 -0700808} // namespace android