blob: e2ea3f9ab1c471350efb2e178087faaa86562517 [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
David Stevens7347f0b2020-01-15 20:19:22 +0900171const size_t FrameEventHistory::MAX_FRAME_HISTORY =
172 sysprop::LibGuiProperties::frame_event_history_size().value_or(8);
173
174FrameEventHistory::FrameEventHistory() : mFrames(std::vector<FrameEvents>(MAX_FRAME_HISTORY)) {}
175
Brian Anderson3890c392016-07-25 12:48:08 -0700176FrameEventHistory::~FrameEventHistory() = default;
Brian Andersond6927fb2016-07-23 23:37:30 -0700177
178FrameEvents* FrameEventHistory::getFrame(uint64_t frameNumber) {
179 auto frame = std::find_if(
180 mFrames.begin(), mFrames.end(), FrameNumberEqual(frameNumber));
181 return frame == mFrames.end() ? nullptr : &(*frame);
182}
183
184FrameEvents* FrameEventHistory::getFrame(uint64_t frameNumber, size_t* iHint) {
185 *iHint = std::min(*iHint, mFrames.size());
186 auto hint = mFrames.begin() + *iHint;
187 auto frame = std::find_if(
188 hint, mFrames.end(), FrameNumberEqual(frameNumber));
189 if (frame == mFrames.end()) {
190 frame = std::find_if(
191 mFrames.begin(), hint, FrameNumberEqual(frameNumber));
192 if (frame == hint) {
193 return nullptr;
194 }
195 }
196 *iHint = static_cast<size_t>(std::distance(mFrames.begin(), frame));
197 return &(*frame);
198}
199
200void FrameEventHistory::checkFencesForCompletion() {
201 for (auto& frame : mFrames) {
202 frame.checkFencesForCompletion();
203 }
204}
205
206// Uses !|valid| as the MSB.
207static bool FrameNumberLessThan(
208 const FrameEvents& lhs, const FrameEvents& rhs) {
209 if (lhs.valid == rhs.valid) {
210 return lhs.frameNumber < rhs.frameNumber;
211 }
212 return lhs.valid;
213}
214
Yiwei Zhang5434a782018-12-05 18:06:32 -0800215void FrameEventHistory::dump(std::string& outString) const {
Brian Andersond6927fb2016-07-23 23:37:30 -0700216 auto earliestFrame = std::min_element(
217 mFrames.begin(), mFrames.end(), &FrameNumberLessThan);
218 if (!earliestFrame->valid) {
Yiwei Zhang5434a782018-12-05 18:06:32 -0800219 outString.append("-- N/A\n");
Brian Andersond6927fb2016-07-23 23:37:30 -0700220 return;
221 }
222 for (auto frame = earliestFrame; frame != mFrames.end(); ++frame) {
223 frame->dump(outString);
224 }
225 for (auto frame = mFrames.begin(); frame != earliestFrame; ++frame) {
226 frame->dump(outString);
227 }
228}
229
Brian Andersond6927fb2016-07-23 23:37:30 -0700230
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 Anderson8cc8b102016-10-21 12:43:09 -0700258 ALOGE("updateAcquireFence: Did not find frame.");
Brian Andersond6927fb2016-07-23 23:37:30 -0700259 return;
260 }
261
Brian Anderson3890c392016-07-25 12:48:08 -0700262 if (acquire->isValid()) {
Brian Anderson3d4039d2016-09-23 16:31:30 -0700263 mAcquireTimeline.push(acquire);
264 frame->acquireFence = std::move(acquire);
Brian Anderson3890c392016-07-25 12:48:08 -0700265 } else {
266 // If there isn't an acquire fence, assume that buffer was
267 // ready for the consumer when posted.
Brian Anderson3d4039d2016-09-23 16:31:30 -0700268 frame->acquireFence = std::make_shared<FenceTime>(frame->postedTime);
Brian Anderson3890c392016-07-25 12:48:08 -0700269 }
270}
271
Brian Anderson3890c392016-07-25 12:48:08 -0700272void ProducerFrameEventHistory::applyDelta(
273 const FrameEventHistoryDelta& delta) {
Brian Anderson0a61b0c2016-12-07 14:55:56 -0800274 mCompositorTiming = delta.mCompositorTiming;
275
Brian Anderson3890c392016-07-25 12:48:08 -0700276 for (auto& d : delta.mDeltas) {
277 // Avoid out-of-bounds access.
Brian Anderson8cc8b102016-10-21 12:43:09 -0700278 if (CC_UNLIKELY(d.mIndex >= mFrames.size())) {
279 ALOGE("applyDelta: Bad index.");
Brian Anderson3890c392016-07-25 12:48:08 -0700280 return;
281 }
282
283 FrameEvents& frame = mFrames[d.mIndex];
284
285 frame.addPostCompositeCalled = d.mAddPostCompositeCalled != 0;
Brian Anderson3890c392016-07-25 12:48:08 -0700286 frame.addReleaseCalled = d.mAddReleaseCalled != 0;
287
288 frame.postedTime = d.mPostedTime;
289 frame.requestedPresentTime = d.mRequestedPresentTime;
290 frame.latchTime = d.mLatchTime;
291 frame.firstRefreshStartTime = d.mFirstRefreshStartTime;
292 frame.lastRefreshStartTime = d.mLastRefreshStartTime;
Brian Andersonf6386862016-10-31 16:34:13 -0700293 frame.dequeueReadyTime = d.mDequeueReadyTime;
Brian Anderson3890c392016-07-25 12:48:08 -0700294
Brian Anderson3d4039d2016-09-23 16:31:30 -0700295 if (frame.frameNumber != d.mFrameNumber) {
296 // We got a new frame. Initialize some of the fields.
Brian Anderson3890c392016-07-25 12:48:08 -0700297 frame.frameNumber = d.mFrameNumber;
Brian Anderson3d4039d2016-09-23 16:31:30 -0700298 frame.acquireFence = FenceTime::NO_FENCE;
299 frame.gpuCompositionDoneFence = FenceTime::NO_FENCE;
300 frame.displayPresentFence = FenceTime::NO_FENCE;
Brian Anderson3d4039d2016-09-23 16:31:30 -0700301 frame.releaseFence = FenceTime::NO_FENCE;
Brian Anderson3890c392016-07-25 12:48:08 -0700302 // The consumer only sends valid frames.
303 frame.valid = true;
Brian Andersond6927fb2016-07-23 23:37:30 -0700304 }
Brian Anderson3d4039d2016-09-23 16:31:30 -0700305
306 applyFenceDelta(&mGpuCompositionDoneTimeline,
307 &frame.gpuCompositionDoneFence, d.mGpuCompositionDoneFence);
308 applyFenceDelta(&mPresentTimeline,
309 &frame.displayPresentFence, d.mDisplayPresentFence);
Brian Anderson3d4039d2016-09-23 16:31:30 -0700310 applyFenceDelta(&mReleaseTimeline,
311 &frame.releaseFence, d.mReleaseFence);
Brian Andersond6927fb2016-07-23 23:37:30 -0700312 }
313}
314
Brian Anderson3d4039d2016-09-23 16:31:30 -0700315void ProducerFrameEventHistory::updateSignalTimes() {
316 mAcquireTimeline.updateSignalTimes();
317 mGpuCompositionDoneTimeline.updateSignalTimes();
318 mPresentTimeline.updateSignalTimes();
Brian Anderson3d4039d2016-09-23 16:31:30 -0700319 mReleaseTimeline.updateSignalTimes();
320}
321
Brian Anderson3da8d272016-07-28 16:20:47 -0700322void ProducerFrameEventHistory::applyFenceDelta(FenceTimeline* timeline,
323 std::shared_ptr<FenceTime>* dst, const FenceTime::Snapshot& src) const {
Brian Anderson5ea5e592016-12-01 16:54:33 -0800324 if (CC_UNLIKELY(dst == nullptr || dst->get() == nullptr)) {
Brian Anderson3da8d272016-07-28 16:20:47 -0700325 ALOGE("applyFenceDelta: dst is null.");
326 return;
327 }
328
329 switch (src.state) {
330 case FenceTime::Snapshot::State::EMPTY:
331 return;
332 case FenceTime::Snapshot::State::FENCE:
Brian Anderson8cc8b102016-10-21 12:43:09 -0700333 ALOGE_IF((*dst)->isValid(), "applyFenceDelta: Unexpected fence.");
Brian Anderson3da8d272016-07-28 16:20:47 -0700334 *dst = createFenceTime(src.fence);
335 timeline->push(*dst);
336 return;
337 case FenceTime::Snapshot::State::SIGNAL_TIME:
338 if ((*dst)->isValid()) {
339 (*dst)->applyTrustedSnapshot(src);
340 } else {
341 *dst = std::make_shared<FenceTime>(src.signalTime);
342 }
343 return;
344 }
345}
346
347std::shared_ptr<FenceTime> ProducerFrameEventHistory::createFenceTime(
348 const sp<Fence>& fence) const {
349 return std::make_shared<FenceTime>(fence);
350}
351
Brian Anderson3890c392016-07-25 12:48:08 -0700352
353// ============================================================================
354// ConsumerFrameEventHistory
355// ============================================================================
356
David Stevens7347f0b2020-01-15 20:19:22 +0900357ConsumerFrameEventHistory::ConsumerFrameEventHistory()
358 : mFramesDirty(std::vector<FrameEventDirtyFields>(MAX_FRAME_HISTORY)) {}
359
Brian Anderson3890c392016-07-25 12:48:08 -0700360ConsumerFrameEventHistory::~ConsumerFrameEventHistory() = default;
361
Brian Anderson5ea5e592016-12-01 16:54:33 -0800362void ConsumerFrameEventHistory::onDisconnect() {
363 mCurrentConnectId++;
364 mProducerWantsEvents = false;
365}
366
Valerie Hau0ca3f992020-01-30 16:07:35 -0800367void ConsumerFrameEventHistory::setProducerWantsEvents() {
368 mProducerWantsEvents = true;
369}
370
Brian Anderson0a61b0c2016-12-07 14:55:56 -0800371void ConsumerFrameEventHistory::initializeCompositorTiming(
372 const CompositorTiming& compositorTiming) {
373 mCompositorTiming = compositorTiming;
374}
375
Brian Anderson3890c392016-07-25 12:48:08 -0700376void ConsumerFrameEventHistory::addQueue(const NewFrameEventsEntry& newEntry) {
377 // Overwrite all fields of the frame with default values unless set here.
378 FrameEvents newTimestamps;
Brian Anderson5ea5e592016-12-01 16:54:33 -0800379 newTimestamps.connectId = mCurrentConnectId;
Brian Anderson3890c392016-07-25 12:48:08 -0700380 newTimestamps.frameNumber = newEntry.frameNumber;
381 newTimestamps.postedTime = newEntry.postedTime;
382 newTimestamps.requestedPresentTime = newEntry.requestedPresentTime;
383 newTimestamps.acquireFence = newEntry.acquireFence;
384 newTimestamps.valid = true;
385 mFrames[mQueueOffset] = newTimestamps;
Brian Anderson7c3ba8a2016-07-25 12:48:08 -0700386
387 // Note: We avoid sending the acquire fence back to the caller since
388 // they have the original one already, so there is no need to set the
389 // acquire dirty bit.
Brian Anderson3890c392016-07-25 12:48:08 -0700390 mFramesDirty[mQueueOffset].setDirty<FrameEvent::POSTED>();
Brian Anderson3890c392016-07-25 12:48:08 -0700391
392 mQueueOffset = (mQueueOffset + 1) % mFrames.size();
393}
394
395void ConsumerFrameEventHistory::addLatch(
396 uint64_t frameNumber, nsecs_t latchTime) {
397 FrameEvents* frame = getFrame(frameNumber, &mCompositionOffset);
398 if (frame == nullptr) {
Brian Anderson4565daa2016-12-13 15:41:28 -0800399 ALOGE_IF(mProducerWantsEvents, "addLatch: Did not find frame.");
Brian Anderson3890c392016-07-25 12:48:08 -0700400 return;
401 }
402 frame->latchTime = latchTime;
403 mFramesDirty[mCompositionOffset].setDirty<FrameEvent::LATCH>();
404}
405
406void ConsumerFrameEventHistory::addPreComposition(
407 uint64_t frameNumber, nsecs_t refreshStartTime) {
408 FrameEvents* frame = getFrame(frameNumber, &mCompositionOffset);
409 if (frame == nullptr) {
Brian Anderson4565daa2016-12-13 15:41:28 -0800410 ALOGE_IF(mProducerWantsEvents,
411 "addPreComposition: Did not find frame.");
Brian Anderson3890c392016-07-25 12:48:08 -0700412 return;
413 }
414 frame->lastRefreshStartTime = refreshStartTime;
415 mFramesDirty[mCompositionOffset].setDirty<FrameEvent::LAST_REFRESH_START>();
Brian Andersoned816e62016-10-26 16:12:21 -0700416 if (!FrameEvents::isValidTimestamp(frame->firstRefreshStartTime)) {
Brian Anderson3890c392016-07-25 12:48:08 -0700417 frame->firstRefreshStartTime = refreshStartTime;
418 mFramesDirty[mCompositionOffset].setDirty<FrameEvent::FIRST_REFRESH_START>();
419 }
420}
421
422void ConsumerFrameEventHistory::addPostComposition(uint64_t frameNumber,
Brian Anderson3d4039d2016-09-23 16:31:30 -0700423 const std::shared_ptr<FenceTime>& gpuCompositionDone,
Brian Anderson0a61b0c2016-12-07 14:55:56 -0800424 const std::shared_ptr<FenceTime>& displayPresent,
425 const CompositorTiming& compositorTiming) {
426 mCompositorTiming = compositorTiming;
427
Brian Anderson3890c392016-07-25 12:48:08 -0700428 FrameEvents* frame = getFrame(frameNumber, &mCompositionOffset);
429 if (frame == nullptr) {
Brian Anderson4565daa2016-12-13 15:41:28 -0800430 ALOGE_IF(mProducerWantsEvents,
431 "addPostComposition: Did not find frame.");
Brian Anderson3890c392016-07-25 12:48:08 -0700432 return;
433 }
434 // Only get GPU and present info for the first composite.
435 if (!frame->addPostCompositeCalled) {
436 frame->addPostCompositeCalled = true;
437 frame->gpuCompositionDoneFence = gpuCompositionDone;
Brian Andersonb04c6f02016-10-21 12:57:46 -0700438 mFramesDirty[mCompositionOffset].setDirty<FrameEvent::GPU_COMPOSITION_DONE>();
Brian Anderson3890c392016-07-25 12:48:08 -0700439 if (!frame->displayPresentFence->isValid()) {
440 frame->displayPresentFence = displayPresent;
441 mFramesDirty[mCompositionOffset].setDirty<FrameEvent::DISPLAY_PRESENT>();
442 }
443 }
444}
445
Brian Andersonf6386862016-10-31 16:34:13 -0700446void ConsumerFrameEventHistory::addRelease(uint64_t frameNumber,
447 nsecs_t dequeueReadyTime, std::shared_ptr<FenceTime>&& release) {
Brian Andersond6927fb2016-07-23 23:37:30 -0700448 FrameEvents* frame = getFrame(frameNumber, &mReleaseOffset);
Brian Anderson5ea5e592016-12-01 16:54:33 -0800449 if (frame == nullptr) {
450 ALOGE_IF(mProducerWantsEvents, "addRelease: Did not find frame.");
Brian Andersond6927fb2016-07-23 23:37:30 -0700451 return;
452 }
Brian Anderson3890c392016-07-25 12:48:08 -0700453 frame->addReleaseCalled = true;
Brian Andersonf6386862016-10-31 16:34:13 -0700454 frame->dequeueReadyTime = dequeueReadyTime;
Brian Anderson3d4039d2016-09-23 16:31:30 -0700455 frame->releaseFence = std::move(release);
Brian Anderson3890c392016-07-25 12:48:08 -0700456 mFramesDirty[mReleaseOffset].setDirty<FrameEvent::RELEASE>();
Brian Andersond6927fb2016-07-23 23:37:30 -0700457}
458
David Stevens7347f0b2020-01-15 20:19:22 +0900459void ConsumerFrameEventHistory::getFrameDelta(FrameEventHistoryDelta* delta,
460 const std::vector<FrameEvents>::iterator& frame) {
Brian Anderson4565daa2016-12-13 15:41:28 -0800461 mProducerWantsEvents = true;
Brian Anderson3d4039d2016-09-23 16:31:30 -0700462 size_t i = static_cast<size_t>(std::distance(mFrames.begin(), frame));
463 if (mFramesDirty[i].anyDirty()) {
Brian Anderson5ea5e592016-12-01 16:54:33 -0800464 // Make sure only to send back deltas for the current connection
465 // since the producer won't have the correct state to apply a delta
466 // from a previous connection.
467 if (mFrames[i].connectId == mCurrentConnectId) {
468 delta->mDeltas.emplace_back(i, *frame, mFramesDirty[i]);
469 }
Brian Anderson3d4039d2016-09-23 16:31:30 -0700470 mFramesDirty[i].reset();
471 }
472}
473
Brian Anderson3890c392016-07-25 12:48:08 -0700474void ConsumerFrameEventHistory::getAndResetDelta(
475 FrameEventHistoryDelta* delta) {
Brian Anderson5ea5e592016-12-01 16:54:33 -0800476 mProducerWantsEvents = true;
Brian Anderson0a61b0c2016-12-07 14:55:56 -0800477 delta->mCompositorTiming = mCompositorTiming;
478
Brian Anderson3d4039d2016-09-23 16:31:30 -0700479 // Write these in order of frame number so that it is easy to
480 // add them to a FenceTimeline in the proper order producer side.
Brian Anderson3890c392016-07-25 12:48:08 -0700481 delta->mDeltas.reserve(mFramesDirty.size());
Brian Anderson3d4039d2016-09-23 16:31:30 -0700482 auto earliestFrame = std::min_element(
483 mFrames.begin(), mFrames.end(), &FrameNumberLessThan);
484 for (auto frame = earliestFrame; frame != mFrames.end(); ++frame) {
485 getFrameDelta(delta, frame);
486 }
487 for (auto frame = mFrames.begin(); frame != earliestFrame; ++frame) {
488 getFrameDelta(delta, frame);
Brian Anderson3890c392016-07-25 12:48:08 -0700489 }
490}
491
492
493// ============================================================================
494// FrameEventsDelta
495// ============================================================================
496
497FrameEventsDelta::FrameEventsDelta(
498 size_t index,
499 const FrameEvents& frameTimestamps,
500 const FrameEventDirtyFields& dirtyFields)
501 : mIndex(index),
502 mFrameNumber(frameTimestamps.frameNumber),
503 mAddPostCompositeCalled(frameTimestamps.addPostCompositeCalled),
Brian Anderson3890c392016-07-25 12:48:08 -0700504 mAddReleaseCalled(frameTimestamps.addReleaseCalled),
505 mPostedTime(frameTimestamps.postedTime),
506 mRequestedPresentTime(frameTimestamps.requestedPresentTime),
507 mLatchTime(frameTimestamps.latchTime),
508 mFirstRefreshStartTime(frameTimestamps.firstRefreshStartTime),
Brian Andersonf6386862016-10-31 16:34:13 -0700509 mLastRefreshStartTime(frameTimestamps.lastRefreshStartTime),
510 mDequeueReadyTime(frameTimestamps.dequeueReadyTime) {
Brian Andersonb04c6f02016-10-21 12:57:46 -0700511 if (dirtyFields.isDirty<FrameEvent::GPU_COMPOSITION_DONE>()) {
Brian Anderson3d4039d2016-09-23 16:31:30 -0700512 mGpuCompositionDoneFence =
513 frameTimestamps.gpuCompositionDoneFence->getSnapshot();
514 }
515 if (dirtyFields.isDirty<FrameEvent::DISPLAY_PRESENT>()) {
516 mDisplayPresentFence =
517 frameTimestamps.displayPresentFence->getSnapshot();
518 }
Brian Anderson3d4039d2016-09-23 16:31:30 -0700519 if (dirtyFields.isDirty<FrameEvent::RELEASE>()) {
520 mReleaseFence = frameTimestamps.releaseFence->getSnapshot();
521 }
Brian Anderson3890c392016-07-25 12:48:08 -0700522}
523
Brian Anderson0a61b0c2016-12-07 14:55:56 -0800524constexpr size_t FrameEventsDelta::minFlattenedSize() {
525 return sizeof(FrameEventsDelta::mFrameNumber) +
Brian Anderson4e606e32017-03-16 15:34:57 -0700526 sizeof(uint16_t) + // mIndex
Brian Anderson3890c392016-07-25 12:48:08 -0700527 sizeof(uint8_t) + // mAddPostCompositeCalled
Brian Anderson3890c392016-07-25 12:48:08 -0700528 sizeof(uint8_t) + // mAddReleaseCalled
529 sizeof(FrameEventsDelta::mPostedTime) +
530 sizeof(FrameEventsDelta::mRequestedPresentTime) +
531 sizeof(FrameEventsDelta::mLatchTime) +
532 sizeof(FrameEventsDelta::mFirstRefreshStartTime) +
Brian Andersonf6386862016-10-31 16:34:13 -0700533 sizeof(FrameEventsDelta::mLastRefreshStartTime) +
534 sizeof(FrameEventsDelta::mDequeueReadyTime);
Brian Anderson3890c392016-07-25 12:48:08 -0700535}
536
537// Flattenable implementation
538size_t FrameEventsDelta::getFlattenedSize() const {
539 auto fences = allFences(this);
540 return minFlattenedSize() +
541 std::accumulate(fences.begin(), fences.end(), size_t(0),
Brian Anderson3d4039d2016-09-23 16:31:30 -0700542 [](size_t a, const FenceTime::Snapshot* fence) {
543 return a + fence->getFlattenedSize();
Brian Anderson3890c392016-07-25 12:48:08 -0700544 });
545}
546
547size_t FrameEventsDelta::getFdCount() const {
548 auto fences = allFences(this);
549 return std::accumulate(fences.begin(), fences.end(), size_t(0),
Brian Anderson3d4039d2016-09-23 16:31:30 -0700550 [](size_t a, const FenceTime::Snapshot* fence) {
551 return a + fence->getFdCount();
Brian Anderson3890c392016-07-25 12:48:08 -0700552 });
553}
554
555status_t FrameEventsDelta::flatten(void*& buffer, size_t& size, int*& fds,
556 size_t& count) const {
557 if (size < getFlattenedSize() || count < getFdCount()) {
558 return NO_MEMORY;
559 }
560
561 if (mIndex >= FrameEventHistory::MAX_FRAME_HISTORY ||
Brian Anderson4e606e32017-03-16 15:34:57 -0700562 mIndex > std::numeric_limits<uint16_t>::max()) {
Brian Anderson3890c392016-07-25 12:48:08 -0700563 return BAD_VALUE;
564 }
565
566 FlattenableUtils::write(buffer, size, mFrameNumber);
567
Brian Anderson4e606e32017-03-16 15:34:57 -0700568 // These are static_cast to uint16_t/uint8_t for alignment.
569 FlattenableUtils::write(buffer, size, static_cast<uint16_t>(mIndex));
Brian Anderson3890c392016-07-25 12:48:08 -0700570 FlattenableUtils::write(
571 buffer, size, static_cast<uint8_t>(mAddPostCompositeCalled));
572 FlattenableUtils::write(
Brian Anderson3890c392016-07-25 12:48:08 -0700573 buffer, size, static_cast<uint8_t>(mAddReleaseCalled));
574
575 FlattenableUtils::write(buffer, size, mPostedTime);
576 FlattenableUtils::write(buffer, size, mRequestedPresentTime);
577 FlattenableUtils::write(buffer, size, mLatchTime);
578 FlattenableUtils::write(buffer, size, mFirstRefreshStartTime);
579 FlattenableUtils::write(buffer, size, mLastRefreshStartTime);
Brian Andersonf6386862016-10-31 16:34:13 -0700580 FlattenableUtils::write(buffer, size, mDequeueReadyTime);
Brian Anderson3890c392016-07-25 12:48:08 -0700581
582 // Fences
583 for (auto fence : allFences(this)) {
Brian Anderson3d4039d2016-09-23 16:31:30 -0700584 status_t status = fence->flatten(buffer, size, fds, count);
Brian Anderson3890c392016-07-25 12:48:08 -0700585 if (status != NO_ERROR) {
586 return status;
587 }
588 }
589 return NO_ERROR;
590}
591
592status_t FrameEventsDelta::unflatten(void const*& buffer, size_t& size,
593 int const*& fds, size_t& count) {
594 if (size < minFlattenedSize()) {
595 return NO_MEMORY;
596 }
597
598 FlattenableUtils::read(buffer, size, mFrameNumber);
599
Brian Anderson4e606e32017-03-16 15:34:57 -0700600 // These were written as uint16_t/uint8_t for alignment.
601 uint16_t temp16 = 0;
602 FlattenableUtils::read(buffer, size, temp16);
603 mIndex = temp16;
Brian Anderson3890c392016-07-25 12:48:08 -0700604 if (mIndex >= FrameEventHistory::MAX_FRAME_HISTORY) {
605 return BAD_VALUE;
606 }
Brian Anderson4e606e32017-03-16 15:34:57 -0700607 uint8_t temp8 = 0;
608 FlattenableUtils::read(buffer, size, temp8);
609 mAddPostCompositeCalled = static_cast<bool>(temp8);
610 FlattenableUtils::read(buffer, size, temp8);
611 mAddReleaseCalled = static_cast<bool>(temp8);
Brian Anderson3890c392016-07-25 12:48:08 -0700612
613 FlattenableUtils::read(buffer, size, mPostedTime);
614 FlattenableUtils::read(buffer, size, mRequestedPresentTime);
615 FlattenableUtils::read(buffer, size, mLatchTime);
616 FlattenableUtils::read(buffer, size, mFirstRefreshStartTime);
617 FlattenableUtils::read(buffer, size, mLastRefreshStartTime);
Brian Andersonf6386862016-10-31 16:34:13 -0700618 FlattenableUtils::read(buffer, size, mDequeueReadyTime);
Brian Anderson3890c392016-07-25 12:48:08 -0700619
620 // Fences
621 for (auto fence : allFences(this)) {
Brian Anderson3d4039d2016-09-23 16:31:30 -0700622 status_t status = fence->unflatten(buffer, size, fds, count);
Brian Anderson3890c392016-07-25 12:48:08 -0700623 if (status != NO_ERROR) {
624 return status;
625 }
626 }
627 return NO_ERROR;
628}
629
630
631// ============================================================================
632// FrameEventHistoryDelta
633// ============================================================================
634
Brian Anderson3d4039d2016-09-23 16:31:30 -0700635FrameEventHistoryDelta& FrameEventHistoryDelta::operator=(
Chih-Hung Hsieh5bc849f2018-09-25 14:21:50 -0700636 FrameEventHistoryDelta&& src) noexcept {
Brian Anderson0a61b0c2016-12-07 14:55:56 -0800637 mCompositorTiming = src.mCompositorTiming;
638
Brian Anderson3d4039d2016-09-23 16:31:30 -0700639 if (CC_UNLIKELY(!mDeltas.empty())) {
Brian Anderson8cc8b102016-10-21 12:43:09 -0700640 ALOGE("FrameEventHistoryDelta assign clobbering history.");
Brian Anderson3d4039d2016-09-23 16:31:30 -0700641 }
642 mDeltas = std::move(src.mDeltas);
Brian Anderson3d4039d2016-09-23 16:31:30 -0700643 return *this;
644}
645
Brian Anderson0a61b0c2016-12-07 14:55:56 -0800646constexpr size_t FrameEventHistoryDelta::minFlattenedSize() {
647 return sizeof(uint32_t) + // mDeltas.size()
648 sizeof(mCompositorTiming);
Brian Anderson3890c392016-07-25 12:48:08 -0700649}
650
651size_t FrameEventHistoryDelta::getFlattenedSize() const {
652 return minFlattenedSize() +
653 std::accumulate(mDeltas.begin(), mDeltas.end(), size_t(0),
654 [](size_t a, const FrameEventsDelta& delta) {
655 return a + delta.getFlattenedSize();
656 });
657}
658
659size_t FrameEventHistoryDelta::getFdCount() const {
660 return std::accumulate(mDeltas.begin(), mDeltas.end(), size_t(0),
661 [](size_t a, const FrameEventsDelta& delta) {
662 return a + delta.getFdCount();
663 });
664}
665
666status_t FrameEventHistoryDelta::flatten(
667 void*& buffer, size_t& size, int*& fds, size_t& count) const {
668 if (mDeltas.size() > FrameEventHistory::MAX_FRAME_HISTORY) {
669 return BAD_VALUE;
670 }
671 if (size < getFlattenedSize()) {
672 return NO_MEMORY;
673 }
674
Brian Anderson0a61b0c2016-12-07 14:55:56 -0800675 FlattenableUtils::write(buffer, size, mCompositorTiming);
676
Brian Anderson3890c392016-07-25 12:48:08 -0700677 FlattenableUtils::write(
678 buffer, size, static_cast<uint32_t>(mDeltas.size()));
679 for (auto& d : mDeltas) {
680 status_t status = d.flatten(buffer, size, fds, count);
681 if (status != NO_ERROR) {
682 return status;
683 }
684 }
685 return NO_ERROR;
686}
687
688status_t FrameEventHistoryDelta::unflatten(
689 void const*& buffer, size_t& size, int const*& fds, size_t& count) {
690 if (size < minFlattenedSize()) {
691 return NO_MEMORY;
692 }
693
Brian Anderson0a61b0c2016-12-07 14:55:56 -0800694 FlattenableUtils::read(buffer, size, mCompositorTiming);
695
Brian Anderson3890c392016-07-25 12:48:08 -0700696 uint32_t deltaCount = 0;
697 FlattenableUtils::read(buffer, size, deltaCount);
698 if (deltaCount > FrameEventHistory::MAX_FRAME_HISTORY) {
699 return BAD_VALUE;
700 }
701 mDeltas.resize(deltaCount);
702 for (auto& d : mDeltas) {
703 status_t status = d.unflatten(buffer, size, fds, count);
704 if (status != NO_ERROR) {
705 return status;
706 }
707 }
708 return NO_ERROR;
709}
710
711
Brian Andersond6927fb2016-07-23 23:37:30 -0700712} // namespace android