blob: 6749c3cd6f6c40563ffa3fcd493d06e78e1e49ff [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
Yiwei Zhang5434a782018-12-05 18:06:32 -080021#include <android-base/stringprintf.h>
Brian Anderson3d4039d2016-09-23 16:31:30 -070022#include <cutils/compiler.h> // For CC_[UN]LIKELY
Brian Andersond6927fb2016-07-23 23:37:30 -070023#include <inttypes.h>
Brian Anderson175a7202016-10-10 16:52:56 -070024#include <utils/Log.h>
Brian Andersond6927fb2016-07-23 23:37:30 -070025
26#include <algorithm>
27#include <limits>
Brian Anderson3890c392016-07-25 12:48:08 -070028#include <numeric>
Brian Andersond6927fb2016-07-23 23:37:30 -070029
30namespace android {
31
Yiwei Zhang5434a782018-12-05 18:06:32 -080032using base::StringAppendF;
Brian Andersond6927fb2016-07-23 23:37:30 -070033
34// ============================================================================
Brian Andersond6927fb2016-07-23 23:37:30 -070035// FrameEvents
36// ============================================================================
37
Brian Anderson3890c392016-07-25 12:48:08 -070038bool FrameEvents::hasPostedInfo() const {
Brian Andersoned816e62016-10-26 16:12:21 -070039 return FrameEvents::isValidTimestamp(postedTime);
Brian Anderson3890c392016-07-25 12:48:08 -070040}
41
42bool FrameEvents::hasRequestedPresentInfo() const {
Brian Andersoned816e62016-10-26 16:12:21 -070043 return FrameEvents::isValidTimestamp(requestedPresentTime);
Brian Anderson3890c392016-07-25 12:48:08 -070044}
45
46bool FrameEvents::hasLatchInfo() const {
Brian Andersoned816e62016-10-26 16:12:21 -070047 return FrameEvents::isValidTimestamp(latchTime);
Brian Anderson3890c392016-07-25 12:48:08 -070048}
49
50bool FrameEvents::hasFirstRefreshStartInfo() const {
Brian Andersoned816e62016-10-26 16:12:21 -070051 return FrameEvents::isValidTimestamp(firstRefreshStartTime);
Brian Anderson3890c392016-07-25 12:48:08 -070052}
53
54bool FrameEvents::hasLastRefreshStartInfo() const {
55 // The last refresh start time may continue to update until a new frame
Brian Anderson4e606e32017-03-16 15:34:57 -070056 // is latched. We know we have the final value once the release info is set.
57 return addReleaseCalled;
Brian Anderson3890c392016-07-25 12:48:08 -070058}
59
Brian Andersonf6386862016-10-31 16:34:13 -070060bool FrameEvents::hasDequeueReadyInfo() const {
Brian Andersoned816e62016-10-26 16:12:21 -070061 return FrameEvents::isValidTimestamp(dequeueReadyTime);
Brian Andersonf6386862016-10-31 16:34:13 -070062}
63
Brian Anderson3890c392016-07-25 12:48:08 -070064bool FrameEvents::hasAcquireInfo() const {
Brian Anderson3d4039d2016-09-23 16:31:30 -070065 return acquireFence->isValid();
Brian Anderson3890c392016-07-25 12:48:08 -070066}
67
68bool FrameEvents::hasGpuCompositionDoneInfo() const {
69 // We may not get a gpuCompositionDone in addPostComposite if
70 // client/gles compositing isn't needed.
71 return addPostCompositeCalled;
72}
73
74bool FrameEvents::hasDisplayPresentInfo() const {
75 // We may not get a displayPresent in addPostComposite for HWC1.
76 return addPostCompositeCalled;
77}
78
Brian Anderson3890c392016-07-25 12:48:08 -070079bool FrameEvents::hasReleaseInfo() const {
80 return addReleaseCalled;
81}
82
Brian Anderson3d4039d2016-09-23 16:31:30 -070083void FrameEvents::checkFencesForCompletion() {
84 acquireFence->getSignalTime();
85 gpuCompositionDoneFence->getSignalTime();
86 displayPresentFence->getSignalTime();
Brian Anderson3d4039d2016-09-23 16:31:30 -070087 releaseFence->getSignalTime();
Brian Andersond6927fb2016-07-23 23:37:30 -070088}
89
Yiwei Zhang5434a782018-12-05 18:06:32 -080090static void dumpFenceTime(std::string& outString, const char* name, bool pending,
91 const FenceTime& fenceTime) {
92 StringAppendF(&outString, "--- %s", name);
Brian Anderson3d4039d2016-09-23 16:31:30 -070093 nsecs_t signalTime = fenceTime.getCachedSignalTime();
94 if (Fence::isValidTimestamp(signalTime)) {
Yiwei Zhang5434a782018-12-05 18:06:32 -080095 StringAppendF(&outString, "%" PRId64 "\n", signalTime);
Brian Anderson3d4039d2016-09-23 16:31:30 -070096 } else if (pending || signalTime == Fence::SIGNAL_TIME_PENDING) {
Yiwei Zhang5434a782018-12-05 18:06:32 -080097 outString.append("Pending\n");
Brian Anderson3d4039d2016-09-23 16:31:30 -070098 } else if (&fenceTime == FenceTime::NO_FENCE.get()){
Yiwei Zhang5434a782018-12-05 18:06:32 -080099 outString.append("N/A\n");
Brian Anderson3d4039d2016-09-23 16:31:30 -0700100 } else {
Yiwei Zhang5434a782018-12-05 18:06:32 -0800101 outString.append("Error\n");
Brian Anderson3d4039d2016-09-23 16:31:30 -0700102 }
Brian Andersond6927fb2016-07-23 23:37:30 -0700103}
104
Yiwei Zhang5434a782018-12-05 18:06:32 -0800105void FrameEvents::dump(std::string& outString) const {
Brian Andersond6927fb2016-07-23 23:37:30 -0700106 if (!valid) {
107 return;
108 }
109
Yiwei Zhang5434a782018-12-05 18:06:32 -0800110 StringAppendF(&outString, "-- Frame %" PRIu64 "\n", frameNumber);
111 StringAppendF(&outString, "--- Posted \t%" PRId64 "\n", postedTime);
112 StringAppendF(&outString, "--- Req. Present\t%" PRId64 "\n", requestedPresentTime);
Brian Andersond6927fb2016-07-23 23:37:30 -0700113
Yiwei Zhang5434a782018-12-05 18:06:32 -0800114 outString.append("--- Latched \t");
Brian Andersoned816e62016-10-26 16:12:21 -0700115 if (FrameEvents::isValidTimestamp(latchTime)) {
Yiwei Zhang5434a782018-12-05 18:06:32 -0800116 StringAppendF(&outString, "%" PRId64 "\n", latchTime);
Brian Andersond6927fb2016-07-23 23:37:30 -0700117 } else {
Yiwei Zhang5434a782018-12-05 18:06:32 -0800118 outString.append("Pending\n");
Brian Andersond6927fb2016-07-23 23:37:30 -0700119 }
120
Yiwei Zhang5434a782018-12-05 18:06:32 -0800121 outString.append("--- Refresh (First)\t");
Brian Andersoned816e62016-10-26 16:12:21 -0700122 if (FrameEvents::isValidTimestamp(firstRefreshStartTime)) {
Yiwei Zhang5434a782018-12-05 18:06:32 -0800123 StringAppendF(&outString, "%" PRId64 "\n", firstRefreshStartTime);
Brian Andersond6927fb2016-07-23 23:37:30 -0700124 } else {
Yiwei Zhang5434a782018-12-05 18:06:32 -0800125 outString.append("Pending\n");
Brian Andersond6927fb2016-07-23 23:37:30 -0700126 }
127
Yiwei Zhang5434a782018-12-05 18:06:32 -0800128 outString.append("--- Refresh (Last)\t");
Brian Andersoned816e62016-10-26 16:12:21 -0700129 if (FrameEvents::isValidTimestamp(lastRefreshStartTime)) {
Yiwei Zhang5434a782018-12-05 18:06:32 -0800130 StringAppendF(&outString, "%" PRId64 "\n", lastRefreshStartTime);
Brian Andersond6927fb2016-07-23 23:37:30 -0700131 } else {
Yiwei Zhang5434a782018-12-05 18:06:32 -0800132 outString.append("Pending\n");
Brian Andersond6927fb2016-07-23 23:37:30 -0700133 }
134
Brian Anderson3d4039d2016-09-23 16:31:30 -0700135 dumpFenceTime(outString, "Acquire \t",
136 true, *acquireFence);
137 dumpFenceTime(outString, "GPU Composite Done\t",
138 !addPostCompositeCalled, *gpuCompositionDoneFence);
139 dumpFenceTime(outString, "Display Present \t",
140 !addPostCompositeCalled, *displayPresentFence);
Brian Andersonf6386862016-10-31 16:34:13 -0700141
Yiwei Zhang5434a782018-12-05 18:06:32 -0800142 outString.append("--- DequeueReady \t");
Brian Andersoned816e62016-10-26 16:12:21 -0700143 if (FrameEvents::isValidTimestamp(dequeueReadyTime)) {
Yiwei Zhang5434a782018-12-05 18:06:32 -0800144 StringAppendF(&outString, "%" PRId64 "\n", dequeueReadyTime);
Brian Andersonf6386862016-10-31 16:34:13 -0700145 } else {
Yiwei Zhang5434a782018-12-05 18:06:32 -0800146 outString.append("Pending\n");
Brian Andersonf6386862016-10-31 16:34:13 -0700147 }
148
Brian Anderson3d4039d2016-09-23 16:31:30 -0700149 dumpFenceTime(outString, "Release \t",
150 true, *releaseFence);
Brian Andersond6927fb2016-07-23 23:37:30 -0700151}
152
153
154// ============================================================================
155// FrameEventHistory
156// ============================================================================
157
158namespace {
159
160struct FrameNumberEqual {
Chih-Hung Hsiehaaf62162018-12-20 15:45:04 -0800161 explicit FrameNumberEqual(uint64_t frameNumber) : mFrameNumber(frameNumber) {}
Brian Andersond6927fb2016-07-23 23:37:30 -0700162 bool operator()(const FrameEvents& frame) {
163 return frame.valid && mFrameNumber == frame.frameNumber;
164 }
165 const uint64_t mFrameNumber;
166};
167
168} // namespace
169
Brian Anderson3890c392016-07-25 12:48:08 -0700170FrameEventHistory::~FrameEventHistory() = default;
Brian Andersond6927fb2016-07-23 23:37:30 -0700171
172FrameEvents* FrameEventHistory::getFrame(uint64_t frameNumber) {
173 auto frame = std::find_if(
174 mFrames.begin(), mFrames.end(), FrameNumberEqual(frameNumber));
175 return frame == mFrames.end() ? nullptr : &(*frame);
176}
177
178FrameEvents* FrameEventHistory::getFrame(uint64_t frameNumber, size_t* iHint) {
179 *iHint = std::min(*iHint, mFrames.size());
180 auto hint = mFrames.begin() + *iHint;
181 auto frame = std::find_if(
182 hint, mFrames.end(), FrameNumberEqual(frameNumber));
183 if (frame == mFrames.end()) {
184 frame = std::find_if(
185 mFrames.begin(), hint, FrameNumberEqual(frameNumber));
186 if (frame == hint) {
187 return nullptr;
188 }
189 }
190 *iHint = static_cast<size_t>(std::distance(mFrames.begin(), frame));
191 return &(*frame);
192}
193
194void FrameEventHistory::checkFencesForCompletion() {
195 for (auto& frame : mFrames) {
196 frame.checkFencesForCompletion();
197 }
198}
199
200// Uses !|valid| as the MSB.
201static bool FrameNumberLessThan(
202 const FrameEvents& lhs, const FrameEvents& rhs) {
203 if (lhs.valid == rhs.valid) {
204 return lhs.frameNumber < rhs.frameNumber;
205 }
206 return lhs.valid;
207}
208
Yiwei Zhang5434a782018-12-05 18:06:32 -0800209void FrameEventHistory::dump(std::string& outString) const {
Brian Andersond6927fb2016-07-23 23:37:30 -0700210 auto earliestFrame = std::min_element(
211 mFrames.begin(), mFrames.end(), &FrameNumberLessThan);
212 if (!earliestFrame->valid) {
Yiwei Zhang5434a782018-12-05 18:06:32 -0800213 outString.append("-- N/A\n");
Brian Andersond6927fb2016-07-23 23:37:30 -0700214 return;
215 }
216 for (auto frame = earliestFrame; frame != mFrames.end(); ++frame) {
217 frame->dump(outString);
218 }
219 for (auto frame = mFrames.begin(); frame != earliestFrame; ++frame) {
220 frame->dump(outString);
221 }
222}
223
Brian Andersond6927fb2016-07-23 23:37:30 -0700224
Brian Anderson3890c392016-07-25 12:48:08 -0700225// ============================================================================
226// ProducerFrameEventHistory
227// ============================================================================
Brian Andersond6927fb2016-07-23 23:37:30 -0700228
Brian Anderson3890c392016-07-25 12:48:08 -0700229ProducerFrameEventHistory::~ProducerFrameEventHistory() = default;
230
Brian Anderson0a61b0c2016-12-07 14:55:56 -0800231nsecs_t ProducerFrameEventHistory::snapToNextTick(
232 nsecs_t timestamp, nsecs_t tickPhase, nsecs_t tickInterval) {
233 nsecs_t tickOffset = (tickPhase - timestamp) % tickInterval;
234 // Integer modulo rounds towards 0 and not -inf before taking the remainder,
235 // so adjust the offset if it is negative.
236 if (tickOffset < 0) {
237 tickOffset += tickInterval;
238 }
239 return timestamp + tickOffset;
240}
241
242nsecs_t ProducerFrameEventHistory::getNextCompositeDeadline(
243 const nsecs_t now) const{
244 return snapToNextTick(
245 now, mCompositorTiming.deadline, mCompositorTiming.interval);
246}
247
Brian Anderson3890c392016-07-25 12:48:08 -0700248void ProducerFrameEventHistory::updateAcquireFence(
Brian Anderson3d4039d2016-09-23 16:31:30 -0700249 uint64_t frameNumber, std::shared_ptr<FenceTime>&& acquire) {
Brian Anderson3890c392016-07-25 12:48:08 -0700250 FrameEvents* frame = getFrame(frameNumber, &mAcquireOffset);
Brian Andersond6927fb2016-07-23 23:37:30 -0700251 if (frame == nullptr) {
Brian Anderson8cc8b102016-10-21 12:43:09 -0700252 ALOGE("updateAcquireFence: Did not find frame.");
Brian Andersond6927fb2016-07-23 23:37:30 -0700253 return;
254 }
255
Brian Anderson3890c392016-07-25 12:48:08 -0700256 if (acquire->isValid()) {
Brian Anderson3d4039d2016-09-23 16:31:30 -0700257 mAcquireTimeline.push(acquire);
258 frame->acquireFence = std::move(acquire);
Brian Anderson3890c392016-07-25 12:48:08 -0700259 } else {
260 // If there isn't an acquire fence, assume that buffer was
261 // ready for the consumer when posted.
Brian Anderson3d4039d2016-09-23 16:31:30 -0700262 frame->acquireFence = std::make_shared<FenceTime>(frame->postedTime);
Brian Anderson3890c392016-07-25 12:48:08 -0700263 }
264}
265
Brian Anderson3890c392016-07-25 12:48:08 -0700266void ProducerFrameEventHistory::applyDelta(
267 const FrameEventHistoryDelta& delta) {
Brian Anderson0a61b0c2016-12-07 14:55:56 -0800268 mCompositorTiming = delta.mCompositorTiming;
269
Brian Anderson3890c392016-07-25 12:48:08 -0700270 for (auto& d : delta.mDeltas) {
271 // Avoid out-of-bounds access.
Brian Anderson8cc8b102016-10-21 12:43:09 -0700272 if (CC_UNLIKELY(d.mIndex >= mFrames.size())) {
273 ALOGE("applyDelta: Bad index.");
Brian Anderson3890c392016-07-25 12:48:08 -0700274 return;
275 }
276
277 FrameEvents& frame = mFrames[d.mIndex];
278
279 frame.addPostCompositeCalled = d.mAddPostCompositeCalled != 0;
Brian Anderson3890c392016-07-25 12:48:08 -0700280 frame.addReleaseCalled = d.mAddReleaseCalled != 0;
281
282 frame.postedTime = d.mPostedTime;
283 frame.requestedPresentTime = d.mRequestedPresentTime;
284 frame.latchTime = d.mLatchTime;
285 frame.firstRefreshStartTime = d.mFirstRefreshStartTime;
286 frame.lastRefreshStartTime = d.mLastRefreshStartTime;
Brian Andersonf6386862016-10-31 16:34:13 -0700287 frame.dequeueReadyTime = d.mDequeueReadyTime;
Brian Anderson3890c392016-07-25 12:48:08 -0700288
Brian Anderson3d4039d2016-09-23 16:31:30 -0700289 if (frame.frameNumber != d.mFrameNumber) {
290 // We got a new frame. Initialize some of the fields.
Brian Anderson3890c392016-07-25 12:48:08 -0700291 frame.frameNumber = d.mFrameNumber;
Brian Anderson3d4039d2016-09-23 16:31:30 -0700292 frame.acquireFence = FenceTime::NO_FENCE;
293 frame.gpuCompositionDoneFence = FenceTime::NO_FENCE;
294 frame.displayPresentFence = FenceTime::NO_FENCE;
Brian Anderson3d4039d2016-09-23 16:31:30 -0700295 frame.releaseFence = FenceTime::NO_FENCE;
Brian Anderson3890c392016-07-25 12:48:08 -0700296 // The consumer only sends valid frames.
297 frame.valid = true;
Brian Andersond6927fb2016-07-23 23:37:30 -0700298 }
Brian Anderson3d4039d2016-09-23 16:31:30 -0700299
300 applyFenceDelta(&mGpuCompositionDoneTimeline,
301 &frame.gpuCompositionDoneFence, d.mGpuCompositionDoneFence);
302 applyFenceDelta(&mPresentTimeline,
303 &frame.displayPresentFence, d.mDisplayPresentFence);
Brian Anderson3d4039d2016-09-23 16:31:30 -0700304 applyFenceDelta(&mReleaseTimeline,
305 &frame.releaseFence, d.mReleaseFence);
Brian Andersond6927fb2016-07-23 23:37:30 -0700306 }
307}
308
Brian Anderson3d4039d2016-09-23 16:31:30 -0700309void ProducerFrameEventHistory::updateSignalTimes() {
310 mAcquireTimeline.updateSignalTimes();
311 mGpuCompositionDoneTimeline.updateSignalTimes();
312 mPresentTimeline.updateSignalTimes();
Brian Anderson3d4039d2016-09-23 16:31:30 -0700313 mReleaseTimeline.updateSignalTimes();
314}
315
Brian Anderson3da8d272016-07-28 16:20:47 -0700316void ProducerFrameEventHistory::applyFenceDelta(FenceTimeline* timeline,
317 std::shared_ptr<FenceTime>* dst, const FenceTime::Snapshot& src) const {
Brian Anderson5ea5e592016-12-01 16:54:33 -0800318 if (CC_UNLIKELY(dst == nullptr || dst->get() == nullptr)) {
Brian Anderson3da8d272016-07-28 16:20:47 -0700319 ALOGE("applyFenceDelta: dst is null.");
320 return;
321 }
322
323 switch (src.state) {
324 case FenceTime::Snapshot::State::EMPTY:
325 return;
326 case FenceTime::Snapshot::State::FENCE:
Brian Anderson8cc8b102016-10-21 12:43:09 -0700327 ALOGE_IF((*dst)->isValid(), "applyFenceDelta: Unexpected fence.");
Brian Anderson3da8d272016-07-28 16:20:47 -0700328 *dst = createFenceTime(src.fence);
329 timeline->push(*dst);
330 return;
331 case FenceTime::Snapshot::State::SIGNAL_TIME:
332 if ((*dst)->isValid()) {
333 (*dst)->applyTrustedSnapshot(src);
334 } else {
335 *dst = std::make_shared<FenceTime>(src.signalTime);
336 }
337 return;
338 }
339}
340
341std::shared_ptr<FenceTime> ProducerFrameEventHistory::createFenceTime(
342 const sp<Fence>& fence) const {
343 return std::make_shared<FenceTime>(fence);
344}
345
Brian Anderson3890c392016-07-25 12:48:08 -0700346
347// ============================================================================
348// ConsumerFrameEventHistory
349// ============================================================================
350
351ConsumerFrameEventHistory::~ConsumerFrameEventHistory() = default;
352
Brian Anderson5ea5e592016-12-01 16:54:33 -0800353void ConsumerFrameEventHistory::onDisconnect() {
354 mCurrentConnectId++;
355 mProducerWantsEvents = false;
356}
357
Valerie Hau0ca3f992020-01-30 16:07:35 -0800358void ConsumerFrameEventHistory::setProducerWantsEvents() {
359 mProducerWantsEvents = true;
360}
361
Brian Anderson0a61b0c2016-12-07 14:55:56 -0800362void ConsumerFrameEventHistory::initializeCompositorTiming(
363 const CompositorTiming& compositorTiming) {
364 mCompositorTiming = compositorTiming;
365}
366
Brian Anderson3890c392016-07-25 12:48:08 -0700367void ConsumerFrameEventHistory::addQueue(const NewFrameEventsEntry& newEntry) {
368 // Overwrite all fields of the frame with default values unless set here.
369 FrameEvents newTimestamps;
Brian Anderson5ea5e592016-12-01 16:54:33 -0800370 newTimestamps.connectId = mCurrentConnectId;
Brian Anderson3890c392016-07-25 12:48:08 -0700371 newTimestamps.frameNumber = newEntry.frameNumber;
372 newTimestamps.postedTime = newEntry.postedTime;
373 newTimestamps.requestedPresentTime = newEntry.requestedPresentTime;
374 newTimestamps.acquireFence = newEntry.acquireFence;
375 newTimestamps.valid = true;
376 mFrames[mQueueOffset] = newTimestamps;
Brian Anderson7c3ba8a2016-07-25 12:48:08 -0700377
378 // Note: We avoid sending the acquire fence back to the caller since
379 // they have the original one already, so there is no need to set the
380 // acquire dirty bit.
Brian Anderson3890c392016-07-25 12:48:08 -0700381 mFramesDirty[mQueueOffset].setDirty<FrameEvent::POSTED>();
Brian Anderson3890c392016-07-25 12:48:08 -0700382
383 mQueueOffset = (mQueueOffset + 1) % mFrames.size();
384}
385
386void ConsumerFrameEventHistory::addLatch(
387 uint64_t frameNumber, nsecs_t latchTime) {
388 FrameEvents* frame = getFrame(frameNumber, &mCompositionOffset);
389 if (frame == nullptr) {
Brian Anderson4565daa2016-12-13 15:41:28 -0800390 ALOGE_IF(mProducerWantsEvents, "addLatch: Did not find frame.");
Brian Anderson3890c392016-07-25 12:48:08 -0700391 return;
392 }
393 frame->latchTime = latchTime;
394 mFramesDirty[mCompositionOffset].setDirty<FrameEvent::LATCH>();
395}
396
397void ConsumerFrameEventHistory::addPreComposition(
398 uint64_t frameNumber, nsecs_t refreshStartTime) {
399 FrameEvents* frame = getFrame(frameNumber, &mCompositionOffset);
400 if (frame == nullptr) {
Brian Anderson4565daa2016-12-13 15:41:28 -0800401 ALOGE_IF(mProducerWantsEvents,
402 "addPreComposition: Did not find frame.");
Brian Anderson3890c392016-07-25 12:48:08 -0700403 return;
404 }
405 frame->lastRefreshStartTime = refreshStartTime;
406 mFramesDirty[mCompositionOffset].setDirty<FrameEvent::LAST_REFRESH_START>();
Brian Andersoned816e62016-10-26 16:12:21 -0700407 if (!FrameEvents::isValidTimestamp(frame->firstRefreshStartTime)) {
Brian Anderson3890c392016-07-25 12:48:08 -0700408 frame->firstRefreshStartTime = refreshStartTime;
409 mFramesDirty[mCompositionOffset].setDirty<FrameEvent::FIRST_REFRESH_START>();
410 }
411}
412
413void ConsumerFrameEventHistory::addPostComposition(uint64_t frameNumber,
Brian Anderson3d4039d2016-09-23 16:31:30 -0700414 const std::shared_ptr<FenceTime>& gpuCompositionDone,
Brian Anderson0a61b0c2016-12-07 14:55:56 -0800415 const std::shared_ptr<FenceTime>& displayPresent,
416 const CompositorTiming& compositorTiming) {
417 mCompositorTiming = compositorTiming;
418
Brian Anderson3890c392016-07-25 12:48:08 -0700419 FrameEvents* frame = getFrame(frameNumber, &mCompositionOffset);
420 if (frame == nullptr) {
Brian Anderson4565daa2016-12-13 15:41:28 -0800421 ALOGE_IF(mProducerWantsEvents,
422 "addPostComposition: Did not find frame.");
Brian Anderson3890c392016-07-25 12:48:08 -0700423 return;
424 }
425 // Only get GPU and present info for the first composite.
426 if (!frame->addPostCompositeCalled) {
427 frame->addPostCompositeCalled = true;
428 frame->gpuCompositionDoneFence = gpuCompositionDone;
Brian Andersonb04c6f02016-10-21 12:57:46 -0700429 mFramesDirty[mCompositionOffset].setDirty<FrameEvent::GPU_COMPOSITION_DONE>();
Brian Anderson3890c392016-07-25 12:48:08 -0700430 if (!frame->displayPresentFence->isValid()) {
431 frame->displayPresentFence = displayPresent;
432 mFramesDirty[mCompositionOffset].setDirty<FrameEvent::DISPLAY_PRESENT>();
433 }
434 }
435}
436
Brian Andersonf6386862016-10-31 16:34:13 -0700437void ConsumerFrameEventHistory::addRelease(uint64_t frameNumber,
438 nsecs_t dequeueReadyTime, std::shared_ptr<FenceTime>&& release) {
Brian Andersond6927fb2016-07-23 23:37:30 -0700439 FrameEvents* frame = getFrame(frameNumber, &mReleaseOffset);
Brian Anderson5ea5e592016-12-01 16:54:33 -0800440 if (frame == nullptr) {
441 ALOGE_IF(mProducerWantsEvents, "addRelease: Did not find frame.");
Brian Andersond6927fb2016-07-23 23:37:30 -0700442 return;
443 }
Brian Anderson3890c392016-07-25 12:48:08 -0700444 frame->addReleaseCalled = true;
Brian Andersonf6386862016-10-31 16:34:13 -0700445 frame->dequeueReadyTime = dequeueReadyTime;
Brian Anderson3d4039d2016-09-23 16:31:30 -0700446 frame->releaseFence = std::move(release);
Brian Anderson3890c392016-07-25 12:48:08 -0700447 mFramesDirty[mReleaseOffset].setDirty<FrameEvent::RELEASE>();
Brian Andersond6927fb2016-07-23 23:37:30 -0700448}
449
Brian Anderson3d4039d2016-09-23 16:31:30 -0700450void ConsumerFrameEventHistory::getFrameDelta(
451 FrameEventHistoryDelta* delta,
452 const std::array<FrameEvents, MAX_FRAME_HISTORY>::iterator& frame) {
Brian Anderson4565daa2016-12-13 15:41:28 -0800453 mProducerWantsEvents = true;
Brian Anderson3d4039d2016-09-23 16:31:30 -0700454 size_t i = static_cast<size_t>(std::distance(mFrames.begin(), frame));
455 if (mFramesDirty[i].anyDirty()) {
Brian Anderson5ea5e592016-12-01 16:54:33 -0800456 // Make sure only to send back deltas for the current connection
457 // since the producer won't have the correct state to apply a delta
458 // from a previous connection.
459 if (mFrames[i].connectId == mCurrentConnectId) {
460 delta->mDeltas.emplace_back(i, *frame, mFramesDirty[i]);
461 }
Brian Anderson3d4039d2016-09-23 16:31:30 -0700462 mFramesDirty[i].reset();
463 }
464}
465
Brian Anderson3890c392016-07-25 12:48:08 -0700466void ConsumerFrameEventHistory::getAndResetDelta(
467 FrameEventHistoryDelta* delta) {
Brian Anderson5ea5e592016-12-01 16:54:33 -0800468 mProducerWantsEvents = true;
Brian Anderson0a61b0c2016-12-07 14:55:56 -0800469 delta->mCompositorTiming = mCompositorTiming;
470
Brian Anderson3d4039d2016-09-23 16:31:30 -0700471 // Write these in order of frame number so that it is easy to
472 // add them to a FenceTimeline in the proper order producer side.
Brian Anderson3890c392016-07-25 12:48:08 -0700473 delta->mDeltas.reserve(mFramesDirty.size());
Brian Anderson3d4039d2016-09-23 16:31:30 -0700474 auto earliestFrame = std::min_element(
475 mFrames.begin(), mFrames.end(), &FrameNumberLessThan);
476 for (auto frame = earliestFrame; frame != mFrames.end(); ++frame) {
477 getFrameDelta(delta, frame);
478 }
479 for (auto frame = mFrames.begin(); frame != earliestFrame; ++frame) {
480 getFrameDelta(delta, frame);
Brian Anderson3890c392016-07-25 12:48:08 -0700481 }
482}
483
484
485// ============================================================================
486// FrameEventsDelta
487// ============================================================================
488
489FrameEventsDelta::FrameEventsDelta(
490 size_t index,
491 const FrameEvents& frameTimestamps,
492 const FrameEventDirtyFields& dirtyFields)
493 : mIndex(index),
494 mFrameNumber(frameTimestamps.frameNumber),
495 mAddPostCompositeCalled(frameTimestamps.addPostCompositeCalled),
Brian Anderson3890c392016-07-25 12:48:08 -0700496 mAddReleaseCalled(frameTimestamps.addReleaseCalled),
497 mPostedTime(frameTimestamps.postedTime),
498 mRequestedPresentTime(frameTimestamps.requestedPresentTime),
499 mLatchTime(frameTimestamps.latchTime),
500 mFirstRefreshStartTime(frameTimestamps.firstRefreshStartTime),
Brian Andersonf6386862016-10-31 16:34:13 -0700501 mLastRefreshStartTime(frameTimestamps.lastRefreshStartTime),
502 mDequeueReadyTime(frameTimestamps.dequeueReadyTime) {
Brian Andersonb04c6f02016-10-21 12:57:46 -0700503 if (dirtyFields.isDirty<FrameEvent::GPU_COMPOSITION_DONE>()) {
Brian Anderson3d4039d2016-09-23 16:31:30 -0700504 mGpuCompositionDoneFence =
505 frameTimestamps.gpuCompositionDoneFence->getSnapshot();
506 }
507 if (dirtyFields.isDirty<FrameEvent::DISPLAY_PRESENT>()) {
508 mDisplayPresentFence =
509 frameTimestamps.displayPresentFence->getSnapshot();
510 }
Brian Anderson3d4039d2016-09-23 16:31:30 -0700511 if (dirtyFields.isDirty<FrameEvent::RELEASE>()) {
512 mReleaseFence = frameTimestamps.releaseFence->getSnapshot();
513 }
Brian Anderson3890c392016-07-25 12:48:08 -0700514}
515
Brian Anderson0a61b0c2016-12-07 14:55:56 -0800516constexpr size_t FrameEventsDelta::minFlattenedSize() {
517 return sizeof(FrameEventsDelta::mFrameNumber) +
Brian Anderson4e606e32017-03-16 15:34:57 -0700518 sizeof(uint16_t) + // mIndex
Brian Anderson3890c392016-07-25 12:48:08 -0700519 sizeof(uint8_t) + // mAddPostCompositeCalled
Brian Anderson3890c392016-07-25 12:48:08 -0700520 sizeof(uint8_t) + // mAddReleaseCalled
521 sizeof(FrameEventsDelta::mPostedTime) +
522 sizeof(FrameEventsDelta::mRequestedPresentTime) +
523 sizeof(FrameEventsDelta::mLatchTime) +
524 sizeof(FrameEventsDelta::mFirstRefreshStartTime) +
Brian Andersonf6386862016-10-31 16:34:13 -0700525 sizeof(FrameEventsDelta::mLastRefreshStartTime) +
526 sizeof(FrameEventsDelta::mDequeueReadyTime);
Brian Anderson3890c392016-07-25 12:48:08 -0700527}
528
529// Flattenable implementation
530size_t FrameEventsDelta::getFlattenedSize() const {
531 auto fences = allFences(this);
532 return minFlattenedSize() +
533 std::accumulate(fences.begin(), fences.end(), size_t(0),
Brian Anderson3d4039d2016-09-23 16:31:30 -0700534 [](size_t a, const FenceTime::Snapshot* fence) {
535 return a + fence->getFlattenedSize();
Brian Anderson3890c392016-07-25 12:48:08 -0700536 });
537}
538
539size_t FrameEventsDelta::getFdCount() const {
540 auto fences = allFences(this);
541 return 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->getFdCount();
Brian Anderson3890c392016-07-25 12:48:08 -0700544 });
545}
546
547status_t FrameEventsDelta::flatten(void*& buffer, size_t& size, int*& fds,
548 size_t& count) const {
549 if (size < getFlattenedSize() || count < getFdCount()) {
550 return NO_MEMORY;
551 }
552
553 if (mIndex >= FrameEventHistory::MAX_FRAME_HISTORY ||
Brian Anderson4e606e32017-03-16 15:34:57 -0700554 mIndex > std::numeric_limits<uint16_t>::max()) {
Brian Anderson3890c392016-07-25 12:48:08 -0700555 return BAD_VALUE;
556 }
557
558 FlattenableUtils::write(buffer, size, mFrameNumber);
559
Brian Anderson4e606e32017-03-16 15:34:57 -0700560 // These are static_cast to uint16_t/uint8_t for alignment.
561 FlattenableUtils::write(buffer, size, static_cast<uint16_t>(mIndex));
Brian Anderson3890c392016-07-25 12:48:08 -0700562 FlattenableUtils::write(
563 buffer, size, static_cast<uint8_t>(mAddPostCompositeCalled));
564 FlattenableUtils::write(
Brian Anderson3890c392016-07-25 12:48:08 -0700565 buffer, size, static_cast<uint8_t>(mAddReleaseCalled));
566
567 FlattenableUtils::write(buffer, size, mPostedTime);
568 FlattenableUtils::write(buffer, size, mRequestedPresentTime);
569 FlattenableUtils::write(buffer, size, mLatchTime);
570 FlattenableUtils::write(buffer, size, mFirstRefreshStartTime);
571 FlattenableUtils::write(buffer, size, mLastRefreshStartTime);
Brian Andersonf6386862016-10-31 16:34:13 -0700572 FlattenableUtils::write(buffer, size, mDequeueReadyTime);
Brian Anderson3890c392016-07-25 12:48:08 -0700573
574 // Fences
575 for (auto fence : allFences(this)) {
Brian Anderson3d4039d2016-09-23 16:31:30 -0700576 status_t status = fence->flatten(buffer, size, fds, count);
Brian Anderson3890c392016-07-25 12:48:08 -0700577 if (status != NO_ERROR) {
578 return status;
579 }
580 }
581 return NO_ERROR;
582}
583
584status_t FrameEventsDelta::unflatten(void const*& buffer, size_t& size,
585 int const*& fds, size_t& count) {
586 if (size < minFlattenedSize()) {
587 return NO_MEMORY;
588 }
589
590 FlattenableUtils::read(buffer, size, mFrameNumber);
591
Brian Anderson4e606e32017-03-16 15:34:57 -0700592 // These were written as uint16_t/uint8_t for alignment.
593 uint16_t temp16 = 0;
594 FlattenableUtils::read(buffer, size, temp16);
595 mIndex = temp16;
Brian Anderson3890c392016-07-25 12:48:08 -0700596 if (mIndex >= FrameEventHistory::MAX_FRAME_HISTORY) {
597 return BAD_VALUE;
598 }
Brian Anderson4e606e32017-03-16 15:34:57 -0700599 uint8_t temp8 = 0;
600 FlattenableUtils::read(buffer, size, temp8);
601 mAddPostCompositeCalled = static_cast<bool>(temp8);
602 FlattenableUtils::read(buffer, size, temp8);
603 mAddReleaseCalled = static_cast<bool>(temp8);
Brian Anderson3890c392016-07-25 12:48:08 -0700604
605 FlattenableUtils::read(buffer, size, mPostedTime);
606 FlattenableUtils::read(buffer, size, mRequestedPresentTime);
607 FlattenableUtils::read(buffer, size, mLatchTime);
608 FlattenableUtils::read(buffer, size, mFirstRefreshStartTime);
609 FlattenableUtils::read(buffer, size, mLastRefreshStartTime);
Brian Andersonf6386862016-10-31 16:34:13 -0700610 FlattenableUtils::read(buffer, size, mDequeueReadyTime);
Brian Anderson3890c392016-07-25 12:48:08 -0700611
612 // Fences
613 for (auto fence : allFences(this)) {
Brian Anderson3d4039d2016-09-23 16:31:30 -0700614 status_t status = fence->unflatten(buffer, size, fds, count);
Brian Anderson3890c392016-07-25 12:48:08 -0700615 if (status != NO_ERROR) {
616 return status;
617 }
618 }
619 return NO_ERROR;
620}
621
622
623// ============================================================================
624// FrameEventHistoryDelta
625// ============================================================================
626
Brian Anderson3d4039d2016-09-23 16:31:30 -0700627FrameEventHistoryDelta& FrameEventHistoryDelta::operator=(
Chih-Hung Hsieh5bc849f2018-09-25 14:21:50 -0700628 FrameEventHistoryDelta&& src) noexcept {
Brian Anderson0a61b0c2016-12-07 14:55:56 -0800629 mCompositorTiming = src.mCompositorTiming;
630
Brian Anderson3d4039d2016-09-23 16:31:30 -0700631 if (CC_UNLIKELY(!mDeltas.empty())) {
Brian Anderson8cc8b102016-10-21 12:43:09 -0700632 ALOGE("FrameEventHistoryDelta assign clobbering history.");
Brian Anderson3d4039d2016-09-23 16:31:30 -0700633 }
634 mDeltas = std::move(src.mDeltas);
Brian Anderson3d4039d2016-09-23 16:31:30 -0700635 return *this;
636}
637
Brian Anderson0a61b0c2016-12-07 14:55:56 -0800638constexpr size_t FrameEventHistoryDelta::minFlattenedSize() {
639 return sizeof(uint32_t) + // mDeltas.size()
640 sizeof(mCompositorTiming);
Brian Anderson3890c392016-07-25 12:48:08 -0700641}
642
643size_t FrameEventHistoryDelta::getFlattenedSize() const {
644 return minFlattenedSize() +
645 std::accumulate(mDeltas.begin(), mDeltas.end(), size_t(0),
646 [](size_t a, const FrameEventsDelta& delta) {
647 return a + delta.getFlattenedSize();
648 });
649}
650
651size_t FrameEventHistoryDelta::getFdCount() const {
652 return std::accumulate(mDeltas.begin(), mDeltas.end(), size_t(0),
653 [](size_t a, const FrameEventsDelta& delta) {
654 return a + delta.getFdCount();
655 });
656}
657
658status_t FrameEventHistoryDelta::flatten(
659 void*& buffer, size_t& size, int*& fds, size_t& count) const {
660 if (mDeltas.size() > FrameEventHistory::MAX_FRAME_HISTORY) {
661 return BAD_VALUE;
662 }
663 if (size < getFlattenedSize()) {
664 return NO_MEMORY;
665 }
666
Brian Anderson0a61b0c2016-12-07 14:55:56 -0800667 FlattenableUtils::write(buffer, size, mCompositorTiming);
668
Brian Anderson3890c392016-07-25 12:48:08 -0700669 FlattenableUtils::write(
670 buffer, size, static_cast<uint32_t>(mDeltas.size()));
671 for (auto& d : mDeltas) {
672 status_t status = d.flatten(buffer, size, fds, count);
673 if (status != NO_ERROR) {
674 return status;
675 }
676 }
677 return NO_ERROR;
678}
679
680status_t FrameEventHistoryDelta::unflatten(
681 void const*& buffer, size_t& size, int const*& fds, size_t& count) {
682 if (size < minFlattenedSize()) {
683 return NO_MEMORY;
684 }
685
Brian Anderson0a61b0c2016-12-07 14:55:56 -0800686 FlattenableUtils::read(buffer, size, mCompositorTiming);
687
Brian Anderson3890c392016-07-25 12:48:08 -0700688 uint32_t deltaCount = 0;
689 FlattenableUtils::read(buffer, size, deltaCount);
690 if (deltaCount > FrameEventHistory::MAX_FRAME_HISTORY) {
691 return BAD_VALUE;
692 }
693 mDeltas.resize(deltaCount);
694 for (auto& d : mDeltas) {
695 status_t status = d.unflatten(buffer, size, fds, count);
696 if (status != NO_ERROR) {
697 return status;
698 }
699 }
700 return NO_ERROR;
701}
702
703
Brian Andersond6927fb2016-07-23 23:37:30 -0700704} // namespace android